Mercurial > repos > pfrommolt > ngsrich
comparison NGSrich_0.5.5/src/org/jdom/output/DOMOutputter.java @ 0:89ad0a9cca52 default tip
Uploaded
author | pfrommolt |
---|---|
date | Mon, 21 Nov 2011 08:12:19 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:89ad0a9cca52 |
---|---|
1 /*-- | |
2 | |
3 $Id: DOMOutputter.java,v 1.43 2007/11/10 05:29:01 jhunter Exp $ | |
4 | |
5 Copyright (C) 2000-2007 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 | |
58 package org.jdom.output; | |
59 | |
60 import java.util.*; | |
61 | |
62 import org.jdom.*; | |
63 import org.jdom.adapters.*; | |
64 | |
65 | |
66 /** | |
67 * Outputs a JDOM {@link org.jdom.Document org.jdom.Document} as a DOM {@link | |
68 * org.w3c.dom.Document org.w3c.dom.Document}. | |
69 * | |
70 * @version $Revision: 1.43 $, $Date: 2007/11/10 05:29:01 $ | |
71 * @author Brett McLaughlin | |
72 * @author Jason Hunter | |
73 * @author Matthew Merlo | |
74 * @author Dan Schaffer | |
75 * @author Yusuf Goolamabbas | |
76 * @author Bradley S. Huffman | |
77 */ | |
78 public class DOMOutputter { | |
79 | |
80 private static final String CVS_ID = | |
81 "@(#) $RCSfile: DOMOutputter.java,v $ $Revision: 1.43 $ $Date: 2007/11/10 05:29:01 $ $Name: jdom_1_1_1 $"; | |
82 | |
83 /** Default adapter class */ | |
84 private static final String DEFAULT_ADAPTER_CLASS = | |
85 "org.jdom.adapters.XercesDOMAdapter"; | |
86 | |
87 /** Adapter to use for interfacing with the DOM implementation */ | |
88 private String adapterClass; | |
89 | |
90 /** Output a DOM with namespaces but just the empty namespace */ | |
91 private boolean forceNamespaceAware; | |
92 | |
93 /** | |
94 * This creates a new DOMOutputter which will attempt to first locate | |
95 * a DOM implementation to use via JAXP, and if JAXP does not exist or | |
96 * there's a problem, will fall back to the default parser. | |
97 */ | |
98 public DOMOutputter() { | |
99 // nothing | |
100 } | |
101 | |
102 /** | |
103 * This creates a new DOMOutputter using the specified DOMAdapter | |
104 * implementation as a way to choose the underlying parser. | |
105 * | |
106 * @param adapterClass <code>String</code> name of class | |
107 * to use for DOM output | |
108 */ | |
109 public DOMOutputter(String adapterClass) { | |
110 this.adapterClass = adapterClass; | |
111 } | |
112 | |
113 /** | |
114 * Controls how NO_NAMESPACE nodes are handeled. If true the outputter | |
115 * always creates a namespace aware DOM. | |
116 * @param flag | |
117 */ | |
118 public void setForceNamespaceAware(boolean flag) { | |
119 this.forceNamespaceAware = flag; | |
120 } | |
121 | |
122 /** | |
123 * Returns whether DOMs will be constructed with namespaces even when | |
124 * the source document has elements all in the empty namespace. | |
125 * @return the forceNamespaceAware flag value | |
126 */ | |
127 public boolean getForceNamespaceAware() { | |
128 return forceNamespaceAware; | |
129 } | |
130 | |
131 /** | |
132 * This converts the JDOM <code>Document</code> parameter to a | |
133 * DOM Document, returning the DOM version. The DOM implementation | |
134 * is the one chosen in the constructor. | |
135 * | |
136 * @param document <code>Document</code> to output. | |
137 * @return an <code>org.w3c.dom.Document</code> version | |
138 */ | |
139 public org.w3c.dom.Document output(Document document) | |
140 throws JDOMException { | |
141 NamespaceStack namespaces = new NamespaceStack(); | |
142 | |
143 org.w3c.dom.Document domDoc = null; | |
144 try { | |
145 // Assign DOCTYPE during construction | |
146 DocType dt = document.getDocType(); | |
147 domDoc = createDOMDocument(dt); | |
148 | |
149 // Add content | |
150 Iterator itr = document.getContent().iterator(); | |
151 while (itr.hasNext()) { | |
152 Object node = itr.next(); | |
153 | |
154 if (node instanceof Element) { | |
155 Element element = (Element) node; | |
156 org.w3c.dom.Element domElement = | |
157 output(element, domDoc, namespaces); | |
158 // Add the root element, first check for existing root | |
159 org.w3c.dom.Element root = domDoc.getDocumentElement(); | |
160 if (root == null) { | |
161 // Normal case | |
162 domDoc.appendChild(domElement); // normal case | |
163 } | |
164 else { | |
165 // Xerces 1.3 creates new docs with a <root /> | |
166 // XXX: Need to address DOCTYPE mismatch still | |
167 domDoc.replaceChild(domElement, root); | |
168 } | |
169 } | |
170 else if (node instanceof Comment) { | |
171 Comment comment = (Comment) node; | |
172 org.w3c.dom.Comment domComment = | |
173 domDoc.createComment(comment.getText()); | |
174 domDoc.appendChild(domComment); | |
175 } | |
176 else if (node instanceof ProcessingInstruction) { | |
177 ProcessingInstruction pi = | |
178 (ProcessingInstruction) node; | |
179 org.w3c.dom.ProcessingInstruction domPI = | |
180 domDoc.createProcessingInstruction( | |
181 pi.getTarget(), pi.getData()); | |
182 domDoc.appendChild(domPI); | |
183 } | |
184 else if (node instanceof DocType) { | |
185 // We already dealt with the DocType above | |
186 } | |
187 else { | |
188 throw new JDOMException( | |
189 "Document contained top-level content with type:" + | |
190 node.getClass().getName()); | |
191 } | |
192 } | |
193 } | |
194 catch (Throwable e) { | |
195 throw new JDOMException("Exception outputting Document", e); | |
196 } | |
197 | |
198 return domDoc; | |
199 } | |
200 | |
201 private org.w3c.dom.Document createDOMDocument(DocType dt) | |
202 throws JDOMException { | |
203 if (adapterClass != null) { | |
204 // The user knows that they want to use a particular impl | |
205 try { | |
206 DOMAdapter adapter = | |
207 (DOMAdapter)Class.forName(adapterClass).newInstance(); | |
208 // System.out.println("using specific " + adapterClass); | |
209 return adapter.createDocument(dt); | |
210 } | |
211 catch (ClassNotFoundException e) { | |
212 // e.printStackTrace(); | |
213 } | |
214 catch (IllegalAccessException e) { | |
215 // e.printStackTrace(); | |
216 } | |
217 catch (InstantiationException e) { | |
218 // e.printStackTrace(); | |
219 } | |
220 } | |
221 else { | |
222 // Try using JAXP... | |
223 try { | |
224 DOMAdapter adapter = | |
225 (DOMAdapter)Class.forName( | |
226 "org.jdom.adapters.JAXPDOMAdapter").newInstance(); | |
227 // System.out.println("using JAXP"); | |
228 return adapter.createDocument(dt); | |
229 } | |
230 catch (ClassNotFoundException e) { | |
231 // e.printStackTrace(); | |
232 } | |
233 catch (IllegalAccessException e) { | |
234 // e.printStackTrace(); | |
235 } | |
236 catch (InstantiationException e) { | |
237 // e.printStackTrace(); | |
238 } | |
239 } | |
240 | |
241 // If no DOM doc yet, try to use a hard coded default | |
242 try { | |
243 DOMAdapter adapter = (DOMAdapter) | |
244 Class.forName(DEFAULT_ADAPTER_CLASS).newInstance(); | |
245 return adapter.createDocument(dt); | |
246 // System.out.println("Using default " + | |
247 // DEFAULT_ADAPTER_CLASS); | |
248 } | |
249 catch (ClassNotFoundException e) { | |
250 // e.printStackTrace(); | |
251 } | |
252 catch (IllegalAccessException e) { | |
253 // e.printStackTrace(); | |
254 } | |
255 catch (InstantiationException e) { | |
256 // e.printStackTrace(); | |
257 } | |
258 | |
259 throw new JDOMException("No JAXP or default parser available"); | |
260 | |
261 } | |
262 | |
263 private org.w3c.dom.Element output(Element element, | |
264 org.w3c.dom.Document domDoc, | |
265 NamespaceStack namespaces) | |
266 throws JDOMException { | |
267 try { | |
268 int previouslyDeclaredNamespaces = namespaces.size(); | |
269 | |
270 org.w3c.dom.Element domElement = null; | |
271 if (element.getNamespace() == Namespace.NO_NAMESPACE) { | |
272 // No namespace, use createElement | |
273 domElement = forceNamespaceAware ? | |
274 domDoc.createElementNS(null, element.getQualifiedName()) | |
275 : domDoc.createElement(element.getQualifiedName()); } | |
276 else { | |
277 domElement = domDoc.createElementNS( | |
278 element.getNamespaceURI(), | |
279 element.getQualifiedName()); | |
280 } | |
281 | |
282 // Add namespace attributes, beginning with the element's own | |
283 // Do this only if it's not the XML namespace and it's | |
284 // not the NO_NAMESPACE with the prefix "" not yet mapped | |
285 // (we do output xmlns="" if the "" prefix was already used | |
286 // and we need to reclaim it for the NO_NAMESPACE) | |
287 Namespace ns = element.getNamespace(); | |
288 if (ns != Namespace.XML_NAMESPACE && | |
289 !(ns == Namespace.NO_NAMESPACE && | |
290 namespaces.getURI("") == null)) { | |
291 String prefix = ns.getPrefix(); | |
292 String uri = namespaces.getURI(prefix); | |
293 if (!ns.getURI().equals(uri)) { // output a new namespace decl | |
294 namespaces.push(ns); | |
295 String attrName = getXmlnsTagFor(ns); | |
296 domElement.setAttribute(attrName, ns.getURI()); | |
297 } | |
298 } | |
299 | |
300 // Add additional namespaces also | |
301 Iterator itr = element.getAdditionalNamespaces().iterator(); | |
302 while (itr.hasNext()) { | |
303 Namespace additional = (Namespace)itr.next(); | |
304 String prefix = additional.getPrefix(); | |
305 String uri = namespaces.getURI(prefix); | |
306 if (!additional.getURI().equals(uri)) { | |
307 String attrName = getXmlnsTagFor(additional); | |
308 domElement.setAttribute(attrName, additional.getURI()); | |
309 namespaces.push(additional); | |
310 } | |
311 } | |
312 | |
313 // Add attributes to the DOM element | |
314 itr = element.getAttributes().iterator(); | |
315 while (itr.hasNext()) { | |
316 Attribute attribute = (Attribute) itr.next(); | |
317 domElement.setAttributeNode(output(attribute, domDoc)); | |
318 Namespace ns1 = attribute.getNamespace(); | |
319 if ((ns1 != Namespace.NO_NAMESPACE) && | |
320 (ns1 != Namespace.XML_NAMESPACE)) { | |
321 String prefix = ns1.getPrefix(); | |
322 String uri = namespaces.getURI(prefix); | |
323 if (!ns1.getURI().equals(uri)) { // output a new decl | |
324 String attrName = getXmlnsTagFor(ns1); | |
325 domElement.setAttribute(attrName, ns1.getURI()); | |
326 namespaces.push(ns1); | |
327 } | |
328 } | |
329 // Crimson doesn't like setAttributeNS() for non-NS attribs | |
330 if (attribute.getNamespace() == Namespace.NO_NAMESPACE) { | |
331 // No namespace, use setAttribute | |
332 if (forceNamespaceAware) { | |
333 domElement.setAttributeNS(null, | |
334 attribute.getQualifiedName(), | |
335 attribute.getValue()); | |
336 } else { | |
337 domElement.setAttribute(attribute.getQualifiedName(), | |
338 attribute.getValue()); | |
339 } | |
340 } | |
341 else { | |
342 domElement.setAttributeNS(attribute.getNamespaceURI(), | |
343 attribute.getQualifiedName(), | |
344 attribute.getValue()); | |
345 } | |
346 } | |
347 | |
348 // Add content to the DOM element | |
349 itr = element.getContent().iterator(); | |
350 while (itr.hasNext()) { | |
351 Object node = itr.next(); | |
352 | |
353 if (node instanceof Element) { | |
354 Element e = (Element) node; | |
355 org.w3c.dom.Element domElt = output(e, domDoc, namespaces); | |
356 domElement.appendChild(domElt); | |
357 } | |
358 else if (node instanceof String) { | |
359 String str = (String) node; | |
360 org.w3c.dom.Text domText = domDoc.createTextNode(str); | |
361 domElement.appendChild(domText); | |
362 } | |
363 else if (node instanceof CDATA) { | |
364 CDATA cdata = (CDATA) node; | |
365 org.w3c.dom.CDATASection domCdata = | |
366 domDoc.createCDATASection(cdata.getText()); | |
367 domElement.appendChild(domCdata); | |
368 } | |
369 else if (node instanceof Text) { | |
370 Text text = (Text) node; | |
371 org.w3c.dom.Text domText = | |
372 domDoc.createTextNode(text.getText()); | |
373 domElement.appendChild(domText); | |
374 } | |
375 else if (node instanceof Comment) { | |
376 Comment comment = (Comment) node; | |
377 org.w3c.dom.Comment domComment = | |
378 domDoc.createComment(comment.getText()); | |
379 domElement.appendChild(domComment); | |
380 } | |
381 else if (node instanceof ProcessingInstruction) { | |
382 ProcessingInstruction pi = | |
383 (ProcessingInstruction) node; | |
384 org.w3c.dom.ProcessingInstruction domPI = | |
385 domDoc.createProcessingInstruction( | |
386 pi.getTarget(), pi.getData()); | |
387 domElement.appendChild(domPI); | |
388 } | |
389 else if (node instanceof EntityRef) { | |
390 EntityRef entity = (EntityRef) node; | |
391 org.w3c.dom.EntityReference domEntity = | |
392 domDoc.createEntityReference(entity.getName()); | |
393 domElement.appendChild(domEntity); | |
394 } | |
395 else { | |
396 throw new JDOMException( | |
397 "Element contained content with type:" + | |
398 node.getClass().getName()); | |
399 } | |
400 } | |
401 | |
402 // Remove declared namespaces from stack | |
403 while (namespaces.size() > previouslyDeclaredNamespaces) { | |
404 namespaces.pop(); | |
405 } | |
406 | |
407 return domElement; | |
408 } | |
409 catch (Exception e) { | |
410 throw new JDOMException("Exception outputting Element " + | |
411 element.getQualifiedName(), e); | |
412 } | |
413 } | |
414 | |
415 private org.w3c.dom.Attr output(Attribute attribute, | |
416 org.w3c.dom.Document domDoc) | |
417 throws JDOMException { | |
418 org.w3c.dom.Attr domAttr = null; | |
419 try { | |
420 if (attribute.getNamespace() == Namespace.NO_NAMESPACE) { | |
421 // No namespace, use createAttribute | |
422 if (forceNamespaceAware) { | |
423 domAttr = domDoc.createAttributeNS(null, attribute.getQualifiedName()); | |
424 } else { | |
425 domAttr = domDoc.createAttribute(attribute.getQualifiedName()); | |
426 } | |
427 } | |
428 else { | |
429 domAttr = domDoc.createAttributeNS(attribute.getNamespaceURI(), | |
430 attribute.getQualifiedName()); | |
431 } | |
432 domAttr.setValue(attribute.getValue()); | |
433 } catch (Exception e) { | |
434 throw new JDOMException("Exception outputting Attribute " + | |
435 attribute.getQualifiedName(), e); | |
436 } | |
437 return domAttr; | |
438 } | |
439 | |
440 /** | |
441 * This will handle adding any <code>{@link Namespace}</code> | |
442 * attributes to the DOM tree. | |
443 * | |
444 * @param ns <code>Namespace</code> to add definition of | |
445 */ | |
446 private static String getXmlnsTagFor(Namespace ns) { | |
447 String attrName = "xmlns"; | |
448 if (!ns.getPrefix().equals("")) { | |
449 attrName += ":"; | |
450 attrName += ns.getPrefix(); | |
451 } | |
452 return attrName; | |
453 } | |
454 } |