1 7 8 package org.dom4j.io; 9 10 import java.util.List ; 11 12 import org.dom4j.Attribute; 13 import org.dom4j.CDATA; 14 import org.dom4j.Comment; 15 import org.dom4j.Document; 16 import org.dom4j.DocumentException; 17 import org.dom4j.Element; 18 import org.dom4j.Entity; 19 import org.dom4j.Namespace; 20 import org.dom4j.ProcessingInstruction; 21 import org.dom4j.Text; 22 import org.dom4j.tree.NamespaceStack; 23 24 import org.w3c.dom.DOMImplementation ; 25 26 35 public class DOMWriter { 36 private static boolean loggedWarning = false; 37 38 private static final String [] DEFAULT_DOM_DOCUMENT_CLASSES = { 39 "org.apache.xerces.dom.DocumentImpl", "gnu.xml.dom.DomDocument", "org.apache.crimson.tree.XmlDocument", "com.sun.xml.tree.XmlDocument", "oracle.xml.parser.v2.XMLDocument", "oracle.xml.parser.XMLDocument", "org.dom4j.dom.DOMDocument" }; 47 48 private Class domDocumentClass; 50 51 52 private NamespaceStack namespaceStack = new NamespaceStack(); 53 54 public DOMWriter() { 55 } 56 57 public DOMWriter(Class domDocumentClass) { 58 this.domDocumentClass = domDocumentClass; 59 } 60 61 public Class getDomDocumentClass() throws DocumentException { 62 Class result = domDocumentClass; 63 64 if (result == null) { 65 int size = DEFAULT_DOM_DOCUMENT_CLASSES.length; 67 68 for (int i = 0; i < size; i++) { 69 try { 70 String name = DEFAULT_DOM_DOCUMENT_CLASSES[i]; 71 result = Class.forName(name, true, DOMWriter.class 72 .getClassLoader()); 73 74 if (result != null) { 75 break; 76 } 77 } catch (Exception e) { 78 } 81 } 82 } 83 84 return result; 85 } 86 87 95 public void setDomDocumentClass(Class domDocumentClass) { 96 this.domDocumentClass = domDocumentClass; 97 } 98 99 110 public void setDomDocumentClassName(String name) throws DocumentException { 111 try { 112 this.domDocumentClass = Class.forName(name, true, DOMWriter.class 113 .getClassLoader()); 114 } catch (Exception e) { 115 throw new DocumentException("Could not load the DOM Document " 116 + "class: " + name, e); 117 } 118 } 119 120 public org.w3c.dom.Document write(Document document) 121 throws DocumentException { 122 if (document instanceof org.w3c.dom.Document ) { 123 return (org.w3c.dom.Document ) document; 124 } 125 126 resetNamespaceStack(); 127 128 org.w3c.dom.Document domDocument = createDomDocument(document); 129 appendDOMTree(domDocument, domDocument, document.content()); 130 namespaceStack.clear(); 131 132 return domDocument; 133 } 134 135 public org.w3c.dom.Document write(Document document, 136 org.w3c.dom.DOMImplementation domImpl) throws DocumentException { 137 if (document instanceof org.w3c.dom.Document ) { 138 return (org.w3c.dom.Document ) document; 139 } 140 141 resetNamespaceStack(); 142 143 org.w3c.dom.Document domDocument = createDomDocument(document, domImpl); 144 appendDOMTree(domDocument, domDocument, document.content()); 145 namespaceStack.clear(); 146 147 return domDocument; 148 } 149 150 protected void appendDOMTree(org.w3c.dom.Document domDocument, 151 org.w3c.dom.Node domCurrent, List content) { 152 int size = content.size(); 153 154 for (int i = 0; i < size; i++) { 155 Object object = content.get(i); 156 157 if (object instanceof Element) { 158 appendDOMTree(domDocument, domCurrent, (Element) object); 159 } else if (object instanceof String ) { 160 appendDOMTree(domDocument, domCurrent, (String ) object); 161 } else if (object instanceof Text) { 162 Text text = (Text) object; 163 appendDOMTree(domDocument, domCurrent, text.getText()); 164 } else if (object instanceof CDATA) { 165 appendDOMTree(domDocument, domCurrent, (CDATA) object); 166 } else if (object instanceof Comment) { 167 appendDOMTree(domDocument, domCurrent, (Comment) object); 168 } else if (object instanceof Entity) { 169 appendDOMTree(domDocument, domCurrent, (Entity) object); 170 } else if (object instanceof ProcessingInstruction) { 171 appendDOMTree(domDocument, domCurrent, 172 (ProcessingInstruction) object); 173 } 174 } 175 } 176 177 protected void appendDOMTree(org.w3c.dom.Document domDocument, 178 org.w3c.dom.Node domCurrent, Element element) { 179 String elUri = element.getNamespaceURI(); 180 String elName = element.getQualifiedName(); 181 org.w3c.dom.Element domElement = domDocument.createElementNS(elUri, 182 elName); 183 184 int stackSize = namespaceStack.size(); 185 186 Namespace elementNamespace = element.getNamespace(); 188 189 if (isNamespaceDeclaration(elementNamespace)) { 190 namespaceStack.push(elementNamespace); 191 writeNamespace(domElement, elementNamespace); 192 } 193 194 List declaredNamespaces = element.declaredNamespaces(); 196 197 for (int i = 0, size = declaredNamespaces.size(); i < size; i++) { 198 Namespace namespace = (Namespace) declaredNamespaces.get(i); 199 200 if (isNamespaceDeclaration(namespace)) { 201 namespaceStack.push(namespace); 202 writeNamespace(domElement, namespace); 203 } 204 } 205 206 for (int i = 0, size = element.attributeCount(); i < size; i++) { 208 Attribute attribute = (Attribute) element.attribute(i); 209 String attUri = attribute.getNamespaceURI(); 210 String attName = attribute.getQualifiedName(); 211 String value = attribute.getValue(); 212 domElement.setAttributeNS(attUri, attName, value); 213 } 214 215 appendDOMTree(domDocument, domElement, element.content()); 217 218 domCurrent.appendChild(domElement); 219 220 while (namespaceStack.size() > stackSize) { 221 namespaceStack.pop(); 222 } 223 } 224 225 protected void appendDOMTree(org.w3c.dom.Document domDocument, 226 org.w3c.dom.Node domCurrent, CDATA cdata) { 227 org.w3c.dom.CDATASection domCDATA = domDocument 228 .createCDATASection(cdata.getText()); 229 domCurrent.appendChild(domCDATA); 230 } 231 232 protected void appendDOMTree(org.w3c.dom.Document domDocument, 233 org.w3c.dom.Node domCurrent, Comment comment) { 234 org.w3c.dom.Comment domComment = domDocument.createComment(comment 235 .getText()); 236 domCurrent.appendChild(domComment); 237 } 238 239 protected void appendDOMTree(org.w3c.dom.Document domDocument, 240 org.w3c.dom.Node domCurrent, String text) { 241 org.w3c.dom.Text domText = domDocument.createTextNode(text); 242 domCurrent.appendChild(domText); 243 } 244 245 protected void appendDOMTree(org.w3c.dom.Document domDocument, 246 org.w3c.dom.Node domCurrent, Entity entity) { 247 org.w3c.dom.EntityReference domEntity = domDocument 248 .createEntityReference(entity.getName()); 249 domCurrent.appendChild(domEntity); 250 } 251 252 protected void appendDOMTree(org.w3c.dom.Document domDoc, 253 org.w3c.dom.Node domCurrent, ProcessingInstruction pi) { 254 org.w3c.dom.ProcessingInstruction domPI = domDoc 255 .createProcessingInstruction(pi.getTarget(), pi.getText()); 256 domCurrent.appendChild(domPI); 257 } 258 259 protected void writeNamespace(org.w3c.dom.Element domElement, 260 Namespace namespace) { 261 String attributeName = attributeNameForNamespace(namespace); 262 263 domElement.setAttribute(attributeName, namespace.getURI()); 265 } 266 267 protected String attributeNameForNamespace(Namespace namespace) { 268 String xmlns = "xmlns"; 269 String prefix = namespace.getPrefix(); 270 271 if (prefix.length() > 0) { 272 return xmlns + ":" + prefix; 273 } 274 275 return xmlns; 276 } 277 278 protected org.w3c.dom.Document createDomDocument(Document document) 279 throws DocumentException { 280 org.w3c.dom.Document result = null; 281 282 if (domDocumentClass != null) { 284 try { 285 result = (org.w3c.dom.Document ) domDocumentClass.newInstance(); 286 } catch (Exception e) { 287 throw new DocumentException( 288 "Could not instantiate an instance " 289 + "of DOM Document with class: " 290 + domDocumentClass.getName(), e); 291 } 292 } else { 293 result = createDomDocumentViaJAXP(); 295 296 if (result == null) { 297 Class theClass = getDomDocumentClass(); 298 299 try { 300 result = (org.w3c.dom.Document ) theClass.newInstance(); 301 } catch (Exception e) { 302 throw new DocumentException("Could not instantiate an " 303 + "instance of DOM Document " + "with class: " 304 + theClass.getName(), e); 305 } 306 } 307 } 308 309 return result; 310 } 311 312 protected org.w3c.dom.Document createDomDocumentViaJAXP() 313 throws DocumentException { 314 try { 315 return JAXPHelper.createDocument(false, true); 316 } catch (Throwable e) { 317 if (!loggedWarning) { 318 loggedWarning = true; 319 320 if (SAXHelper.isVerboseErrorReporting()) { 321 System.out.println("Warning: Caught exception attempting " 324 + "to use JAXP to create a W3C DOM " + "document"); 325 System.out.println("Warning: Exception was: " + e); 326 e.printStackTrace(); 327 } else { 328 System.out.println("Warning: Error occurred using JAXP to " 329 + "create a DOM document."); 330 } 331 } 332 } 333 334 return null; 335 } 336 337 protected org.w3c.dom.Document createDomDocument(Document document, 338 DOMImplementation domImpl) throws DocumentException { 339 String namespaceURI = null; 340 String qualifiedName = null; 341 org.w3c.dom.DocumentType docType = null; 342 343 return domImpl.createDocument(namespaceURI, qualifiedName, docType); 344 } 345 346 protected boolean isNamespaceDeclaration(Namespace ns) { 347 if ((ns != null) && (ns != Namespace.NO_NAMESPACE) 348 && (ns != Namespace.XML_NAMESPACE)) { 349 String uri = ns.getURI(); 350 351 if ((uri != null) && (uri.length() > 0)) { 352 if (!namespaceStack.contains(ns)) { 353 return true; 354 } 355 } 356 } 357 358 return false; 359 } 360 361 protected void resetNamespaceStack() { 362 namespaceStack.clear(); 363 namespaceStack.push(Namespace.XML_NAMESPACE); 364 } 365 } 366 367 403 | Popular Tags |