XmlStringBuilder.java

  1. /**
  2.  *
  3.  * Copyright 2014 Florian Schmaus
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smack.util;

  18. import java.util.Collection;

  19. import org.jivesoftware.smack.packet.Element;
  20. import org.jivesoftware.smack.packet.NamedElement;
  21. import org.jivesoftware.smack.packet.ExtensionElement;

  22. public class XmlStringBuilder implements Appendable, CharSequence {
  23.     public static final String RIGHT_ANGLE_BRACKET = Character.toString('>');

  24.     private final LazyStringBuilder sb;

  25.     public XmlStringBuilder() {
  26.         sb = new LazyStringBuilder();
  27.     }

  28.     public XmlStringBuilder(ExtensionElement pe) {
  29.         this();
  30.         prelude(pe);
  31.     }

  32.     public XmlStringBuilder(NamedElement e) {
  33.         this();
  34.         halfOpenElement(e.getElementName());
  35.     }

  36.     public XmlStringBuilder escapedElement(String name, String escapedContent) {
  37.         assert escapedContent != null;
  38.         openElement(name);
  39.         append(escapedContent);
  40.         closeElement(name);
  41.         return this;
  42.     }

  43.     /**
  44.      *
  45.      * @param name
  46.      * @param content
  47.      * @return the XmlStringBuilder
  48.      */
  49.     public XmlStringBuilder element(String name, String content) {
  50.         assert content != null;
  51.         openElement(name);
  52.         escape(content);
  53.         closeElement(name);
  54.         return this;
  55.     }

  56.     /**
  57.     *
  58.     * @param name
  59.     * @param content
  60.     * @return the XmlStringBuilder
  61.     */
  62.    public XmlStringBuilder element(String name, CharSequence content) {
  63.        return element(name, content.toString());
  64.    }

  65.     public XmlStringBuilder element(String name, Enum<?> content) {
  66.         assert content != null;
  67.         element(name, content.name());
  68.         return this;
  69.     }

  70.     public XmlStringBuilder element(Element element) {
  71.         assert element != null;
  72.         return append(element.toXML());
  73.     }

  74.     public XmlStringBuilder optElement(String name, String content) {
  75.         if (content != null) {
  76.             element(name, content);
  77.         }
  78.         return this;
  79.     }

  80.     public XmlStringBuilder optElement(String name, CharSequence content) {
  81.         if (content != null) {
  82.             element(name, content.toString());
  83.         }
  84.         return this;
  85.     }

  86.     public XmlStringBuilder optElement(Element element) {
  87.         if (element != null) {
  88.             append(element.toXML());
  89.         }
  90.         return this;
  91.     }

  92.     public XmlStringBuilder optElement(String name, Enum<?> content) {
  93.         if (content != null) {
  94.             element(name, content);
  95.         }
  96.         return this;
  97.     }

  98.     public XmlStringBuilder optIntElement(String name, int value) {
  99.         if (value >= 0) {
  100.             element(name, String.valueOf(value));
  101.         }
  102.         return this;
  103.     }

  104.     public XmlStringBuilder halfOpenElement(String name) {
  105.         assert(StringUtils.isNotEmpty(name));
  106.         sb.append('<').append(name);
  107.         return this;
  108.     }

  109.     public XmlStringBuilder halfOpenElement(NamedElement namedElement) {
  110.         return halfOpenElement(namedElement.getElementName());
  111.     }

  112.     public XmlStringBuilder openElement(String name) {
  113.         halfOpenElement(name).rightAngleBracket();
  114.         return this;
  115.     }

  116.     public XmlStringBuilder closeElement(String name) {
  117.         sb.append("</").append(name);
  118.         rightAngleBracket();
  119.         return this;
  120.     }

  121.     public XmlStringBuilder closeElement(NamedElement e) {
  122.         closeElement(e.getElementName());
  123.         return this;
  124.     }

  125.     public XmlStringBuilder closeEmptyElement() {
  126.         sb.append("/>");
  127.         return this;
  128.     }

  129.     /**
  130.      * Add a right angle bracket '>'
  131.      *
  132.      * @return a reference to this object.
  133.      */
  134.     public XmlStringBuilder rightAngleBracket() {
  135.         sb.append(RIGHT_ANGLE_BRACKET);
  136.         return this;
  137.     }

  138.     /**
  139.      *
  140.      * @return a reference to this object
  141.      * @deprecated use {@link #rightAngleBracket()} instead
  142.      */
  143.     @Deprecated
  144.     public XmlStringBuilder rightAngelBracket() {
  145.         return rightAngleBracket();
  146.     }

  147.     /**
  148.      * Does nothing if value is null.
  149.      *
  150.      * @param name
  151.      * @param value
  152.      * @return the XmlStringBuilder
  153.      */
  154.     public XmlStringBuilder attribute(String name, String value) {
  155.         assert value != null;
  156.         sb.append(' ').append(name).append("='");
  157.         escape(value);
  158.         sb.append('\'');
  159.         return this;
  160.     }

  161.     public XmlStringBuilder attribute(String name, CharSequence value) {
  162.         return attribute(name, value.toString());
  163.     }

  164.     public XmlStringBuilder attribute(String name, Enum<?> value) {
  165.         assert value != null;
  166.         attribute(name, value.name());
  167.         return this;
  168.     }

  169.     public XmlStringBuilder attribute(String name, int value) {
  170.         assert name != null;
  171.         return attribute(name, String.valueOf(value));
  172.     }

  173.     public XmlStringBuilder optAttribute(String name, String value) {
  174.         if (value != null) {
  175.             attribute(name, value);
  176.         }
  177.         return this;
  178.     }

  179.     public XmlStringBuilder optAttribute(String name, CharSequence value) {
  180.         if (value != null) {
  181.             attribute(name, value.toString());
  182.         }
  183.         return this;
  184.     }

  185.     public XmlStringBuilder optAttribute(String name, Enum<?> value) {
  186.         if (value != null) {
  187.             attribute(name, value.toString());
  188.         }
  189.         return this;
  190.     }

  191.     /**
  192.      * Add the given attribute if value => 0
  193.      *
  194.      * @param name
  195.      * @param value
  196.      * @return a reference to this object
  197.      */
  198.     public XmlStringBuilder optIntAttribute(String name, int value) {
  199.         if (value >= 0) {
  200.             attribute(name, Integer.toString(value));
  201.         }
  202.         return this;
  203.     }

  204.     /**
  205.      * Add the given attribute if value not null and value => 0.
  206.      *
  207.      * @param name
  208.      * @param value
  209.      * @return a reference to this object
  210.      */
  211.     public XmlStringBuilder optLongAttribute(String name, Long value) {
  212.         if (value != null && value >= 0) {
  213.             attribute(name, Long.toString(value));
  214.         }
  215.         return this;
  216.     }

  217.     public XmlStringBuilder optBooleanAttribute(String name, boolean bool) {
  218.         if (bool) {
  219.             sb.append(' ').append(name).append("='true'");
  220.         }
  221.         return this;
  222.     }

  223.     public XmlStringBuilder xmlnsAttribute(String value) {
  224.         optAttribute("xmlns", value);
  225.         return this;
  226.     }

  227.     public XmlStringBuilder xmllangAttribute(String value) {
  228.         optAttribute("xml:lang", value);
  229.         return this;
  230.     }
  231.  
  232.     public XmlStringBuilder escape(String text) {
  233.         assert text != null;
  234.         sb.append(StringUtils.escapeForXML(text));
  235.         return this;
  236.     }

  237.     public XmlStringBuilder escape(CharSequence text) {
  238.         return escape(text.toString());
  239.     }

  240.     public XmlStringBuilder prelude(ExtensionElement pe) {
  241.         return prelude(pe.getElementName(), pe.getNamespace());
  242.     }

  243.     public XmlStringBuilder prelude(String elementName, String namespace) {
  244.         halfOpenElement(elementName);
  245.         xmlnsAttribute(namespace);
  246.         return this;
  247.     }

  248.     public XmlStringBuilder optAppend(CharSequence csq) {
  249.         if (csq != null) {
  250.             append(csq);
  251.         }
  252.         return this;
  253.     }

  254.     public XmlStringBuilder optAppend(Element element) {
  255.         if (element != null) {
  256.             append(element.toXML());
  257.         }
  258.         return this;
  259.     }

  260.     public XmlStringBuilder append(XmlStringBuilder xsb) {
  261.         assert xsb != null;
  262.         sb.append(xsb.sb);
  263.         return this;
  264.     }

  265.     public XmlStringBuilder append(Collection<? extends Element> elements) {
  266.         for (Element element : elements) {
  267.             append(element.toXML());
  268.         }
  269.         return this;
  270.     }

  271.     public XmlStringBuilder emptyElement(Enum<?> element) {
  272.         return emptyElement(element.name());
  273.     }

  274.     public XmlStringBuilder emptyElement(String element) {
  275.         halfOpenElement(element);
  276.         return closeEmptyElement();
  277.     }

  278.     public XmlStringBuilder condEmptyElement(boolean condition, String element) {
  279.         if (condition) {
  280.             emptyElement(element);
  281.         }
  282.         return this;
  283.     }

  284.     public XmlStringBuilder condAttribute(boolean condition, String name, String value) {
  285.         if (condition) {
  286.             attribute(name, value);
  287.         }
  288.         return this;
  289.     }

  290.     @Override
  291.     public XmlStringBuilder append(CharSequence csq) {
  292.         assert csq != null;
  293.         sb.append(csq);
  294.         return this;
  295.     }

  296.     @Override
  297.     public XmlStringBuilder append(CharSequence csq, int start, int end) {
  298.         assert csq != null;
  299.         sb.append(csq, start, end);
  300.         return this;
  301.     }

  302.     @Override
  303.     public XmlStringBuilder append(char c) {
  304.         sb.append(c);
  305.         return this;
  306.     }

  307.     @Override
  308.     public int length() {
  309.         return sb.length();
  310.     }

  311.     @Override
  312.     public char charAt(int index) {
  313.         return sb.charAt(index);
  314.     }

  315.     @Override
  316.     public CharSequence subSequence(int start, int end) {
  317.         return sb.subSequence(start, end);
  318.     }

  319.     @Override
  320.     public String toString() {
  321.         return sb.toString();
  322.     }

  323.     @Override
  324.     public boolean equals(Object other) {
  325.         if (!(other instanceof CharSequence)) {
  326.             return false;
  327.         }
  328.         CharSequence otherCharSequenceBuilder = (CharSequence) other;
  329.         return toString().equals(otherCharSequenceBuilder.toString());
  330.     }

  331.     @Override
  332.     public int hashCode() {
  333.         return toString().hashCode();
  334.     }
  335. }