1 /* GnomeDocument.java - 2 Copyright (C) 2004 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 package gnu.xml.libxmlj.dom; 39 40 import gnu.java.lang.CPStringBuilder; 41 import gnu.xml.dom.DomNodeIterator; 42 43 import java.util.Iterator; 44 45 import org.w3c.dom.Attr; 46 import org.w3c.dom.CDATASection; 47 import org.w3c.dom.Comment; 48 import org.w3c.dom.Document; 49 import org.w3c.dom.DocumentFragment; 50 import org.w3c.dom.DocumentType; 51 import org.w3c.dom.DOMConfiguration; 52 import org.w3c.dom.DOMErrorHandler; 53 import org.w3c.dom.DOMException; 54 import org.w3c.dom.DOMImplementation; 55 import org.w3c.dom.DOMStringList; 56 import org.w3c.dom.Element; 57 import org.w3c.dom.EntityReference; 58 import org.w3c.dom.Node; 59 import org.w3c.dom.NodeList; 60 import org.w3c.dom.ProcessingInstruction; 61 import org.w3c.dom.Text; 62 import org.w3c.dom.UserDataHandler; 63 import org.w3c.dom.traversal.DocumentTraversal; 64 import org.w3c.dom.traversal.NodeFilter; 65 import org.w3c.dom.traversal.NodeIterator; 66 import org.w3c.dom.traversal.TreeWalker; 67 import org.w3c.dom.xpath.XPathEvaluator; 68 import org.w3c.dom.xpath.XPathException; 69 import org.w3c.dom.xpath.XPathExpression; 70 import org.w3c.dom.xpath.XPathNSResolver; 71 72 /** 73 * A DOM document node implemented in libxml2. 74 * 75 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> 76 */ 77 public class GnomeDocument 78 extends GnomeNode 79 implements Document, DOMConfiguration, XPathEvaluator, DocumentTraversal 80 { 81 82 DOMImplementation dom; 83 84 /** 85 * Not currently used. 86 */ 87 boolean strictErrorChecking; 88 89 /* DOMConfiguration */ 90 boolean canonicalForm = false; 91 boolean cdataSections = true; 92 boolean checkCharacterNormalization = false; 93 boolean comments = true; 94 boolean datatypeNormalization = false; 95 boolean elementContentWhitespace = true; 96 boolean entities = true; 97 DOMErrorHandler errorHandler; 98 boolean namespaces = true; 99 boolean namespaceDeclarations = true; 100 boolean normalizeCharacters = false; 101 boolean splitCdataSections = true; 102 boolean validate = false; 103 boolean validateIfSchema = false; 104 boolean wellFormed = true; 105 GnomeDocument(Object id)106 GnomeDocument(Object id) 107 { 108 super(id); 109 strictErrorChecking = true; 110 } 111 finalize()112 protected void finalize() 113 { 114 free(id); 115 } 116 free(Object id)117 private native void free(Object id); 118 getDoctype()119 public native DocumentType getDoctype(); 120 getImplementation()121 public DOMImplementation getImplementation() 122 { 123 return dom; 124 } 125 getDocumentElement()126 public native Element getDocumentElement(); 127 createElement(String tagName)128 public Element createElement(String tagName) 129 throws DOMException 130 { 131 return createElementNS(null, tagName); 132 } 133 createDocumentType(String name, String publicId, String systemId)134 public native DocumentType createDocumentType(String name, String publicId, 135 String systemId); 136 createDocumentFragment()137 public native DocumentFragment createDocumentFragment(); 138 createTextNode(String data)139 public native Text createTextNode(String data); 140 createComment(String data)141 public native Comment createComment(String data); 142 createCDATASection(String data)143 public native CDATASection createCDATASection(String data) 144 throws DOMException; 145 createProcessingInstruction(String target, String data)146 public native ProcessingInstruction createProcessingInstruction(String target, 147 String data) 148 throws DOMException; 149 createAttribute(String name)150 public Attr createAttribute(String name) 151 throws DOMException 152 { 153 return createAttributeNS(null, name); 154 } 155 createEntityReference(String name)156 public native EntityReference createEntityReference(String name) 157 throws DOMException; 158 getElementsByTagName(String tagName)159 public native NodeList getElementsByTagName(String tagName); 160 importNode(Node importedNode, boolean deep)161 public Node importNode(Node importedNode, boolean deep) 162 throws DOMException 163 { 164 Node ret = xmljImportNode(importedNode, deep); 165 if (importedNode instanceof GnomeNode) 166 { 167 ((GnomeNode) importedNode) 168 .notifyUserDataHandlers(UserDataHandler.NODE_IMPORTED, 169 importedNode, ret); 170 } 171 return ret; 172 } 173 xmljImportNode(Node importedNode, boolean deep)174 private native Node xmljImportNode(Node importedNode, boolean deep) 175 throws DOMException; 176 createElementNS(String namespaceURI, String qualifiedName)177 public native Element createElementNS(String namespaceURI, String 178 qualifiedName) 179 throws DOMException; 180 createAttributeNS(String namespaceURI, String qualifiedName)181 public native Attr createAttributeNS(String namespaceURI, String 182 qualifiedName) 183 throws DOMException; 184 getElementsByTagNameNS(String namespaceURI, String localName)185 public native NodeList getElementsByTagNameNS(String namespaceURI, 186 String localName); 187 getElementById(String elementId)188 public Element getElementById(String elementId) 189 { 190 Element element = xmljGetElementById(elementId); 191 if (element == null) 192 { 193 TreeWalker walker = createTreeWalker(this, NodeFilter.SHOW_ELEMENT, 194 null, false); 195 for (Node node = walker.nextNode(); node != null; 196 node = walker.nextNode()) 197 { 198 GnomeElement e = (GnomeElement) node; 199 if (e.userIdAttrs != null) 200 { 201 for (Iterator i = e.userIdAttrs.iterator(); i.hasNext(); ) 202 { 203 Attr attr = (Attr) i.next(); 204 if (attr.getNodeValue().equals(elementId)) 205 { 206 return e; 207 } 208 } 209 } 210 } 211 } 212 return element; 213 } 214 xmljGetElementById(String elementId)215 private native Element xmljGetElementById(String elementId); 216 217 // DOM Level 3 methods 218 getInputEncoding()219 public native String getInputEncoding(); 220 getXmlEncoding()221 public native String getXmlEncoding(); 222 getXmlStandalone()223 public native boolean getXmlStandalone(); 224 setXmlStandalone(boolean xmlStandalone)225 public native void setXmlStandalone(boolean xmlStandalone); 226 getXmlVersion()227 public native String getXmlVersion(); 228 setXmlVersion(String xmlVersion)229 public native void setXmlVersion(String xmlVersion); 230 getStrictErrorChecking()231 public boolean getStrictErrorChecking() 232 { 233 return strictErrorChecking; 234 } 235 setStrictErrorChecking(boolean strictErrorChecking)236 public void setStrictErrorChecking(boolean strictErrorChecking) 237 { 238 this.strictErrorChecking = strictErrorChecking; 239 } 240 getDocumentURI()241 public native String getDocumentURI(); 242 setDocumentURI(String documentURI)243 public native void setDocumentURI(String documentURI); 244 adoptNode(Node source)245 public Node adoptNode(Node source) 246 throws DOMException 247 { 248 if (source == null || !(source instanceof GnomeNode)) 249 { 250 return null; 251 } 252 Node ret = xmljAdoptNode(source); 253 if (source instanceof GnomeNode) 254 { 255 ((GnomeNode) source). 256 notifyUserDataHandlers(UserDataHandler.NODE_ADOPTED, 257 source, ret); 258 } 259 return ret; 260 } 261 xmljAdoptNode(Node source)262 private native Node xmljAdoptNode(Node source) 263 throws DOMException; 264 getDomConfig()265 public DOMConfiguration getDomConfig() 266 { 267 return this; 268 } 269 normalizeDocument()270 public void normalizeDocument() 271 { 272 normalize(); 273 } 274 renameNode(Node n, String namespaceURI, String qualifiedName)275 public native Node renameNode(Node n, String namespaceURI, 276 String qualifiedName); 277 278 // -- DOMConfiguration methods -- 279 setParameter(String name, Object value)280 public void setParameter(String name, Object value) 281 throws DOMException 282 { 283 name = name.toLowerCase(); 284 if ("canonical-form".equals(name)) 285 { 286 /* optional 287 canonicalForm = getBooleanValue(value);*/ 288 } 289 else if ("cdata-sections".equals(name)) 290 { 291 cdataSections = getBooleanValue(value); 292 } 293 else if ("check-character-normalization".equals(name)) 294 { 295 /* optional 296 checkCharacterNormalization = getBooleanValue(value);*/ 297 } 298 else if ("comments".equals(name)) 299 { 300 comments = getBooleanValue(value); 301 } 302 else if ("datatype-normalization".equals(name)) 303 { 304 /* optional 305 datatypeNormalization = getBooleanValue(value);*/ 306 } 307 else if ("element-content-whitespace".equals(name)) 308 { 309 /* optional 310 elementContentWhitespace = getBooleanValue(value);*/ 311 } 312 else if ("entities".equals(name)) 313 { 314 entities = getBooleanValue(value); 315 } 316 else if ("error-handler".equals(name)) 317 { 318 errorHandler = (DOMErrorHandler) value; 319 } 320 else if ("infoset".equals(name)) 321 { 322 if (getBooleanValue(value)) 323 { 324 validateIfSchema = false; 325 entities = false; 326 datatypeNormalization = false; 327 cdataSections = false; 328 namespaceDeclarations = true; 329 wellFormed = true; 330 elementContentWhitespace = true; 331 comments = true; 332 namespaces = true; 333 } 334 } 335 else if ("namespaces".equals(name)) 336 { 337 /* optional 338 namespaces = getBooleanValue(value);*/ 339 } 340 else if ("namespace-declarations".equals(name)) 341 { 342 namespaceDeclarations = getBooleanValue(value); 343 } 344 else if ("normalize-characters".equals(name)) 345 { 346 /* optional 347 normalizeCharacters = getBooleanValue(value);*/ 348 } 349 else if ("split-cdata-sections".equals(name)) 350 { 351 splitCdataSections = getBooleanValue(value); 352 } 353 else if ("validate".equals(name)) 354 { 355 /* optional 356 validate = getBooleanValue(value);*/ 357 } 358 else if ("validate-if-schema".equals(name)) 359 { 360 /* optional 361 validateIfSchema = getBooleanValue(value);*/ 362 } 363 else if ("well-formed".equals(name)) 364 { 365 /* optional 366 wellFormed = getBooleanValue(value);*/ 367 } 368 else 369 { 370 throw new GnomeDOMException(DOMException.NOT_FOUND_ERR, name); 371 } 372 } 373 getParameter(String name)374 public Object getParameter(String name) 375 throws DOMException 376 { 377 name = name.toLowerCase(); 378 if ("canonical-form".equals(name)) 379 { 380 return Boolean.valueOf(canonicalForm); 381 } 382 else if ("cdata-sections".equals(name)) 383 { 384 return Boolean.valueOf(cdataSections); 385 } 386 else if ("check-character-normalization".equals(name)) 387 { 388 return Boolean.valueOf(checkCharacterNormalization); 389 } 390 else if ("comments".equals(name)) 391 { 392 return Boolean.valueOf(comments); 393 } 394 else if ("datatype-normalization".equals(name)) 395 { 396 return Boolean.valueOf(datatypeNormalization); 397 } 398 else if ("element-content-whitespace".equals(name)) 399 { 400 return Boolean.valueOf(elementContentWhitespace); 401 } 402 else if ("entities".equals(name)) 403 { 404 return Boolean.valueOf(entities); 405 } 406 else if ("error-handler".equals(name)) 407 { 408 return errorHandler; 409 } 410 else if ("infoset".equals(name)) 411 { 412 return Boolean.valueOf(!validateIfSchema && 413 !entities && 414 !datatypeNormalization && 415 !cdataSections && 416 namespaceDeclarations && 417 wellFormed && 418 elementContentWhitespace && 419 comments && 420 namespaces); 421 } 422 else if ("namespaces".equals(name)) 423 { 424 return Boolean.valueOf(namespaces); 425 } 426 else if ("namespace-declarations".equals(name)) 427 { 428 return Boolean.valueOf(namespaceDeclarations); 429 } 430 else if ("normalize-characters".equals(name)) 431 { 432 return Boolean.valueOf(normalizeCharacters); 433 } 434 else if ("split-cdata-sections".equals(name)) 435 { 436 return Boolean.valueOf(splitCdataSections); 437 } 438 else if ("validate".equals(name)) 439 { 440 return Boolean.valueOf(validate); 441 } 442 else if ("validate-if-schema".equals(name)) 443 { 444 return Boolean.valueOf(validateIfSchema); 445 } 446 else if ("well-formed".equals(name)) 447 { 448 return Boolean.valueOf(wellFormed); 449 } 450 else 451 { 452 throw new GnomeDOMException(DOMException.NOT_FOUND_ERR, name); 453 } 454 } 455 canSetParameter(String name, Object value)456 public boolean canSetParameter(String name, Object value) 457 { 458 name = name.toLowerCase(); 459 if ("error-handler".equals(name)) 460 { 461 return (value == null || value instanceof DOMErrorHandler); 462 } 463 return ("cdata-sections".equals(name) || 464 "comments".equals(name) || 465 "entities".equals(name) || 466 "namespace-declarations".equals(name) || 467 "split-cdata-sections".equals(name)); 468 } 469 getParameterNames()470 public DOMStringList getParameterNames() 471 { 472 String[] names = new String[] { 473 "canonical-form", 474 "cdata-sections", 475 "check-character-normalization", 476 "comments", 477 "datatype-normalization", 478 "element-content-whitespace", 479 "entities", 480 "error-handler", 481 "infoset", 482 "namespaces", 483 "namespace-declarations", 484 "normalize-characters", 485 "split-cdata-sections", 486 "validate", 487 "validate-if-schema", 488 "well-formed" 489 }; 490 return new GnomeDOMStringList(names); 491 } 492 getBooleanValue(Object value)493 private boolean getBooleanValue(Object value) 494 { 495 if (value instanceof Boolean) 496 { 497 return ((Boolean) value).booleanValue(); 498 } 499 else if (value instanceof String) 500 { 501 return Boolean.valueOf ((String) value).booleanValue(); 502 } 503 return false; 504 } 505 506 // -- XPathEvaluator methods -- 507 createExpression(String expression, XPathNSResolver resolver)508 public XPathExpression createExpression(String expression, 509 XPathNSResolver resolver) 510 throws XPathException, DOMException 511 { 512 return new GnomeXPathExpression(this, expression, resolver); 513 } 514 createNSResolver(Node nodeResolver)515 public XPathNSResolver createNSResolver(Node nodeResolver) 516 { 517 return new GnomeXPathNSResolver(nodeResolver); 518 } 519 evaluate(String expression, Node contextNode, XPathNSResolver resolver, short type, Object result)520 public native Object evaluate(String expression, 521 Node contextNode, 522 XPathNSResolver resolver, 523 short type, 524 Object result) 525 throws XPathException, DOMException; 526 527 // -- DocumentTraversal methods -- 528 createNodeIterator(Node root, int whatToShow, NodeFilter filter, boolean entityReferenceExpansion)529 public NodeIterator createNodeIterator(Node root, 530 int whatToShow, 531 NodeFilter filter, 532 boolean entityReferenceExpansion) 533 throws DOMException 534 { 535 return new DomNodeIterator(root, whatToShow, filter, 536 entityReferenceExpansion, false); 537 } 538 createTreeWalker(Node root, int whatToShow, NodeFilter filter, boolean entityReferenceExpansion)539 public TreeWalker createTreeWalker(Node root, 540 int whatToShow, 541 NodeFilter filter, 542 boolean entityReferenceExpansion) 543 throws DOMException 544 { 545 return new DomNodeIterator(root, whatToShow, filter, 546 entityReferenceExpansion, true); 547 } 548 549 // -- Debugging -- 550 toString()551 public String toString() 552 { 553 CPStringBuilder buffer = new CPStringBuilder(getClass().getName()); 554 buffer.append("[version="); 555 buffer.append(getXmlVersion()); 556 buffer.append(",standalone="); 557 buffer.append(getXmlStandalone()); 558 buffer.append("]"); 559 return buffer.toString(); 560 } 561 562 } 563