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 }