KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > util > DOMWriter


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.catalina.util;
19
20 import java.io.OutputStreamWriter JavaDoc;
21 import java.io.PrintWriter JavaDoc;
22 import java.io.UnsupportedEncodingException JavaDoc;
23 import java.io.Writer JavaDoc;
24
25 import org.w3c.dom.Attr JavaDoc;
26 import org.w3c.dom.Document JavaDoc;
27 import org.w3c.dom.NamedNodeMap JavaDoc;
28 import org.w3c.dom.Node JavaDoc;
29 import org.w3c.dom.NodeList JavaDoc;
30
31 /**
32  * A sample DOM writer. This sample program illustrates how to
33  * traverse a DOM tree in order to print a document that is parsed.
34  */

35 public class DOMWriter {
36
37    //
38
// Data
39
//
40

41    /** Default Encoding */
42    private static String JavaDoc
43    PRINTWRITER_ENCODING = "UTF8";
44
45    private static String JavaDoc 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    /** Output qualified names */
56    private boolean qualifiedNames = true;
57
58    /** Print writer. */
59    protected PrintWriter JavaDoc out;
60
61    /** Canonical output. */
62    protected boolean canonical;
63
64
65    public DOMWriter(String JavaDoc encoding, boolean canonical)
66    throws UnsupportedEncodingException JavaDoc {
67       out = new PrintWriter JavaDoc(new OutputStreamWriter JavaDoc(System.out, encoding));
68       this.canonical = canonical;
69    } // <init>(String,boolean)
70

71    //
72
// Constructors
73
//
74

75    /** Default constructor. */
76    public DOMWriter(boolean canonical) throws UnsupportedEncodingException JavaDoc {
77       this( getWriterEncoding(), canonical);
78    }
79
80     public DOMWriter(Writer JavaDoc writer, boolean canonical) {
81         out = new PrintWriter JavaDoc(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 JavaDoc getWriterEncoding( ) {
94       return (PRINTWRITER_ENCODING);
95    }// getWriterEncoding
96

97    public static void setWriterEncoding( String JavaDoc 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    }// setWriterEncoding
105

106
107    public static boolean isValidJavaEncoding( String JavaDoc 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    }// isValidJavaEncoding
114

115
116    /** Prints the specified node, recursively. */
117    public void print(Node JavaDoc node) {
118
119       // is there anything to do?
120
if ( node == null ) {
121          return;
122       }
123
124       int type = node.getNodeType();
125       switch ( type ) {
126          // print document
127
case Node.DOCUMENT_NODE: {
128                if ( !canonical ) {
129                   String JavaDoc 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 JavaDoc)node).getDocumentElement());
141                out.flush();
142                break;
143             }
144
145             // print element with attributes
146
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 JavaDoc attrs[] = sortAttributes(node.getAttributes());
154                for ( int i = 0; i < attrs.length; i++ ) {
155                   Attr JavaDoc 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 JavaDoc 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             // handle entity reference nodes
179
case Node.ENTITY_REFERENCE_NODE: {
180                if ( canonical ) {
181                   NodeList JavaDoc 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             // print cdata sections
201
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             // print text
213
case Node.TEXT_NODE: {
214                out.print(normalize(node.getNodeValue()));
215                break;
216             }
217
218             // print processing instruction
219
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 JavaDoc 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    } // print(Node)
250

251    /** Returns a sorted list of attributes. */
252    protected Attr JavaDoc[] sortAttributes(NamedNodeMap JavaDoc attrs) {
253
254       int len = (attrs != null) ? attrs.getLength() : 0;
255       Attr JavaDoc array[] = new Attr JavaDoc[len];
256       for ( int i = 0; i < len; i++ ) {
257          array[i] = (Attr JavaDoc)attrs.item(i);
258       }
259       for ( int i = 0; i < len - 1; i++ ) {
260          String JavaDoc 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 JavaDoc 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 JavaDoc temp = array[i];
281             array[i] = array[index];
282             array[index] = temp;
283          }
284       }
285
286       return (array);
287
288    } // sortAttributes(NamedNodeMap):Attr[]
289

290
291    /** Normalizes the given string. */
292    protected String JavaDoc normalize(String JavaDoc s) {
293       StringBuffer JavaDoc str = new StringBuffer JavaDoc();
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("&lt;");
301                   break;
302                }
303             case '>': {
304                   str.append("&gt;");
305                   break;
306                }
307             case '&': {
308                   str.append("&amp;");
309                   break;
310                }
311             case '"': {
312                   str.append("&quot;");
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                   // else, default append char
324
}
325             default: {
326                   str.append(ch);
327                }
328          }
329       }
330
331       return (str.toString());
332
333    } // normalize(String):String
334

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    } // printJavaEncoding()
348

349 }
350
Popular Tags