001/*
002 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
003 * 
004 * This software is open source. 
005 * See the bottom of this file for the licence.
006 * 
007 * $Id: Node.java,v 1.23 2001/12/19 09:51:39 jstrachan Exp $
008 */
009
010package org.dom4j;
011
012import java.io.IOException;
013import java.io.Writer;
014
015import java.util.List;
016
017/** <p><code>Node</code> defines the polymorphic behavior 
018  * for all XML nodes in a DOM4J tree.</p>
019  *
020  * <p>A node may optionally support the parent relationship and may be 
021  * read only.</p>
022  *
023  * @see #supportsParent 
024  * @see #isReadOnly
025  *
026  * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
027  * @version $Revision: 1.23 $
028  */
029public interface Node extends Cloneable {
030
031    // W3C DOM complient node type codes
032    
033    /** Matches Element nodes */
034    public static final short ANY_NODE = 0;
035    /** Matches Element nodes */
036    public static final short ELEMENT_NODE = 1;
037    /** Matches elements nodes */
038    public static final short ATTRIBUTE_NODE = 2;
039    /** Matches elements nodes */
040    public static final short TEXT_NODE = 3;
041    /** Matches elements nodes */
042    public static final short CDATA_SECTION_NODE = 4;
043    /** Matches elements nodes */
044    public static final short ENTITY_REFERENCE_NODE = 5;
045    /** Matches elements nodes */
046    //public static final short ENTITY_NODE = 6;
047    /** Matches ProcessingInstruction */
048    public static final short PROCESSING_INSTRUCTION_NODE = 7;
049    /** Matches Comments nodes */
050    public static final short COMMENT_NODE = 8;
051    /** Matches Document nodes */
052    public static final short DOCUMENT_NODE = 9;
053    /** Matches DocumentType nodes */
054    public static final short DOCUMENT_TYPE_NODE = 10;
055    //public static final short DOCUMENT_FRAGMENT_NODE = 11;
056    //public static final short NOTATION_NODE = 12;
057    
058    /** Matchs a Namespace Node - NOTE this differs from DOM */
059    // XXXX: ????
060    public static final short NAMESPACE_NODE = 13;
061    
062    /** Does not match any valid node */
063    public static final short UNKNOWN_NODE = 14;
064    
065    /** The maximum number of node types for sizing purposes */
066    public static final short MAX_NODE_TYPE = 14;
067    
068    
069    /** <p><code>supportsParent</code> returns true if this node supports the 
070      * parent relationship.</p>
071      * 
072      * <p>Some XML tree implementations are singly linked and only support
073      * downward navigation through children relationships. 
074      * The default case is that both parent and children relationships are
075      * supported though for memory and performance reasons the parent
076      * relationship may not be supported.
077      * </p>
078      *
079      * @return true if this node supports the parent relationship
080      * or false it is not supported
081      */
082    public boolean supportsParent();
083
084    /** <p><code>getParent</code> returns the parent <code>Element</code> 
085      * if this node supports the parent relationship or null if it is 
086      * the root element or does not support the parent relationship.</p>
087      *
088      * <p>This method is an optional feature and may not be supported
089      * for all <code>Node</code> implementations.</p>
090      *
091      * @return the parent of this node or null if it is the root of the 
092      * tree or the parent relationship is not supported.
093      */
094    public Element getParent();
095
096    /** <p><code>setParent</code> sets the parent relationship of
097      * this node if the parent relationship is supported or does nothing
098      * if the parent relationship is not supported.</p>
099      *
100      * <p>This method should only be called from inside an 
101      * <code>Element</code> implementation method and is not intended for 
102      * general use.</p>
103      *
104      * @param parent is the new parent of this node.
105      */
106    public void setParent(Element parent);
107    
108
109    /** <p><code>getDocument</code> returns the <code>Document</code>
110      * that this <code>Node</code> is part of if this node supports
111      * the parent relationship.</p>
112      *
113      * <p>This method is an optional feature and may not be supported
114      * for all <code>Node</code> implementations.</p>
115      *
116      * @return the document of this node or null if this feature is not 
117      * supported or the node is not associated with a <code>Document</code>
118      */
119    public Document getDocument();
120
121    /** <p><code>setDocument</code> sets the document of this node if the 
122      * parent relationship is supported or does nothing if the parent 
123      * relationship is not supported.</p>
124      *
125      * <p>This method should only be called from inside a
126      * <code>Document</code> implementation method and is not intended for 
127      * general use.</p>
128      *
129      * @param document is the new document of this node.
130      */
131    public void setDocument(Document document);
132    
133    
134    /** <p><code>isReadOnly</code> returns true if this node is read only
135      * and cannot be modified. 
136      * Any attempt to modify a read-only <code>Node</code> will result in 
137      * an <code>UnsupportedOperationException</code> being thrown.</p>
138      *
139      * @return true if this <code>Node</code> is read only 
140      * and cannot be modified otherwise false.
141      */
142    public boolean isReadOnly();
143
144    /** <p><code>hasContent</code> returns true if this node is a Branch
145      * (either an Element or a Document) and it contains at least one
146      * content node such as a child Element or Text node.</p>
147      *
148      * @return true if this <code>Node</code> is a Branch
149      * with a nodeCount() of one or more.
150      */
151    public boolean hasContent();
152    
153
154    
155    /** <p><code>getName</code> returns the name of this node.
156      * This is the XML local name of the element, attribute, entity or 
157      * processing instruction. 
158      * For CDATA and Text nodes this method will return null.</p>
159      *
160      * @return the XML name of this node
161      */
162    public String getName();    
163
164    
165   /** <p>Sets the text data of this node or this method will 
166     * throw an <code>UnsupportedOperationException</code> if it is 
167     * read-only.</p>
168     *
169     * @param name is the new name of this node
170     */
171    public void setName(String name);
172
173    /** <p>Returns the text of this node.</p>
174      *
175      * @return the text for this node.
176      */
177    public String getText();
178    
179   /** <p>Sets the text data of this node or this method will 
180     * throw an <code>UnsupportedOperationException</code> if it is 
181     * read-only.</p>
182     *
183     * @param text is the new textual value of this node
184     */
185    public void setText(String text);
186    
187    /** Returns the XPath string-value of this node. 
188      * The behaviour of this method is defined in the 
189      * <a href="http://www.w3.org/TR/xpath">XPath specification</a>.
190      *
191      * @return the text from all the child Text and Element nodes appended 
192      * together.
193      */
194    public String getStringValue();    
195    
196    /** <p>Returns the XPath expression which will return a node set
197      * containing the given node such as /a/b/@c. No indexing will
198      * be used to restrict the path if multiple elements with the
199      * same name occur on the path.</p>
200      *
201      * @return the XPath expression which will return a nodeset
202      * containing at least this node.
203      */
204    public String getPath();
205    
206    /** <p>Returns the relative XPath expression which will return a node set
207      * containing the given node such as a/b/@c. No indexing will
208      * be used to restrict the path if multiple elements with the
209      * same name occur on the path.
210      *
211      * @param context is the parent context from which the relative path should 
212      * start. If the context is null or the context is not an ancestor of
213      * this node then the path will be absolute and start from the document and so 
214      * begin with the '/' character.
215      *
216      * @return the XPath expression relative to the given context 
217      * which will return a nodeset containing at least this node.
218      */
219    public String getPath(Element context);
220    
221    /** <p>Returns the XPath expression which will return a nodeset
222      * of one node which is the current node. This method will use
223      * the XPath index operator to restrict the path if
224      * multiple elements with the same name occur on the path.</p>
225      *
226      * @return the XPath expression which will return a nodeset
227      * containing just this node.
228      */
229    public String getUniquePath();
230    
231    /** <p>Returns the relative unique XPath expression from the given context
232      * which will return a nodeset
233      * of one node which is the current node. 
234      * This method will use the XPath index operator to restrict the 
235      * path if multiple elements with the same name occur on the path.
236      * </p>
237      *
238      * @param context is the parent context from which the path should 
239      * start. If the context is null or the context is not an ancestor of
240      * this node then the path will start from the document and so 
241      * begin with the '/' character.
242      *
243      * @return the XPath expression relative to the given context 
244      * which will return a nodeset containing just this node.
245      */
246    public String getUniquePath(Element context);
247    
248    
249    /** <p><code>asXML</code> returns the textual XML representation of this 
250      * node.</p>
251      *
252      * @return the XML representation of this node
253      */
254    public String asXML();    
255
256    /** <p><code>write</code> writes this node as the default XML 
257      * notation for this node. If you wish to control the XML output
258      * (such as for pretty printing, changing the indentation policy etc.) 
259      * then please use {@link org.dom4j.io.XMLWriter} or its derivations.
260      *
261      * @param writer is the <code>Writer</code> to output the XML to
262      */
263    public void write(Writer writer) throws IOException;
264
265    
266    /** Returns the code according to the type of node. 
267      * This makes processing nodes polymorphically much easier as the
268      * switch statement can be used instead of multiple if (instanceof) 
269      * statements.
270      *
271      * @return a W3C DOM complient code for the node type such as 
272      * ELEMENT_NODE or ATTRIBUTE_NODE
273      */
274    public short getNodeType();
275
276    /** @return the name of the type of node such as "Document", "Element", "Attribute" or "Text"
277     */
278    public String getNodeTypeName();
279    
280    
281    /** <p>Removes this node from its parent if there is one. 
282      * If this node is the root element of a document then it is removed
283      * from the document as well.</p>
284      *
285      * <p>This method is useful if you want to remove
286      * a node from its source document and add it to another document.
287      * For example</p>
288      *
289      * <code>
290      *     Node node = ...;
291      *     Element someOtherElement = ...;
292      *     someOtherElement.add( node.detach() );
293      * </code>
294      *
295      * @return the node that has been removed from its parent node if 
296      * any and its document if any.
297      */
298    public Node detach();
299    
300    
301    
302    /** <p><code>selectNodes</code> evaluates an XPath expression and returns 
303      * the result as a <code>List</code> of <code>Node</code> instances or 
304      * <code>String</code> instances depending on the XPath expression.</p>
305      *
306      * @param xpathExpression is the XPath expression to be evaluated
307      * @return the list of <code>Node</code> or <code>String</code> instances 
308      * depending on the XPath expression
309      */
310    public List selectNodes(String xpathExpression);
311    
312    /** <p><code>selectObject</code> evaluates an XPath expression and returns 
313      * the result as an {@link Object}. The object returned can
314      * either be a {@link List} of one or more {@link Node} instances
315      * or a scalar object like a {@link String} or a {@link Number} 
316      * instance depending on the XPath expression. 
317      *
318      * @param xpathExpression is the XPath expression to be evaluated
319      * @return the value of the XPath expression as a
320      * {@link List} of {@link Node} instances, a {@link String} or 
321      * a {@link Number} instance depending on the XPath expression. 
322      */
323    public Object selectObject(String xpathExpression);
324    
325    /** <p><code>selectNodes</code> evaluates an XPath expression then
326      * sorts the results using a secondary XPath expression
327      * Returns a sorted <code>List</code> of <code>Node</code> instances.</p>
328      *
329      * @param xpathExpression is the XPath expression to be evaluated
330      * @param comparisonXPathExpression is the XPath expression used
331      *     to compare the results by for sorting
332      * @return the list of <code>Node</code> instances 
333      * sorted by the comparisonXPathExpression
334      */
335    public List selectNodes( 
336        String xpathExpression, 
337        String comparisonXPathExpression 
338    );
339    
340    /** <p><code>selectNodes</code> evaluates an XPath expression then
341      * sorts the results using a secondary XPath expression
342      * Returns a sorted <code>List</code> of <code>Node</code> instances.</p>
343      *
344      * @param xpathExpression is the XPath expression to be evaluated
345      * @param comparisonXPathExpression is the XPath expression used
346      *     to compare the results by for sorting
347      * @param removeDuplicates if this parameter is true then duplicate 
348      *     values (using the comparisonXPathExpression) are removed from
349      *     the result List.
350      * @return the list of <code>Node</code> instances 
351      * sorted by the comparisonXPathExpression
352      */
353    public List selectNodes(
354        String xpathExpression, 
355        String comparisonXPathExpression, 
356        boolean removeDuplicates
357    );
358    
359    /** <p><code>selectSingleNode</code> evaluates an XPath expression
360      * and returns the result as a single <code>Node</code> instance.</p>
361      *
362      * @param xpathExpression is the XPath expression to be evaluated
363      * @return the <code>Node</code> matching the XPath expression
364      */
365    public Node selectSingleNode(String xpathExpression);
366
367    /** <p><code>valueOf</code> evaluates an XPath expression
368      * and returns the textual representation of the results the XPath 
369      * string-value of this node. 
370      * The string-value for a given node type is defined in the 
371      * <a href="http://www.w3.org/TR/xpath">XPath specification</a>.
372      *
373      * @param xpathExpression is the XPath expression to be evaluated
374      * @return the string-value representation of the results of the XPath 
375      * expression
376      */
377    public String valueOf(String xpathExpression);
378
379    /** <p><code>numberValueOf</code> evaluates an XPath expression
380      * and returns the numeric value of the XPath expression if the XPath
381      * expression results in a number, or null if the result is not a number.
382      *
383      * @param xpathExpression is the XPath expression to be evaluated
384      * @return the numeric result of the XPath expression or null
385      * if the result is not a number.
386      */
387    public Number numberValueOf(String xpathExpression);
388
389        
390    /** <p><code>matches</code> returns true if evaluating the given
391      * XPath expression on this node returns true or a non-empty node set.
392      * So calling this method is equivalent to calling 
393      * <code>&lt;xsl:if test="xpathExpression"/&gt;</code>
394      * in XSLT.</p>
395      *
396      * @param xpathExpression is an XPath expression
397      * @return true if the given node matches this XSLT Pattern
398      */
399    public boolean matches(String xpathExpression);
400
401    /** <p><code>createXPath</code> creates an XPath object for
402      * the given xpathExpression.
403      * The XPath object allows the variable context to be specified.</p>
404      *
405      * @param xpathExpression is the XPath expression to be evaluated
406      * @return an XPath object represeting the given expression
407      * @throws InvalidXPathException if the XPath expression is invalid
408      */
409    public XPath createXPath(String xpathExpression) throws InvalidXPathException;
410
411    /** <p><code>asXPathResult</code> returns a version of this node which is
412      * capable of being an XPath result. 
413      * The result of an XPath expression should always support the parent 
414      * relationship, whether the original XML tree was singly or doubly linked.
415      * If the node does not support the parent relationship then a new node
416      * will be created which is linked to its parent and returned.
417      *
418      * @return a <code>Node</code> which supports the parent relationship
419      */
420    public Node asXPathResult(Element parent);
421
422    
423    /** <p><code>accept</code> is the method used in the Visitor Pattern.</p>
424      *
425      * @param visitor is the visitor in the Visitor Pattern
426      */
427    public void accept(Visitor visitor);
428
429    
430    
431    /** <p><code>clone</code> will return a deep clone or if this node is
432      * read-only then clone will return the same instance.
433      *
434      * @@return a deep clone of myself or myself if I am read only.
435      */
436    public Object clone();
437}
438
439
440
441
442/*
443 * Redistribution and use of this software and associated documentation
444 * ("Software"), with or without modification, are permitted provided
445 * that the following conditions are met:
446 *
447 * 1. Redistributions of source code must retain copyright
448 *    statements and notices.  Redistributions must also contain a
449 *    copy of this document.
450 *
451 * 2. Redistributions in binary form must reproduce the
452 *    above copyright notice, this list of conditions and the
453 *    following disclaimer in the documentation and/or other
454 *    materials provided with the distribution.
455 *
456 * 3. The name "DOM4J" must not be used to endorse or promote
457 *    products derived from this Software without prior written
458 *    permission of MetaStuff, Ltd.  For written permission,
459 *    please contact dom4j-info@metastuff.com.
460 *
461 * 4. Products derived from this Software may not be called "DOM4J"
462 *    nor may "DOM4J" appear in their names without prior written
463 *    permission of MetaStuff, Ltd. DOM4J is a registered
464 *    trademark of MetaStuff, Ltd.
465 *
466 * 5. Due credit should be given to the DOM4J Project
467 *    (http://dom4j.org/).
468 *
469 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
470 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
471 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
472 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
473 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
474 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
475 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
476 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
477 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
478 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
479 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
480 * OF THE POSSIBILITY OF SUCH DAMAGE.
481 *
482 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
483 *
484 * $Id: Node.java,v 1.23 2001/12/19 09:51:39 jstrachan Exp $
485 */