KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > om > AbstractNode


1 package com.icl.saxon.om;
2 import com.icl.saxon.om.Axis;
3 import com.icl.saxon.expr.NodeSetExtent;
4 import com.icl.saxon.expr.XPathException;
5 import com.icl.saxon.pattern.NodeTest;
6 import com.icl.saxon.pattern.NameTest;
7 import com.icl.saxon.pattern.AnyNodeTest;
8 import com.icl.saxon.pattern.NodeTypeTest;
9 import com.icl.saxon.output.Outputter;
10 import com.icl.saxon.tree.DOMExceptionImpl;
11 import com.icl.saxon.sort.LocalOrderComparer;
12
13 import org.w3c.dom.*;
14
15 import javax.xml.transform.SourceLocator JavaDoc;
16 import javax.xml.transform.dom.DOMLocator JavaDoc;
17 import javax.xml.transform.TransformerException JavaDoc;
18
19
20 /**
21   * This class is an abstract implementation of the Saxon NodeInfo interface;
22   * it also contains concrete implementations of most of the DOM methods in terms
23   * of the NodeInfo methods. These include all the methods defined on the DOM Node
24   * class itself, and most of those defined on subclasses such as Document, Text,
25   * and Comment: because
26   * of the absence of multiple inheritance, this is the only way of making these
27   * methods reusable by multiple implementations.
28   * The class contains no data, and can be used as a common
29   * superclass for different implementations of Node and NodeInfo.
30   * @author <A HREF="mailto:mhkay@iclway.co.uk>Michael H. Kay</A>
31   */

32
33 public abstract class AbstractNode implements Node, NodeInfo, SourceLocator JavaDoc, DOMLocator JavaDoc {
34
35     /**
36     * Chararacteristic letters to identify each type of node, indexed using the node type
37     * values. These are used as the initial letter of the result of generate-id()
38     */

39
40     public static final char[] NODE_LETTER =
41         {'x', 'e', 'a', 't', 'x', 'x', 'x', 'p', 'c', 'r', 'x', 'x', 'x', 'n'};
42    
43     /**
44     * Determine whether this is the same node as another node
45     * @return true if this Node object and the supplied Node object represent the
46     * same node in the tree.
47     */

48
49     public abstract boolean isSameNode(NodeInfo other);
50
51     /**
52     * Get a character string that uniquely identifies this node
53     * @return a string.
54     */

55
56     public abstract String JavaDoc generateId();
57
58     /**
59     * Get the system ID for the entity containing the node.
60     */

61
62     public abstract String JavaDoc getSystemId();
63
64     /**
65     * Get the base URI for the node. Default implementation for child nodes gets
66     * the base URI of the parent node.
67     */

68
69     public abstract String JavaDoc getBaseURI();
70
71     /**
72     * Get the node corresponding to this javax.xml.transform.dom.DOMLocator
73     */

74
75     public Node getOriginatingNode() {
76         return this;
77     }
78
79     /**
80     * Determine the relative position of this node and another node, in document order.
81     * The other node will always be in the same document.
82     * @param other The other node, whose position is to be compared with this node
83     * @return -1 if this node precedes the other node, +1 if it follows the other
84     * node, or 0 if they are the same node. (In this case, isSameNode() will always
85     * return true, and the two nodes will produce the same result for generateId())
86     */

87     
88     public abstract int compareOrder(NodeInfo other);
89
90     /**
91     * Get the name code of the node, used for displaying names
92     */

93     
94     public abstract int getNameCode();
95
96     /**
97     * Get the fingerprint of the node, used for matching names
98     */

99     
100     public abstract int getFingerprint();
101
102     /**
103     * Get the name of this node, following the DOM rules
104     * @return The name of the node. For an element this is the element name, for an attribute
105     * it is the attribute name, as a QName. Other node types return conventional names such
106     * as "#text" or "#comment"
107     */

108
109     public String JavaDoc getNodeName() {
110         switch (getNodeType()) {
111             case NodeInfo.ROOT:
112                 return "#document";
113             case NodeInfo.ELEMENT:
114                 return getDisplayName();
115             case NodeInfo.ATTRIBUTE:
116                 return getDisplayName();
117             case NodeInfo.TEXT:
118                 return "#text";
119             case NodeInfo.COMMENT:
120                 return "#comment";
121             case NodeInfo.PI:
122                 return getLocalName();
123             case NodeInfo.NAMESPACE:
124                 return getLocalName();
125             default:
126                 return "#unknown";
127        }
128     }
129
130     /**
131     * Get the prefix part of the name of this node. This is the name before the ":" if any.
132     * @return the prefix part of the name. For an unnamed node, return "".
133     */

134
135     public abstract String JavaDoc getPrefix();
136
137     /**
138     * Get the URI part of the name of this node. This is the URI corresponding to the
139     * prefix, or the URI of the default namespace if appropriate.
140     * @return The URI of the namespace of this node. For an unnamed node, or for
141     * an element or attribute in the default namespace, return an empty string.
142     */

143
144     public abstract String JavaDoc getURI();
145     
146     /**
147     * Get the display name of this node. For elements and attributes this is [prefix:]localname.
148     * For unnamed nodes, it is an empty string.
149     * @return The display name of this node.
150     * For a node with no name, return an empty string.
151     */

152
153     public String JavaDoc getDisplayName() {
154         String JavaDoc localName = getLocalName();
155         if ("".equals(localName)) {
156             return "";
157         }
158         String JavaDoc prefix = getPrefix();
159         if ("".equals(prefix)) {
160             return localName;
161         }
162         return prefix + ":" + localName;
163     }
164
165     /**
166     * Get the local name of this node.
167     * @return The local name of this node.
168     * For a node with no name, return an empty string.
169     */

170
171     public abstract String JavaDoc getLocalName();
172
173     /**
174     * Determine whether the node has any children.
175     * @return <code>true</code> if this node has any attributes,
176     * <code>false</code> otherwise.
177     */

178
179     public abstract boolean hasChildNodes();
180
181     /**
182      * Returns whether this node has any attributes.
183      * @return <code>true</code> if this node has any attributes,
184      * <code>false</code> otherwise.
185      * @since DOM Level 2
186      */

187     
188     public abstract boolean hasAttributes();
189     
190     /**
191      * Find the value of a given attribute of this node. <BR>
192      * This method is defined on all nodes to meet XSL requirements, but for nodes
193      * other than elements it will always return null.
194      * @param uri the namespace uri of an attribute
195      * @param localName the local name of an attribute
196      * @return the value of the attribute, if it exists, otherwise null
197      */

198
199     public abstract String JavaDoc getAttributeValue( String JavaDoc uri, String JavaDoc localName );
200     
201     /**
202     * Get the value of a given attribute of this node
203     * @param fingerprint The fingerprint of the attribute name
204     * @return the attribute value if it exists or null if not
205     */

206     
207     public abstract String JavaDoc getAttributeValue(int fingerprint);
208
209     /**
210     * Get the line number of the node within its source document entity.
211     * The default implementation returns -1, meaning unknown
212     */

213
214     public int getLineNumber() {
215         return -1;
216     }
217
218     /**
219     * Get the column number of the node.
220     * The default implementation returns -1, meaning unknown
221     */

222
223     public int getColumnNumber() {
224         return -1;
225     }
226
227     /**
228     * Get the public identifier of the document entity containing this node.
229     * The default implementation returns null, meaning unknown
230     */

231
232     public String JavaDoc getPublicId() {
233         return null;
234     }
235
236     /**
237     * Return an enumeration over the nodes reached by the given axis from this node
238     * @param node NodeInfo representing the node from which the enumeration starts
239     * @param nodeType the type(s) of node to be included, e.g. NodeInfo.ELEMENT, NodeInfo.TEXT.
240     * The value NodeInfo.NODE means include any type of node.
241     * @param nodeTest A pattern to be matched by the returned nodes
242     * @return a AxisEnumeration that scans the nodes reached by the axis in turn.
243     */

244
245     public abstract AxisEnumeration getEnumeration(
246                                         byte axisNumber,
247                                         NodeTest nodeTest);
248
249     /**
250      * Find the parent node of this node.
251      * @return The Node object describing the containing element or root node.
252      */

253
254     public abstract NodeInfo getParent();
255
256     /**
257     * Get the root (document) node
258     * @return the DocumentInfo representing the containing document
259     */

260
261     public DocumentInfo getDocumentRoot() {
262         NodeInfo parent = this;
263         while (parent.getNodeType() != NodeInfo.ROOT) {
264             parent = parent.getParent();
265         }
266         return (DocumentInfo)parent;
267     }
268
269     /**
270      * Find the parent node of this node (DOM method).
271      * @return The Node object describing the containing element or root node.
272      */

273
274     public Node getParentNode() {
275         return (Node)getParent();
276     }
277
278     /**
279     * Get the previous sibling of the node (DOM method)
280     * @return The previous sibling node. Returns null if the current node is the first
281     * child of its parent.
282     */

283     
284     public Node getPreviousSibling() {
285         AxisEnumeration prev =
286             getEnumeration(Axis.PRECEDING_SIBLING, AnyNodeTest.getInstance());
287         if (prev.hasMoreElements()) {
288             return (Node)prev.nextElement();
289         } else {
290             return null;
291         }
292     }
293
294    /**
295     * Get next sibling node (DOM method)
296     * @return The next sibling node. Returns null if the current node is the last
297     * child of its parent.
298     */

299
300     public Node getNextSibling() {
301         AxisEnumeration foll =
302             getEnumeration(Axis.FOLLOWING_SIBLING, AnyNodeTest.getInstance());
303         if (foll.hasMoreElements()) {
304             return (Node)foll.nextElement();
305         } else {
306             return null;
307         }
308     }
309
310     /**
311     * Get first child (DOM method)
312     * @return the first child node of this node, or null if it has no children
313     */

314
315     public Node getFirstChild() {
316         AxisEnumeration children =
317             getEnumeration(Axis.CHILD, AnyNodeTest.getInstance());
318         if (children.hasMoreElements()) {
319             return (Node)children.nextElement();
320         } else {
321             return null;
322         }
323     }
324
325     /**
326     * Get last child (DOM method)
327     * @return last child of this node, or null if it has no children
328     */

329
330     public Node getLastChild() {
331         AxisEnumeration children =
332             getEnumeration(Axis.CHILD, AnyNodeTest.getInstance());
333         NodeInfo last = null;
334         while (children.hasMoreElements()) {
335             last = children.nextElement();
336         }
337         return (Node)last;
338     }
339
340
341     /**
342      * Get the outermost element. (DOM method)
343      * @return the Element for the outermost element of the document. If the document is
344      * not well-formed, this returns the last element child of the root if there is one, otherwise
345      * null.
346      */

347      
348     public Element getDocumentElement() {
349         NodeInfo root = getDocumentRoot();
350         AxisEnumeration children =
351             root.getEnumeration(Axis.CHILD, new NodeTypeTest(NodeInfo.ELEMENT));
352         if (children.hasMoreElements()) {
353             return (Element)children.nextElement();
354         } else {
355             return null;
356         }
357
358     }
359
360     /**
361     * Copy the string-value of this node to a given outputter.
362     * Default implementation does "out.writeContent(getStringValue());" but it
363     * is useful to provide an optimized implementation.
364     */

365
366     public void copyStringValue(Outputter out) throws TransformerException JavaDoc {
367         out.writeContent(getStringValue()); // default implementation
368
}
369
370     /**
371     * Output all namespace nodes associated with this element. Does nothing if
372     * the node is not an element.
373     * @param out The relevant outputter
374     * @param includeAncestors True if namespaces declared on ancestor elements must
375     * be output; false if it is known that these are already on the result tree
376     */

377
378     public void outputNamespaceNodes(Outputter out, boolean includeAncestors)
379         throws TransformerException JavaDoc
380     {}
381
382
383     /**
384     * Get the node value as defined in the DOM.
385     * This is not necessarily the same as the XPath string-value.
386     */

387
388     public String JavaDoc getNodeValue() {
389         switch (getNodeType()) {
390             case NodeInfo.ROOT:
391             case NodeInfo.ELEMENT:
392                 return null;
393             case NodeInfo.ATTRIBUTE:
394             case NodeInfo.TEXT:
395             case NodeInfo.COMMENT:
396             case NodeInfo.PI:
397             case NodeInfo.NAMESPACE:
398                 return getStringValue();
399             default:
400                 return null;
401         }
402     }
403
404     /**
405     * Set the node value. DOM method: always fails
406     */

407
408     public void setNodeValue(String JavaDoc nodeValue) throws DOMException {
409         disallowUpdate();
410     }
411
412     /**
413      * Return a <code>NodeList</code> that contains all children of this node. If
414      * there are no children, this is a <code>NodeList</code> containing no
415      * nodes. DOM Method.
416      */

417      
418     public NodeList getChildNodes() {
419         try {
420             return new NodeSetExtent(
421                     getEnumeration(Axis.CHILD, AnyNodeTest.getInstance()),
422                     LocalOrderComparer.getInstance());
423         } catch (XPathException err) {
424             return null;
425             // can't happen
426
}
427     }
428
429     /**
430      * Return a <code>NamedNodeMap</code> containing the attributes of this node (if
431      * it is an <code>Element</code> ) or <code>null</code> otherwise. (DOM method)
432      */

433      
434     public NamedNodeMap getAttributes() {
435         if (getNodeType()==NodeInfo.ELEMENT) {
436             return new AttributeMap();
437         } else {
438             return null;
439         }
440     }
441
442     /**
443      * Return the <code>Document</code> object associated with this node. (DOM method)
444      */

445      
446     public Document getOwnerDocument() {
447         return (Document)getDocumentRoot();
448     }
449
450     /**
451      * Insert the node <code>newChild</code> before the existing child node
452      * <code>refChild</code>. DOM method: always fails.
453      * @param newChild The node to insert.
454      * @param refChild The reference node, i.e., the node before which the
455      * new node must be inserted.
456      * @return The node being inserted.
457      * @exception DOMException
458      * NO_MODIFICATION_ALLOWED_ERR: Always raised.
459      */

460      
461     public Node insertBefore(Node newChild,
462                              Node refChild)
463                              throws DOMException {
464         disallowUpdate();
465         return null;
466     }
467
468     /**
469      * Replace the child node <code>oldChild</code> with
470      * <code>newChild</code> in the list of children, and returns the
471      * <code>oldChild</code> node. Always fails.
472      * @param newChild The new node to put in the child list.
473      * @param oldChild The node being replaced in the list.
474      * @return The node replaced.
475      * @exception DOMException
476      * NO_MODIFICATION_ALLOWED_ERR: Always raised.
477      */

478      
479     public Node replaceChild(Node newChild,
480                              Node oldChild)
481                              throws DOMException{
482         disallowUpdate();
483         return null;
484     }
485     
486     /**
487      * Remove the child node indicated by <code>oldChild</code> from the
488      * list of children, and returns it. DOM method: always fails.
489      * @param oldChild The node being removed.
490      * @return The node removed.
491      * @exception DOMException
492      * NO_MODIFICATION_ALLOWED_ERR: Always raised.
493      */

494      
495     public Node removeChild(Node oldChild) throws DOMException {
496         disallowUpdate();
497         return null;
498     }
499     
500     /**
501      * Adds the node <code>newChild</code> to the end of the list of children
502      * of this node. DOM method: always fails.
503      * @param newChild The node to add.
504      * @return The node added.
505      * @exception DOMException
506      * <br> NO_MODIFICATION_ALLOWED_ERR: Always raised.
507      */

508      
509     public Node appendChild(Node newChild) throws DOMException {
510         disallowUpdate();
511         return null;
512     }
513
514     /**
515      * Returns a duplicate of this node, i.e., serves as a generic copy
516      * constructor for nodes. The duplicate node has no parent. Not
517      * implemented: always returns null. (Because trees are read-only, there
518      * would be no way of using the resulting node.)
519      * @param deep If <code>true</code> , recursively clone the subtree under
520      * the specified node; if <code>false</code> , clone only the node
521      * itself (and its attributes, if it is an <code>Element</code> ).
522      * @return The duplicate node.
523      */

524      
525     public Node cloneNode(boolean deep) {
526         // Not implemented
527
return null;
528     }
529
530     /**
531      * Puts all <code>Text</code> nodes in the full depth of the sub-tree
532      * underneath this <code>Node</code>, including attribute nodes, into a
533      * "normal" form where only structure (e.g., elements, comments,
534      * processing instructions, CDATA sections, and entity references)
535      * separates <code>Text</code> nodes, i.e., there are neither adjacent
536      * <code>Text</code> nodes nor empty <code>Text</code> nodes.
537      * @since DOM Level 2
538      */

539      
540     public void normalize() {
541         // null operation; nodes are always normalized
542
}
543
544     /**
545      * Tests whether the DOM implementation implements a specific feature and
546      * that feature is supported by this node.
547      * @param feature The name of the feature to test. This is the same name
548      * which can be passed to the method <code>hasFeature</code> on
549      * <code>DOMImplementation</code> .
550      * @param version This is the version number of the feature to test. In
551      * Level 2, version 1, this is the string "2.0". If the version is not
552      * specified, supporting any version of the feature will cause the
553      * method to return <code>true</code> .
554      * @return Returns <code>true</code> if the specified feature is supported
555      * on this node, <code>false</code> otherwise.
556      * @since DOM Level 2
557      */

558      
559     public boolean isSupported(String JavaDoc feature,
560                                String JavaDoc version) {
561         return feature.equalsIgnoreCase("xml");
562     }
563
564     /**
565     * Alternative to isSupported(), defined in a draft DOM spec
566     */

567     
568     public boolean supports(String JavaDoc feature,
569                                String JavaDoc version) {
570         return isSupported(feature, version);
571     }
572
573     /**
574      * The namespace URI of this node, or <code>null</code> if it is
575      * unspecified. DOM method.
576      * <br> This is not a computed value that is the result of a namespace
577      * lookup based on an examination of the namespace declarations in scope.
578      * It is merely the namespace URI given at creation time.
579      * <br> For nodes of any type other than <code>ELEMENT_NODE</code> and
580      * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
581      * method, such as <code>createElement</code> from the
582      * <code>Document</code> interface, this is always <code>null</code> .
583      * Per the Namespaces in XML Specification an attribute does not
584      * inherit its namespace from the element it is attached to. If an
585      * attribute is not explicitly given a namespace, it simply has no
586      * namespace.
587      * @since DOM Level 2
588      */

589      
590     public String JavaDoc getNamespaceURI() {
591         String JavaDoc uri = getURI();
592         return (uri.equals("") ? null : uri);
593     }
594
595     /**
596     * Set the namespace prefix of this node. Always fails.
597     */

598     
599     public void setPrefix(String JavaDoc prefix)
600                             throws DOMException {
601         disallowUpdate();
602     }
603
604     /**
605     * Internal method used to indicate that update operations are not allowed
606     */

607
608     protected void disallowUpdate() throws DOMException {
609         throw new UnsupportedOperationException JavaDoc("The Saxon DOM cannot be updated");
610     }
611
612     ////////////////////////////////////////////////////////////////////////////
613
// DOM methods defined on the Document class
614
////////////////////////////////////////////////////////////////////////////
615

616     /**
617      * Get the Document Type Declaration (see <code>DocumentType</code> )
618      * associated with this document. For HTML documents as well as XML
619      * documents without a document type declaration this returns
620      * <code>null</code>. DOM method.
621      * @return null: The Saxon tree model does not include the document type
622      * information.
623      */

624      
625     public DocumentType getDoctype() {
626         return null;
627     }
628
629     /**
630      * Get a <code>DOMImplementation</code> object that handles this document.
631      * A DOM application may use objects from multiple implementations.
632      * DOM method.
633      */

634      
635     public DOMImplementation getImplementation() {
636         return new DOMImplementationImpl();
637     }
638
639     /**
640      * Creates an element of the type specified. DOM method: always fails,
641      * because the Saxon tree is not updateable.
642      */

643
644     public Element createElement(String JavaDoc tagName) throws DOMException {
645         disallowUpdate();
646         return null;
647     }
648
649     /**
650      * Creates an empty <code>DocumentFragment</code> object.
651      * @return A new <code>DocumentFragment</code> .
652      * DOM method: returns null, because the Saxon tree is not updateable.
653      */

654      
655     public DocumentFragment createDocumentFragment() {
656         return null;
657     }
658
659     /**
660      * Create a <code>Text</code> node given the specified string.
661      * DOM method: returns null, because the Saxon tree is not updateable.
662      * @param data The data for the node.
663      * @return The new <code>Text</code> object.
664      */

665      
666     public Text createTextNode(String JavaDoc data) {
667         return null;
668     }
669
670     /**
671      * Create a <code>Comment</code> node given the specified string.
672      * DOM method: returns null, because the Saxon tree is not updateable.
673      * @param data The data for the node.
674      * @return The new <code>Comment</code> object.
675      */

676     public Comment createComment(String JavaDoc data) {
677         return null;
678     }
679
680     /**
681      * Create a <code>CDATASection</code> node whose value is the specified
682      * string.
683      * DOM method: always fails, because the Saxon tree is not updateable.
684      * @param data The data for the <code>CDATASection</code> contents.
685      * @return The new <code>CDATASection</code> object.
686      * @exception DOMException
687      * NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
688      */

689      
690     public CDATASection createCDATASection(String JavaDoc data) throws DOMException {
691         disallowUpdate();
692         return null;
693     }
694
695     /**
696      * Create a <code>ProcessingInstruction</code> node given the specified
697      * name and data strings.
698      * DOM method: returns null, because the Saxon tree is not updateable.
699      * @param target The target part of the processing instruction.
700      * @param data The data for the node.
701      * @return The new <code>ProcessingInstruction</code> object.
702      * @exception DOMException
703      * INVALID_CHARACTER_ERR: Raised if the specified target contains an
704      * illegal character.
705      * <br> NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
706      */

707      
708     public ProcessingInstruction createProcessingInstruction(String JavaDoc target,
709                                                              String JavaDoc data)
710                                                              throws DOMException {
711         disallowUpdate();
712         return null;
713     }
714
715     /**
716      * Create an <code>Attr</code> of the given name.
717      * DOM method: always fails, because the Saxon tree is not updateable.
718      * @param name The name of the attribute.
719      * @return A new <code>Attr</code> object with the <code>nodeName</code>
720      * attribute set to <code>name</code> , and <code>localName</code> ,
721      * <code>prefix</code> , and <code>namespaceURI</code> set to
722      * <code>null</code> .
723      * @exception DOMException
724      * INVALID_CHARACTER_ERR: Raised if the specified name contains an
725      * illegal character.
726      */

727      
728     public Attr createAttribute(String JavaDoc name) throws DOMException {
729         disallowUpdate();
730         return null;
731     }
732
733     /**
734      * Create an <code>EntityReference</code> object.
735      * DOM method: returns null, because the Saxon tree is not updateable.
736      * @param name The name of the entity to reference.
737      * @return The new <code>EntityReference</code> object.
738      * @exception DOMException
739      * INVALID_CHARACTER_ERR: Raised if the specified name contains an
740      * illegal character.
741      * <br> NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
742      */

743      
744     public EntityReference createEntityReference(String JavaDoc name) throws DOMException {
745         disallowUpdate();
746         return null;
747     }
748
749     /**
750      * Return a <code>NodeList</code> of all the <code>Elements</code> with
751      * a given tag name in the order in which they are encountered in a
752      * preorder traversal of the <code>Document</code> tree.
753      * @param tagname The name of the tag to match on. The special value "*"
754      * matches all tags.
755      * @return A new <code>NodeList</code> object containing all the matched
756      * <code>Elements</code> .
757      */

758      
759     public NodeList getElementsByTagName(String JavaDoc tagname) {
760         // The DOM method is defined only on the Document and Element nodes,
761
// but we'll support it on any node.
762

763         AxisEnumeration allElements =
764             getEnumeration(Axis.DESCENDANT, AnyNodeTest.getInstance());
765         NodeSetExtent nodes = new NodeSetExtent(LocalOrderComparer.getInstance());
766         while(allElements.hasMoreElements()) {
767             NodeInfo next = allElements.nextElement();
768             if (next.getNodeType()==ELEMENT) {
769                 if (tagname.equals("*") || tagname.equals(next.getDisplayName())) {
770                     nodes.append(next);
771                 }
772             }
773         }
774         return nodes;
775     }
776         
777
778     /**
779      * Import a node from another document to this document.
780      * DOM method: always fails, because the Saxon tree is not updateable.
781      * @exception DOMException
782      * @since DOM Level 2
783      */

784      
785     public Node importNode(Node importedNode, boolean deep) throws DOMException {
786         disallowUpdate();
787         return null;
788     }
789
790     /**
791      * Create an element of the given qualified name and namespace URI.
792      * HTML-only DOM implementations do not need to implement this method.
793      * DOM method: always fails, because the Saxon tree is not updateable.
794      * @param namespaceURI The namespace URI of the element to create.
795      * @param qualifiedName The qualified name of the element type to
796      * instantiate.
797      * @return A new <code>Element</code> object
798      * @exception DOMException
799      */

800      
801     public Element createElementNS(String JavaDoc namespaceURI,
802                                    String JavaDoc qualifiedName)
803                                    throws DOMException
804     {
805         disallowUpdate();
806         return null;
807     }
808
809     /**
810      * Create an attribute of the given qualified name and namespace URI.
811      * HTML-only DOM implementations do not need to implement this method.
812      * DOM method: returns null, because the Saxon tree is not updateable.
813      * @param namespaceURI The namespace URI of the attribute to create.
814      * @param qualifiedName The qualified name of the attribute to
815      * instantiate.
816      * @return A new <code>Attr</code> object.
817      * @exception DOMException
818      */

819      
820     public Attr createAttributeNS(String JavaDoc namespaceURI,
821                                   String JavaDoc qualifiedName)
822                                   throws DOMException {
823         disallowUpdate();
824         return null;
825     }
826
827     /**
828      * Return a <code>NodeList</code> of all the <code>Elements</code> with
829      * a given local name and namespace URI in the order in which they are
830      * encountered in a preorder traversal of the <code>Document</code> tree.
831      * DOM method.
832      * @param namespaceURI The namespace URI of the elements to match on.
833      * The special value "*" matches all namespaces.
834      * @param localName The local name of the elements to match on. The
835      * special value "*" matches all local names.
836      * @return A new <code>NodeList</code> object containing all the matched
837      * <code>Elements</code> .
838      * @since DOM Level 2
839      */

840      
841     public NodeList getElementsByTagNameNS(String JavaDoc namespaceURI, String JavaDoc localName) {
842         // The DOM method is defined only on the Document and Element nodes,
843
// but we'll support it on any node.
844

845         AxisEnumeration allElements =
846             getEnumeration(Axis.DESCENDANT, AnyNodeTest.getInstance());
847         NodeSetExtent nodes = new NodeSetExtent(LocalOrderComparer.getInstance());
848         while(allElements.hasMoreElements()) {
849             NodeInfo next = allElements.nextElement();
850             if (next.getNodeType()==ELEMENT) {
851                 if ((namespaceURI.equals("*") || namespaceURI.equals(next.getURI())) &&
852                     (localName.equals("*") || localName.equals(next.getLocalName()))) {
853                     nodes.append(next);
854                 }
855             }
856         }
857         return nodes;
858     }
859
860     /**
861      * Return the <code>Element</code> whose <code>ID</code> is given by
862      * <code>elementId</code> . If no such element exists, returns
863      * <code>null</code> . Behavior is not defined if more than one element
864      * has this <code>ID</code> . The DOM implementation must have
865      * information that says which attributes are of type ID. Attributes with
866      * the name "ID" are not of type ID unless so defined. Implementations
867      * that do not know whether attributes are of type ID or not are expected
868      * to return <code>null</code> .
869      * @param elementId The unique <code>id</code> value for an element.
870      * @return The matching element, or null if there is none.
871      * @since DOM Level 2
872      */

873      
874     public Element getElementById(String JavaDoc elementId) {
875         // Defined on Document node; but we support it on any node.
876
return (Element)getDocumentRoot().selectID(elementId);
877     }
878
879     //////////////////////////////////////////////////////////////////
880
// Methods defined on the DOM Element class
881
//////////////////////////////////////////////////////////////////
882

883     /**
884      * The name of the element (DOM interface).
885      */

886      
887     public String JavaDoc getTagName() {
888         return getDisplayName();
889     }
890
891     /**
892      * Retrieves an attribute value by name. Namespace declarations will not
893      * be retrieved. DOM interface.
894      * @param name The QName of the attribute to retrieve.
895      * @return The <code>Attr</code> value as a string, or the empty string if
896      * that attribute does not have a specified or default value.
897      */

898      
899     public String JavaDoc getAttribute(String JavaDoc name) {
900         AxisEnumeration atts = getEnumeration(Axis.ATTRIBUTE, AnyNodeTest.getInstance());
901         while (atts.hasMoreElements()) {
902             NodeInfo att = atts.nextElement();
903             if (att.getDisplayName().equals(name)) {
904                 String JavaDoc val = att.getStringValue();
905                 if (val==null) return "";
906                 return val;
907             }
908         }
909         return "";
910     }
911    
912     /**
913      * Retrieves an attribute node by name.
914      * Namespace declarations will not be retrieved.
915      * <br> To retrieve an attribute node by qualified name and namespace URI,
916      * use the <code>getAttributeNodeNS</code> method.
917      * @param name The name (<code>nodeName</code> ) of the attribute to
918      * retrieve.
919      * @return The <code>Attr</code> node with the specified name (
920      * <code>nodeName</code> ) or <code>null</code> if there is no such
921      * attribute.
922      */

923      
924     public Attr getAttributeNode(String JavaDoc name) {
925         AxisEnumeration atts = getEnumeration(Axis.ATTRIBUTE, AnyNodeTest.getInstance());
926         while (atts.hasMoreElements()) {
927             NodeInfo att = atts.nextElement();
928             if (att.getDisplayName().equals(name)) {
929                 return (Attr)att;
930             }
931         }
932         return null;
933     }
934
935     /**
936      * Adds a new attribute node. Always fails
937      * @exception DOMException
938      * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
939      */

940      
941     public Attr setAttributeNode(Attr newAttr) throws DOMException {
942         disallowUpdate();
943         return null;
944     }
945
946     /**
947      * Removes the specified attribute. Always fails
948      * @exception DOMException
949      * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
950      */

951
952     public void removeAttribute(String JavaDoc oldAttr) throws DOMException {
953         disallowUpdate();
954     }
955
956     /**
957      * Removes the specified attribute node. Always fails
958      * @exception DOMException
959      * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
960      */

961
962     public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
963         disallowUpdate();
964         return null;
965     }
966
967
968     /**
969      * Retrieves an attribute value by local name and namespace URI.
970      * HTML-only DOM implementations do not need to implement this method.
971      * @param namespaceURI The namespace URI of the attribute to retrieve.
972      * @param localName The local name of the attribute to retrieve.
973      * @return The <code>Attr</code> value as a string, or the empty string if
974      * that attribute does not have a specified or default value.
975      * @since DOM Level 2
976      */

977      
978     public String JavaDoc getAttributeNS(String JavaDoc namespaceURI, String JavaDoc localName) {
979         String JavaDoc val = getAttributeValue(namespaceURI, localName);
980         if (val==null) return "";
981         return val;
982     }
983
984     /**
985      * Adds a new attribute. Always fails.
986      * @param namespaceURI The namespace URI of the attribute to create or
987      * alter.
988      * @param qualifiedName The qualified name of the attribute to create or
989      * alter.
990      * @param value The value to set in string form.
991      * @exception DOMException
992      * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
993      */

994      
995     public void setAttributeNS(String JavaDoc namespaceURI,
996                                String JavaDoc qualifiedName,
997                                String JavaDoc value)
998                                throws DOMException {
999         disallowUpdate();
1000    }
1001
1002    /**
1003     * Removes an attribute by local name and namespace URI. Always fails
1004     * @exception DOMException
1005     * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
1006     * @since DOM Level 2
1007     */

1008     
1009    public void removeAttributeNS(String JavaDoc namespaceURI,
1010                                  String JavaDoc localName)
1011                                  throws DOMException{
1012        disallowUpdate();
1013    }
1014    
1015    /**
1016     * Retrieves an <code>Attr</code> node by local name and namespace URI.
1017     * DOM method, so namespace declarations count as attributes.
1018     * @param namespaceURI The namespace URI of the attribute to retrieve.
1019     * @param localName The local name of the attribute to retrieve.
1020     * @return The <code>Attr</code> node with the specified attribute local
1021     * name and namespace URI or <code>null</code> if there is no such
1022     * attribute.
1023     * @since DOM Level 2
1024     */

1025     
1026    public Attr getAttributeNodeNS(String JavaDoc namespaceURI, String JavaDoc localName) {
1027        int fingerprint = getDocumentRoot().getNamePool().getFingerprint(namespaceURI, localName);
1028        if (fingerprint==-1) return null;
1029        NameTest test = new NameTest(ATTRIBUTE, fingerprint);
1030        AxisEnumeration atts = getEnumeration(Axis.ATTRIBUTE, test);
1031        if (atts.hasMoreElements()) return (Attr)atts.nextElement();
1032        return null;
1033    }
1034
1035    /**
1036     * Add a new attribute. Always fails.
1037     * @param newAttr The <code>Attr</code> node to add to the attribute list.
1038     * @return If the <code>newAttr</code> attribute replaces an existing
1039     * attribute with the same local name and namespace URI , the
1040     * replaced <code>Attr</code> node is returned, otherwise
1041     * <code>null</code> is returned.
1042     * @exception DOMException
1043     * <br> NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
1044     * @since DOM Level 2
1045     */

1046     
1047    public Attr setAttributeNodeNS(Attr newAttr)
1048                                   throws DOMException{
1049        disallowUpdate();
1050        return null;
1051    }
1052
1053    /**
1054     * Returns <code>true</code> when an attribute with a given name is
1055     * specified on this element or has a default value, <code>false</code>
1056     * otherwise.
1057     * Namespace declarations will not be retrieved.
1058     * @param name The name of the attribute to look for.
1059     * @return <code>true</code> if an attribute with the given name is
1060     * specified on this element or has a default value, <code>false</code>
1061     * otherwise.
1062     * @since DOM Level 2
1063     */

1064     
1065    public boolean hasAttribute(String JavaDoc name) {
1066        AxisEnumeration atts = getEnumeration(Axis.ATTRIBUTE, AnyNodeTest.getInstance());
1067        while (atts.hasMoreElements()) {
1068            NodeInfo att = atts.nextElement();
1069            if (att.getDisplayName().equals(name)) {
1070                return true;
1071            }
1072        }
1073        return false;
1074    }
1075
1076    /**
1077     * Returns <code>true</code> when an attribute with a given local name
1078     * and namespace URI is specified on this element or has a default value,
1079     * <code>false</code> otherwise.
1080     * Namespace declarations will not be retrieved.
1081     * @param namespaceURI The namespace URI of the attribute to look for.
1082     * @param localName The local name of the attribute to look for.
1083     * @return <code>true</code> if an attribute with the given local name and
1084     * namespace URI is specified or has a default value on this element,
1085     * <code>false</code> otherwise.
1086     * @since DOM Level 2
1087     */

1088     
1089    public boolean hasAttributeNS(String JavaDoc namespaceURI, String JavaDoc localName) {
1090        return (getAttributeValue(namespaceURI, localName) != null);
1091    }
1092    
1093
1094
1095
1096    ///////////////////////////////////////////////////////////////////
1097
// Methods defined on the DOM Text and Comment classes
1098
///////////////////////////////////////////////////////////////////
1099

1100
1101    /**
1102    * Get the character data of a Text or Comment node.
1103    * DOM method.
1104    */

1105     
1106    public String JavaDoc getData() {
1107        return getStringValue();
1108    }
1109
1110    /**
1111    * Set the character data of a Text or Comment node.
1112    * DOM method: always fails, Saxon tree is immutable.
1113    */

1114    
1115    public void setData(String JavaDoc data) throws DOMException {
1116        disallowUpdate();
1117    }
1118
1119    /**
1120    * Get the length of a Text or Comment node.
1121    * DOM method.
1122    */

1123
1124    public int getLength() {
1125        return getStringValue().length();
1126    }
1127
1128    /**
1129     * Extract a range of data from a Text or Comment node. DOM method.
1130     * @param offset Start offset of substring to extract.
1131     * @param count The number of 16-bit units to extract.
1132     * @return The specified substring. If the sum of <code>offset</code> and
1133     * <code>count</code> exceeds the <code>length</code> , then all 16-bit
1134     * units to the end of the data are returned.
1135     * @exception DOMException
1136     * INDEX_SIZE_ERR: Raised if the specified <code>offset</code> is
1137     * negative or greater than the number of 16-bit units in
1138     * <code>data</code> , or if the specified <code>count</code> is
1139     * negative.
1140     */

1141     
1142    public String JavaDoc substringData(int offset, int count) throws DOMException {
1143        try {
1144            return getStringValue().substring(offset, offset+count);
1145        } catch (IndexOutOfBoundsException JavaDoc err2) {
1146            throw new DOMExceptionImpl(DOMException.INDEX_SIZE_ERR,
1147                             "substringData: index out of bounds");
1148        }
1149    }
1150
1151    /**
1152     * Append the string to the end of the character data of the node.
1153     * DOM method: always fails.
1154     * @param arg The <code>DOMString</code> to append.
1155     * @exception DOMException
1156     * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
1157     */

1158     
1159    public void appendData(String JavaDoc arg) throws DOMException {
1160        disallowUpdate();
1161    }
1162
1163    /**
1164     * Insert a string at the specified character offset.
1165     * DOM method: always fails.
1166     * @param offset The character offset at which to insert.
1167     * @param arg The <code>DOMString</code> to insert.
1168     * @exception DOMException
1169     */

1170     
1171    public void insertData(int offset, String JavaDoc arg) throws DOMException {
1172        disallowUpdate();
1173    }
1174
1175    /**
1176     * Remove a range of 16-bit units from the node.
1177     * DOM method: always fails.
1178     * @param offset The offset from which to start removing.
1179     * @param count The number of 16-bit units to delete.
1180     * @exception DOMException
1181     */

1182     
1183    public void deleteData(int offset, int count) throws DOMException {
1184        disallowUpdate();
1185    }
1186
1187    /**
1188     * Replace the characters starting at the specified 16-bit unit offset
1189     * with the specified string. DOM method: always fails.
1190     * @param offset The offset from which to start replacing.
1191     * @param count The number of 16-bit units to replace.
1192     * @param arg The <code>DOMString</code> with which the range must be
1193     * replaced.
1194     * @exception DOMException
1195     * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
1196     */

1197     
1198    public void replaceData(int offset,
1199                            int count,
1200                            String JavaDoc arg) throws DOMException {
1201        disallowUpdate();
1202    }
1203
1204
1205    /**
1206     * Break this node into two nodes at the specified offset,
1207     * keeping both in the tree as siblings. DOM method, always fails.
1208     * @param offset The 16-bit unit offset at which to split, starting from 0.
1209     * @return The new node, of the same type as this node.
1210     * @exception DOMException
1211     */

1212     
1213    public Text splitText(int offset)
1214                          throws DOMException {
1215        disallowUpdate();
1216        return null;
1217    }
1218
1219    /////////////////////////////////////////////////////////////////////////
1220
// Methods to implement the DOM Attr interface
1221
/////////////////////////////////////////////////////////////////////////
1222

1223    /**
1224    * Get the name of an attribute node (the QName) (DOM method)
1225    */

1226
1227    public String JavaDoc getName() {
1228        return getDisplayName();
1229    }
1230
1231    /**
1232    * Return the character value of an attribute node (DOM method)
1233    * @return the attribute value
1234    */

1235
1236    public String JavaDoc getValue() {
1237        return getStringValue();
1238    }
1239
1240    /**
1241     * If this attribute was explicitly given a value in the original
1242     * document, this is <code>true</code> ; otherwise, it is
1243     * <code>false</code>. (DOM method)
1244     * @return Always true in this implementation.
1245     */

1246     
1247    public boolean getSpecified() {
1248        return true;
1249    }
1250
1251    /**
1252    * Set the value of an attribute node. (DOM method).
1253    * Always fails (because tree is readonly)
1254    */

1255
1256    public void setValue(String JavaDoc value) throws DOMException {
1257        disallowUpdate();
1258    }
1259
1260    /**
1261     * The <code>Element</code> node this attribute is attached to or
1262     * <code>null</code> if this attribute is not in use.
1263     * @since DOM Level 2
1264     */

1265     
1266    public Element getOwnerElement() {
1267        if (getNodeType()!=ATTRIBUTE) {
1268            throw new UnsupportedOperationException JavaDoc(
1269                        "This method is defined only on attribute nodes");
1270        }
1271        return (Element)getParent();
1272    }
1273    
1274    /////////////////////////////////////////////////////////////////////////
1275
// Methods to implement the DOMImplementation interface
1276
/////////////////////////////////////////////////////////////////////////
1277

1278    /**
1279    * Inner class implementing the DOMImplementation interface
1280    */

1281
1282    private class DOMImplementationImpl implements DOMImplementation {
1283        
1284     /**
1285     * Test if the DOM implementation implements a specific feature.
1286     * @param feature The name of the feature to test (case-insensitive).
1287     * @param version This is the version number of the feature to test.
1288     * @return <code>true</code> if the feature is implemented in the
1289     * specified version, <code>false</code> otherwise.
1290     */

1291     
1292    public boolean hasFeature(String JavaDoc feature, String JavaDoc version) {
1293        return false;
1294    }
1295                                
1296
1297    /**
1298     * Creates an empty <code>DocumentType</code> node.
1299     * @param qualifiedName The qualified name of the document type to be
1300     * created.
1301     * @param publicId The external subset public identifier.
1302     * @param systemId The external subset system identifier.
1303     * @return A new <code>DocumentType</code> node with
1304     * <code>Node.ownerDocument</code> set to <code>null</code> .
1305     * @exception DOMException
1306     * INVALID_CHARACTER_ERR: Raised if the specified qualified name
1307     * contains an illegal character.
1308     * <br> NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is
1309     * malformed.
1310     * @since DOM Level 2
1311     */

1312     
1313    public DocumentType createDocumentType(String JavaDoc qualifiedName,
1314                                           String JavaDoc publicId,
1315                                           String JavaDoc systemId)
1316                                           throws DOMException
1317    {
1318        disallowUpdate();
1319        return null;
1320    }
1321
1322    /**
1323     * Creates an XML <code>Document</code> object of the specified type with
1324     * its document element.
1325     * @param namespaceURI The namespace URI of the document element to
1326     * create.
1327     * @param qualifiedName The qualified name of the document element to be
1328     * created.
1329     * @param doctype The type of document to be created or <code>null</code>.
1330     * @return A new <code>Document</code> object.
1331     * @exception DOMException
1332     * @since DOM Level 2
1333     */

1334    public Document createDocument(String JavaDoc namespaceURI,
1335                                   String JavaDoc qualifiedName,
1336                                   DocumentType doctype)
1337                                   throws DOMException
1338    {
1339        disallowUpdate();
1340        return null;
1341    }
1342
1343    } // end of inner class DOMImplementationImpl
1344

1345    //////////////////////////////////////////////////////////////////////
1346
// Inner class to implement DOM NamedNodeMap (the set of attributes)
1347
//////////////////////////////////////////////////////////////////////
1348

1349    private class AttributeMap implements NamedNodeMap {
1350
1351    /**
1352    * Get named attribute (DOM NamedNodeMap method)
1353    */

1354
1355    public Node getNamedItem(String JavaDoc name) {
1356        AxisEnumeration atts =
1357            getEnumeration(Axis.ATTRIBUTE, AnyNodeTest.getInstance());
1358        while (atts.hasMoreElements()) {
1359            NodeInfo att = atts.nextElement();
1360            if (name.equals(att.getDisplayName())) {
1361                return (Node)att;
1362            }
1363        }
1364        return null;
1365    }
1366
1367    /**
1368    * Get n'th attribute (DOM NamedNodeMap method).
1369    * Namespace declarations are not retrieved.
1370    */

1371
1372    public Node item(int index) {
1373        if (index<0) {
1374            return null;
1375        }
1376        int length = 0;
1377        AxisEnumeration atts =
1378            getEnumeration(Axis.ATTRIBUTE, AnyNodeTest.getInstance());
1379        while (atts.hasMoreElements()) {
1380            NodeInfo att = atts.nextElement();
1381            if (length==index) {
1382                return (Node)att;
1383            }
1384            length++;
1385        }
1386        return null;
1387    }
1388
1389    /**
1390    * Get number of attributes (DOM NamedNodeMap method).
1391    */

1392
1393    public int getLength() {
1394        int length = 0;
1395        AxisEnumeration atts =
1396            getEnumeration(Axis.ATTRIBUTE, AnyNodeTest.getInstance());
1397        while (atts.hasMoreElements()) {
1398            atts.nextElement();
1399            length++;
1400        }
1401        return length;
1402    }
1403
1404    /**
1405    * Get named attribute (DOM NamedNodeMap method)
1406    */

1407
1408    public Node getNamedItemNS(String JavaDoc uri, String JavaDoc localName) {
1409        if (uri==null) uri="";
1410        AxisEnumeration atts =
1411            getEnumeration(Axis.ATTRIBUTE, AnyNodeTest.getInstance());
1412        while (atts.hasMoreElements()) {
1413            NodeInfo att = atts.nextElement();
1414            if (uri.equals(att.getURI()) && localName.equals(att.getLocalName())) {
1415                return (Node)att;
1416            }
1417        }
1418        return null;
1419    }
1420    
1421    /**
1422    * Set named attribute (DOM NamedNodeMap method: always fails)
1423    */

1424
1425    public Node setNamedItem(Node arg) throws DOMException {
1426        disallowUpdate();
1427        return null;
1428    }
1429
1430    /**
1431    * Remove named attribute (DOM NamedNodeMap method: always fails)
1432    */

1433
1434    public Node removeNamedItem(String JavaDoc name) throws DOMException {
1435        disallowUpdate();
1436        return null;
1437    }
1438    /**
1439    * Set named attribute (DOM NamedNodeMap method: always fails)
1440    */

1441
1442    public Node setNamedItemNS(Node arg) throws DOMException {
1443        disallowUpdate();
1444        return null;
1445    }
1446
1447    /**
1448    * Remove named attribute (DOM NamedNodeMap method: always fails)
1449    */

1450
1451    public Node removeNamedItemNS(String JavaDoc uri, String JavaDoc localName) throws DOMException {
1452        disallowUpdate();
1453        return null;
1454    }
1455    
1456    } // end of inner class NamedAttributeMap
1457

1458}
1459
1460//
1461
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
1462
// you may not use this file except in compliance with the License. You may obtain a copy of the
1463
// License at http://www.mozilla.org/MPL/
1464
//
1465
// Software distributed under the License is distributed on an "AS IS" basis,
1466
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
1467
// See the License for the specific language governing rights and limitations under the License.
1468
//
1469
// The Original Code is: all this file.
1470
//
1471
// The Initial Developer of the Original Code is
1472
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
1473
//
1474
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
1475
//
1476
// Contributor(s): none.
1477
//
1478
Popular Tags