View Javadoc

1   /*
2    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3    *
4    * This software is open source.
5    * See the bottom of this file for the licence.
6    */
7   
8   package org.dom4j.tree;
9   
10  import java.io.IOException;
11  import java.io.Serializable;
12  import java.io.Writer;
13  import java.util.List;
14  
15  import org.dom4j.Document;
16  import org.dom4j.DocumentFactory;
17  import org.dom4j.Element;
18  import org.dom4j.Node;
19  import org.dom4j.NodeFilter;
20  import org.dom4j.XPath;
21  import org.dom4j.rule.Pattern;
22  
23  /***
24   * <p>
25   * <code>AbstractNode</code> is an abstract base class for tree implementors
26   * to use for implementation inheritence.
27   * </p>
28   * 
29   * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
30   * @version $Revision: 1.31 $
31   */
32  public abstract class AbstractNode implements Node, Cloneable, Serializable {
33      protected static final String[] NODE_TYPE_NAMES = {"Node", "Element",
34              "Attribute", "Text", "CDATA", "Entity", "Entity",
35              "ProcessingInstruction", "Comment", "Document", "DocumentType",
36              "DocumentFragment", "Notation", "Namespace", "Unknown" };
37  
38      /*** The <code>DocumentFactory</code> instance used by default */
39      private static final DocumentFactory DOCUMENT_FACTORY = DocumentFactory
40              .getInstance();
41  
42      public AbstractNode() {
43      }
44  
45      public short getNodeType() {
46          return UNKNOWN_NODE;
47      }
48  
49      public String getNodeTypeName() {
50          int type = getNodeType();
51  
52          if ((type < 0) || (type >= NODE_TYPE_NAMES.length)) {
53              return "Unknown";
54          }
55  
56          return NODE_TYPE_NAMES[type];
57      }
58  
59      public Document getDocument() {
60          Element element = getParent();
61  
62          return (element != null) ? element.getDocument() : null;
63      }
64  
65      public void setDocument(Document document) {
66      }
67  
68      public Element getParent() {
69          return null;
70      }
71  
72      public void setParent(Element parent) {
73      }
74  
75      public boolean supportsParent() {
76          return false;
77      }
78  
79      public boolean isReadOnly() {
80          return true;
81      }
82  
83      public boolean hasContent() {
84          return false;
85      }
86  
87      public String getPath() {
88          return getPath(null);
89      }
90  
91      public String getUniquePath() {
92          return getUniquePath(null);
93      }
94  
95      public Object clone() {
96          if (isReadOnly()) {
97              return this;
98          } else {
99              try {
100                 Node answer = (Node) super.clone();
101                 answer.setParent(null);
102                 answer.setDocument(null);
103 
104                 return answer;
105             } catch (CloneNotSupportedException e) {
106                 // should never happen
107                 throw new RuntimeException("This should never happen. Caught: "
108                         + e);
109             }
110         }
111     }
112 
113     public Node detach() {
114         Element parent = getParent();
115 
116         if (parent != null) {
117             parent.remove(this);
118         } else {
119             Document document = getDocument();
120 
121             if (document != null) {
122                 document.remove(this);
123             }
124         }
125 
126         setParent(null);
127         setDocument(null);
128 
129         return this;
130     }
131 
132     public String getName() {
133         return null;
134     }
135 
136     public void setName(String name) {
137         throw new UnsupportedOperationException("This node cannot be modified");
138     }
139 
140     public String getText() {
141         return null;
142     }
143 
144     public String getStringValue() {
145         return getText();
146     }
147 
148     public void setText(String text) {
149         throw new UnsupportedOperationException("This node cannot be modified");
150     }
151 
152     public void write(Writer writer) throws IOException {
153         writer.write(asXML());
154     }
155 
156     // XPath methods
157     public Object selectObject(String xpathExpression) {
158         XPath xpath = createXPath(xpathExpression);
159 
160         return xpath.evaluate(this);
161     }
162 
163     public List selectNodes(String xpathExpression) {
164         XPath xpath = createXPath(xpathExpression);
165 
166         return xpath.selectNodes(this);
167     }
168 
169     public List selectNodes(String xpathExpression,
170             String comparisonXPathExpression) {
171         return selectNodes(xpathExpression, comparisonXPathExpression, false);
172     }
173 
174     public List selectNodes(String xpathExpression,
175             String comparisonXPathExpression, boolean removeDuplicates) {
176         XPath xpath = createXPath(xpathExpression);
177         XPath sortBy = createXPath(comparisonXPathExpression);
178 
179         return xpath.selectNodes(this, sortBy, removeDuplicates);
180     }
181 
182     public Node selectSingleNode(String xpathExpression) {
183         XPath xpath = createXPath(xpathExpression);
184 
185         return xpath.selectSingleNode(this);
186     }
187 
188     public String valueOf(String xpathExpression) {
189         XPath xpath = createXPath(xpathExpression);
190 
191         return xpath.valueOf(this);
192     }
193 
194     public Number numberValueOf(String xpathExpression) {
195         XPath xpath = createXPath(xpathExpression);
196 
197         return xpath.numberValueOf(this);
198     }
199 
200     public boolean matches(String patternText) {
201         NodeFilter filter = createXPathFilter(patternText);
202 
203         return filter.matches(this);
204     }
205 
206     public XPath createXPath(String xpathExpression) {
207         return getDocumentFactory().createXPath(xpathExpression);
208     }
209 
210     public NodeFilter createXPathFilter(String patternText) {
211         return getDocumentFactory().createXPathFilter(patternText);
212     }
213 
214     public Pattern createPattern(String patternText) {
215         return getDocumentFactory().createPattern(patternText);
216     }
217 
218     public Node asXPathResult(Element parent) {
219         if (supportsParent()) {
220             return this;
221         }
222 
223         return createXPathResult(parent);
224     }
225 
226     protected DocumentFactory getDocumentFactory() {
227         return DOCUMENT_FACTORY;
228     }
229 
230     protected Node createXPathResult(Element parent) {
231         throw new RuntimeException("asXPathResult() not yet implemented fully "
232                 + "for: " + this);
233     }
234 }
235 
236 /*
237  * Redistribution and use of this software and associated documentation
238  * ("Software"), with or without modification, are permitted provided that the
239  * following conditions are met:
240  * 
241  * 1. Redistributions of source code must retain copyright statements and
242  * notices. Redistributions must also contain a copy of this document.
243  * 
244  * 2. Redistributions in binary form must reproduce the above copyright notice,
245  * this list of conditions and the following disclaimer in the documentation
246  * and/or other materials provided with the distribution.
247  * 
248  * 3. The name "DOM4J" must not be used to endorse or promote products derived
249  * from this Software without prior written permission of MetaStuff, Ltd. For
250  * written permission, please contact dom4j-info@metastuff.com.
251  * 
252  * 4. Products derived from this Software may not be called "DOM4J" nor may
253  * "DOM4J" appear in their names without prior written permission of MetaStuff,
254  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
255  * 
256  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
257  * 
258  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
259  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
260  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
261  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
262  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
263  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
264  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
265  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
266  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
267  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
268  * POSSIBILITY OF SUCH DAMAGE.
269  * 
270  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
271  */