1 17 18 package org.apache.catalina.util; 19 20 import java.io.OutputStreamWriter ; 21 import java.io.PrintWriter ; 22 import java.io.UnsupportedEncodingException ; 23 import java.io.Writer ; 24 25 import org.w3c.dom.Attr ; 26 import org.w3c.dom.Document ; 27 import org.w3c.dom.NamedNodeMap ; 28 import org.w3c.dom.Node ; 29 import org.w3c.dom.NodeList ; 30 31 35 public class DOMWriter { 36 37 41 42 private static String 43 PRINTWRITER_ENCODING = "UTF8"; 44 45 private static String MIME2JAVA_ENCODINGS[] = 46 { "Default", "UTF-8", "US-ASCII", "ISO-8859-1", "ISO-8859-2", "ISO-8859-3", "ISO-8859-4", 47 "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", "ISO-8859-8", "ISO-8859-9", "ISO-2022-JP", 48 "SHIFT_JIS", "EUC-JP","GB2312", "BIG5", "EUC-KR", "ISO-2022-KR", "KOI8-R", "EBCDIC-CP-US", 49 "EBCDIC-CP-CA", "EBCDIC-CP-NL", "EBCDIC-CP-DK", "EBCDIC-CP-NO", "EBCDIC-CP-FI", "EBCDIC-CP-SE", 50 "EBCDIC-CP-IT", "EBCDIC-CP-ES", "EBCDIC-CP-GB", "EBCDIC-CP-FR", "EBCDIC-CP-AR1", 51 "EBCDIC-CP-HE", "EBCDIC-CP-CH", "EBCDIC-CP-ROECE","EBCDIC-CP-YU", 52 "EBCDIC-CP-IS", "EBCDIC-CP-AR2", "UTF-16" 53 }; 54 55 56 private boolean qualifiedNames = true; 57 58 59 protected PrintWriter out; 60 61 62 protected boolean canonical; 63 64 65 public DOMWriter(String encoding, boolean canonical) 66 throws UnsupportedEncodingException { 67 out = new PrintWriter (new OutputStreamWriter (System.out, encoding)); 68 this.canonical = canonical; 69 } 71 75 76 public DOMWriter(boolean canonical) throws UnsupportedEncodingException { 77 this( getWriterEncoding(), canonical); 78 } 79 80 public DOMWriter(Writer writer, boolean canonical) { 81 out = new PrintWriter (writer); 82 this.canonical = canonical; 83 } 84 85 public boolean getQualifiedNames() { 86 return this.qualifiedNames; 87 } 88 89 public void setQualifiedNames(boolean qualifiedNames) { 90 this.qualifiedNames = qualifiedNames; 91 } 92 93 public static String getWriterEncoding( ) { 94 return (PRINTWRITER_ENCODING); 95 } 97 public static void setWriterEncoding( String encoding ) { 98 if( encoding.equalsIgnoreCase( "DEFAULT" ) ) 99 PRINTWRITER_ENCODING = "UTF8"; 100 else if( encoding.equalsIgnoreCase( "UTF-16" ) ) 101 PRINTWRITER_ENCODING = "Unicode"; 102 else 103 PRINTWRITER_ENCODING = MIME2Java.convert( encoding ); 104 } 106 107 public static boolean isValidJavaEncoding( String encoding ) { 108 for ( int i = 0; i < MIME2JAVA_ENCODINGS.length; i++ ) 109 if ( encoding.equals( MIME2JAVA_ENCODINGS[i] ) ) 110 return (true); 111 112 return (false); 113 } 115 116 117 public void print(Node node) { 118 119 if ( node == null ) { 121 return; 122 } 123 124 int type = node.getNodeType(); 125 switch ( type ) { 126 case Node.DOCUMENT_NODE: { 128 if ( !canonical ) { 129 String Encoding = getWriterEncoding(); 130 if( Encoding.equalsIgnoreCase( "DEFAULT" ) ) 131 Encoding = "UTF-8"; 132 else if( Encoding.equalsIgnoreCase( "Unicode" ) ) 133 Encoding = "UTF-16"; 134 else 135 Encoding = MIME2Java.reverse( Encoding ); 136 137 out.println("<?xml version=\"1.0\" encoding=\""+ 138 Encoding + "\"?>"); 139 } 140 print(((Document )node).getDocumentElement()); 141 out.flush(); 142 break; 143 } 144 145 case Node.ELEMENT_NODE: { 147 out.print('<'); 148 if (this.qualifiedNames) { 149 out.print(node.getNodeName()); 150 } else { 151 out.print(node.getLocalName()); 152 } 153 Attr attrs[] = sortAttributes(node.getAttributes()); 154 for ( int i = 0; i < attrs.length; i++ ) { 155 Attr attr = attrs[i]; 156 out.print(' '); 157 if (this.qualifiedNames) { 158 out.print(attr.getNodeName()); 159 } else { 160 out.print(attr.getLocalName()); 161 } 162 163 out.print("=\""); 164 out.print(normalize(attr.getNodeValue())); 165 out.print('"'); 166 } 167 out.print('>'); 168 NodeList children = node.getChildNodes(); 169 if ( children != null ) { 170 int len = children.getLength(); 171 for ( int i = 0; i < len; i++ ) { 172 print(children.item(i)); 173 } 174 } 175 break; 176 } 177 178 case Node.ENTITY_REFERENCE_NODE: { 180 if ( canonical ) { 181 NodeList children = node.getChildNodes(); 182 if ( children != null ) { 183 int len = children.getLength(); 184 for ( int i = 0; i < len; i++ ) { 185 print(children.item(i)); 186 } 187 } 188 } else { 189 out.print('&'); 190 if (this.qualifiedNames) { 191 out.print(node.getNodeName()); 192 } else { 193 out.print(node.getLocalName()); 194 } 195 out.print(';'); 196 } 197 break; 198 } 199 200 case Node.CDATA_SECTION_NODE: { 202 if ( canonical ) { 203 out.print(normalize(node.getNodeValue())); 204 } else { 205 out.print("<![CDATA["); 206 out.print(node.getNodeValue()); 207 out.print("]]>"); 208 } 209 break; 210 } 211 212 case Node.TEXT_NODE: { 214 out.print(normalize(node.getNodeValue())); 215 break; 216 } 217 218 case Node.PROCESSING_INSTRUCTION_NODE: { 220 out.print("<?"); 221 if (this.qualifiedNames) { 222 out.print(node.getNodeName()); 223 } else { 224 out.print(node.getLocalName()); 225 } 226 227 String data = node.getNodeValue(); 228 if ( data != null && data.length() > 0 ) { 229 out.print(' '); 230 out.print(data); 231 } 232 out.print("?>"); 233 break; 234 } 235 } 236 237 if ( type == Node.ELEMENT_NODE ) { 238 out.print("</"); 239 if (this.qualifiedNames) { 240 out.print(node.getNodeName()); 241 } else { 242 out.print(node.getLocalName()); 243 } 244 out.print('>'); 245 } 246 247 out.flush(); 248 249 } 251 252 protected Attr [] sortAttributes(NamedNodeMap attrs) { 253 254 int len = (attrs != null) ? attrs.getLength() : 0; 255 Attr array[] = new Attr [len]; 256 for ( int i = 0; i < len; i++ ) { 257 array[i] = (Attr )attrs.item(i); 258 } 259 for ( int i = 0; i < len - 1; i++ ) { 260 String name = null; 261 if (this.qualifiedNames) { 262 name = array[i].getNodeName(); 263 } else { 264 name = array[i].getLocalName(); 265 } 266 int index = i; 267 for ( int j = i + 1; j < len; j++ ) { 268 String curName = null; 269 if (this.qualifiedNames) { 270 curName = array[j].getNodeName(); 271 } else { 272 curName = array[j].getLocalName(); 273 } 274 if ( curName.compareTo(name) < 0 ) { 275 name = curName; 276 index = j; 277 } 278 } 279 if ( index != i ) { 280 Attr temp = array[i]; 281 array[i] = array[index]; 282 array[index] = temp; 283 } 284 } 285 286 return (array); 287 288 } 290 291 292 protected String normalize(String s) { 293 StringBuffer str = new StringBuffer (); 294 295 int len = (s != null) ? s.length() : 0; 296 for ( int i = 0; i < len; i++ ) { 297 char ch = s.charAt(i); 298 switch ( ch ) { 299 case '<': { 300 str.append("<"); 301 break; 302 } 303 case '>': { 304 str.append(">"); 305 break; 306 } 307 case '&': { 308 str.append("&"); 309 break; 310 } 311 case '"': { 312 str.append("""); 313 break; 314 } 315 case '\r': 316 case '\n': { 317 if ( canonical ) { 318 str.append("&#"); 319 str.append(Integer.toString(ch)); 320 str.append(';'); 321 break; 322 } 323 } 325 default: { 326 str.append(ch); 327 } 328 } 329 } 330 331 return (str.toString()); 332 333 } 335 private static void printValidJavaEncoding() { 336 System.err.println( " ENCODINGS:" ); 337 System.err.print( " " ); 338 for( int i = 0; 339 i < MIME2JAVA_ENCODINGS.length; i++) { 340 System.err.print( MIME2JAVA_ENCODINGS[i] + " " ); 341 if( (i % 7 ) == 0 ){ 342 System.err.println(); 343 System.err.print( " " ); 344 } 345 } 346 347 } 349 } 350 | Popular Tags |