KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdom > input > DOMBuilder


1 /*--
2
3  $Id: DOMBuilder.java,v 1.59 2004/09/03 06:03:41 jhunter Exp $
4
5  Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
6  All rights 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 disclaimer that follows
17     these conditions in the documentation and/or other materials
18     provided with the distribution.
19
20  3. The name "JDOM" must not be used to endorse or promote products
21     derived from this software without prior written permission. For
22     written permission, please contact <request_AT_jdom_DOT_org>.
23
24  4. Products derived from this software may not be called "JDOM", nor
25     may "JDOM" appear in their name, without prior written permission
26     from the JDOM Project Management <request_AT_jdom_DOT_org>.
27
28  In addition, we request (but do not require) that you include in the
29  end-user documentation provided with the redistribution and/or in the
30  software itself an acknowledgement equivalent to the following:
31      "This product includes software developed by the
32       JDOM Project (http://www.jdom.org/)."
33  Alternatively, the acknowledgment may be graphical using the logos
34  available at http://www.jdom.org/images/logos.
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 JDOM AUTHORS OR THE PROJECT
40  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  This software consists of voluntary contributions made by many
50  individuals on behalf of the JDOM Project and was originally
51  created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52  Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
53  on the JDOM Project, please see <http://www.jdom.org/>.
54
55  */

56
57 package org.jdom.input;
58
59 import org.jdom.*;
60 import org.jdom.Document;
61 import org.jdom.Element;
62 import org.w3c.dom.*;
63
64 /**
65  * Builds a JDOM {@link org.jdom.Document org.jdom.Document} from a pre-existing
66  * DOM {@link org.w3c.dom.Document org.w3c.dom.Document}. Also handy for testing
67  * builds from files to sanity check {@link SAXBuilder}.
68  *
69  * @version $Revision: 1.59 $, $Date: 2004/09/03 06:03:41 $
70  * @author Brett McLaughlin
71  * @author Jason Hunter
72  * @author Philip Nelson
73  * @author Kevin Regan
74  * @author Yusuf Goolamabbas
75  * @author Dan Schaffer
76  * @author Bradley S. Huffman
77  */

78 public class DOMBuilder {
79
80     private static final String JavaDoc CVS_ID =
81       "@(#) $RCSfile: DOMBuilder.java,v $ $Revision: 1.59 $ $Date: 2004/09/03 06:03:41 $ $Name: $";
82
83     /** Adapter class to use */
84     private String JavaDoc adapterClass;
85
86     /** The factory for creating new JDOM objects */
87     private JDOMFactory factory = new DefaultJDOMFactory();
88
89     /**
90      * This creates a new DOMBuilder which will attempt to first locate
91      * a parser via JAXP, then will try to use a set of default parsers.
92      * The underlying parser will not validate.
93      */

94     public DOMBuilder() {
95     }
96
97     /**
98      * This creates a new DOMBuilder using the specified DOMAdapter
99      * implementation as a way to choose the underlying parser.
100      * The underlying parser will not validate.
101      *
102      * @param adapterClass <code>String</code> name of class
103      * to use for DOM building.
104      */

105     public DOMBuilder(String JavaDoc adapterClass) {
106         this.adapterClass = adapterClass;
107     }
108
109     /*
110      * This sets a custom JDOMFactory for the builder. Use this to build
111      * the tree with your own subclasses of the JDOM classes.
112      *
113      * @param factory <code>JDOMFactory</code> to use
114      */

115     public void setFactory(JDOMFactory factory) {
116         this.factory = factory;
117     }
118
119     /**
120      * Returns the current {@link org.jdom.JDOMFactory} in use.
121      * @return the factory in use
122      */

123     public JDOMFactory getFactory() {
124         return factory;
125     }
126
127     /**
128      * This will build a JDOM tree from an existing DOM tree.
129      *
130      * @param domDocument <code>org.w3c.dom.Document</code> object
131      * @return <code>Document</code> - JDOM document object.
132      */

133     public Document build(org.w3c.dom.Document JavaDoc domDocument) {
134         Document doc = factory.document(null);
135         buildTree(domDocument, doc, null, true);
136         return doc;
137     }
138
139     /**
140      * This will build a JDOM Element from an existing DOM Element
141      *
142      * @param domElement <code> org.w3c.dom.Element</code> object
143      * @return <code>Element</code> - JDOM Element object
144      */

145     public org.jdom.Element build(org.w3c.dom.Element JavaDoc domElement) {
146         Document doc = factory.document(null);
147         buildTree(domElement, doc, null, true);
148         return doc.getRootElement();
149     }
150
151     /**
152      * This takes a DOM <code>Node</code> and builds up
153      * a JDOM tree, recursing until the DOM tree is exhausted
154      * and the JDOM tree results.
155      *
156      * @param node <code>Code</node> to examine.
157      * @param doc JDOM <code>Document</code> being built.
158      * @param current <code>Element</code> that is current parent.
159      * @param atRoot <code>boolean</code> indicating whether at root level.
160      */

161     private void buildTree(Node node,
162                            Document doc,
163                            Element current,
164                            boolean atRoot) {
165         // Recurse through the tree
166
switch (node.getNodeType()) {
167             case Node.DOCUMENT_NODE:
168                 NodeList nodes = node.getChildNodes();
169                 for (int i=0, size=nodes.getLength(); i<size; i++) {
170                     buildTree(nodes.item(i), doc, current, true);
171                 }
172                 break;
173
174             case Node.ELEMENT_NODE:
175                 String JavaDoc nodeName = node.getNodeName();
176                 String JavaDoc prefix = "";
177                 String JavaDoc localName = nodeName;
178                 int colon = nodeName.indexOf(':');
179                 if (colon >= 0) {
180                     prefix = nodeName.substring(0, colon);
181                     localName = nodeName.substring(colon + 1);
182                 }
183
184                 // Get element's namespace
185
Namespace ns = null;
186                 String JavaDoc uri = node.getNamespaceURI();
187                 if (uri == null) {
188                     ns = (current == null) ? Namespace.NO_NAMESPACE
189                                            : current.getNamespace(prefix);
190                 }
191                 else {
192                     ns = Namespace.getNamespace(prefix, uri);
193                 }
194
195                 Element element = factory.element(localName, ns);
196
197                 if (atRoot) {
198                     // If at root, set as document root
199
doc.setRootElement(element); // XXX should we use a factory call?
200
} else {
201                     // else add to parent element
202
factory.addContent(current, element);
203                 }
204
205                 // Add namespaces
206
NamedNodeMap attributeList = node.getAttributes();
207                 int attsize = attributeList.getLength();
208
209                 for (int i = 0; i < attsize; i++) {
210                     Attr att = (Attr) attributeList.item(i);
211
212                     String JavaDoc attname = att.getName();
213                     if (attname.startsWith("xmlns")) {
214                         String JavaDoc attPrefix = "";
215                         colon = attname.indexOf(':');
216                         if (colon >= 0) {
217                             attPrefix = attname.substring(colon + 1);
218                         }
219
220                         String JavaDoc attvalue = att.getValue();
221
222                         Namespace declaredNS =
223                             Namespace.getNamespace(attPrefix, attvalue);
224
225                         // Add as additional namespaces if it's different
226
// than this element's namespace (perhaps we should
227
// also have logic not to mark them as additional if
228
// it's been done already, but it probably doesn't
229
// matter)
230
if (prefix.equals(attPrefix)) {
231                             element.setNamespace(declaredNS);
232                         }
233                         else {
234                             factory.addNamespaceDeclaration(element, declaredNS);
235                         }
236                     }
237                 }
238
239                 // Add attributes
240
for (int i = 0; i < attsize; i++) {
241                     Attr att = (Attr) attributeList.item(i);
242
243                     String JavaDoc attname = att.getName();
244
245                     if ( !attname.startsWith("xmlns")) {
246                         String JavaDoc attPrefix = "";
247                         String JavaDoc attLocalName = attname;
248                         colon = attname.indexOf(':');
249                         if (colon >= 0) {
250                             attPrefix = attname.substring(0, colon);
251                             attLocalName = attname.substring(colon + 1);
252                         }
253
254                         String JavaDoc attvalue = att.getValue();
255
256                         // Get attribute's namespace
257
Namespace attns = null;
258                         if ("".equals(attPrefix)) {
259                             attns = Namespace.NO_NAMESPACE;
260                         }
261                         else {
262                             attns = element.getNamespace(attPrefix);
263                         }
264
265                         Attribute attribute =
266                             factory.attribute(attLocalName, attvalue, attns);
267                         factory.setAttribute(element, attribute);
268                     }
269                 }
270
271                 // Recurse on child nodes
272
// The list should never be null nor should it ever contain
273
// null nodes, but some DOM impls are broken
274
NodeList children = node.getChildNodes();
275                 if (children != null) {
276                     int size = children.getLength();
277                     for (int i = 0; i < size; i++) {
278                         Node item = children.item(i);
279                         if (item != null) {
280                             buildTree(item, doc, element, false);
281                         }
282                     }
283                 }
284                 break;
285
286             case Node.TEXT_NODE:
287                 String JavaDoc data = node.getNodeValue();
288                 factory.addContent(current, factory.text(data));
289                 break;
290
291             case Node.CDATA_SECTION_NODE:
292                 String JavaDoc cdata = node.getNodeValue();
293                 factory.addContent(current, factory.cdata(cdata));
294                 break;
295
296
297             case Node.PROCESSING_INSTRUCTION_NODE:
298                 if (atRoot) {
299                     factory.addContent(doc,
300                         factory.processingInstruction(node.getNodeName(),
301                                                       node.getNodeValue()));
302                 } else {
303                     factory.addContent(current,
304                         factory.processingInstruction(node.getNodeName(),
305                                                       node.getNodeValue()));
306                 }
307                 break;
308
309             case Node.COMMENT_NODE:
310                 if (atRoot) {
311                     factory.addContent(doc, factory.comment(node.getNodeValue()));
312                 } else {
313                     factory.addContent(current, factory.comment(node.getNodeValue()));
314                 }
315                 break;
316
317             case Node.ENTITY_REFERENCE_NODE:
318                 EntityRef entity = factory.entityRef(node.getNodeName());
319                 factory.addContent(current, entity);
320                 break;
321
322             case Node.ENTITY_NODE:
323                 // ??
324
break;
325
326             case Node.DOCUMENT_TYPE_NODE:
327                 DocumentType domDocType = (DocumentType)node;
328                 String JavaDoc publicID = domDocType.getPublicId();
329                 String JavaDoc systemID = domDocType.getSystemId();
330                 String JavaDoc internalDTD = domDocType.getInternalSubset();
331
332                 DocType docType = factory.docType(domDocType.getName());
333                 docType.setPublicID(publicID);
334                 docType.setSystemID(systemID);
335                 docType.setInternalSubset(internalDTD);
336
337                 factory.addContent(doc, docType);
338                 break;
339         }
340     }
341 }
342
Popular Tags