KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nu > xom > Node


1 /* Copyright 2002-2005 Elliotte Rusty Harold
2    
3    This library is free software; you can redistribute it and/or modify
4    it under the terms of version 2.1 of the GNU Lesser General Public
5    License as published by the Free Software Foundation.
6    
7    This library is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10    GNU Lesser General Public License for more details.
11    
12    You should have received a copy of the GNU Lesser General Public
13    License along with this library; if not, write to the
14    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15    Boston, MA 02111-1307 USA
16    
17    You can contact Elliotte Rusty Harold by sending e-mail to
18    elharo@metalab.unc.edu. Please include the word "XOM" in the
19    subject line. The XOM home page is located at http://www.xom.nu/
20 */

21
22 package nu.xom;
23
24 /**
25  *
26  * <p>
27  * The generic superclass for all the contents
28  * of an XML document. There are exactly seven kinds of
29  * nodes in XOM:
30  * </p>
31  *
32  * <ul>
33  * <li><code>Element</code></li>
34  * <li><code>Document</code></li>
35  * <li><code>Text</code></li>
36  * <li><code>Comment</code></li>
37  * <li><code>Attribute</code></li>
38  * <li><code>ProcessingInstruction</code></li>
39  * <li><code>DocType</code></li>
40  * </ul>
41  *
42  * <p>
43  * Every instance of <code>Node</code> is an
44  * instance of one of these seven classes
45  * (including, possibly, one of their subclasses).
46  * </p>
47  *
48  *
49  * @author Elliotte Rusty Harold
50  * @version 1.0
51  *
52  */

53 public abstract class Node {
54     
55     
56     private ParentNode parent = null;
57     
58     /**
59      * <p>
60      * Creates a new <code>Node</code> object.
61      * Can only be invoked by other members of
62      * the <code>nu.xom</code> package.
63      * </p>
64      */

65     Node() {}
66
67      
68     /**
69      * <p>
70      * Returns the XPath 1.0 string-value of this node.
71      * </p>
72      *
73      * @return the XPath 1.0 string-value of this node
74      */

75     public abstract String JavaDoc getValue();
76     
77     
78     /**
79      *
80      * <p>
81      * Returns the document that contains this node,
82      * or null if this node is not currently part of a document.
83      * Each node belongs to no more than one document at a time.
84      * If this node is a <code>Document</code>, then it returns
85      * this node.
86      * </p>
87      *
88      * @return the document this node is a part of
89      */

90     public final Document getDocument() {
91         Node parent = this;
92         while (parent != null && !(parent.isDocument())) {
93             parent = parent.getParent();
94         }
95         return (Document) parent;
96     }
97     
98     
99     /**
100      *
101      * <p>
102      * Returns the base URI of this node as specified by
103      * <a HREF="http://www.w3.org/TR/xmlbase/" target="_top">XML
104      * Base</a>, or the empty string if this is not known. In most
105      * cases, this is the URL against which relative URLs in this node
106      * should be resolved.
107      * </p>
108      *
109      * <p>
110      * The base URI of a non-parent node is the base URI of the
111      * element containing the node. The base URI of a document
112      * node is the URI from which the document was parsed,
113      * or which was set by calling <code>setBaseURI</code> on
114      * on the document.
115      * </p>
116      *
117      * <p>
118      * The base URI of an element is determined as follows:
119      * </p>
120      *
121      * <ul>
122      * <li>
123      * If the element has an <code>xml:base</code> attribute,
124      * then the value of that attribute is
125      * converted from an IRI to a URI, absolutized if possible,
126      * and returned.
127      * </li>
128      * <li>
129      * Otherwise, if any ancestor element of the element loaded
130      * from the same entity has an <code>xml:base</code>
131      * attribute, then the value of that attribute from the
132      * nearest such ancestor is converted from an IRI to a URI,
133      * absolutized if possible, and returned.
134      * <em><code>xml:base</code> attributes from other entities are
135      * not considered.</em>
136      * </li>
137      * <li>
138      * Otherwise, if <code>setBaseURI()</code> has been invoked on
139      * this element, then the URI most recently passed to that method
140      * is absolutized if possible and returned.
141      * </li>
142      * <li>
143      * Otherwise, if the element comes from an externally
144      * parsed entity or the document entity, and the
145      * original base URI has not been changed by invoking
146      * <code>setBaseURI()</code>, then the URI of that entity is
147      * returned.
148      * </li>
149      * <li>
150      * Otherwise, (the element was created by a constructor
151      * rather then being parsed from an existing document), the
152      * base URI of the nearest ancestor that does have a base URI
153      * is returned. If no ancestors have a base URI, then the
154      * empty string is returned.
155      * </li>
156      * </ul>
157      *
158      * <p>
159      * Absolutization takes place as specified by the
160      * <a target="_top" HREF="http://www.w3.org/TR/xmlbase/">XML
161      * Base specification</a>. However, it is not always possible to
162      * absolutize a relative URI, in which case the empty string will
163      * be returned.
164      * </p>
165      *
166      * @return the base URI of this node
167      */

168     public String JavaDoc getBaseURI() {
169         if (parent == null) return "";
170         return parent.getBaseURI();
171     }
172
173
174     /**
175      *
176      * <p>
177      * Returns the node that contains this node,
178      * or null if this node does not have a parent.
179      * </p>
180      *
181      * @return the element or document that most immediately
182      * contains this node
183      */

184     public final ParentNode getParent() {
185         return this.parent;
186     }
187     
188     
189     final void setParent(ParentNode parent) {
190         this.parent = parent;
191     }
192     
193     
194     /**
195      * <p>
196      * Removes this node from its parent so that it can be added
197      * to a different parent node or document. This method does nothing
198      * if the node does not have a parent.
199      * </p>
200      *
201      * @throws XMLException if the parent refuses to detach this node
202      */

203     public void detach() {
204
205         if (parent == null) return;
206         else if (this.isAttribute()) {
207             Element element = (Element) parent;
208             element.removeAttribute((Attribute) this);
209         }
210         else {
211             parent.removeChild(this);
212         }
213
214     }
215
216
217     /**
218      * <p>
219      * Returns the child of this node at the specified position.
220      * </p>
221      *
222      * @param position the index of the child node to return
223      *
224      * @return the position<sup>th</sup> child node of this node
225      *
226      * @throws IndexOutOfBoundsException if this node does not have children
227      */

228     public abstract Node getChild(int position);
229
230     
231     /**
232      * <p>
233      * Returns the number of children of this node.
234      * This is always non-negative (greater than or equal to zero).
235      * </p>
236      *
237      * @return the number of children of this node
238      */

239     public abstract int getChildCount();
240
241     
242     /**
243      * <p>
244      * Returns a deep copy of this node with no parent,
245      * that can be added to the current document or a different one.
246      * </p>
247      *
248      * <p>
249      * Per Bloch, the <code>Cloneable</code>
250      * interface is just a mess and should
251      * be avoided. However, I do not follow his suggestion of a copy
252      * constructor exclusively because it is useful to be able to
253      * copy a node without knowing its more specific type.
254      * Ken Arnold agrees with this. It's more effective for
255      * subclasses that can return an instance of the subclass.
256      * </p>
257      *
258      * @return a copy of this node without a parent
259      */

260     public abstract Node copy();
261
262     
263     /**
264      * <p>
265      * Returns the actual XML form of this node, such as might be
266      * copied and pasted from the original document. However, this
267      * does not preserve semantically insignificant details such as
268      * white space inside tags or the use of empty-element tags vs.
269      * start-tag end-tag pairs.
270      * </p>
271      *
272      * @return an XML representation of this node
273      */

274     public abstract String JavaDoc toXML();
275     
276     
277     /**
278      * <p>
279      * Tests for node identity. That is, two
280      * <code>Node</code> objects are equal
281      * if and only if they are the same object.
282      * </p>
283      *
284      * @param o the object compared for equality to this node
285      *
286      * @return true if <code>o</code> is this node; false otherwise
287      *
288      * @see java.lang.Object#equals(Object)
289      */

290     public final boolean equals(Object JavaDoc o) {
291         return this == o;
292     }
293
294     
295     /**
296      * <p>
297      * Returns a unique identifier for this node.
298      * The value returned is the same as returned by
299      * <code>super.hashCode()</code>
300      * because nodes use identity semantics.
301      * </p>
302      *
303      * @return a probably unique identifier for this node
304      *
305      * @see java.lang.Object#hashCode()
306      */

307     public final int hashCode() {
308         return super.hashCode();
309     }
310
311     
312     // Methods to replace instanceof tests to improve performance
313
boolean isElement() {
314         return false;
315     }
316             
317     boolean isText() {
318         return false;
319     }
320             
321     boolean isComment() {
322         return false;
323     }
324             
325     boolean isProcessingInstruction() {
326         return false;
327     }
328             
329     boolean isAttribute() {
330         return false;
331     }
332             
333     boolean isDocument() {
334         return false;
335     }
336             
337     boolean isDocType() {
338         return false;
339     }
340   
341     
342 }
343
Popular Tags