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 }