KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > soap > util > xml > DOM2Writer


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 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 "SOAP" 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) 2000, 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 org.apache.soap.util.xml;
59
60 import java.io.*;
61 import java.util.*;
62 import org.w3c.dom.*;
63 import org.apache.soap.util.*;
64
65 /**
66  * This class is a utility to serialize a DOM node as XML. This class
67  * uses the <code>DOM Level 2</code> APIs.
68  * The main difference between this class and DOMWriter is that this class
69  * generates and prints out namespace declarations.
70  *
71  * @author Matthew J. Duftler (duftler@us.ibm.com)
72  * @author Joseph Kesselman
73  */

74 public class DOM2Writer
75 {
76   /**
77    * The namespaceURI represented by the prefix <code>xmlns</code>.
78    */

79   private static String JavaDoc NS_URI_XMLNS = "http://www.w3.org/2000/xmlns/";
80
81   /**
82    * Return a string containing this node serialized as XML.
83    */

84   public static String JavaDoc nodeToString(Node node)
85   {
86     StringWriter sw = new StringWriter();
87
88     serializeAsXML(node, sw);
89
90     return sw.toString();
91   }
92
93   /**
94   * Serialize this node into the writer as XML.
95   */

96   public static void serializeAsXML(Node node, Writer writer)
97   {
98     print(node, null, new PrintWriter(writer));
99   }
100
101   private static void print(Node node, ObjectRegistry namespaceStack,
102                             PrintWriter out)
103   {
104     if (node == null)
105     {
106       return;
107     }
108
109     boolean hasChildren = false;
110     int type = node.getNodeType();
111
112     switch (type)
113     {
114       case Node.DOCUMENT_NODE :
115       {
116         out.println("<?xml version=\"1.0\"?>");
117
118         NodeList children = node.getChildNodes();
119
120         if (children != null)
121         {
122           int numChildren = children.getLength();
123
124           for (int i = 0; i < numChildren; i++)
125           {
126             print(children.item(i), namespaceStack, out);
127           }
128         }
129         break;
130       }
131
132       case Node.ELEMENT_NODE :
133       {
134         namespaceStack = new ObjectRegistry(namespaceStack);
135
136         out.print('<' + node.getNodeName());
137
138         String JavaDoc elPrefix = node.getPrefix();
139         String JavaDoc elNamespaceURI = node.getNamespaceURI();
140
141         if (elPrefix != null && elNamespaceURI != null)
142         {
143           boolean prefixIsDeclared = false;
144
145           try
146           {
147             String JavaDoc namespaceURI = (String JavaDoc)namespaceStack.lookup(elPrefix);
148
149             if (elNamespaceURI.equals(namespaceURI))
150             {
151               prefixIsDeclared = true;
152             }
153           }
154           catch (IllegalArgumentException JavaDoc e)
155           {
156           }
157
158           if (!prefixIsDeclared)
159           {
160             printNamespaceDecl(node, namespaceStack, out);
161           }
162         }
163
164         NamedNodeMap attrs = node.getAttributes();
165         int len = (attrs != null) ? attrs.getLength() : 0;
166
167         for (int i = 0; i < len; i++)
168         {
169           Attr attr = (Attr)attrs.item(i);
170
171           out.print(' ' + attr.getNodeName() +"=\"" +
172                     normalize(attr.getValue()) + '\"');
173
174           String JavaDoc attrPrefix = attr.getPrefix();
175           String JavaDoc attrNamespaceURI = attr.getNamespaceURI();
176
177           if (attrPrefix != null && attrNamespaceURI != null)
178           {
179             boolean prefixIsDeclared = false;
180
181             try
182             {
183               String JavaDoc namespaceURI = (String JavaDoc)namespaceStack.lookup(attrPrefix);
184
185               if (attrNamespaceURI.equals(namespaceURI))
186               {
187                 prefixIsDeclared = true;
188               }
189             }
190             catch (IllegalArgumentException JavaDoc e)
191             {
192             }
193
194             if (!prefixIsDeclared)
195             {
196               printNamespaceDecl(attr, namespaceStack, out);
197             }
198           }
199         }
200
201         NodeList children = node.getChildNodes();
202
203         if (children != null)
204         {
205           int numChildren = children.getLength();
206
207           hasChildren = (numChildren > 0);
208
209           if (hasChildren)
210           {
211             out.print('>');
212           }
213
214           for (int i = 0; i < numChildren; i++)
215           {
216             print(children.item(i), namespaceStack, out);
217           }
218         }
219         else
220         {
221           hasChildren = false;
222         }
223
224         if (!hasChildren)
225         {
226           out.print("/>");
227         }
228         break;
229       }
230
231       case Node.ENTITY_REFERENCE_NODE :
232       {
233         out.print('&');
234         out.print(node.getNodeName());
235         out.print(';');
236         break;
237       }
238
239       case Node.CDATA_SECTION_NODE :
240       {
241         out.print("<![CDATA[");
242         out.print(node.getNodeValue());
243         out.print("]]>");
244         break;
245       }
246
247       case Node.TEXT_NODE :
248       {
249         out.print(normalize(node.getNodeValue()));
250         break;
251       }
252
253       case Node.COMMENT_NODE :
254       {
255         out.print("<!--");
256         out.print(node.getNodeValue());
257         out.print("-->");
258         break;
259       }
260
261       case Node.PROCESSING_INSTRUCTION_NODE :
262       {
263         out.print("<?");
264         out.print(node.getNodeName());
265
266         String JavaDoc data = node.getNodeValue();
267
268         if (data != null && data.length() > 0)
269         {
270           out.print(' ');
271           out.print(data);
272         }
273
274         out.println("?>");
275         break;
276       }
277     }
278
279     if (type == Node.ELEMENT_NODE && hasChildren == true)
280     {
281       out.print("</");
282       out.print(node.getNodeName());
283       out.print('>');
284       hasChildren = false;
285     }
286   }
287
288   private static void printNamespaceDecl(Node node,
289                                          ObjectRegistry namespaceStack,
290                                          PrintWriter out)
291   {
292     switch (node.getNodeType())
293     {
294       case Node.ATTRIBUTE_NODE :
295       {
296         printNamespaceDecl(((Attr)node).getOwnerElement(), node,
297                            namespaceStack, out);
298         break;
299       }
300
301       case Node.ELEMENT_NODE :
302       {
303         printNamespaceDecl((Element)node, node, namespaceStack, out);
304         break;
305       }
306     }
307   }
308
309   private static void printNamespaceDecl(Element owner, Node node,
310                                          ObjectRegistry namespaceStack,
311                                          PrintWriter out)
312   {
313     String JavaDoc namespaceURI = node.getNamespaceURI();
314     String JavaDoc prefix = node.getPrefix();
315
316     if (!(namespaceURI.equals(NS_URI_XMLNS) && prefix.equals("xmlns")))
317     {
318       if (DOMUtils.getAttributeNS(owner, NS_URI_XMLNS, prefix) == null)
319       {
320         out.print(" xmlns:" + prefix + "=\"" + namespaceURI + '\"');
321       }
322     }
323     else
324     {
325       prefix = node.getLocalName();
326       namespaceURI = node.getNodeValue();
327     }
328
329     namespaceStack.register(prefix, namespaceURI);
330   }
331
332   private static String JavaDoc normalize(String JavaDoc s)
333   {
334     StringBuffer JavaDoc str = new StringBuffer JavaDoc();
335     int len = (s != null) ? s.length() : 0;
336
337     for (int i = 0; i < len; i++)
338     {
339       char ch = s.charAt(i);
340
341       switch (ch)
342       {
343         case '<' :
344         {
345           str.append("&lt;");
346           break;
347         }
348         case '>' :
349         {
350           str.append("&gt;");
351           break;
352         }
353         case '&' :
354         {
355           str.append("&amp;");
356           break;
357         }
358         case '"' :
359         {
360           str.append("&quot;");
361           break;
362         }
363         case '\n' :
364         {
365           if (i > 0)
366           {
367             char lastChar = str.charAt(str.length() - 1);
368
369             if (lastChar != '\r')
370             {
371               str.append(StringUtils.lineSeparator);
372             }
373             else
374             {
375               str.append('\n');
376             }
377           }
378           else
379           {
380             str.append(StringUtils.lineSeparator);
381           }
382           break;
383         }
384         default :
385         {
386           str.append(ch);
387         }
388       }
389     }
390
391     return (str.toString());
392   }
393 }
394
Popular Tags