KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > om > Orphan


1 package net.sf.saxon.om;
2 import net.sf.saxon.Configuration;
3 import net.sf.saxon.Err;
4 import net.sf.saxon.event.Receiver;
5 import net.sf.saxon.pattern.NodeTest;
6 import net.sf.saxon.trans.XPathException;
7 import net.sf.saxon.type.SchemaType;
8 import net.sf.saxon.type.Type;
9 import net.sf.saxon.value.UntypedAtomicValue;
10 import net.sf.saxon.value.Value;
11
12 /**
13   * A node (implementing the NodeInfo interface) representing an attribute, text node,
14   * comment, processing instruction, or namespace that has no parent (and of course no children).
15   * Exceptionally it is also used (during whitespace stripping) to represent a standalone element.
16   * @author Michael H. Kay
17   */

18
19 public final class Orphan implements NodeInfo, FingerprintedNode {
20
21     private short kind;
22     private int nameCode = -1;
23     private CharSequence JavaDoc stringValue;
24     private int typeAnnotation = -1;
25     private Configuration config;
26     private String JavaDoc systemId;
27
28     public Orphan(Configuration config) {
29         this.config = config;
30     }
31
32     public void setNodeKind(short kind) {
33         this.kind = kind;
34     }
35
36     public void setNameCode(int nameCode) {
37         this.nameCode = nameCode;
38     }
39
40     public void setStringValue(CharSequence JavaDoc stringValue) {
41         this.stringValue = stringValue;
42     }
43
44     public void setTypeAnnotation(int typeAnnotation) {
45         this.typeAnnotation = typeAnnotation;
46     }
47
48     public void setSystemId(String JavaDoc systemId) {
49         this.systemId = systemId;
50     }
51
52     /**
53     * Return the type of node.
54     * @return one of the values Node.ELEMENT, Node.TEXT, Node.ATTRIBUTE, etc.
55     */

56
57     public int getNodeKind() {
58         return kind;
59     }
60
61     /**
62     * Get the typed value of the item
63     */

64
65     public SequenceIterator getTypedValue() throws XPathException {
66         if (typeAnnotation == -1) {
67             return SingletonIterator.makeIterator(
68                     new UntypedAtomicValue(stringValue));
69         } else {
70             SchemaType stype = config.getSchemaType(typeAnnotation);
71             if (stype == null) {
72                 String JavaDoc typeName = config.getNamePool().getDisplayName(typeAnnotation);
73                 throw new IllegalStateException JavaDoc("Unknown type annotation " +
74                         Err.wrap(typeName) + " in standalone node");
75             } else {
76                 return stype.getTypedValue(this);
77             }
78         }
79     }
80
81     /**
82      * Get the typed value. The result of this method will always be consistent with the method
83      * {@link Item#getTypedValue()}. However, this method is often more convenient and may be
84      * more efficient, especially in the common case where the value is expected to be a singleton.
85      *
86      * @return the typed value. If requireSingleton is set to true, the result will always be an
87      * AtomicValue. In other cases it may be a Value representing a sequence whose items are atomic
88      * values.
89      * @since 8.5
90      */

91
92     public Value atomize() throws XPathException {
93         if (typeAnnotation == -1) {
94             return new UntypedAtomicValue(stringValue);
95         } else {
96             SchemaType stype = config.getSchemaType(typeAnnotation);
97             if (stype == null) {
98                 String JavaDoc typeName = config.getNamePool().getDisplayName(typeAnnotation);
99                 throw new IllegalStateException JavaDoc("Unknown type annotation " +
100                         Err.wrap(typeName) + " in standalone node");
101             } else {
102                 return stype.atomize(this);
103             }
104         }
105     }
106
107     /**
108      * Get the configuration
109      */

110
111     public Configuration getConfiguration() {
112         return config;
113     }
114
115     /**
116      * Get the name pool
117      */

118
119     public NamePool getNamePool() {
120         return config.getNamePool();
121     }
122
123     /**
124     * Get the type annotation
125     */

126
127     public int getTypeAnnotation() {
128         return typeAnnotation;
129     }
130
131     /**
132     * Determine whether this is the same node as another node. <br />
133     * Note: a.isSameNode(b) if and only if generateId(a)==generateId(b)
134     * @return true if this Node object and the supplied Node object represent the
135     * same node in the tree.
136     */

137
138     public boolean isSameNodeInfo(NodeInfo other) {
139         return this==other;
140     }
141
142     /**
143     * Get the System ID for the node.
144     * @return the System Identifier of the entity in the source document containing the node,
145     * or null if not known. Note this is not the same as the base URI: the base URI can be
146     * modified by xml:base, but the system ID cannot.
147     */

148
149     public String JavaDoc getSystemId() {
150         return systemId;
151     }
152
153     /**
154     * Get the Base URI for the node, that is, the URI used for resolving a relative URI contained
155     * in the node. This will be the same as the System ID unless xml:base has been used.
156     */

157
158     public String JavaDoc getBaseURI() {
159         if (kind == Type.PROCESSING_INSTRUCTION) {
160             return systemId;
161         } else {
162             return null;
163         }
164     }
165
166     /**
167     * Get line number
168     * @return the line number of the node in its original source document; or -1 if not available
169     */

170
171     public int getLineNumber() {
172         return -1;
173     }
174
175     /**
176     * Determine the relative position of this node and another node, in document order.
177     * The other node will always be in the same document.
178     * @param other The other node, whose position is to be compared with this node
179     * @return -1 if this node precedes the other node, +1 if it follows the other
180     * node, or 0 if they are the same node. (In this case, isSameNode() will always
181     * return true, and the two nodes will produce the same result for generateId())
182     */

183
184     public int compareOrder(NodeInfo other) {
185
186         // are they the same node?
187
if (this.isSameNodeInfo(other)) {
188             return 0;
189         }
190         return (this.hashCode() < other.hashCode() ? -1 : +1);
191     }
192
193     /**
194     * Return the string value of the node.
195     * @return the string value of the node
196     */

197
198     public String JavaDoc getStringValue() {
199         return stringValue.toString();
200     }
201
202     /**
203      * Get the value of the item as a CharSequence. This is in some cases more efficient than
204      * the version of the method that returns a String.
205      */

206
207     public CharSequence JavaDoc getStringValueCS() {
208         return stringValue;
209     }
210
211     /**
212     * Get name code. The name code is a coded form of the node name: two nodes
213     * with the same name code have the same namespace URI, the same local name,
214     * and the same prefix. By masking the name code with &0xfffff, you get a
215     * fingerprint: two nodes with the same fingerprint have the same local name
216     * and namespace URI.
217     * @see net.sf.saxon.om.NamePool#allocate allocate
218     */

219
220     public int getNameCode() {
221         return nameCode;
222     }
223
224     /**
225     * Get fingerprint. The fingerprint is a coded form of the expanded name
226     * of the node: two nodes
227     * with the same name code have the same namespace URI and the same local name.
228     * A fingerprint of -1 should be returned for a node with no name.
229     */

230
231     public int getFingerprint() {
232         if (nameCode == -1) {
233             return -1;
234         } else {
235             return getNameCode()&0xfffff;
236         }
237     }
238
239     /**
240     * Get the local part of the name of this node. This is the name after the ":" if any.
241     * @return the local part of the name. For an unnamed node, returns "".
242     */

243
244     public String JavaDoc getLocalPart() {
245         if (nameCode == -1) {
246             return "";
247         } else {
248             return config.getNamePool().getLocalName(nameCode);
249         }
250     }
251
252     /**
253     * Get the URI part of the name of this node. This is the URI corresponding to the
254     * prefix, or the URI of the default namespace if appropriate.
255     * @return The URI of the namespace of this node. For an unnamed node, return null.
256     * For a node with an empty prefix, return an empty string.
257     */

258
259     public String JavaDoc getURI() {
260         if (nameCode == -1) {
261             return "";
262         } else {
263             return config.getNamePool().getURI(nameCode);
264         }
265     }
266
267     /**
268      * Get the prefix of the name of the node. This is defined only for elements and attributes.
269      * If the node has no prefix, or for other kinds of node, return a zero-length string.
270      *
271      * @return The prefix of the name of the node.
272      */

273
274     public String JavaDoc getPrefix() {
275         if (nameCode == -1) {
276             return "";
277         } else {
278             return config.getNamePool().getPrefix(nameCode);
279         }
280     }
281
282     /**
283     * Get the display name of this node. For elements and attributes this is [prefix:]localname.
284     * For unnamed nodes, it is an empty string.
285     * @return The display name of this node.
286     * For a node with no name, return an empty string.
287     */

288
289     public String JavaDoc getDisplayName() {
290         if (nameCode == -1) {
291             return "";
292         } else {
293             return config.getNamePool().getDisplayName(nameCode);
294         }
295     }
296
297     /**
298     * Get the NodeInfo object representing the parent of this node
299      * @return null - an Orphan has no parent.
300     */

301
302     public NodeInfo getParent() {
303         return null;
304     }
305
306     /**
307     * Return an iteration over the nodes reached by the given axis from this node
308     * @param axisNumber the axis to be searched, e.g. Axis.CHILD or Axis.ANCESTOR
309     * @return a SequenceIterator that scans the nodes reached by the axis in turn.
310     */

311
312     public AxisIterator iterateAxis(byte axisNumber) {
313         switch (axisNumber) {
314             case Axis.ANCESTOR_OR_SELF:
315             case Axis.DESCENDANT_OR_SELF:
316             case Axis.SELF:
317                 return SingletonIterator.makeIterator(this);
318             case Axis.ANCESTOR:
319             case Axis.ATTRIBUTE:
320             case Axis.CHILD:
321             case Axis.DESCENDANT:
322             case Axis.FOLLOWING:
323             case Axis.FOLLOWING_SIBLING:
324             case Axis.NAMESPACE:
325             case Axis.PARENT:
326             case Axis.PRECEDING:
327             case Axis.PRECEDING_SIBLING:
328             case Axis.PRECEDING_OR_ANCESTOR:
329                 return EmptyIterator.getInstance();
330             default:
331                  throw new IllegalArgumentException JavaDoc("Unknown axis number " + axisNumber);
332         }
333     }
334
335
336     /**
337     * Return an iteration over the nodes reached by the given axis from this node
338     * @param axisNumber the axis to be searched, e.g. Axis.CHILD or Axis.ANCESTOR
339     * @param nodeTest A pattern to be matched by the returned nodes
340     * @return a SequenceIterator that scans the nodes reached by the axis in turn.
341     */

342
343     public AxisIterator iterateAxis(byte axisNumber, NodeTest nodeTest) {
344         switch (axisNumber) {
345             case Axis.ANCESTOR_OR_SELF:
346             case Axis.DESCENDANT_OR_SELF:
347             case Axis.SELF:
348                 if (nodeTest.matches(this)) {
349                     return SingletonIterator.makeIterator(this);
350                 } else {
351                     return EmptyIterator.getInstance();
352                 }
353             case Axis.ANCESTOR:
354             case Axis.ATTRIBUTE:
355             case Axis.CHILD:
356             case Axis.DESCENDANT:
357             case Axis.FOLLOWING:
358             case Axis.FOLLOWING_SIBLING:
359             case Axis.NAMESPACE:
360             case Axis.PARENT:
361             case Axis.PRECEDING:
362             case Axis.PRECEDING_SIBLING:
363             case Axis.PRECEDING_OR_ANCESTOR:
364                 return EmptyIterator.getInstance();
365             default:
366                  throw new IllegalArgumentException JavaDoc("Unknown axis number " + axisNumber);
367         }
368     }
369
370     /**
371     * Get the value of a given attribute of this node
372     * @param fingerprint The fingerprint of the attribute name
373     * @return the attribute value if it exists or null if not
374     */

375
376     public String JavaDoc getAttributeValue(int fingerprint) {
377         return null;
378     }
379
380     /**
381     * Get the root node of this tree (not necessarily a document node).
382     * Always returns this node in the case of an Orphan node.
383     */

384
385     public NodeInfo getRoot() {
386         return this;
387     }
388
389     /**
390     * Get the root (document) node
391     * @return the DocumentInfo representing the containing document, or null if the
392     * node is not part of a document. Always null for an Orphan node.
393     */

394
395     public DocumentInfo getDocumentRoot() {
396         return null;
397     }
398
399     /**
400     * Determine whether the node has any children.
401     * @return false - an orphan node never has any children
402     */

403
404     public boolean hasChildNodes() {
405         return false;
406     }
407
408     /**
409     * Get a character string that uniquely identifies this node.
410     * Note: a.isSameNode(b) if and only if generateId(a)==generateId(b)
411     * @return a string that uniquely identifies this node, within this
412     * document. The calling code prepends information to make the result
413     * unique across all documents.
414     */

415
416     public String JavaDoc generateId() {
417         return "Q" + hashCode();
418     }
419
420     /**
421      * Get the document number of the document containing this node. For a free-standing
422      * orphan node, just return the hashcode.
423      */

424
425     public int getDocumentNumber() {
426         return hashCode() & 0xffffff;
427         // lose the top bits because we need to subtract these values for comparison
428
}
429
430     /**
431     * Copy this node to a given outputter (deep copy)
432     */

433
434     public void copy(Receiver out, int whichNamespaces, boolean copyAnnotations, int locationId) throws XPathException {
435         Navigator.copy(this, out, config.getNamePool(), whichNamespaces, copyAnnotations, locationId);
436     }
437
438     /**
439     * Output all namespace nodes associated with this element. Does nothing if
440     * the node is not an element.
441     * @param out The relevant outputter
442      * @param includeAncestors True if namespaces declared on ancestor elements must
443      */

444
445     public void sendNamespaceDeclarations(Receiver out, boolean includeAncestors) {
446     }
447
448     /**
449      * Get all namespace undeclarations and undeclarations defined on this element.
450      *
451      * @param buffer If this is non-null, and the result array fits in this buffer, then the result
452      * may overwrite the contents of this array, to avoid the cost of allocating a new array on the heap.
453      * @return An array of integers representing the namespace declarations and undeclarations present on
454      * this element. For a node other than an element, return null. Otherwise, the returned array is a
455      * sequence of namespace codes, whose meaning may be interpreted by reference to the name pool. The
456      * top half word of each namespace code represents the prefix, the bottom half represents the URI.
457      * If the bottom half is zero, then this is a namespace undeclaration rather than a declaration.
458      * The XML namespace is never included in the list. If the supplied array is larger than required,
459      * then the first unused entry will be set to -1.
460      * <p/>
461      * <p>For a node other than an element, the method returns null.</p>
462      */

463
464     public int[] getDeclaredNamespaces(int[] buffer) {
465         return null;
466     }
467
468 }
469
470 //
471
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
472
// you may not use this file except in compliance with the License. You may obtain a copy of the
473
// License at http://www.mozilla.org/MPL/
474
//
475
// Software distributed under the License is distributed on an "AS IS" basis,
476
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
477
// See the License for the specific language governing rights and limitations under the License.
478
//
479
// The Original Code is: all this file.
480
//
481
// The Initial Developer of the Original Code is
482
// Michael H. Kay.
483
//
484
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
485
//
486
// Contributor(s): none.
487
//
488
Popular Tags