001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/framework/xml/DOMPrinter.java $
002    package org.deegree.framework.xml;
003    
004    import java.io.PrintWriter;
005    
006    import org.deegree.framework.util.StringTools;
007    import org.w3c.dom.Document;
008    import org.w3c.dom.NamedNodeMap;
009    import org.w3c.dom.Node;
010    import org.w3c.dom.NodeList;
011    
012    public class DOMPrinter {
013    
014        public static void printNode(PrintWriter out, Node node) {
015            switch (node.getNodeType()) {
016            case Node.DOCUMENT_NODE: {
017                out.print("<?xml version=\"1.0\"?>");
018                Document doc = (Document) node;
019                printNode(out, doc.getDocumentElement());
020                break;
021            }
022            case Node.ELEMENT_NODE: {
023                String name = node.getNodeName();
024                out.print("<" + name);
025                NamedNodeMap attributes = node.getAttributes();
026                for (int i = 0; i < attributes.getLength(); i++) {
027                    Node current = attributes.item(i);
028                    String value = current.getNodeValue();
029                    value = StringTools.replace(value, "&", "&amp;", true);
030                    out.print(" " + current.getNodeName() + "=\"" + value + "\"");
031                }
032                out.print(">");
033    
034                // Kinder durchgehen
035                NodeList children = node.getChildNodes();
036                if (children != null) {
037                    for (int i = 0; i < children.getLength(); i++) {
038                        printNode(out, children.item(i));
039                    }
040                }
041    
042                out.print("</" + name + ">");
043                break;
044            }
045            case Node.TEXT_NODE:
046            case Node.CDATA_SECTION_NODE: {
047                String trimmed = node.getNodeValue().trim();
048                if (!trimmed.equals(""))
049                    out.print(validateCDATA(trimmed));
050                break;
051            }
052            case Node.PROCESSING_INSTRUCTION_NODE: {
053                break;
054            }
055            case Node.ENTITY_REFERENCE_NODE: {
056                break;
057            }
058            case Node.DOCUMENT_TYPE_NODE: {
059                break;
060            }
061            }
062        }
063    
064        public static void printNode(Node node, String indent) {
065            if (node == null) {
066                return;
067            }
068    
069            switch (node.getNodeType()) {
070            case Node.DOCUMENT_NODE: {
071                System.out.println("<?xml version=\"1.0\"?>");
072                Document doc = (Document) node;
073                printNode(doc.getDocumentElement(), "");
074                break;
075            }
076            case Node.ELEMENT_NODE: {
077                String name = node.getNodeName();
078                System.out.print(indent + "<" + name);
079                NamedNodeMap attributes = node.getAttributes();
080                for (int i = 0; i < attributes.getLength(); i++) {
081                    Node current = attributes.item(i);
082                    String value = current.getNodeValue();
083                    if ( value != null ) {
084                        value = StringTools.replace(value, "&", "&amp;", true);
085                        System.out.print(" " + current.getNodeName() + "=\"" + value + "\"");
086                    }
087                }
088                // Kinder durchgehen
089                NodeList children = node.getChildNodes();
090                if (children != null && children.getLength() != 0) {
091                    boolean complexContent = false;
092                    for (int i = 0; i < children.getLength(); i++) {
093                        if (children.item(i).getNodeType() != Node.TEXT_NODE
094                                && children.item(i).getNodeType() != Node.CDATA_SECTION_NODE) {
095                            complexContent = true;
096                        }
097                    }
098                    if (complexContent) {
099                        System.out.println(">");
100                    } else {
101                        System.out.print(">");
102                    }
103    
104                    for (int i = 0; i < children.getLength(); i++) {
105                        printNode(children.item(i), indent + "  ");
106                    }
107    
108                    if (complexContent) {
109                        System.out.println(indent + "</" + name + ">");
110                    } else {
111                        System.out.println("</" + name + ">");
112                    }
113                } else {
114                    System.out.println("/>");
115                }
116                break;
117            }
118            case Node.TEXT_NODE:
119            case Node.CDATA_SECTION_NODE: {
120                if (node.getNodeValue() != null) {
121                    String trimmed = node.getNodeValue().trim();
122                    if (!trimmed.equals(""))
123                        System.out.print(trimmed);
124                }
125                break;
126            }
127            case Node.PROCESSING_INSTRUCTION_NODE: {
128                break;
129            }
130            case Node.ENTITY_REFERENCE_NODE: {
131                break;
132            }
133            case Node.DOCUMENT_TYPE_NODE: {
134                break;
135            }
136            }
137        }
138    
139        public static String nodeToString(Node node, String encoding) {
140            StringBuffer sb = new StringBuffer(10000);
141    
142            switch (node.getNodeType()) {
143            case Node.DOCUMENT_NODE: {
144                sb.append("<?xml version=\"1.0\" encoding=\"" + encoding + "\" ?>");
145                Document doc = (Document) node;
146                sb.append(nodeToString(doc.getDocumentElement(), ""));
147                break;
148            }
149            case Node.ELEMENT_NODE: {
150                String name = node.getNodeName();
151                sb.append("\n<" + name);
152                NamedNodeMap attributes = node.getAttributes();
153                for (int i = 0; i < attributes.getLength(); i++) {
154                    Node current = attributes.item(i);
155                    String value = current.getNodeValue();
156                    if ( value != null ) {
157                        value = StringTools.replace( value, "&", "&amp;", true);
158                        sb.append(" " + current.getNodeName() + "=\"" + value + "\"");
159                    }
160                }
161                sb.append(">");
162    
163                // Kinder durchgehen
164                NodeList children = node.getChildNodes();
165                if (children != null) {
166                    for (int i = 0; i < children.getLength(); i++) {
167                        sb.append(nodeToString(children.item(i), encoding));
168                    }
169                }
170    
171                sb.append("</" + name + ">");
172                break;
173            }
174            case Node.CDATA_SECTION_NODE: {
175                String trimmed = node.getNodeValue().trim();
176                if (!trimmed.equals(""))
177                    sb.append("<![CDATA[" + trimmed + "]]>");
178                break;
179            }
180            case Node.TEXT_NODE: {
181                String trimmed = node.getNodeValue();
182                if ( trimmed != null ) {
183                    trimmed = trimmed.trim();
184                    if (!trimmed.equals("")) {
185                        sb.append(validateCDATA(trimmed));
186                    }
187                }
188                break;
189            }
190            case Node.PROCESSING_INSTRUCTION_NODE: {
191                break;
192            }
193            case Node.ENTITY_REFERENCE_NODE: {
194                break;
195            }
196            case Node.DOCUMENT_TYPE_NODE: {
197                break;
198            }
199            }
200            return sb.toString();
201        }
202    
203        /**
204         * Checks if a given CDATA-value has to be escaped if it is used as a text value in an XML
205         * element. If the submitted string contains a character that have to be escaped or if the
206         * string is made of more than 1500 characters it is encapsulated into a CDATA-section. Returns
207         * a version that is safe to be used.
208         * <p>
209         * The method is just proofed for the UTF-8 character encoding.
210         * 
211         * @param cdata
212         *            value to be used
213         * @return the very same value (but escaped if necessary)
214         * @todo refactoring required
215         */
216        public static StringBuffer validateCDATA( String cdata ) {
217            StringBuffer sb = null;
218            if ( cdata != null
219                && ( cdata.length() > 1000
220                    || cdata.indexOf( '<' ) >= 0 || cdata.indexOf( '>' ) >= 0
221                    || cdata.indexOf( '&' ) >= 0 || cdata.indexOf( '"' ) >= 0 
222                    || cdata.indexOf( "'" ) >= 0 ) ) {
223                sb = new StringBuffer( cdata.length() + 15 );
224                sb.append( "<![CDATA[" ).append( cdata ).append( "]]>" );
225            } else {
226                if ( cdata != null ) {
227                    sb = new StringBuffer( cdata );
228                }
229            }
230            return sb;
231        }    
232    }/* ********************************************************************
233    Changes to this class. What the people have been up to:
234    $Log$
235    Revision 1.7  2006/07/12 14:46:16  poth
236    comment footer added
237    
238    ********************************************************************** */