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: AbstractNode.java,v 1.23 2001/09/15 14:55:14 jstrachan Exp $ 008 */ 009 010package org.dom4j.tree; 011 012import java.io.IOException; 013import java.io.Serializable; 014import java.io.StringWriter; 015import java.io.Writer; 016import java.util.List; 017 018import org.dom4j.Document; 019import org.dom4j.DocumentFactory; 020import org.dom4j.Element; 021import org.dom4j.Node; 022import org.dom4j.NodeFilter; 023import org.dom4j.Visitor; 024import org.dom4j.XPath; 025import org.dom4j.rule.Pattern; 026 027/** <p><code>AbstractNode</code> is an abstract base class for 028 * tree implementors to use for implementation inheritence.</p> 029 * 030 * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a> 031 * @version $Revision: 1.23 $ 032 */ 033public abstract class AbstractNode implements Node, Cloneable, Serializable { 034 035 protected static final String[] NODE_TYPE_NAMES ={ 036 "Node", "Element", "Attribute", "Text", "CDATA", "Entity", "Entity", "ProcessingInstruction", 037 "Comment", "Document", "DocumentType", "DocumentFragment", "Notation", "Namespace","Unknown" 038 }; 039 040 /** The <code>DocumentFactory</code> instance used by default */ 041 private static final DocumentFactory DOCUMENT_FACTORY = DocumentFactory.getInstance(); 042 043 044 public AbstractNode() { 045 } 046 047 public short getNodeType() { 048 return UNKNOWN_NODE; 049 } 050 051 public String getNodeTypeName() { 052 int type = getNodeType(); 053 if ( type < 0 || type >= NODE_TYPE_NAMES.length ) { 054 return "Unknown"; 055 } 056 return NODE_TYPE_NAMES[type]; 057 } 058 059 public Document getDocument() { 060 Element element = getParent(); 061 return ( element != null ) ? element.getDocument() : null; 062 } 063 064 public void setDocument(Document document) { 065 } 066 067 public Element getParent() { 068 return null; 069 } 070 071 public void setParent(Element parent) { 072 } 073 074 public boolean supportsParent() { 075 return false; 076 } 077 078 public boolean isReadOnly() { 079 return true; 080 } 081 082 public boolean hasContent() { 083 return false; 084 } 085 086 public String getPath() { 087 return getPath(null); 088 } 089 090 public String getUniquePath() { 091 return getUniquePath(null); 092 } 093 094 095 public Object clone() { 096 if ( isReadOnly() ) { 097 return this; 098 } 099 else { 100 try { 101 Node answer = (Node) super.clone(); 102 answer.setParent( null ); 103 answer.setDocument( null ); 104 return answer; 105 } 106 catch (CloneNotSupportedException e) { 107 // should never happen 108 throw new RuntimeException( "This should never happen. Caught: " + e ); 109 } 110 } 111 } 112 113 public Node detach() { 114 Element parent = getParent(); 115 if ( parent != null ) { 116 parent.remove( this ); 117 } 118 else { 119 Document document = getDocument(); 120 if ( document != null ) { 121 document.remove( this ); 122 } 123 } 124 setParent(null); 125 setDocument(null); 126 return this; 127 } 128 129 public String getName() { 130 return null; 131 } 132 133 public void setName(String name) { 134 throw new UnsupportedOperationException( "This node cannot be modified" ); 135 } 136 137 public String getText() { 138 return null; 139 } 140 141 public String getStringValue() { 142 return getText(); 143 } 144 145 public void setText(String text) { 146 throw new UnsupportedOperationException( "This node cannot be modified" ); 147 } 148 149 150 public void write(Writer writer) throws IOException { 151 writer.write( asXML() ); 152 } 153 154 155 // XPath methods 156 157 public Object selectObject(String xpathExpression) { 158 XPath xpath = createXPath(xpathExpression); 159 return xpath.selectObject(this); 160 } 161 162 public List selectNodes(String xpathExpression) { 163 XPath xpath = createXPath(xpathExpression); 164 return xpath.selectNodes(this); 165 } 166 167 public List selectNodes( 168 String xpathExpression, 169 String comparisonXPathExpression 170 ) { 171 return selectNodes( 172 xpathExpression, comparisonXPathExpression, false 173 ); 174 } 175 176 public List selectNodes( 177 String xpathExpression, 178 String comparisonXPathExpression, 179 boolean removeDuplicates 180 ) { 181 XPath xpath = createXPath(xpathExpression); 182 XPath sortBy = createXPath(comparisonXPathExpression); 183 return xpath.selectNodes(this, sortBy, removeDuplicates); 184 } 185 186 public Node selectSingleNode(String xpathExpression) { 187 XPath xpath = createXPath(xpathExpression); 188 return xpath.selectSingleNode(this); 189 } 190 191 public String valueOf(String xpathExpression) { 192 XPath xpath = createXPath(xpathExpression); 193 return xpath.valueOf(this); 194 } 195 196 public Number numberValueOf(String xpathExpression) { 197 XPath xpath = createXPath(xpathExpression); 198 return xpath.numberValueOf(this); 199 } 200 201 public boolean matches(String patternText) { 202 NodeFilter filter = createXPathFilter(patternText); 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 219 public Node asXPathResult(Element parent) { 220 if (supportsParent()) { 221 return this; 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 for: " + this ); 232 } 233 234} 235 236 237 238 239/* 240 * Redistribution and use of this software and associated documentation 241 * ("Software"), with or without modification, are permitted provided 242 * that the following conditions are met: 243 * 244 * 1. Redistributions of source code must retain copyright 245 * statements and notices. Redistributions must also contain a 246 * copy of this document. 247 * 248 * 2. Redistributions in binary form must reproduce the 249 * above copyright notice, this list of conditions and the 250 * following disclaimer in the documentation and/or other 251 * materials provided with the distribution. 252 * 253 * 3. The name "DOM4J" must not be used to endorse or promote 254 * products derived from this Software without prior written 255 * permission of MetaStuff, Ltd. For written permission, 256 * please contact dom4j-info@metastuff.com. 257 * 258 * 4. Products derived from this Software may not be called "DOM4J" 259 * nor may "DOM4J" appear in their names without prior written 260 * permission of MetaStuff, Ltd. DOM4J is a registered 261 * trademark of MetaStuff, Ltd. 262 * 263 * 5. Due credit should be given to the DOM4J Project 264 * (http://dom4j.org/). 265 * 266 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS 267 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 268 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 269 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 270 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 271 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 272 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 273 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 274 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 275 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 276 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 277 * OF THE POSSIBILITY OF SUCH DAMAGE. 278 * 279 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. 280 * 281 * $Id: AbstractNode.java,v 1.23 2001/09/15 14:55:14 jstrachan Exp $ 282 */