diff options
Diffstat (limited to 'subsonic-main/src/main/java/net/sourceforge/subsonic/util/XMLBuilder.java')
-rw-r--r-- | subsonic-main/src/main/java/net/sourceforge/subsonic/util/XMLBuilder.java | 328 |
1 files changed, 0 insertions, 328 deletions
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/XMLBuilder.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/util/XMLBuilder.java deleted file mode 100644 index a572ac0f..00000000 --- a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/XMLBuilder.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - This file is part of Subsonic. - - Subsonic is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Subsonic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Subsonic. If not, see <http://www.gnu.org/licenses/>. - - Copyright 2009 (C) Sindre Mehus - */ -package net.sourceforge.subsonic.util; - -import org.apache.commons.lang.StringEscapeUtils; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.XML; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Stack; - - -/** - * Simplifies building of XML documents. - * <p/> - * <b>Example:</b><br/> - * The following code: - * <pre> - * XMLBuilder builder = XMLBuilder.createXMLBuilder(); - * builder.add("foo").add("bar"); - * builder.add("zonk", 42); - * builder.end().end(); - * System.out.println(builder.toString()); - * </pre> - * produces the following XML: - * <pre> - * <foo> - * <bar> - * <zonk>42</zonk> - * </bar> - * </foo> - * </pre> - * This class is <em>not</em> thread safe. - * <p/> - * Also supports JSON and JSONP formats. - * - * @author Sindre Mehus - */ -public class XMLBuilder { - - private static final String INDENTATION = " "; - private static final String NEWLINE = "\n"; - - private final Writer writer = new StringWriter(); - private final Stack<String> elementStack = new Stack<String>(); - private final boolean json; - private final String jsonpCallback; - - public static XMLBuilder createXMLBuilder() { - return new XMLBuilder(false, null); - } - - public static XMLBuilder createJSONBuilder() { - return new XMLBuilder(true, null); - } - - public static XMLBuilder createJSONPBuilder(String callback) { - return new XMLBuilder(true, callback); - } - - /** - * Creates a new instance. - * - * @param json Whether to produce JSON rather than XML. - * @param jsonpCallback Name of javascript callback for JSONP. - */ - private XMLBuilder(boolean json, String jsonpCallback) { - this.json = json; - this.jsonpCallback = jsonpCallback; - } - - /** - * Adds an XML preamble, with the given encoding. The preamble will typically - * look like this: - * <p/> - * <code><?xml version="1.0" encoding="UTF-8"?></code> - * - * @param encoding The encoding to put in the preamble. - * @return A reference to this object. - */ - public XMLBuilder preamble(String encoding) throws IOException { - writer.write("<?xml version=\"1.0\" encoding=\""); - writer.write(encoding); - writer.write("\"?>"); - newline(); - return this; - } - - /** - * Adds an element with the given name and a single attribute. - * - * @param element The element name. - * @param attributeKey The attributes key. - * @param attributeValue The attributes value. - * @param close Whether to close the element. - * @return A reference to this object. - */ - public XMLBuilder add(String element, String attributeKey, Object attributeValue, boolean close) throws IOException { - return add(element, close, new Attribute(attributeKey, attributeValue)); - } - - /** - * Adds an element with the given name and attributes. - * - * @param element The element name. - * @param close Whether to close the element. - * @param attributes The element attributes. - * @return A reference to this object. - */ - public XMLBuilder add(String element, boolean close, Attribute... attributes) throws IOException { - return add(element, Arrays.asList(attributes), close); - } - - /** - * Adds an element with the given name and attributes. - * - * @param element The element name. - * @param attributes The element attributes. - * @param close Whether to close the element. - * @return A reference to this object. - */ - public XMLBuilder add(String element, Iterable<Attribute> attributes, boolean close) throws IOException { - return add(element, attributes, null, close); - } - - /** - * Adds an element with the given name, attributes and character data. - * - * @param element The element name. - * @param attributes The element attributes. - * @param text The character data. - * @param close Whether to close the element. - * @return A reference to this object. - */ - public XMLBuilder add(String element, Iterable<Attribute> attributes, String text, boolean close) throws IOException { - indent(); - elementStack.push(element); - writer.write('<'); - writer.write(element); - - if (attributes == null) { - attributes = Collections.emptyList(); - } - - Iterator<Attribute> iterator = attributes.iterator(); - - if (iterator.hasNext()) { - writer.write(' '); - } - while (iterator.hasNext()) { - Attribute attribute = iterator.next(); - attribute.append(writer); - if (iterator.hasNext()) { - writer.write(' '); - } - } - - if (close && text == null) { - elementStack.pop(); - writer.write("/>"); - } else { - writer.write('>'); - } - - if (text != null) { - writer.write(text); - - if (close) { - elementStack.pop(); - writer.write("</"); - writer.write(element); - writer.write('>'); - } - } - - newline(); - return this; - } - - /** - * Closes the current element. - * - * @return A reference to this object. - * @throws IllegalStateException If there are no unclosed elements. - */ - public XMLBuilder end() throws IllegalStateException, IOException { - if (elementStack.isEmpty()) { - throw new IllegalStateException("There are no unclosed elements."); - } - - String element = elementStack.pop(); - indent(); - writer.write("</"); - writer.write(element); - writer.write('>'); - newline(); - return this; - } - - /** - * Closes all unclosed elements. - * - * @return A reference to this object. - */ - public XMLBuilder endAll() throws IOException { - while (!elementStack.isEmpty()) { - end(); - } - return this; - } - - /** - * Returns the XML document as a string. - */ - @Override - public String toString() { - String xml = writer.toString(); - if (!json) { - return xml; - } - try { - JSONObject jsonObject = XML.toJSONObject(xml); - - if (jsonpCallback != null) { - return jsonpCallback + "(" + jsonObject.toString(1) + ");"; - } - - return jsonObject.toString(1); - } catch (JSONException x) { - throw new RuntimeException("Failed to convert from XML to JSON.", x); - } - } - - private void indent() throws IOException { - int depth = elementStack.size(); - for (int i = 0; i < depth; i++) { - writer.write(INDENTATION); - } - } - - private void newline() throws IOException { - writer.write(NEWLINE); - } - - /** - * An XML element attribute. - */ - public static class Attribute { - - private final String key; - private final Object value; - - public Attribute(String key, Object value) { - this.key = key; - this.value = value; - } - - public String getKey() { - return key; - } - - public Object getValue() { - return value; - } - - private void append(Writer writer) throws IOException { - if (key != null && value != null) { - writer.write(key); - writer.write("=\""); - writer.write(StringEscapeUtils.escapeXml(value.toString())); - writer.write("\""); - } - } - } - - /** - * A set of attributes. - */ - public static class AttributeSet implements Iterable<Attribute> { - - private final Map<String, Attribute> attributes = new LinkedHashMap<String, Attribute>(); - - public void add(Attribute attribute) { - attributes.put(attribute.getKey(), attribute); - } - - public void add(String key, Object value) { - if (key != null && value != null) { - add(new Attribute(key, value)); - } - } - - public void addAll(Iterable<Attribute> attributes) { - for (Attribute attribute : attributes) { - add(attribute); - } - } - - public Iterator<Attribute> iterator() { - return attributes.values().iterator(); - } - } - -} |