View Javadoc
1 /* 2 * Copyright (C) 2002 Carsten Krebs (Team-Konzept GmbH & Co.KG) 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 package com.teamkonzept.dom4jb.saxon; 19 20 import java.util.Hashtable; 21 22 import javax.xml.transform.TransformerException; 23 24 25 import com.icl.saxon.KeyManager; 26 import com.icl.saxon.om.Axis; 27 import com.icl.saxon.om.AxisEnumeration; 28 import com.icl.saxon.om.DocumentInfo; 29 import com.icl.saxon.om.EmptyEnumeration; 30 import com.icl.saxon.om.NamePool; 31 import com.icl.saxon.om.NodeInfo; 32 import com.icl.saxon.om.SingletonEnumeration; 33 import com.icl.saxon.output.Outputter; 34 import com.icl.saxon.pattern.AnyNodeTest; 35 import com.icl.saxon.pattern.NodeTest; 36 import com.teamkonzept.dom4jb.schema.AttributeDescriptor; 37 import com.teamkonzept.dom4jb.schema.ElementDescriptor; 38 import com.teamkonzept.dom4jb.schema.TextDescriptor; 39 40 public class Document 41 extends com.teamkonzept.dom4jb.dom.Document 42 implements DocumentInfo, AxisNode { 43 44 private DescendantAxis axis; 45 private int position; 46 private Namespace[] namespaces = new Namespace[0]; 47 48 protected String baseURI; 49 protected NamePool namePool; 50 protected Hashtable keyTable = new Hashtable(); 51 52 public Document(final String baseURI) { 53 this.baseURI = baseURI == null ? "" : baseURI; 54 } 55 56 public com.teamkonzept.dom4jb.dom.Element createElement( 57 final ElementDescriptor descriptor, 58 final Object bean) { 59 60 return new Element(this, descriptor, bean); 61 } 62 63 public com.teamkonzept.dom4jb.dom.Element createElement( 64 final String name, 65 final Object bean) { 66 67 return new Element(this, name, bean); 68 } 69 70 public com.teamkonzept.dom4jb.dom.Attribute createAttribute( 71 final AttributeDescriptor descriptor, 72 final Object bean) { 73 74 return new Attribute(this, descriptor, bean); 75 } 76 77 public com.teamkonzept.dom4jb.dom.Text createText( 78 final TextDescriptor descriptor, 79 final Object bean) { 80 81 return new Text(this, descriptor, bean); 82 } 83 84 public void attachAxis(final int position, final DescendantAxis axis) { 85 this.axis = axis; 86 this.position = position; 87 } 88 89 public DescendantAxis getAxis() { 90 return axis; 91 } 92 93 public int getPosition() { 94 return position; 95 } 96 97 /*** 98 * Return the string value of the node. The interpretation of this depends 99 * on the type of node. For an element it is the accumulated character 100 * content of the element, including descendant elements. 101 * @return the string value of the node 102 */ 103 public String getStringValue() { 104 final StringBuffer sb = new StringBuffer(); 105 expandStringValue(getChildNodes(), sb); 106 return sb.toString(); 107 } 108 109 private void expandStringValue( 110 final org.w3c.dom.NodeList list, 111 final StringBuffer sb) { 112 int i = 0; 113 for (org.w3c.dom.Node node = list.item(i); 114 node != null; 115 node = list.item(++i)) { 116 expandStringValue(node.getChildNodes(), sb); 117 } 118 } 119 120 /*** 121 * Get the display name of this node. For elements and attributes 122 * this is [prefix:]localname. For unnamed nodes, it is an empty string. 123 * @return The display name of this node. 124 * For a node with no name, return an empty string. 125 */ 126 public String getDisplayName() { 127 return ""; 128 } 129 130 /*** 131 * Find the value of a given attribute of this node. <BR> 132 * This method is defined on all nodes to meet XSL requirements, 133 * but for nodes other than elements it will always return null. 134 * @param uri the namespace uri of an attribute ("" if no namespace) 135 * @param localname the local name of the attribute 136 * @return the value of the attribute, if it exists, otherwise null 137 */ 138 139 public String getAttributeValue(final String uri, final String localName) { 140 return ""; 141 } 142 143 /*** 144 * Get the value of a given attribute of this node 145 * @param fingerprint The fingerprint of the attribute name 146 * @return the attribute value if it exists or null if not 147 */ 148 public String getAttributeValue(final int fingerprint) { 149 return null; 150 } 151 152 /*** 153 * Get a character string that uniquely identifies this node.<br /> 154 * Note: a.isSameNode(b) if and only if generateId(a)==generateId(b) 155 * @return a string that uniquely identifies this node, within this 156 * document. The calling code prepends information to make the result 157 * unique across all documents. 158 */ 159 public String generateId() { 160 final StringBuffer buf = new StringBuffer("j"); 161 buf.append(hashCode()); 162 return buf.toString(); 163 } 164 165 /*** 166 * Copy this node to a given outputter (deep copy) 167 */ 168 public void copy(final Outputter out) throws TransformerException { 169 final AxisEnumeration children0 = 170 getEnumeration(Axis.CHILD, AnyNodeTest.getInstance()); 171 while (children0.hasMoreElements()) { 172 children0.nextElement().copy(out); 173 } 174 return; 175 } 176 177 /*** 178 * Output all namespace nodes associated with this element. Does nothing if 179 * the node is not an element. 180 * @param out The relevant outputter 181 * @param includeAncestors True if namespaces declared on ancestor 182 * elements must be output; false if it is known that these are already 183 * on the result tree 184 */ 185 public void outputNamespaceNodes( 186 final Outputter out, 187 final boolean includeAncestors) 188 throws TransformerException { 189 } 190 191 public void expandStringValue(final StringBuffer sb) { 192 } 193 194 public Namespace[] getNamespaces() { 195 return namespaces; 196 } 197 198 /*** 199 * Set the name pool used for all names in this document 200 */ 201 public void setNamePool(final NamePool pool) { 202 namePool = pool; 203 } 204 205 /*** 206 * Get the name pool used for the names in this document 207 */ 208 public NamePool getNamePool() { 209 return namePool; 210 } 211 212 public String getSystemId() { 213 return this.baseURI; 214 } 215 216 /*** 217 * Set the system identifier for this Source. 218 * 219 * <p>The system identifier is optional if the source does not 220 * get its data from a URL, but it may still be useful to provide one. 221 * The application can use a system identifier, for example, to resolve 222 * relative URIs and to include in error messages and warnings.</p> 223 * 224 * @param systemId The system identifier as a URL string. 225 */ 226 public void setSystemId(final String systemId) { 227 this.baseURI = systemId; 228 } 229 230 /*** 231 * Get the element with a given ID, if any 232 * @param id the required ID value 233 * @return null: not yet implemented 234 */ 235 236 public NodeInfo selectID(final String id) { 237 return null; 238 } 239 240 /*** 241 * Get the index for a given key 242 * @param keyManager The key manager managing this key 243 * @param fingerprint The fingerprint of the name of the key 244 * (unique with the key manager) 245 * @return The index, if one has been built, in the form of a 246 * Hashtable that maps the key value to a list of nodes having that key 247 * value. If no index 248 * has been built, returns null. 249 */ 250 public Hashtable getKeyIndex( 251 final KeyManager keyManager, 252 final int fingerprint) { 253 return (Hashtable) keyTable.get(getKey(keyManager, fingerprint)); 254 } 255 256 /*** 257 * Set the index for a given key 258 * @param keyManager The key manager managing this key 259 * @param fingerprint The fingerprint of the name of the key 260 * (unique with the key manager) 261 * @param index the index, in the form of a Hashtable that 262 * maps the key value to a list of nodes having that key value 263 */ 264 public void setKeyIndex( 265 final KeyManager keyManager, 266 final int fingerprint, 267 final Hashtable index) { 268 keyTable.put(getKey(keyManager, fingerprint), index); 269 } 270 271 /*** 272 * Get the unparsed entity with a given name 273 * @param name the name of the entity 274 * @return null: not yet implemented 275 */ 276 public String getUnparsedEntity(String name) { 277 return null; 278 } 279 280 private static String getKey( 281 final KeyManager keyManager, 282 final int fingerprint) { 283 final StringBuffer buf = 284 new StringBuffer(Integer.toString(keyManager.hashCode())); 285 buf.append('#'); 286 buf.append(fingerprint); 287 return buf.toString(); 288 } 289 290 // ------- GENERAL stuff ------- 291 292 /*** 293 * Get the Base URI for the node, that is, the URI used for resolving a 294 * relative URI contained in the node. This will be the same as the 295 * System ID unless xml:base has been used. 296 */ 297 public String getBaseURI() { 298 return getSystemId(); 299 } 300 301 /*** 302 * Get line number 303 * @return the line number of the node in its original source document; 304 * or -1 if not available 305 */ 306 public int getLineNumber() { 307 return -1; 308 } 309 310 /*** 311 * Get name code. The name code is a coded form of the node name: two nodes 312 * with the same name code have the same namespace URI, the same local name, 313 * and the same prefix. By masking the name code with &0xfffff, you get a 314 * fingerprint: two nodes with the same fingerprint have the same local name 315 * and namespace URI. 316 * @see com.icl.saxon.om.NamePool#allocate allocate 317 */ 318 public int getNameCode() { 319 return -1; 320 } 321 322 /*** 323 * Get fingerprint. The fingerprint is a coded form of the expanded name 324 * of the node: two nodes 325 * with the same name code have the same namespace URI and the same 326 * local name. A fingerprint of -1 should be returned for a node with 327 * no name. 328 */ 329 public int getFingerprint() { 330 return -1; 331 } 332 333 /*** 334 * Get the URI part of the name of this node. This is the URI corresponding 335 * to the prefix, or the URI of the default namespace if appropriate. 336 * @return The URI of the namespace of this node. For an unnamed node, 337 * return null. For a node with an empty prefix, return an empty string. 338 */ 339 public String getURI() { 340 return this.getNamespaceURI(); 341 } 342 343 /*** 344 * Get the NodeInfo object representing the parent of this node 345 */ 346 public NodeInfo getParent() { 347 return null; 348 } 349 350 /*** 351 * Get the root (document) node 352 * @return the DocumentInfo representing the containing document 353 */ 354 public DocumentInfo getDocumentRoot() { 355 return this; 356 } 357 358 /*** 359 * Copy the string-value of this node to a given outputter 360 */ 361 public void copyStringValue(final Outputter out) 362 throws TransformerException { 363 out.writeContent(getStringValue()); 364 } 365 366 /*** 367 * Return an enumeration over the nodes reached by the given axis from 368 * this node The value NodeInfo.NODE means include any type of node. 369 * @param nodeTest A pattern to be matched by the returned nodes 370 * @return a NodeEnumeration that scans the nodes reached by the axis 371 * in turn. 372 */ 373 public AxisEnumeration getEnumeration( 374 final byte axisNumber, 375 final NodeTest nodeTest) { 376 switch (axisNumber) { 377 case Axis.ANCESTOR : 378 case Axis.ANCESTOR_OR_SELF : 379 case Axis.ATTRIBUTE : 380 return EmptyEnumeration.getInstance(); 381 382 case Axis.CHILD : 383 if (hasChildNodes()) { 384 return new FilterEnumeration( 385 new ChildEnumeration(this), 386 nodeTest); 387 } else { 388 return EmptyEnumeration.getInstance(); 389 } 390 391 case Axis.DESCENDANT : 392 if (hasChildNodes()) { 393 return new FilterEnumeration( 394 new DescendantEnumeration(this, false), 395 nodeTest); 396 } else { 397 return EmptyEnumeration.getInstance(); 398 } 399 400 case Axis.DESCENDANT_OR_SELF : 401 return new FilterEnumeration( 402 new DescendantEnumeration(this, true), 403 nodeTest); 404 405 case Axis.FOLLOWING : 406 return new FilterEnumeration( 407 new FollowingEnumeration(this), 408 nodeTest); 409 410 case Axis.FOLLOWING_SIBLING : 411 case Axis.NAMESPACE : 412 case Axis.PARENT : 413 case Axis.PRECEDING : 414 case Axis.PRECEDING_SIBLING : 415 case Axis.PRECEDING_OR_ANCESTOR : 416 return EmptyEnumeration.getInstance(); 417 418 case Axis.SELF : 419 if (nodeTest.matches(this)) 420 return new SingletonEnumeration(this); 421 return EmptyEnumeration.getInstance(); 422 423 default : 424 throw new IllegalArgumentException( 425 "Unknown axis number " + axisNumber); 426 } 427 } 428 429 /*** 430 * Determine the relative position of this node and another node, in 431 * document order. The other node will always be in the same document. 432 * @param other The other node, whose position is to be compared with 433 * this node 434 * @return -1 if this node precedes the other node, +1 if it follows the 435 * other node, or 0 if they are the same node. (In this case, isSameNode() 436 * will always return true, and the two nodes will produce the same result 437 * for generateId()) 438 */ 439 public int compareOrder(final NodeInfo other) { 440 if (other != this) { 441 return 1; 442 } 443 // are they the same node? 444 if (this == other || this.isSameNode(other)) { 445 return 0; 446 } 447 return 1; 448 } 449 450 /*** 451 * Determine whether this is the same node as another node. <br /> 452 * Note: a.isSameNode(b) if and only if generateId(a)==generateId(b) 453 * @return true if this Node object and the supplied Node object 454 * represent the same node in the tree. 455 */ 456 public boolean isSameNode(final NodeInfo other) { 457 return this == other; 458 } 459 460 }

This page was automatically generated by Maven