synchronized from quantum plugin
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.quantum.sql / src / com / quantum / util / xml / XMLRenderer.java
diff --git a/archive/net.sourceforge.phpeclipse.quantum.sql/src/com/quantum/util/xml/XMLRenderer.java b/archive/net.sourceforge.phpeclipse.quantum.sql/src/com/quantum/util/xml/XMLRenderer.java
new file mode 100644 (file)
index 0000000..4bd4632
--- /dev/null
@@ -0,0 +1,225 @@
+package com.quantum.util.xml;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author BC Holmes
+ */
+public class XMLRenderer {
+
+    protected boolean insertNewLine = false;
+    protected int numberOfTabs;
+
+    protected final static String LINE_SEPARATOR = System
+            .getProperty("line.separator");
+
+    protected final static String INDENT_STRING = "\t";
+
+    /** Returns a sorted list of attributes. */
+    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 XMLRenderer() {
+        this.numberOfTabs = 0;
+        this.insertNewLine = true;
+    }
+
+    protected void newLine(StringBuffer buffer) {
+        if (this.insertNewLine) {
+            buffer.append(LINE_SEPARATOR);
+            for (int i = 0; i < this.numberOfTabs; i++) {
+                buffer.append(INDENT_STRING);
+            }
+        }
+    }
+
+    /** Prints the specified node, recursively. */
+    protected void print(Node node, StringBuffer buffer) {
+        // is there anything to do?
+        if (node != null) {
+            int type = node.getNodeType();
+            switch (type) {
+
+            case Node.DOCUMENT_NODE:
+                printDocumentNode(node, buffer);
+                break;
+
+            // print element with attributes
+            case Node.ELEMENT_NODE:
+                printElementNode(node, buffer);
+                break;
+            // handle entity reference nodes
+            case Node.ENTITY_REFERENCE_NODE:
+                printEntityReferenceNode(node, buffer);
+                break;
+
+            // print cdata sections
+            case Node.CDATA_SECTION_NODE:
+                printCDataSectionNode(node, buffer);
+                break;
+
+            // print text
+            case Node.TEXT_NODE:
+                printTextNode(node, buffer);
+                break;
+
+            // print processing instruction
+            case Node.PROCESSING_INSTRUCTION_NODE:
+                printProcessingInstructionNode(node, buffer);
+                break;
+            }
+        }
+    }
+
+    protected void printProcessingInstructionNode(Node node, StringBuffer buffer) {
+        buffer.append("<?");
+        buffer.append(node.getNodeName());
+        String data = node.getNodeValue();
+        if (data != null && data.length() > 0) {
+            buffer.append(' ');
+            buffer.append(data);
+        }
+        buffer.append("?>");
+    }
+
+    protected void printTextNode(Node node, StringBuffer buffer) {
+        printString(node.getNodeValue(), buffer);
+        this.insertNewLine = false;
+    }
+
+    protected void printCDataSectionNode(Node node, StringBuffer buffer) {
+        buffer.append("<![CDATA[");
+        buffer.append(node.getNodeValue());
+        buffer.append("]]>");
+    }
+
+    protected void printEntityReferenceNode(Node node, StringBuffer buffer) {
+        buffer.append('&');
+        buffer.append(node.getNodeName());
+        buffer.append(';');
+    }
+
+    protected void printElementNode(Node node, StringBuffer buffer) {
+        newLine(buffer);
+        this.numberOfTabs++;
+        buffer.append('<');
+        buffer.append(node.getNodeName());
+        Attr attrs[] = sortAttributes(node.getAttributes());
+        for (int i = 0; i < attrs.length; i++) {
+            Attr attr = attrs[i];
+            buffer.append(' ');
+            buffer.append(attr.getNodeName());
+            buffer.append("=\"");
+            printString(attr.getNodeValue(), buffer);
+            buffer.append('"');
+        }
+
+        if (!node.hasChildNodes()) {
+            buffer.append(" />");
+            this.numberOfTabs--;
+        } else {
+            buffer.append(">");
+            printAllChildNodes(node, buffer);
+            this.numberOfTabs--;
+            newLine(buffer);
+
+            buffer.append("</");
+            buffer.append(node.getNodeName());
+            buffer.append(">");
+        }
+        this.insertNewLine = true;
+    }
+
+    protected void printDocumentNode(Node node, StringBuffer buffer) {
+        buffer.append("<?xml version=\"1.0\" ?>");
+
+        printAllChildNodes(node, buffer);
+    }
+
+    protected void printAllChildNodes(Node node, StringBuffer buffer) {
+        NodeList children = node.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            print(children.item(i), buffer);
+        }
+    }
+
+    /** Normalizes the given string. */
+    protected void printString(String s, StringBuffer buffer) {
+
+        int len = (s != null) ? s.length() : 0;
+        for (int i = 0; i < len; i++) {
+            char ch = s.charAt(i);
+            switch (ch) {
+            case '<': {
+                buffer.append("&lt;");
+                break;
+            }
+            case '>': {
+                buffer.append("&gt;");
+                break;
+            }
+            case '&': {
+                buffer.append("&amp;");
+                break;
+            }
+            case '"':
+                buffer.append("&quot;");
+                break;
+            case '\r':
+            case '\n':
+            default: {
+                buffer.append(ch);
+            }
+            }
+        }
+    }
+
+    public static String render(Node node) {
+        XMLRenderer renderer = new XMLRenderer();
+        StringBuffer buffer = new StringBuffer();
+        renderer.print(node, buffer);
+
+        return buffer.toString();
+    }
+
+    /**
+     * <p>
+     * Renders a String in a format that it would appear in a text node. That is
+     * to say, special characters (such as &amp;) are converted into entity
+     * references (&amp;amp;).
+     */
+    public static String render(String string) {
+        XMLRenderer renderer = new XMLRenderer();
+        StringBuffer buffer = new StringBuffer();
+        renderer.printString(string, buffer);
+        return buffer.toString();
+    }
+}
\ No newline at end of file