KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > tinytree > TinyNodeImpl


1 package com.icl.saxon.tinytree;
2 import com.icl.saxon.om.*;
3 import com.icl.saxon.Context;
4 import com.icl.saxon.expr.NodeSetExtent;
5 import com.icl.saxon.pattern.NodeTest;
6 import com.icl.saxon.pattern.NameTest;
7 import com.icl.saxon.output.Outputter;
8 import com.icl.saxon.tree.DOMExceptionImpl;
9
10 import org.w3c.dom.*;
11 import javax.xml.transform.TransformerException JavaDoc;
12
13
14 /**
15   * A node in the XML parse tree representing an XML element, character content, or attribute.<P>
16   * This is the top-level class in the implementation class hierarchy; it essentially contains
17   * all those methods that can be defined using other primitive methods, without direct access
18   * to data.
19   * @author <A HREF="mailto:mhkay@iclway.co.uk>Michael H. Kay</A>
20   */

21
22 abstract class TinyNodeImpl extends AbstractNode {
23    
24     protected TinyDocumentImpl document;
25     protected int nodeNr;
26     protected TinyNodeImpl parent = null;
27
28     /**
29     * Set the system id of this node. <br />
30     * This method is present to ensure that
31     * the class implements the javax.xml.transform.Source interface, so a node can
32     * be used as the source of a transformation.
33     */

34
35     public void setSystemId(String JavaDoc uri) {
36         short type = document.nodeType[nodeNr];
37         if (type==ATTRIBUTE || type==NAMESPACE) {
38             ((TinyNodeImpl)getParent()).setSystemId(uri);
39         } else {
40             document.setSystemId(nodeNr, uri);
41         }
42     }
43
44     /**
45     * Set the parent of this node. Providing this information is useful,
46     * if it is known, because otherwise getParent() has to search backwards
47     * through the document.
48     */

49
50     protected void setParentNode(TinyNodeImpl parent) {
51         this.parent = parent;
52     }
53
54     /**
55     * Determine whether this is the same node as another node
56     * @return true if this Node object and the supplied Node object represent the
57     * same node in the tree.
58     */

59
60     public boolean isSameNode(NodeInfo other) {
61         if (this==other) return true;
62         if (!(other instanceof TinyNodeImpl)) return false;
63         return this.document==((TinyNodeImpl)other).document &&
64              this.nodeNr==((TinyNodeImpl)other).nodeNr;
65     }
66
67     /**
68     * Get the system ID for the entity containing the node.
69     */

70
71     public String JavaDoc getSystemId() {
72         return document.getSystemId(nodeNr);
73     }
74
75     /**
76     * Get the base URI for the node. Default implementation for child nodes gets
77     * the base URI of the parent node.
78     */

79
80     public String JavaDoc getBaseURI() {
81         return (getParent()).getBaseURI();
82     }
83
84     /**
85     * Get the node corresponding to this javax.xml.transform.dom.DOMLocator
86     */

87
88     public Node getOriginatingNode() {
89         return this;
90     }
91
92
93     /**
94     * Set the line number of the node within its source document entity
95     */

96
97     public void setLineNumber(int line) {
98         document.setLineNumber(nodeNr, line);
99     }
100
101
102     /**
103     * Get the line number of the node within its source document entity
104     */

105
106     public int getLineNumber() {
107         return document.getLineNumber(nodeNr);
108     }
109
110     /**
111     * Get the node sequence number (in document order). Sequence numbers are monotonic but not
112     * consecutive. The sequence number must be unique within the document (not, as in
113     * previous releases, within the whole document collection)
114     */

115
116     protected long getSequenceNumber() {
117         return (long)nodeNr << 32;
118     }
119
120     /**
121     * Determine the relative position of this node and another node, in document order.
122     * The other node will always be in the same document.
123     * @param other The other node, whose position is to be compared with this node
124     * @return -1 if this node precedes the other node, +1 if it follows the other
125     * node, or 0 if they are the same node. (In this case, isSameNode() will always
126     * return true, and the two nodes will produce the same result for generateId())
127     */

128     
129     public final int compareOrder(NodeInfo other) {
130         long a = getSequenceNumber();
131         long b = ((TinyNodeImpl)other).getSequenceNumber();
132         if (a<b) return -1;
133         if (a>b) return +1;
134         return 0;
135     }
136
137     /**
138     * Get the fingerprint of the node, used for matching names
139     */

140     
141     public int getFingerprint() {
142         int nc = getNameCode();
143         if (nc==-1) return -1;
144         return nc & 0xfffff;
145     }
146
147     /**
148     * Get the name code of the node, used for matching names
149     */

150     
151     public int getNameCode() {
152         // overridden for attributes and namespace nodes.
153
return document.nameCode[nodeNr];
154     }
155
156     /**
157     * Get the prefix part of the name of this node. This is the name before the ":" if any.
158     * @return the prefix part of the name. For an unnamed node, return "".
159     */

160
161     public String JavaDoc getPrefix() {
162         int code = document.nameCode[nodeNr];
163         if (code<0) return "";
164         if ((code>>20 & 0xff) == 0) return "";
165         return document.getNamePool().getPrefix(code);
166     }
167
168     /**
169     * Get the URI part of the name of this node. This is the URI corresponding to the
170     * prefix, or the URI of the default namespace if appropriate.
171     * @return The URI of the namespace of this node. For an unnamed node, or for
172     * an element or attribute in the default namespace, return an empty string.
173     */

174
175     public String JavaDoc getURI() {
176         int code = document.nameCode[nodeNr];
177         if (code<0) return "";
178         return document.getNamePool().getURI(code);
179     }
180     
181     /**
182     * Get the display name of this node. For elements and attributes this is [prefix:]localname.
183     * For unnamed nodes, it is an empty string.
184     * @return The display name of this node.
185     * For a node with no name, return an empty string.
186     */

187
188     public String JavaDoc getDisplayName() {
189         int code = document.nameCode[nodeNr];
190         if (code<0) return "";
191         return document.getNamePool().getDisplayName(code);
192     }
193
194     /**
195     * Get the local name of this node.
196     * @return The local name of this node.
197     * For a node with no name, return an empty string.
198     */

199
200     public String JavaDoc getLocalName() {
201         int code = document.nameCode[nodeNr];
202         if (code<0) return "";
203         return document.getNamePool().getLocalName(code);
204     }
205
206     /**
207     * Return an enumeration over the nodes reached by the given axis from this node
208     * @param axisNumber Identifies the required axis, eg. Axis.CHILD or Axis.PARENT
209     * @param nodeTest A pattern to be matched by the returned nodes
210     * @return a AxisEnumeration that scans the nodes reached by the axis in turn.
211     */

212
213     public AxisEnumeration getEnumeration(
214                                         byte axisNumber,
215                                         NodeTest nodeTest) {
216                                             
217         // System.err.println("Get enumeration of axis " + axisNumber + " from " + generateId());
218

219         short type = getNodeType();
220         switch (axisNumber) {
221             case Axis.ANCESTOR:
222                 if (type==ROOT) {
223                     return EmptyEnumeration.getInstance();
224                 } else {
225                     return new AncestorEnumeration(document, this, nodeTest, false);
226                 }
227                  
228             case Axis.ANCESTOR_OR_SELF:
229                 if (type==ROOT) {
230                     if (nodeTest.matches(this)) {
231                         return new SingletonEnumeration(this);
232                     } else {
233                         return EmptyEnumeration.getInstance();
234                     }
235                 } else {
236                     return new AncestorEnumeration(document, this, nodeTest, true);
237                 }
238               
239             case Axis.ATTRIBUTE:
240                  if (type!=ELEMENT) return EmptyEnumeration.getInstance();
241                  if (document.offset[nodeNr]<0) return EmptyEnumeration.getInstance();
242                  return new AttributeEnumeration(document, nodeNr, nodeTest);
243                  
244             case Axis.CHILD:
245                  if (hasChildNodes()) {
246                     return new SiblingEnumeration(document, this, nodeTest, true);
247                  } else {
248                     return EmptyEnumeration.getInstance();
249                  }
250                  
251             case Axis.DESCENDANT:
252                 if (type==ROOT &&
253                         nodeTest instanceof NameTest &&
254                         nodeTest.getNodeType()==ELEMENT) {
255                     return ((TinyDocumentImpl)this).getAllElements(
256                                 ((NameTest)nodeTest).getFingerprint());
257                 } else if (hasChildNodes()) {
258                     return new DescendantEnumeration(document, this, nodeTest, false);
259                 } else {
260                     return EmptyEnumeration.getInstance();
261                 }
262                  
263             case Axis.DESCENDANT_OR_SELF:
264                  if (hasChildNodes()) {
265                     return new DescendantEnumeration(document, this, nodeTest, true);
266                  } else {
267                     if (nodeTest.matches(this)) {
268                         return new SingletonEnumeration(this);
269                     } else {
270                         return EmptyEnumeration.getInstance();
271                     }
272                  }
273             case Axis.FOLLOWING:
274                 if (type==ROOT) {
275                     return EmptyEnumeration.getInstance();
276                 } else if (type==ATTRIBUTE || type==NAMESPACE) {
277                     return new FollowingEnumeration(
278                                 document, (TinyNodeImpl)getParent(), nodeTest, true);
279                 } else {
280                     return new FollowingEnumeration(
281                                 document, this, nodeTest, false);
282                 }
283                  
284             case Axis.FOLLOWING_SIBLING:
285                 if (type==ROOT || type==ATTRIBUTE || type==NAMESPACE) {
286                     return EmptyEnumeration.getInstance();
287                 } else {
288                     return new SiblingEnumeration(
289                                 document, this, nodeTest, false);
290                 }
291                  
292             case Axis.NAMESPACE:
293                 if (type!=ELEMENT) return EmptyEnumeration.getInstance();
294                 return new NamespaceEnumeration((TinyElementImpl)this, nodeTest);
295                     
296             case Axis.PARENT:
297                  NodeInfo parent = (NodeInfo)getParent();
298                  if (parent==null) return EmptyEnumeration.getInstance();
299                  if (nodeTest.matches(parent)) return new SingletonEnumeration(parent);
300                  return EmptyEnumeration.getInstance();
301                  
302             case Axis.PRECEDING:
303                 if (type==ROOT) {
304                     return EmptyEnumeration.getInstance();
305                 } else if (type==ATTRIBUTE || type==NAMESPACE) {
306                     return new PrecedingEnumeration(
307                                 document, (TinyNodeImpl)getParent(), nodeTest, false);
308                 } else {
309                     return new PrecedingEnumeration(
310                                 document, this, nodeTest, false);
311                 }
312                  
313             case Axis.PRECEDING_SIBLING:
314                 if (type==ROOT || type==ATTRIBUTE || type==NAMESPACE) {
315                     return EmptyEnumeration.getInstance();
316                 } else {
317                     return new PrecedingSiblingEnumeration(
318                                 document, this, nodeTest);
319                 }
320                  
321             case Axis.SELF:
322                 if (nodeTest.matches(this)) return new SingletonEnumeration(this);
323                 return EmptyEnumeration.getInstance();
324
325             case Axis.PRECEDING_OR_ANCESTOR:
326                 if (type==ROOT) {
327                     return EmptyEnumeration.getInstance();
328                 } else if (type==ATTRIBUTE || type==NAMESPACE) {
329                     return new PrecedingEnumeration(
330                                 document, (TinyNodeImpl)getParent(), nodeTest, true);
331                 } else {
332                     return new PrecedingEnumeration(
333                                 document, this, nodeTest, true);
334                 }
335                  
336             default:
337                  throw new IllegalArgumentException JavaDoc("Unknown axis number " + axisNumber);
338         }
339     }
340
341     /**
342      * Find the parent node of this node.
343      * @return The Node object describing the containing element or root node.
344      */

345
346     public NodeInfo getParent() {
347         if (parent!=null) return parent;
348
349         // if parent is unknown, search backwards for it
350
for (int i=nodeNr-1; i>=0; i--) {
351             if (document.depth[i]<document.depth[nodeNr]) {
352                 parent = document.getNode(i);
353                 return parent;
354             }
355         }
356         parent = document;
357         return parent;
358     }
359
360     /**
361     * Determine whether the node has any children.
362     * @return <code>true</code> if this node has any attributes,
363     * <code>false</code> otherwise.
364     */

365
366     public boolean hasChildNodes() {
367         // overridden in TinyParentNodeImpl
368
return false;
369     }
370
371     /**
372      * Returns whether this node has any attributes.
373      * @return <code>true</code> if this node has any attributes,
374      * <code>false</code> otherwise.
375      * @since DOM Level 2
376      */

377     
378     public boolean hasAttributes() {
379         // overridden in TinyElementImpl
380
return false;
381     }
382     
383     /**
384      * Find the value of a given attribute of this node. <BR>
385      * This method is defined on all nodes to meet XSL requirements, but for nodes
386      * other than elements it will always return null.
387      * @param uri the namespace uri of an attribute
388      * @param localName the local name of an attribute
389      * @return the value of the attribute, if it exists, otherwise null
390      */

391
392     public String JavaDoc getAttributeValue( String JavaDoc uri, String JavaDoc localName ) {
393         return null;
394     }
395
396
397     /**
398      * Find the value of a given attribute of this node. <BR>
399      * This method is defined on all nodes to meet XSL requirements, but for nodes
400      * other than elements it will always return null.
401      * @param name the name of an attribute. This must be an unqualified attribute name,
402      * i.e. one with no namespace prefix.
403      * @return the value of the attribute, if it exists, otherwise null
404      */

405
406     //public String getAttributeValue( String name ) {
407
// overridden in TinyElementImpl
408
// return null;
409
//}
410

411     
412     /**
413     * Get the value of a given attribute of this node
414     * @param fingerprint The fingerprint of the attribute name
415     * @return the attribute value if it exists or null if not
416     */

417     
418     public String JavaDoc getAttributeValue(int fingerprint) {
419         // overridden in TElementImpl
420
return null;
421     }
422
423     /**
424     * Get the root (document) node
425     * @return the DocumentInfo representing the containing document
426     */

427
428     public DocumentInfo getDocumentRoot() {
429         return document;
430     }
431
432     /**
433     * Output all namespace nodes associated with this element. Does nothing if
434     * the node is not an element.
435     * @param out The relevant outputter
436     * @param includeAncestors True if namespaces declared on ancestor elements must
437     * be output; false if it is known that these are already on the result tree
438     */

439
440     public void outputNamespaceNodes(Outputter out, boolean includeAncestors)
441         throws TransformerException JavaDoc
442     {}
443     
444     /**
445     * Get a character string that uniquely identifies this node
446     * @return a string.
447     */

448
449     public String JavaDoc generateId() {
450         return document.generateId() +
451                 NODE_LETTER[getNodeType()] +
452                 nodeNr;
453     }
454
455 }
456
457 //
458
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
459
// you may not use this file except in compliance with the License. You may obtain a copy of the
460
// License at http://www.mozilla.org/MPL/
461
//
462
// Software distributed under the License is distributed on an "AS IS" basis,
463
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
464
// See the License for the specific language governing rights and limitations under the License.
465
//
466
// The Original Code is: all this file.
467
//
468
// The Initial Developer of the Original Code is
469
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
470
//
471
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
472
//
473
// Contributor(s): none.
474
//
475
Popular Tags