001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/framework/xml/DOMPrinter.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.framework.xml;
037
038 import java.io.PrintWriter;
039
040 import org.deegree.framework.util.StringTools;
041 import org.w3c.dom.Document;
042 import org.w3c.dom.NamedNodeMap;
043 import org.w3c.dom.Node;
044 import org.w3c.dom.NodeList;
045
046 /**
047 * <code>DOMPrinter</code> contains various methods to print DOM-XML-elements to a String,PrintWriter or Standard out.
048 *
049 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
050 * @author last edited by: $Author: mschneider $
051 *
052 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
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 // erwachsenen 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 the String representation of the given node.
196 */
197 public static String nodeToString( Node node, String encoding ) {
198 StringBuilder sb = new StringBuilder( 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 // Opas 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 element. If the submitted
263 * string contains a character that have to be escaped or if the string is made of more than 1500 characters it is
264 * encapsulated into a CDATA-section. Returns a version that is safe to be used.
265 * <p>
266 * The method is just proofed for the UTF-8 character encoding.
267 *
268 * @param cdata
269 * value to be used
270 * @return the very same value (but escaped if necessary)
271 * @todo refactoring required
272 */
273 public static StringBuffer validateCDATA( String cdata ) {
274 StringBuffer sb = null;
275 if ( cdata != null
276 && ( cdata.length() > 1000 || cdata.indexOf( '<' ) >= 0 || cdata.indexOf( '>' ) >= 0
277 || cdata.indexOf( '&' ) >= 0 || cdata.indexOf( '"' ) >= 0 || cdata.indexOf( "'" ) >= 0 ) ) {
278 sb = new StringBuffer( cdata.length() + 15 );
279 sb.append( "<![CDATA[" ).append( cdata ).append( "]]>" );
280 } else {
281 if ( cdata != null ) {
282 sb = new StringBuffer( cdata );
283 }
284 }
285 return sb;
286 }
287 }