package org.jboss.util.xml;
import java.io.PrintWriter;
import java.io.Writer;
import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DOMWriter
{
protected PrintWriter out;
protected boolean canonical;
public DOMWriter(Writer w)
{
this(w, false);
}
public DOMWriter(Writer w, boolean canonical)
{
out = new PrintWriter(w);
this.canonical = canonical;
}
public void print(Node node)
{
print(node, true);
}
public void print(Node node, boolean prettyprint)
{
if (node == null)
{
return;
}
int type = node.getNodeType();
switch (type)
{
case Node.DOCUMENT_NODE:
{
if (!canonical)
{
out.println("<?xml version=\"1.0\"?>");
}
NodeList children = node.getChildNodes();
for (int iChild = 0; iChild < children.getLength(); iChild++)
{
print(children.item(iChild));
}
out.flush();
break;
}
case Node.ELEMENT_NODE:
{
out.print('<');
out.print(node.getNodeName());
Attr attrs[] = sortAttributes(node.getAttributes());
for (int i = 0; i < attrs.length; i++)
{
Attr attr = attrs[i];
out.print(' ');
out.print(attr.getNodeName());
out.print("=\"");
out.print(normalize(attr.getNodeValue()));
out.print('"');
}
out.print('>');
NodeList children = node.getChildNodes();
if (children != null)
{
int len = children.getLength();
for (int i = 0; i < len; i++)
{
print(children.item(i));
}
}
break;
}
case Node.ENTITY_REFERENCE_NODE:
{
if (canonical)
{
NodeList children = node.getChildNodes();
if (children != null)
{
int len = children.getLength();
for (int i = 0; i < len; i++)
{
print(children.item(i));
}
}
}
else
{
out.print('&');
out.print(node.getNodeName());
out.print(';');
}
break;
}
case Node.CDATA_SECTION_NODE:
{
if (canonical)
{
out.print(normalize(node.getNodeValue()));
}
else
{
out.print("<![CDATA[");
out.print(node.getNodeValue());
out.print("]]>");
}
break;
}
case Node.TEXT_NODE:
{
out.print(normalize(node.getNodeValue()));
break;
}
case Node.PROCESSING_INSTRUCTION_NODE:
{
out.print("<?");
out.print(node.getNodeName());
String data = node.getNodeValue();
if (data != null && data.length() > 0)
{
out.print(' ');
out.print(data);
}
out.print("?>");
break;
}
case Node.COMMENT_NODE:
{
out.print("<!--");
String data = node.getNodeValue();
if (data != null)
{
out.print(data);
}
out.print("-->");
break;
}
}
if (type == Node.ELEMENT_NODE)
{
out.print("</");
out.print(node.getNodeName());
out.print('>');
}
out.flush();
}
protected Attr[] sortAttributes(NamedNodeMap attrs)
{
int len = (attrs != null) ? attrs.getLength() : 0;
Attr array[] = new Attr[len];
for (int i = 0; i < len; i++)
{
array[i] = (Attr) attrs.item(i);
}
for (int i = 0; i < len - 1; i++)
{
String name = array[i].getNodeName();
int index = i;
for (int j = i + 1; j < len; j++)
{
String curName = array[j].getNodeName();
if (curName.compareTo(name) < 0)
{
name = curName;
index = j;
}
}
if (index != i)
{
Attr temp = array[i];
array[i] = array[index];
array[index] = temp;
}
}
return (array);
}
protected String normalize(String s)
{
StringBuffer str = new StringBuffer();
int len = (s != null) ? s.length() : 0;
for (int i = 0; i < len; i++)
{
char ch = s.charAt(i);
switch (ch)
{
case '<':
{
str.append("<");
break;
}
case '>':
{
str.append(">");
break;
}
case '&':
{
str.append("&");
break;
}
case '"':
{
str.append(""");
break;
}
case '\r':
case '\n':
{
if (canonical)
{
str.append("&#");
str.append(Integer.toString(ch));
str.append(';');
break;
}
}
default:
{
str.append(ch);
}
}
}
return (str.toString());
}
}