001    /* 
002        Licensed to the Apache Software Foundation (ASF) under one
003        or more contributor license agreements.  See the NOTICE file
004        distributed with this work for additional information
005        regarding copyright ownership.  The ASF licenses this file
006        to you under the Apache License, Version 2.0 (the
007        "License"); you may not use this file except in compliance
008        with the License.  You may obtain a copy of the License at
009    
010           http://www.apache.org/licenses/LICENSE-2.0
011    
012        Unless required by applicable law or agreed to in writing,
013        software distributed under the License is distributed on an
014        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015        KIND, either express or implied.  See the License for the
016        specific language governing permissions and limitations
017        under the License.  
018     */
019    
020    package org.apache.wiki.util;
021    
022    import org.jdom2.Element;
023    import org.jdom2.output.Format;
024    import org.jdom2.output.XMLOutputter;
025    
026    /**
027     *  A utility class to generate XHTML objects and ultimately, serialised markup.
028     *  This class is incomplete but serves as a basic utility for JSPWiki, to be
029     *  expanded upon as needed.
030     *  <p>
031     *  This uses JDOM2 as its backing implementation.
032     *  </p>
033     *  
034     *  <h3>Example</h3>
035     *  <p>
036     *  To generate a single element, an Element with PCDATA content, and then
037     *  embed the latter in the former:
038     *  </p>
039     *  <pre>
040     *    Element div = XhtmlUtil.element(XHTML.div);
041     *    Element p   = XhtmlUtil.element(XHTML.p,"Some content");
042     *    div.addContent(p);
043     *  </pre>
044     *  <p>
045     *  There is also a convenient link and link target constructor methods:
046     *  </p>
047     *  <pre>
048     *    Element link   = XhtmlUtil.link("hrefValue","linkText");
049     *    Element target = XhtmlUtil.target("targetIdValue","linkText");
050     *  </pre>
051     *
052     * @since 2.10
053     */
054    public final class XhtmlUtil {
055        
056        private XhtmlUtil() {}
057        
058        /**
059         *  Serializes the Element to a String using a compact serialization format.
060         *  
061         * @param element  the element to serialize.
062         * @return the serialized Element.
063         */
064        public static String serialize( Element element ) { 
065            return serialize( element, false );
066        }
067    
068        /**
069         *  Serializes the Element to a String. If <tt>pretty</tt> is true,
070         *  uses a pretty whitespace format, otherwise a compact format.
071         *  
072         * @param element  the element to serialize.
073         * @param pretty   if true, use a pretty whitespace format.
074         * @return the serialized Element.
075         */
076        public static String serialize( Element element, boolean pretty ) {
077            return serialize( element,pretty ? Format.getPrettyFormat() : Format.getCompactFormat() );
078        }
079    
080        /**
081         *  Serializes the Element to a String. Allows to use a custom <tt>format</tt>.
082         *  
083         * @param element  the element to serialize.
084         * @param format   custom <tt>format</tt> used to serialize the Element.
085         * @return the serialized Element.
086         */
087        public static String serialize( Element element, Format format ) {
088            XMLOutputter out = new XMLOutputter( format );
089            return out.outputString( element );
090        }
091        
092        /**
093         *  Return an Element with an element type name matching the parameter.
094         *  
095         * @param element  the XHTML element type.
096         * @return a JDOM2 Element.
097         */
098        public static Element element( XHTML element ) {
099            return element( element, null );
100        }
101    
102        /**
103         *  Return an Element with an element type name matching the parameter,
104         *  and optional PCDATA (parsed character data, a String) content.
105         *  
106         * @param element  the XHTML element type.
107         * @param content  the optional PCDATA content.
108         * @return a JDOM2 Element.
109         */
110        public static Element element( XHTML element, String content ) {
111            Element elt = new Element( element.name() );
112            if( content != null ) {
113                elt.addContent( content );
114            }
115            return elt;
116        }
117    
118        /**
119         *  Return an XHTML link with a required 'href' attribute value and optional link (PCDATA) content.
120         *  
121         * @param href     the required 'href' value.
122         * @param content  the optional link (PCDATA) content.
123         * @return a JDOM2 Element.
124         */
125        public static Element link( String href, String content ) {
126            if( href == null ) {
127                throw new IllegalArgumentException("missing 'href' attribute value.");
128            }
129            return fLink(href,content,null);
130        }
131        
132        /**
133         *  Return an XHTML link target with a required 'id' attribute value.
134         *  
135         * @param id    the required 'id' link target value.
136         * @return a JDOM2 Element.
137         */
138        public static Element target( String id, String content ) {
139            if( id == null ) {
140                throw new IllegalArgumentException( "missing 'id' attribute value." );
141            }
142            return fLink( null, content, id );
143        }
144        
145        /**
146         *  Return an XHTML link with an optional 'href' attribute, optional
147         *  link content, and optional 'id' link target value.
148         *  
149         * @param href     the optional 'href' value.
150         * @param content  the optional link (PCDATA) content.
151         * @param id       the optional 'id' link target value.
152         * @return a JDOM2 Element.
153         */
154        private static Element fLink( String href, String content, String id ) {
155            Element a = element( XHTML.a );
156            if( href != null ) {
157                a.setAttribute( XHTML.ATTR_href, href );
158            }        
159            if( content != null ) {
160                a.addContent( content );
161            }
162            if( id != null ) {
163                a.setAttribute( XHTML.ATTR_id, id );   
164            }
165            return a;
166        }
167        
168        /**
169         *  Return an XHTML <tt>img</tt> element with an required 'src' attribute
170         *  and optional 'alt' alternative text value.
171         *  
172         * @param src      the required 'src' value.
173         * @param alt      the optional 'alt' alternative text value.
174         * @return a JDOM2 Element.
175         */
176        public static Element img( String src, String alt ) {
177            Element img = element( XHTML.img );
178            if( src == null ) {
179                throw new IllegalArgumentException( "missing 'src' attribute value." );
180            }
181            img.setAttribute( XHTML.ATTR_href, src );
182            if( alt != null ) {
183                img.setAttribute( XHTML.ATTR_alt, alt );   
184            }
185            return img;
186        }
187        
188        /**
189         *  Return an XHTML form <tt>input</tt> element with optional 'type', 'name' and 'value' attributes.
190         *  
191         * @param type   the optional 'type' value.
192         * @param name   the optional 'name' value.
193         * @param value  the optional 'value' value.
194         * @return a JDOM2 Element.
195         */
196        public static Element input( String type, String name, String value ) {
197            Element input = element( XHTML.input );
198            if( type != null ) {
199                input.setAttribute( XHTML.ATTR_type, type );
200            }
201            if( name != null ) {
202                input.setAttribute( XHTML.ATTR_name, name );   
203            }
204            if( value != null ) {
205                input.setAttribute( XHTML.ATTR_value, value );   
206            }
207            return input;
208        }
209        
210        public static void setClass( Element element, String classValue ) {
211            if( classValue == null ) {
212                throw new IllegalArgumentException( "missing 'class' attribute value." );
213            }
214            element.setAttribute( XHTML.ATTR_class, classValue );
215        }
216        
217    }