/******************************************************************************* | |
* Copyright 2011 See AUTHORS file. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
******************************************************************************/ | |
package com.badlogic.gdx.utils; | |
import java.io.IOException; | |
import java.io.Writer; | |
//@off | |
/** | |
* Builder style API for emitting XML. <pre> | |
* StringWriter writer = new StringWriter(); | |
* XmlWriter xml = new XmlWriter(writer); | |
* xml.element("meow") | |
* .attribute("moo", "cow") | |
* .element("child") | |
* .attribute("moo", "cow") | |
* .element("child") | |
* .attribute("moo", "cow") | |
* .text("XML is like violence. If it doesn't solve your problem, you're not using enough of it.") | |
* .pop() | |
* .pop() | |
* .pop(); | |
* System.out.println(writer); | |
* </pre> | |
* @author Nathan Sweet | |
*/ | |
//@on | |
public class XmlWriter extends Writer { | |
private final Writer writer; | |
private final Array<String> stack = new Array(); | |
private String currentElement; | |
private boolean indentNextClose; | |
public int indent; | |
public XmlWriter (Writer writer) { | |
this.writer = writer; | |
} | |
private void indent () throws IOException { | |
int count = indent; | |
if (currentElement != null) count++; | |
for (int i = 0; i < count; i++) | |
writer.write('\t'); | |
} | |
public XmlWriter element (String name) throws IOException { | |
if (startElementContent()) writer.write('\n'); | |
indent(); | |
writer.write('<'); | |
writer.write(name); | |
currentElement = name; | |
return this; | |
} | |
public XmlWriter element (String name, Object text) throws IOException { | |
return element(name).text(text).pop(); | |
} | |
private boolean startElementContent () throws IOException { | |
if (currentElement == null) return false; | |
indent++; | |
stack.add(currentElement); | |
currentElement = null; | |
writer.write(">"); | |
return true; | |
} | |
public XmlWriter attribute (String name, Object value) throws IOException { | |
if (currentElement == null) throw new IllegalStateException(); | |
writer.write(' '); | |
writer.write(name); | |
writer.write("=\""); | |
writer.write(value == null ? "null" : value.toString()); | |
writer.write('"'); | |
return this; | |
} | |
public XmlWriter text (Object text) throws IOException { | |
startElementContent(); | |
String string = text == null ? "null" : text.toString(); | |
indentNextClose = string.length() > 64; | |
if (indentNextClose) { | |
writer.write('\n'); | |
indent(); | |
} | |
writer.write(string); | |
if (indentNextClose) writer.write('\n'); | |
return this; | |
} | |
public XmlWriter pop () throws IOException { | |
if (currentElement != null) { | |
writer.write("/>\n"); | |
currentElement = null; | |
} else { | |
indent = Math.max(indent - 1, 0); | |
if (indentNextClose) indent(); | |
writer.write("</"); | |
writer.write(stack.pop()); | |
writer.write(">\n"); | |
} | |
indentNextClose = true; | |
return this; | |
} | |
/** Calls {@link #pop()} for each remaining open element, if any, and closes the stream. */ | |
public void close () throws IOException { | |
while (stack.size != 0) | |
pop(); | |
writer.close(); | |
} | |
public void write (char[] cbuf, int off, int len) throws IOException { | |
startElementContent(); | |
writer.write(cbuf, off, len); | |
} | |
public void flush () throws IOException { | |
writer.flush(); | |
} | |
} |