KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > dom > DOMWriter


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package dom;
59
60 import java.io.OutputStreamWriter JavaDoc;
61 import java.io.PrintWriter JavaDoc;
62 import java.io.UnsupportedEncodingException JavaDoc;
63
64 import org.enhydra.apache.xerces.readers.MIME2Java;
65 import org.w3c.dom.Attr JavaDoc;
66 import org.w3c.dom.Document JavaDoc;
67 import org.w3c.dom.NamedNodeMap JavaDoc;
68 import org.w3c.dom.Node JavaDoc;
69 import org.w3c.dom.NodeList JavaDoc;
70
71 import util.Arguments;
72
73
74 /**
75  * A sample DOM writer. This sample program illustrates how to
76  * traverse a DOM tree in order to print a document that is parsed.
77  *
78  * @version $Id: DOMWriter.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
79  */

80 public class DOMWriter {
81
82     //
83
// Constants
84
//
85

86
87     /** Default parser name. */
88     private static final String JavaDoc
89     DEFAULT_PARSER_NAME = "dom.wrappers.DOMParser";
90
91
92     private static boolean setValidation = false; //defaults
93
private static boolean setNameSpaces = true;
94     private static boolean setSchemaSupport = true;
95     private static boolean setSchemaFullSupport = false;
96     private static boolean setDeferredDOM = true;
97
98
99
100     //
101
// Data
102
//
103

104     /** Default Encoding */
105     private static String JavaDoc
106     PRINTWRITER_ENCODING = "UTF8";
107
108     private static String JavaDoc MIME2JAVA_ENCODINGS[] =
109     { "Default", "UTF-8", "US-ASCII", "ISO-8859-1", "ISO-8859-2", "ISO-8859-3", "ISO-8859-4",
110         "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", "ISO-8859-8", "ISO-8859-9", "ISO-2022-JP",
111         "SHIFT_JIS", "EUC-JP","GB2312", "BIG5", "EUC-KR", "ISO-2022-KR", "KOI8-R", "EBCDIC-CP-US",
112         "EBCDIC-CP-CA", "EBCDIC-CP-NL", "EBCDIC-CP-DK", "EBCDIC-CP-NO", "EBCDIC-CP-FI", "EBCDIC-CP-SE",
113         "EBCDIC-CP-IT", "EBCDIC-CP-ES", "EBCDIC-CP-GB", "EBCDIC-CP-FR", "EBCDIC-CP-AR1",
114         "EBCDIC-CP-HE", "EBCDIC-CP-CH", "EBCDIC-CP-ROECE","EBCDIC-CP-YU",
115         "EBCDIC-CP-IS", "EBCDIC-CP-AR2", "UTF-16"
116     };
117
118
119 /*
120    private static String JAVA_SUPPORTED_ENCODINGS[] =
121    { "Default", "8859_1", "8859_2", "8859_3", "8859_4", "8859_5", "8859_6",
122       "8859_7", "8859_8", "8859_9", "Cp037", "Cp273", "Cp277", "Cp278",
123       "Cp280", "Cp284", "Cp285", "Cp297", "Cp420", "Cp424", "Cp437",
124       "Cp500", "Cp737", "Cp775", "Cp838", "Cp850", "Cp852", "Cp855", "Cp856",
125       "Cp857", "Cp860", "Cp861",
126       "Cp862", "Cp863", "Cp864", "Cp865", "Cp866", "Cp868", "Cp869", "Cp870",
127       "Cp871", "Cp874", "Cp875",
128       "Cp918", "Cp921", "Cp922", "Cp930", "Cp933", "Cp935", "Cp937", "Cp939",
129       "Cp942", "Cp948", "Cp949",
130       "Cp950", "Cp964", "Cp970", "Cp1006", "Cp1025", "Cp1026", "Cp1046",
131       "Cp1097", "Cp1098", "Cp1112",
132       "Cp1122", "Cp1123", "Cp1124", "Cp1250", "Cp1251", "Cp1252", "Cp1253",
133       "Cp1254", "Cp1255", "Cp1256",
134       "Cp1257", "Cp1258", "Cp1381", "Cp1383", "Cp33722", "MS874",
135       "EUCJIS", "GB2312",
136        "GBK", "ISO2022CN_CNS", "ISO2022CN_GB",
137       "JIS",
138       "JIS0208", "KOI8_R", "KSC5601","MS874",
139       "SJIS", "Big5", "CNS11643",
140       "MacArabic", "MacCentralEurope", "MacCroatian", "MacCyrillic",
141       "MacDingbat", "MacGreek",
142       "MacHebrew", "MacIceland", "MacRoman", "MacRomania", "MacSymbol",
143       "MacThai", "MacTurkish",
144       "MacUkraine", "SJIS", "Unicode", "UnicodeBig", "UnicodeLittle", "UTF8"};
145 */

146
147     /** Print writer. */
148     protected PrintWriter JavaDoc out;
149
150     /** Canonical output. */
151     protected boolean canonical;
152
153
154     public DOMWriter(String JavaDoc encoding, boolean canonical)
155     throws UnsupportedEncodingException JavaDoc {
156         out = new PrintWriter JavaDoc(new OutputStreamWriter JavaDoc(System.out, encoding));
157         this.canonical = canonical;
158     } // <init>(String,boolean)
159

160     //
161
// Constructors
162
//
163

164     /** Default constructor. */
165     public DOMWriter(boolean canonical) throws UnsupportedEncodingException JavaDoc {
166         this( getWriterEncoding(), canonical);
167     }
168
169     public static String JavaDoc getWriterEncoding( ) {
170         return(PRINTWRITER_ENCODING);
171     }// getWriterEncoding
172

173     public static void setWriterEncoding( String JavaDoc encoding ) {
174         if ( encoding.equalsIgnoreCase( "DEFAULT" ) )
175             PRINTWRITER_ENCODING = "UTF8";
176         else if ( encoding.equalsIgnoreCase( "UTF-16" ) )
177             PRINTWRITER_ENCODING = "Unicode";
178         else
179             PRINTWRITER_ENCODING = MIME2Java.convert( encoding );
180     }// setWriterEncoding
181

182
183     public static boolean isValidJavaEncoding( String JavaDoc encoding ) {
184         for ( int i = 0; i < MIME2JAVA_ENCODINGS.length; i++ )
185             if ( encoding.equals( MIME2JAVA_ENCODINGS[i] ) )
186                 return(true);
187
188         return(false);
189     }// isValidJavaEncoding
190

191
192
193     /** Prints the resulting document tree. */
194     public static void print(String JavaDoc parserWrapperName, String JavaDoc uri,
195                              boolean canonical ) {
196         try {
197             DOMParserWrapper parser =
198             (DOMParserWrapper)Class.forName(parserWrapperName).newInstance();
199
200             parser.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion",
201                                setDeferredDOM );
202             parser.setFeature( "http://xml.org/sax/features/validation",
203                                setValidation );
204             parser.setFeature( "http://xml.org/sax/features/namespaces",
205                                setNameSpaces );
206             parser.setFeature( "http://apache.org/xml/features/validation/schema",
207                                setSchemaSupport );
208             parser.setFeature( "http://apache.org/xml/features/validation/schema-full-checking",
209                                setSchemaFullSupport );
210
211             Document JavaDoc document = parser.parse(uri);
212             DOMWriter writer = new DOMWriter(canonical);
213             writer.print(document);
214         } catch ( Exception JavaDoc e ) {
215             //e.printStackTrace(System.err);
216
}
217
218     } // print(String,String,boolean)
219

220
221     /** Prints the specified node, recursively. */
222     public void print(Node JavaDoc node) {
223
224         // is there anything to do?
225
if ( node == null ) {
226             return;
227         }
228
229         int type = node.getNodeType();
230         switch ( type ) {
231         // print document
232
case Node.DOCUMENT_NODE: {
233                 if ( !canonical ) {
234                     String JavaDoc Encoding = getWriterEncoding();
235                     if ( Encoding.equalsIgnoreCase( "DEFAULT" ) )
236                         Encoding = "UTF-8";
237                     else if ( Encoding.equalsIgnoreCase( "Unicode" ) )
238                         Encoding = "UTF-16";
239                     else
240                         Encoding = MIME2Java.reverse( Encoding );
241
242                     out.println("<?xml version=\"1.0\" encoding=\""+
243                                 Encoding + "\"?>");
244                 }
245                 //print(((Document)node).getDocumentElement());
246

247                 NodeList JavaDoc children = node.getChildNodes();
248                 for ( int iChild = 0; iChild < children.getLength(); iChild++ ) {
249                     print(children.item(iChild));
250                 }
251                 out.flush();
252                 break;
253             }
254
255             // print element with attributes
256
case Node.ELEMENT_NODE: {
257                 out.print('<');
258                 out.print(node.getNodeName());
259                 Attr JavaDoc attrs[] = sortAttributes(node.getAttributes());
260                 for ( int i = 0; i < attrs.length; i++ ) {
261                     Attr JavaDoc attr = attrs[i];
262                     out.print(' ');
263                     out.print(attr.getNodeName());
264                     out.print("=\"");
265                     out.print(normalize(attr.getNodeValue()));
266                     out.print('"');
267                 }
268                 out.print('>');
269                 NodeList JavaDoc children = node.getChildNodes();
270                 if ( children != null ) {
271                     int len = children.getLength();
272                     for ( int i = 0; i < len; i++ ) {
273                         print(children.item(i));
274                     }
275                 }
276                 break;
277             }
278
279             // handle entity reference nodes
280
case Node.ENTITY_REFERENCE_NODE: {
281                 if ( canonical ) {
282                     NodeList JavaDoc children = node.getChildNodes();
283                     if ( children != null ) {
284                         int len = children.getLength();
285                         for ( int i = 0; i < len; i++ ) {
286                             print(children.item(i));
287                         }
288                     }
289                 } else {
290                     out.print('&');
291                     out.print(node.getNodeName());
292                     out.print(';');
293                 }
294                 break;
295             }
296
297             // print cdata sections
298
case Node.CDATA_SECTION_NODE: {
299                 if ( canonical ) {
300                     out.print(normalize(node.getNodeValue()));
301                 } else {
302                     out.print("<![CDATA[");
303                     out.print(node.getNodeValue());
304                     out.print("]]>");
305                 }
306                 break;
307             }
308
309             // print text
310
case Node.TEXT_NODE: {
311                 out.print(normalize(node.getNodeValue()));
312                 break;
313             }
314
315             // print processing instruction
316
case Node.PROCESSING_INSTRUCTION_NODE: {
317                 out.print("<?");
318                 out.print(node.getNodeName());
319                 String JavaDoc data = node.getNodeValue();
320                 if ( data != null && data.length() > 0 ) {
321                     out.print(' ');
322                     out.print(data);
323                 }
324                 out.println("?>");
325                 break;
326             }
327         }
328
329         if ( type == Node.ELEMENT_NODE ) {
330             out.print("</");
331             out.print(node.getNodeName());
332             out.print('>');
333         }
334
335         out.flush();
336
337     } // print(Node)
338

339     /** Returns a sorted list of attributes. */
340     protected Attr JavaDoc[] sortAttributes(NamedNodeMap JavaDoc attrs) {
341
342         int len = (attrs != null) ? attrs.getLength() : 0;
343         Attr JavaDoc array[] = new Attr JavaDoc[len];
344         for ( int i = 0; i < len; i++ ) {
345             array[i] = (Attr JavaDoc)attrs.item(i);
346         }
347         for ( int i = 0; i < len - 1; i++ ) {
348             String JavaDoc name = array[i].getNodeName();
349             int index = i;
350             for ( int j = i + 1; j < len; j++ ) {
351                 String JavaDoc curName = array[j].getNodeName();
352                 if ( curName.compareTo(name) < 0 ) {
353                     name = curName;
354                     index = j;
355                 }
356             }
357             if ( index != i ) {
358                 Attr JavaDoc temp = array[i];
359                 array[i] = array[index];
360                 array[index] = temp;
361             }
362         }
363
364         return(array);
365
366     } // sortAttributes(NamedNodeMap):Attr[]
367

368
369     //
370
// Main
371
//
372

373     /** Main program entry point. */
374     public static void main(String JavaDoc argv[]) {
375         Arguments argopt = new Arguments();
376         argopt.setUsage( new String JavaDoc[] {
377                              "usage: java dom.DOMWriter (options) uri ...","",
378                              "options:",
379                              " -n | -N Turn on/off namespace [default=on]",
380                              " -v | -V Turn on/off validation [default=off]",
381                              " -s | -S Turn on/off Schema support [default=on]",
382                              " -f | -F Turn on/off Schema full consraint checking [default=off]",
383                              " -d | -D Turn on/off deferred DOM [default=on]",
384                              " -c Canonical XML output.",
385                              " -h This help screen.",
386                              " -e Output Java Encoding.",
387                              " Default encoding: UTF-8"} );
388
389
390
391         // is there anything to do?
392
if ( argv.length == 0 ) {
393             argopt.printUsage();
394             System.exit(1);
395         }
396
397         // vars
398
String JavaDoc parserName = DEFAULT_PARSER_NAME;
399         boolean canonical = false;
400         String JavaDoc encoding = "UTF8"; // default encoding
401

402         argopt.parseArgumentTokens(argv, new char[] { 'p', 'e'} );
403
404         int c;
405         String JavaDoc arg = null;
406         while ( ( arg = argopt.getlistFiles() ) != null ) {
407
408             outer:
409             while ( (c = argopt.getArguments()) != -1 ){
410                 switch (c) {
411                 case 'c':
412                     canonical = true;
413                     break;
414                 case 'e':
415                     encoding = argopt.getStringParameter();
416                     if ( encoding != null && isValidJavaEncoding( encoding ) )
417                         setWriterEncoding( encoding );
418                     else {
419                         printValidJavaEncoding();
420                         System.exit( 1 );
421                     }
422                     break;
423                 case 'v':
424                     setValidation = true;
425                     break;
426                 case 'V':
427                     setValidation = false;
428                     break;
429                 case 'N':
430                     setNameSpaces = false;
431                     break;
432                 case 'n':
433                     setNameSpaces = true;
434                     break;
435                 case 'p':
436                     parserName = argopt.getStringParameter();
437                     break;
438                 case 'd':
439                     setDeferredDOM = true;
440                     break;
441                 case 'D':
442                     setDeferredDOM = false;
443                     break;
444                 case 's':
445                     setSchemaSupport = true;
446                     break;
447                 case 'S':
448                     setSchemaSupport = false;
449                     break;
450                 case 'f':
451                     setSchemaFullSupport = true;
452                     break;
453                 case 'F':
454                     setSchemaFullSupport = false;
455                     break;
456                 case '?':
457                 case 'h':
458                 case '-':
459                     argopt.printUsage();
460                     System.exit(1);
461                     break;
462                 case -1:
463                     break outer;
464                 default:
465                     break;
466                 }
467             }
468             // print uri
469
// print uri
470
System.err.println(arg+':');
471             print(parserName, arg, canonical );
472             System.err.println();
473         }
474     } // main(String[])
475

476
477     /** Normalizes the given string. */
478     protected String JavaDoc normalize(String JavaDoc s) {
479         StringBuffer JavaDoc str = new StringBuffer JavaDoc();
480
481         int len = (s != null) ? s.length() : 0;
482         for ( int i = 0; i < len; i++ ) {
483             char ch = s.charAt(i);
484             switch ( ch ) {
485             case '<': {
486                     str.append("&lt;");
487                     break;
488                 }
489             case '>': {
490                     str.append("&gt;");
491                     break;
492                 }
493             case '&': {
494                     str.append("&amp;");
495                     break;
496                 }
497             case '"': {
498                     str.append("&quot;");
499                     break;
500                 }
501             case '\'': {
502                     str.append("&apos;");
503                     break;
504                 }
505             case '\r':
506             case '\n': {
507                     if ( canonical ) {
508                         str.append("&#");
509                         str.append(Integer.toString(ch));
510                         str.append(';');
511                         break;
512                     }
513                     // else, default append char
514
}
515             default: {
516                     str.append(ch);
517                 }
518             }
519         }
520
521         return(str.toString());
522
523     } // normalize(String):String
524

525
526     private static void printValidJavaEncoding() {
527         System.err.println( " ENCODINGS:" );
528         System.err.print( " " );
529         for ( int i = 0;
530             i < MIME2JAVA_ENCODINGS.length; i++) {
531             System.err.print( MIME2JAVA_ENCODINGS[i] + " " );
532             if ( (i % 7 ) == 0 ){
533                 System.err.println();
534                 System.err.print( " " );
535             }
536         }
537
538     } // printJavaEncoding()
539

540 }
541
Popular Tags