blob: 0346fb4dbc4635635d0899032f248df04a919158 [file] [log] [blame]
/*
* Copyright 2003-2007 the original author or authors.
*
* 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 groovy.util;
import groovy.xml.QName;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.codehaus.groovy.runtime.InvokerHelper;
/**
* Prints a node with all childs in XML format.
*
* @see groovy.util.NodePrinter
* @author Christian Stein
*/
public class XmlNodePrinter {
protected final IndentPrinter out;
private final String quote;
public XmlNodePrinter() {
this(new PrintWriter(new OutputStreamWriter(System.out)));
}
public XmlNodePrinter(PrintWriter out) {
this(out, " ");
}
public XmlNodePrinter(PrintWriter out, String indent) {
this(out, indent, "\"");
}
public XmlNodePrinter(PrintWriter out, String indent, String quote) {
this(new IndentPrinter(out, indent), quote);
}
public XmlNodePrinter(IndentPrinter out, String quote) {
if (out == null) {
throw new IllegalArgumentException("Argument 'IndentPrinter out' must not be null!");
}
this.out = out;
this.quote = quote;
}
public String getNameOfNode(Node node) {
if (node == null) {
throw new IllegalArgumentException("Node must not be null!");
}
Object name = node.name();
if (name instanceof QName) {
QName qname = (QName) name;
return /* qname.getPrefix() + ":" + */qname.getLocalPart();
}
return name.toString();
}
public boolean isEmptyElement(Node node) {
if (node == null) {
throw new IllegalArgumentException("Node must not be null!");
}
if (!node.children().isEmpty()) {
return false;
}
return node.text().length() == 0;
}
public void print(Node node) {
/*
* Handle empty elements like '<br/>', '<img/> or '<hr noshade="noshade"/>.
*/
if (isEmptyElement(node)) {
// System.err.println("empty-dead");
printLineBegin();
out.print("<");
out.print(getNameOfNode(node));
printNameAttributes(node.attributes());
out.print("/>");
printLineEnd(); // "node named '" + node.name() + "'"
out.flush();
return;
}
/*
* Handle GSP tag element!
*/
if (printSpecialNode(node)) {
// System.err.println("special-dead");
out.flush();
return;
}
/*
* Handle normal element like <html> ... </html>.
*/
Object value = node.value();
if (value instanceof List) {
printName(node, true);
printList((List) value);
printName(node, false);
out.flush();
return;
}
/*
* Still here?!
*/
throw new RuntimeException("Unsupported node value: " + node.value());
}
protected void printLineBegin() {
out.printIndent();
}
protected void printLineEnd() {
printLineEnd(null);
}
protected void printLineEnd(String comment) {
if (comment != null) {
out.print(" <!-- ");
out.print(comment);
out.print(" -->");
}
out.print("\n");
}
protected void printList(List list) {
out.incrementIndent();
for (Iterator iter = list.iterator(); iter.hasNext();) {
Object value = iter.next();
/*
* If the current value is a node, recurse into that node.
*/
if (value instanceof Node) {
print((Node) value);
continue;
}
/*
* Print out "simple" text nodes.
*/
printLineBegin();
out.print(InvokerHelper.toString(value));
printLineEnd();
}
out.decrementIndent();
}
protected void printName(Node node, boolean begin) {
if (node == null) {
throw new NullPointerException("Node must not be null.");
}
Object name = node.name();
if (name == null) {
throw new NullPointerException("Name must not be null.");
}
printLineBegin();
out.print("<");
if (!begin) {
out.print("/");
}
out.print(getNameOfNode(node));
if (begin) {
printNameAttributes(node.attributes());
}
out.print(">");
printLineEnd();
}
protected void printNameAttributes(Map attributes) {
if (attributes == null || attributes.isEmpty()) {
return;
}
for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
out.print(" ");
out.print(entry.getKey().toString());
out.print("=");
Object value = entry.getValue();
out.print(quote);
if (value instanceof String) {
out.print((String) value);
} else {
out.print(InvokerHelper.toString(value));
}
out.print(quote);
}
}
protected boolean printSpecialNode(Node node) {
return false;
}
}