KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > groovy > tools > xml > DomToGroovy


1 /*
2  $Id: DomToGroovy.java,v 1.5 2003/11/04 12:00:48 jstrachan Exp $
3
4  Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5
6  Redistribution and use of this software and associated documentation
7  ("Software"), with or without modification, are permitted provided
8  that the following conditions are met:
9
10  1. Redistributions of source code must retain copyright
11     statements and notices. Redistributions must also contain a
12     copy of this document.
13
14  2. Redistributions in binary form must reproduce the
15     above copyright notice, this list of conditions and the
16     following disclaimer in the documentation and/or other
17     materials provided with the distribution.
18
19  3. The name "groovy" must not be used to endorse or promote
20     products derived from this Software without prior written
21     permission of The Codehaus. For written permission,
22     please contact info@codehaus.org.
23
24  4. Products derived from this Software may not be called "groovy"
25     nor may "groovy" appear in their names without prior written
26     permission of The Codehaus. "groovy" is a registered
27     trademark of The Codehaus.
28
29  5. Due credit should be given to The Codehaus -
30     http://groovy.codehaus.org/
31
32  THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
36  THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43  OF THE POSSIBILITY OF SUCH DAMAGE.
44
45  */

46 package org.codehaus.groovy.tools.xml;
47
48 import groovy.util.IndentPrinter;
49
50 import java.io.PrintWriter JavaDoc;
51 import java.util.HashMap JavaDoc;
52 import java.util.Map JavaDoc;
53
54 import org.w3c.dom.Attr JavaDoc;
55 import org.w3c.dom.Comment JavaDoc;
56 import org.w3c.dom.Document JavaDoc;
57 import org.w3c.dom.Element JavaDoc;
58 import org.w3c.dom.NamedNodeMap JavaDoc;
59 import org.w3c.dom.Node JavaDoc;
60 import org.w3c.dom.NodeList JavaDoc;
61 import org.w3c.dom.ProcessingInstruction JavaDoc;
62 import org.w3c.dom.Text JavaDoc;
63
64 /**
65  * A SAX handler for turning XML into Groovy scripts
66  *
67  * @author <a HREF="mailto:james@coredevelopers.net">James Strachan</a>
68  * @version $Revision: 1.5 $
69  */

70 public class DomToGroovy {
71
72     private IndentPrinter out;
73
74     public DomToGroovy(PrintWriter JavaDoc out) {
75         this(new IndentPrinter(out));
76     }
77
78     public DomToGroovy(IndentPrinter out) {
79         this.out = out;
80     }
81
82
83     public void print(Document JavaDoc document) {
84         printChildren(document, new HashMap JavaDoc());
85     }
86
87     // Implementation methods
88
//-------------------------------------------------------------------------
89
protected void print(Node JavaDoc node, Map JavaDoc namespaces, boolean endWithComma) {
90         switch (node.getNodeType()) {
91             case Node.ELEMENT_NODE :
92                 printElement((Element JavaDoc) node, namespaces, endWithComma);
93                 break;
94             case Node.PROCESSING_INSTRUCTION_NODE :
95                 printPI((ProcessingInstruction JavaDoc) node, endWithComma);
96                 break;
97             case Node.TEXT_NODE :
98                 printText((Text JavaDoc) node, endWithComma);
99                 break;
100             case Node.COMMENT_NODE :
101                 printComment((Comment JavaDoc) node, endWithComma);
102                 break;
103         }
104     }
105
106     protected void printElement(Element JavaDoc element, Map JavaDoc namespaces, boolean endWithComma) {
107         namespaces = defineNamespaces(element, namespaces);
108
109         element.normalize();
110         printIndent();
111
112         String JavaDoc prefix = element.getPrefix();
113         if (prefix != null && prefix.length() > 0) {
114             print(prefix);
115             print(".");
116         }
117         print(getLocalName(element));
118
119         boolean hasAttributes = printAttributes(element);
120
121         NodeList JavaDoc list = element.getChildNodes();
122         int length = list.getLength();
123         if (length == 0) {
124             printEnd("", endWithComma);
125         }
126         else {
127             Node JavaDoc node = list.item(0);
128             if (length == 1 && node instanceof Text JavaDoc) {
129                 Text JavaDoc textNode = (Text JavaDoc) node;
130                 String JavaDoc text = getTextNodeData(textNode);
131                 if (hasAttributes) {
132                     print(" [\"");
133                     print(text);
134                     printEnd("\"]", endWithComma);
135                 }
136                 else {
137                     print("(\"");
138                     print(text);
139                     printEnd("\")", endWithComma);
140                 }
141             }
142             else if (mixedContent(list)) {
143                 println(" [");
144                 out.incrementIndent();
145                 for (node = element.getFirstChild(); node != null; node = node.getNextSibling()) {
146                     boolean useComma = node.getNextSibling() != null;
147                     print(node, namespaces, useComma);
148                 }
149                 out.decrementIndent();
150                 printIndent();
151                 printEnd("]", endWithComma);
152             }
153             else {
154                 println(" {");
155                 out.incrementIndent();
156                 printChildren(element, namespaces);
157                 out.decrementIndent();
158                 printIndent();
159                 printEnd("}", endWithComma);
160             }
161         }
162     }
163
164     protected void printPI(ProcessingInstruction JavaDoc instruction, boolean endWithComma) {
165         printIndent();
166         print("xml.pi('");
167         print(instruction.getTarget());
168         print("', '");
169         print(instruction.getData());
170         printEnd("');", endWithComma);
171     }
172
173     protected void printComment(Comment JavaDoc comment, boolean endWithComma) {
174         String JavaDoc text = comment.getData().trim();
175         if (text.length() >0) {
176             printIndent();
177             print("/* ");
178             print(text);
179             printEnd(" */", endWithComma);
180         }
181     }
182
183     protected void printText(Text JavaDoc node, boolean endWithComma) {
184         String JavaDoc text = getTextNodeData(node);
185         if (text.length() > 0) {
186             printIndent();
187             // print("xml.append('");
188
// print(text);
189
// println("');");
190
print("\"");
191             print(text);
192             printEnd("\"", endWithComma);
193         }
194     }
195
196     protected Map JavaDoc defineNamespaces(Element JavaDoc element, Map JavaDoc namespaces) {
197         Map JavaDoc answer = null;
198         String JavaDoc prefix = element.getPrefix();
199         if (prefix != null && prefix.length() > 0 && !namespaces.containsKey(prefix)) {
200             answer = new HashMap JavaDoc(namespaces);
201             defineNamespace(answer, prefix, element.getNamespaceURI());
202         }
203         NamedNodeMap JavaDoc attributes = element.getAttributes();
204         int length = attributes.getLength();
205         for (int i = 0; i < length; i++) {
206             Attr JavaDoc attribute = (Attr JavaDoc) attributes.item(i);
207             prefix = attribute.getPrefix();
208             if (prefix != null && prefix.length() > 0 && !namespaces.containsKey(prefix)) {
209                 if (answer == null) {
210                     answer = new HashMap JavaDoc(namespaces);
211                 }
212                 defineNamespace(answer, prefix, attribute.getNamespaceURI());
213             }
214         }
215         return (answer != null) ? answer : namespaces;
216     }
217
218     protected void defineNamespace(Map JavaDoc namespaces, String JavaDoc prefix, String JavaDoc uri) {
219         namespaces.put(prefix, uri);
220         if (!prefix.equals("xmlns") && !prefix.equals("xml")) {
221             printIndent();
222             print(prefix);
223             print(" = xmlns.namespace('");
224             print(uri);
225             println("')");
226         }
227     }
228
229     protected boolean printAttributes(Element JavaDoc element) {
230         boolean hasAttribute = false;
231
232         NamedNodeMap JavaDoc attributes = element.getAttributes();
233         int length = attributes.getLength();
234         if (length > 0) {
235             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
236             for (int i = 0; i < length; i++) {
237                 Attr JavaDoc attribute = (Attr JavaDoc) attributes.item(i);
238                 String JavaDoc prefix = attribute.getPrefix();
239                 if (prefix != null && prefix.length() > 0) {
240                     if (buffer.length() > 0) {
241                         buffer.append(", ");
242                     }
243                     buffer.append(prefix);
244                     buffer.append(".");
245                     buffer.append(getLocalName(attribute));
246                     buffer.append(":'");
247                     buffer.append(attribute.getValue());
248                     buffer.append("'");
249                 }
250             }
251
252             print("(");
253             for (int i = 0; i < length; i++) {
254                 Attr JavaDoc attribute = (Attr JavaDoc) attributes.item(i);
255                 String JavaDoc prefix = attribute.getPrefix();
256                 if (prefix == null || prefix.length() == 0) {
257                     if (!hasAttribute) {
258                         hasAttribute = true;
259                     }
260                     else {
261                         print(", ");
262                     }
263                     print(getLocalName(attribute));
264                     print(":'");
265                     print(attribute.getValue());
266                     print("'");
267                 }
268             }
269             if (buffer.length() > 0) {
270                 if (hasAttribute) {
271                     print(", ");
272                 }
273                 print("xmlns=[");
274                 print(buffer.toString());
275                 print("]");
276                 hasAttribute = true;
277             }
278             print(")");
279         }
280         return hasAttribute;
281     }
282
283     protected String JavaDoc getTextNodeData(Text JavaDoc node) {
284         String JavaDoc text = node.getData().trim();
285         return text;
286     }
287
288     protected boolean mixedContent(NodeList JavaDoc list) {
289         boolean hasText = false;
290         boolean hasElement = false;
291         for (int i = 0, size = list.getLength(); i < size; i++) {
292             Node JavaDoc node = list.item(i);
293             if (node instanceof Element JavaDoc) {
294                 hasElement = true;
295             }
296             else if (node instanceof Text JavaDoc) {
297                 String JavaDoc text = getTextNodeData((Text JavaDoc) node);
298                 if (text.length() > 0) {
299                     hasText = true;
300                 }
301             }
302         }
303         return hasText && hasElement;
304     }
305
306     protected void printChildren(Node JavaDoc parent, Map JavaDoc namespaces) {
307         for (Node JavaDoc node = parent.getFirstChild(); node != null; node = node.getNextSibling()) {
308             print(node, namespaces, false);
309         }
310     }
311
312     protected String JavaDoc getLocalName(Node JavaDoc node) {
313         String JavaDoc answer = node.getLocalName();
314         if (answer == null) {
315             answer = node.getNodeName();
316         }
317         return answer.trim();
318     }
319
320     protected void printEnd(String JavaDoc text, boolean endWithComma) {
321         if (endWithComma) {
322             print(text);
323             println(",");
324         }
325         else {
326             println(text);
327         }
328     }
329
330     protected void println(String JavaDoc text) {
331         out.println(text); }
332
333     protected void print(String JavaDoc text) {
334         out.print(text);
335     }
336
337     protected void printIndent() {
338         out.printIndent();
339     }
340 }
341
Popular Tags