001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/framework/xml/DOMPrinter.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2008 by:
006 EXSE, Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/deegree/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 This library is free software; you can redistribute it and/or
012 modify it under the terms of the GNU Lesser General Public
013 License as published by the Free Software Foundation; either
014 version 2.1 of the License, or (at your option) any later version.
015
016 This library is distributed in the hope that it will be useful,
017 but WITHOUT ANY WARRANTY; without even the implied warranty of
018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 Lesser General Public License for more details.
020
021 You should have received a copy of the GNU Lesser General Public
022 License along with this library; if not, write to the Free Software
023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024
025 Contact:
026
027 Andreas Poth
028 lat/lon GmbH
029 Aennchenstr. 19
030 53115 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Prof. Dr. Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: greve@giub.uni-bonn.de
041
042
043 ---------------------------------------------------------------------------*/
044 package org.deegree.framework.xml;
045
046 import java.io.PrintWriter;
047
048 import org.deegree.framework.util.StringTools;
049 import org.w3c.dom.Document;
050 import org.w3c.dom.NamedNodeMap;
051 import org.w3c.dom.Node;
052 import org.w3c.dom.NodeList;
053
054 public class DOMPrinter {
055
056 /**
057 *
058 * @param out
059 * @param node
060 */
061 public static void printNode(PrintWriter out, Node node) {
062 switch (node.getNodeType()) {
063 case Node.DOCUMENT_NODE: {
064 out.print("<?xml version=\"1.0\"?>");
065 Document doc = (Document) node;
066 printNode(out, doc.getDocumentElement());
067 break;
068 }
069 case Node.ELEMENT_NODE: {
070 String name = node.getNodeName();
071 out.print("<" + name);
072 NamedNodeMap attributes = node.getAttributes();
073 for (int i = 0; i < attributes.getLength(); i++) {
074 Node current = attributes.item(i);
075 String value = current.getNodeValue();
076 value = StringTools.replace(value, "&", "&", true);
077 out.print(" " + current.getNodeName() + "=\"" + value + "\"");
078 }
079 out.print(">");
080
081 // Kinder durchgehen
082 NodeList children = node.getChildNodes();
083 if (children != null) {
084 for (int i = 0; i < children.getLength(); i++) {
085 printNode(out, children.item(i));
086 }
087 }
088
089 out.print("</" + name + ">");
090 break;
091 }
092 case Node.TEXT_NODE:
093 case Node.CDATA_SECTION_NODE: {
094 String trimmed = node.getNodeValue().trim();
095 if (!trimmed.equals(""))
096 out.print(validateCDATA(trimmed));
097 break;
098 }
099 case Node.PROCESSING_INSTRUCTION_NODE: {
100 break;
101 }
102 case Node.ENTITY_REFERENCE_NODE: {
103 break;
104 }
105 case Node.DOCUMENT_TYPE_NODE: {
106 break;
107 }
108 }
109 }
110
111 /**
112 *
113 * @param node
114 * @param indent
115 */
116 public static void printNode(Node node, String indent) {
117 if (node == null) {
118 return;
119 }
120
121 switch (node.getNodeType()) {
122 case Node.DOCUMENT_NODE: {
123 System.out.println("<?xml version=\"1.0\"?>");
124 Document doc = (Document) node;
125 printNode(doc.getDocumentElement(), "");
126 break;
127 }
128 case Node.ELEMENT_NODE: {
129 String name = node.getNodeName();
130 System.out.print(indent + "<" + name);
131 NamedNodeMap attributes = node.getAttributes();
132 for (int i = 0; i < attributes.getLength(); i++) {
133 Node current = attributes.item(i);
134 String value = current.getNodeValue();
135 if ( value != null ) {
136 value = StringTools.replace(value, "&", "&", true);
137 System.out.print(" " + current.getNodeName() + "=\"" + value + "\"");
138 }
139 }
140 // Kinder durchgehen
141 NodeList children = node.getChildNodes();
142 if (children != null && children.getLength() != 0) {
143 boolean complexContent = false;
144 for (int i = 0; i < children.getLength(); i++) {
145 if (children.item(i).getNodeType() != Node.TEXT_NODE
146 && children.item(i).getNodeType() != Node.CDATA_SECTION_NODE) {
147 complexContent = true;
148 }
149 }
150 if (complexContent) {
151 System.out.println(">");
152 } else {
153 System.out.print(">");
154 }
155
156 for (int i = 0; i < children.getLength(); i++) {
157 printNode(children.item(i), indent + " ");
158 }
159
160 if (complexContent) {
161 System.out.println(indent + "</" + name + ">");
162 } else {
163 System.out.println("</" + name + ">");
164 }
165 } else {
166 System.out.println("/>");
167 }
168 break;
169 }
170 case Node.TEXT_NODE:
171 case Node.CDATA_SECTION_NODE: {
172 if (node.getNodeValue() != null) {
173 String trimmed = node.getNodeValue().trim();
174 if (!trimmed.equals(""))
175 System.out.print(trimmed);
176 }
177 break;
178 }
179 case Node.PROCESSING_INSTRUCTION_NODE: {
180 break;
181 }
182 case Node.ENTITY_REFERENCE_NODE: {
183 break;
184 }
185 case Node.DOCUMENT_TYPE_NODE: {
186 break;
187 }
188 }
189 }
190
191 /**
192 *
193 * @param node
194 * @param encoding
195 * @return
196 */
197 public static String nodeToString(Node node, String encoding) {
198 StringBuffer sb = new StringBuffer(10000);
199
200 switch (node.getNodeType()) {
201 case Node.DOCUMENT_NODE: {
202 sb.append("<?xml version=\"1.0\" encoding=\"" + encoding + "\" ?>");
203 Document doc = (Document) node;
204 sb.append(nodeToString(doc.getDocumentElement(), ""));
205 break;
206 }
207 case Node.ELEMENT_NODE: {
208 String name = node.getNodeName();
209 sb.append("\n<" + name);
210 NamedNodeMap attributes = node.getAttributes();
211 for (int i = 0; i < attributes.getLength(); i++) {
212 Node current = attributes.item(i);
213 String value = current.getNodeValue();
214 if ( value != null ) {
215 value = StringTools.replace( value, "&", "&", true);
216 sb.append(" " + current.getNodeName() + "=\"" + value + "\"");
217 }
218 }
219 sb.append(">");
220
221 // Kinder durchgehen
222 NodeList children = node.getChildNodes();
223 if (children != null) {
224 for (int i = 0; i < children.getLength(); i++) {
225 sb.append(nodeToString(children.item(i), encoding));
226 }
227 }
228
229 sb.append("</" + name + ">");
230 break;
231 }
232 case Node.CDATA_SECTION_NODE: {
233 String trimmed = node.getNodeValue().trim();
234 if (!trimmed.equals(""))
235 sb.append("<![CDATA[" + trimmed + "]]>");
236 break;
237 }
238 case Node.TEXT_NODE: {
239 String trimmed = node.getNodeValue();
240 if ( trimmed != null ) {
241 trimmed = trimmed.trim();
242 if (!trimmed.equals("")) {
243 sb.append(validateCDATA(trimmed));
244 }
245 }
246 break;
247 }
248 case Node.PROCESSING_INSTRUCTION_NODE: {
249 break;
250 }
251 case Node.ENTITY_REFERENCE_NODE: {
252 break;
253 }
254 case Node.DOCUMENT_TYPE_NODE: {
255 break;
256 }
257 }
258 return sb.toString();
259 }
260
261 /**
262 * Checks if a given CDATA-value has to be escaped if it is used as a text value in an XML
263 * element. If the submitted string contains a character that have to be escaped or if the
264 * string is made of more than 1500 characters it is encapsulated into a CDATA-section. Returns
265 * a version that is safe to be used.
266 * <p>
267 * The method is just proofed for the UTF-8 character encoding.
268 *
269 * @param cdata
270 * value to be used
271 * @return the very same value (but escaped if necessary)
272 * @todo refactoring required
273 */
274 public static StringBuffer validateCDATA( String cdata ) {
275 StringBuffer sb = null;
276 if ( cdata != null
277 && ( cdata.length() > 1000
278 || cdata.indexOf( '<' ) >= 0 || cdata.indexOf( '>' ) >= 0
279 || cdata.indexOf( '&' ) >= 0 || cdata.indexOf( '"' ) >= 0
280 || cdata.indexOf( "'" ) >= 0 ) ) {
281 sb = new StringBuffer( cdata.length() + 15 );
282 sb.append( "<![CDATA[" ).append( cdata ).append( "]]>" );
283 } else {
284 if ( cdata != null ) {
285 sb = new StringBuffer( cdata );
286 }
287 }
288 return sb;
289 }
290 }