    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
    020package org.apache.wiki.util;
    021
    022import org.jdom2.Element;
    023import org.jdom2.output.Format;
    024import 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 */
    054public final class XhtmlUtil {
    055
    056    private XhtmlUtil() {}
    057
    058    /** to print <td></td> instead of <td /> */
    059    public static final Format EXPAND_EMPTY_NODES = Format.getCompactFormat().setExpandEmptyElements( true );
    060
    061    /**
    062     *  Serializes the Element to a String using a compact serialization format.
    063     *
    064     * @param element  the element to serialize.
    065     * @return the serialized Element.
    066     */
    067    public static String serialize(final Element element ) {
    068        return serialize( element, false );
    069    }
    070
    071    /**
    072     *  Serializes the Element to a String. If <tt>pretty</tt> is true,
    073     *  uses a pretty whitespace format, otherwise a compact format.
    074     *
    075     * @param element  the element to serialize.
    076     * @param pretty   if true, use a pretty whitespace format.
    077     * @return the serialized Element.
    078     */
    079    public static String serialize(final Element element, final boolean pretty ) {
    080        return serialize( element,pretty ? Format.getPrettyFormat() : Format.getCompactFormat() );
    081    }
    082
    083    /**
    084     *  Serializes the Element to a String. Allows to use a custom <tt>format</tt>.
    085     *
    086     * @param element  the element to serialize.
    087     * @param format   custom <tt>format</tt> used to serialize the Element.
    088     * @return the serialized Element.
    089     */
    090    public static String serialize(final Element element, final Format format ) {
    091        final XMLOutputter out = new XMLOutputter( format );
    092        return out.outputString( element );
    093    }
    094
    095    /**
    096     *  Return an Element with an element type name matching the parameter.
    097     *
    098     * @param element  the XHTML element type.
    099     * @return a JDOM2 Element.
    100     */
    101    public static Element element(final XHTML element ) {
    102        return element( element, null );
    103    }
    104
    105    /**
    106     *  Return an Element with an element type name matching the parameter,
    107     *  and optional PCDATA (parsed character data, a String) content.
    108     *
    109     * @param element  the XHTML element type.
    110     * @param content  the optional PCDATA content.
    111     * @return a JDOM2 Element.
    112     */
    113    public static Element element(final XHTML element, final String content ) {
    114        final Element elt = new Element( element.name() );
    115        if( content != null ) {
    116            elt.addContent( content );
    117        }
    118        return elt;
    119    }
    120
    121    /**
    122     *  Return an XHTML link with a required 'href' attribute value and optional link (PCDATA) content.
    123     *
    124     * @param href     the required 'href' value.
    125     * @param content  the optional link (PCDATA) content.
    126     * @return a JDOM2 Element.
    127     */
    128    public static Element link(final String href, final String content ) {
    129        if( href == null ) {
    130            throw new IllegalArgumentException("missing 'href' attribute value.");
    131        }
    132        return fLink(href,content,null);
    133    }
    134
    135    /**
    136     *  Return an XHTML link target with a required 'id' attribute value.
    137     *
    138     * @param id    the required 'id' link target value.
    139     * @return a JDOM2 Element.
    140     */
    141    public static Element target(final String id, final String content ) {
    142        if( id == null ) {
    143            throw new IllegalArgumentException( "missing 'id' attribute value." );
    144        }
    145        return fLink( null, content, id );
    146    }
    147
    148    /**
    149     *  Return an XHTML link with an optional 'href' attribute, optional
    150     *  link content, and optional 'id' link target value.
    151     *
    152     * @param href     the optional 'href' value.
    153     * @param content  the optional link (PCDATA) content.
    154     * @param id       the optional 'id' link target value.
    155     * @return a JDOM2 Element.
    156     */
    157    private static Element fLink(final String href, final String content, final String id ) {
    158        final Element a = element( XHTML.a );
    159        if( href != null ) {
    160            a.setAttribute( XHTML.ATTR_href, href );
    161        }
    162        if( content != null ) {
    163            a.addContent( content );
    164        }
    165        if( id != null ) {
    166            a.setAttribute( XHTML.ATTR_id, id );
    167        }
    168        return a;
    169    }
    170
    171    /**
    172     *  Return an XHTML <tt>img</tt> element with an required 'src' attribute
    173     *  and optional 'alt' alternative text value.
    174     *
    175     * @param src      the required 'src' value.
    176     * @param alt      the optional 'alt' alternative text value.
    177     * @return a JDOM2 Element.
    178     */
    179    public static Element img(final String src, final String alt ) {
    180        final Element img = element( XHTML.img );
    181        if( src == null ) {
    182            throw new IllegalArgumentException( "missing 'src' attribute value." );
    183        }
    184        img.setAttribute( XHTML.ATTR_src, src );
    185        if( alt != null ) {
    186            img.setAttribute( XHTML.ATTR_alt, alt );
    187        }
    188        return img;
    189    }
    190
    191    /**
    192     *  Return an XHTML form <tt>input</tt> element with optional 'type', 'name' and 'value' attributes.
    193     *
    194     * @param type   the optional 'type' value.
    195     * @param name   the optional 'name' value.
    196     * @param value  the optional 'value' value.
    197     * @return a JDOM2 Element.
    198     */
    199    public static Element input(final String type, final String name, final String value ) {
    200        final Element input = element( XHTML.input );
    201        if( type != null ) {
    202            input.setAttribute( XHTML.ATTR_type, type );
    203        }
    204        if( name != null ) {
    205            input.setAttribute( XHTML.ATTR_name, name );
    206        }
    207        if( value != null ) {
    208            input.setAttribute( XHTML.ATTR_value, value );
    209        }
    210        return input;
    211    }
    212
    213    public static void setClass(final Element element, final String classValue ) {
    214        if( classValue == null ) {
    215            throw new IllegalArgumentException( "missing 'class' attribute value." );
    216        }
    217        element.setAttribute( XHTML.ATTR_class, classValue );
    218    }
    219
    220}