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: DOMNodeHelper.java,v 1.6 2001/04/10 23:43:44 jstrachan Exp $ 008 */ 009 010package org.dom4j.dom; 011 012import java.util.List; 013 014import org.dom4j.Branch; 015import org.dom4j.CharacterData; 016import org.dom4j.Document; 017import org.dom4j.DocumentType; 018import org.dom4j.Node; 019import org.dom4j.Element; 020import org.dom4j.QName; 021import org.dom4j.Namespace; 022import org.dom4j.Text; 023 024import org.w3c.dom.DOMException; 025import org.w3c.dom.NamedNodeMap; 026import org.w3c.dom.NodeList; 027 028/** <p><code>DOMNodeHelper</code> contains a collection of utility methods 029 * for use across Node implementations.</p> 030 * 031 * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a> 032 * @version $Revision: 1.6 $ 033 */ 034public class DOMNodeHelper { 035 036 public static final NodeList EMPTY_NODE_LIST = new EmptyNodeList(); 037 038 public static class EmptyNodeList implements NodeList { 039 public org.w3c.dom.Node item(int index) { 040 return null; 041 } 042 public int getLength() { 043 return 0; 044 } 045 } 046 047 048 // Node API 049 //------------------------------------------------------------------------- 050 051 public static String getNamespaceURI(Node node) { 052 return null; 053 } 054 055 public static String getPrefix(Node node) { 056 return null; 057 } 058 059 public static String getLocalName(Node node) { 060 return null; 061 } 062 063 public static void setPrefix(Node node, String prefix) throws DOMException { 064 notSupported(); 065 } 066 067 public static String getNodeValue(Node node) throws DOMException { 068 return node.getText(); 069 } 070 071 public static void setNodeValue(Node node, String nodeValue) throws DOMException { 072 node.setText(nodeValue); 073 } 074 075 public static org.w3c.dom.Node getParentNode(Node node) { 076 return asDOMNode( node.getParent() ); 077 } 078 079 public static NodeList getChildNodes(Node node) { 080 return EMPTY_NODE_LIST; 081 } 082 083 public static org.w3c.dom.Node getFirstChild(Node node) { 084 return null; 085 } 086 087 public static org.w3c.dom.Node getLastChild(Node node) { 088 return null; 089 } 090 091 public static org.w3c.dom.Node getPreviousSibling(Node node) { 092 Element parent = node.getParent(); 093 if ( parent != null ) { 094 int index = parent.indexOf( node ); 095 if ( index > 0 ) { 096 Node previous = parent.node(index - 1); 097 return asDOMNode( previous ); 098 } 099 } 100 return null; 101 } 102 103 public static org.w3c.dom.Node getNextSibling(Node node) { 104 Element parent = node.getParent(); 105 if ( parent != null ) { 106 int index = parent.indexOf( node ); 107 if ( index >= 0 ) { 108 if ( ++index < parent.nodeCount() ) { 109 Node next = parent.node(index); 110 return asDOMNode( next ); 111 } 112 } 113 } 114 return null; 115 } 116 117 public static NamedNodeMap getAttributes(Node node) { 118 return null; 119 } 120 121 public static org.w3c.dom.Document getOwnerDocument(Node node) { 122 return asDOMDocument( node.getDocument() ); 123 } 124 125 public static org.w3c.dom.Node insertBefore( 126 Node node, 127 org.w3c.dom.Node newChild, 128 org.w3c.dom.Node refChild 129 ) throws DOMException { 130 throw new DOMException( DOMException.HIERARCHY_REQUEST_ERR, "Children not allowed for this node: " + node ); 131 } 132 133 public static org.w3c.dom.Node replaceChild( 134 Node node, 135 org.w3c.dom.Node newChild, 136 org.w3c.dom.Node oldChild 137 ) throws DOMException { 138 throw new DOMException( DOMException.HIERARCHY_REQUEST_ERR, "Children not allowed for this node: " + node ); 139 } 140 141 public static org.w3c.dom.Node removeChild( 142 Node node, 143 org.w3c.dom.Node oldChild 144 ) throws DOMException { 145 throw new DOMException( DOMException.HIERARCHY_REQUEST_ERR, "Children not allowed for this node: " + node ); 146 } 147 148 public static org.w3c.dom.Node appendChild( 149 Node node, 150 org.w3c.dom.Node newChild 151 ) throws DOMException { 152 throw new DOMException( DOMException.HIERARCHY_REQUEST_ERR, "Children not allowed for this node: " + node ); 153 } 154 155 public static boolean hasChildNodes(Node node) { 156 return false; 157 } 158 159 public static org.w3c.dom.Node cloneNode(Node node, boolean deep) { 160 return asDOMNode( (Node) node.clone() ); 161 } 162 163 public static void normalize(Node node) { 164 notSupported(); 165 } 166 167 public static boolean isSupported(Node node, String feature, String version) { 168 return false; 169 } 170 171 public static boolean hasAttributes(Node node) { 172 return false; 173 } 174 175 176 // CharacterData API 177 //------------------------------------------------------------------------- 178 179 public static String getData(CharacterData charData) throws DOMException { 180 return charData.getText(); 181 } 182 183 public static void setData(CharacterData charData, String data) throws DOMException { 184 charData.setText(data); 185 } 186 187 public static int getLength(CharacterData charData) { 188 String text = charData.getText(); 189 return ( text != null ) ? text.length() : 0; 190 } 191 192 public static String substringData( 193 CharacterData charData, int offset, int count 194 ) throws DOMException { 195 String text = charData.getText(); 196 int length = ( text != null ) ? text.length() : 0; 197 if ( offset < 0 || offset >= length ) { 198 throw new DOMException( 199 DOMException.INDEX_SIZE_ERR, 200 "No text at offset: " + offset 201 ); 202 } 203 return text.substring( offset, offset + count ); 204 } 205 206 public static void appendData( 207 CharacterData charData, String arg 208 ) throws DOMException { 209 if ( charData.isReadOnly() ) { 210 throw new DOMException( 211 DOMException.NO_MODIFICATION_ALLOWED_ERR, 212 "CharacterData node is read only: " + charData 213 ); 214 } 215 else { 216 String text = charData.getText(); 217 if ( text == null ) { 218 charData.setText( text ); 219 } 220 else { 221 charData.setText( text + arg ); 222 } 223 } 224 } 225 226 public static void insertData(CharacterData charData, int offset, String arg) throws DOMException { 227 if ( charData.isReadOnly() ) { 228 throw new DOMException( 229 DOMException.NO_MODIFICATION_ALLOWED_ERR, 230 "CharacterData node is read only: " + charData 231 ); 232 } 233 else { 234 String text = charData.getText(); 235 if ( text == null ) { 236 charData.setText( arg ); 237 } 238 else { 239 int length = text.length(); 240 if ( offset < 0 || offset >= length ) { 241 throw new DOMException( 242 DOMException.INDEX_SIZE_ERR, 243 "No text at offset: " + offset 244 ); 245 } 246 else { 247 StringBuffer buffer = new StringBuffer( text ); 248 buffer.insert( offset, arg ); 249 charData.setText( buffer.toString() ); 250 } 251 } 252 } 253 } 254 255 public static void deleteData(CharacterData charData, int offset, int count) throws DOMException { 256 if ( charData.isReadOnly() ) { 257 throw new DOMException( 258 DOMException.NO_MODIFICATION_ALLOWED_ERR, 259 "CharacterData node is read only: " + charData 260 ); 261 } 262 else { 263 String text = charData.getText(); 264 if ( text != null ) { 265 int length = text.length(); 266 if ( offset < 0 || offset >= length ) { 267 throw new DOMException( 268 DOMException.INDEX_SIZE_ERR, 269 "No text at offset: " + offset 270 ); 271 } 272 else { 273 StringBuffer buffer = new StringBuffer( text ); 274 buffer.delete( offset, offset + count ); 275 charData.setText( buffer.toString() ); 276 } 277 } 278 } 279 } 280 281 public static void replaceData( 282 CharacterData charData, int offset, int count, String arg 283 ) throws DOMException { 284 if ( charData.isReadOnly() ) { 285 throw new DOMException( 286 DOMException.NO_MODIFICATION_ALLOWED_ERR, 287 "CharacterData node is read only: " + charData 288 ); 289 } 290 else { 291 String text = charData.getText(); 292 if ( text != null ) { 293 int length = text.length(); 294 if ( offset < 0 || offset >= length ) { 295 throw new DOMException( 296 DOMException.INDEX_SIZE_ERR, 297 "No text at offset: " + offset 298 ); 299 } 300 else { 301 StringBuffer buffer = new StringBuffer( text ); 302 buffer.replace( offset, offset + count, arg ); 303 charData.setText( buffer.toString() ); 304 } 305 } 306 } 307 } 308 309 310 // Branch API 311 //------------------------------------------------------------------------- 312 313 public static void appendElementsByTagName( 314 List list, Branch parent, String name 315 ) { 316 for ( int i = 0, size = parent.nodeCount(); i < size; i++ ) { 317 Node node = parent.node(i); 318 if ( node instanceof Element ) { 319 Element element = (Element) node; 320 if ( name.equals( element.getName() ) ) { 321 list.add( element ); 322 } 323 appendElementsByTagName(list, element, name); 324 } 325 } 326 } 327 328 public static void appendElementsByTagNameNS( 329 List list, Branch parent, String namespaceURI, String localName 330 ) { 331 for ( int i = 0, size = parent.nodeCount(); i < size; i++ ) { 332 Node node = parent.node(i); 333 if ( node instanceof Element ) { 334 Element element = (Element) node; 335 if ( namespaceURI.equals( element.getNamespaceURI() ) 336 && localName.equals( element.getName() ) ) { 337 list.add( element ); 338 } 339 appendElementsByTagNameNS(list, element, namespaceURI, localName); 340 } 341 } 342 } 343 344 345 // Helper methods 346 //------------------------------------------------------------------------- 347 348 public static NodeList createNodeList( final List list ) { 349 return new NodeList() { 350 public org.w3c.dom.Node item(int index) { 351 return DOMNodeHelper.asDOMNode( (Node) list.get( index ) ); 352 } 353 public int getLength() { 354 return list.size(); 355 } 356 }; 357 } 358 359 public static org.w3c.dom.Node asDOMNode(Node node) { 360 if ( node instanceof org.w3c.dom.Node ) { 361 return (org.w3c.dom.Node) node; 362 } 363 else { 364 // Use DOMWriter? 365 System.out.println( "Cannot convert: " + node + " into a W3C DOM Node"); 366 notSupported(); 367 return null; 368 } 369 } 370 371 public static org.w3c.dom.Document asDOMDocument(Document document) { 372 if ( document instanceof org.w3c.dom.Document ) { 373 return (org.w3c.dom.Document) document; 374 } 375 else { 376 // Use DOMWriter? 377 notSupported(); 378 return null; 379 } 380 } 381 382 public static org.w3c.dom.DocumentType asDOMDocumentType(DocumentType documentType) { 383 if ( documentType instanceof org.w3c.dom.DocumentType ) { 384 return (org.w3c.dom.DocumentType) documentType; 385 } 386 else { 387 // Use DOMWriter? 388 notSupported(); 389 return null; 390 } 391 } 392 393 public static org.w3c.dom.Text asDOMText(CharacterData text) { 394 if ( text instanceof org.w3c.dom.Text ) { 395 return (org.w3c.dom.Text) text; 396 } 397 else { 398 // Use DOMWriter? 399 notSupported(); 400 return null; 401 } 402 } 403 404 public static org.w3c.dom.Element asDOMElement(Node element) { 405 if ( element instanceof org.w3c.dom.Element ) { 406 return (org.w3c.dom.Element) element; 407 } 408 else { 409 // Use DOMWriter? 410 notSupported(); 411 return null; 412 } 413 } 414 415 public static org.w3c.dom.Attr asDOMAttr(Node attribute) { 416 if ( attribute instanceof org.w3c.dom.Attr ) { 417 return (org.w3c.dom.Attr) attribute; 418 } 419 else { 420 // Use DOMWriter? 421 notSupported(); 422 return null; 423 } 424 } 425 426 /** Called when a method has not been implemented yet 427 */ 428 public static void notSupported() { 429 throw new DOMException( DOMException.NOT_SUPPORTED_ERR, "Not supported yet"); 430 } 431 432} 433 434 435 436 437/* 438 * Redistribution and use of this software and associated documentation 439 * ("Software"), with or without modification, are permitted provided 440 * that the following conditions are met: 441 * 442 * 1. Redistributions of source code must retain copyright 443 * statements and notices. Redistributions must also contain a 444 * copy of this document. 445 * 446 * 2. Redistributions in binary form must reproduce the 447 * above copyright notice, this list of conditions and the 448 * following disclaimer in the documentation and/or other 449 * materials provided with the distribution. 450 * 451 * 3. The name "DOM4J" must not be used to endorse or promote 452 * products derived from this Software without prior written 453 * permission of MetaStuff, Ltd. For written permission, 454 * please contact dom4j-info@metastuff.com. 455 * 456 * 4. Products derived from this Software may not be called "DOM4J" 457 * nor may "DOM4J" appear in their names without prior written 458 * permission of MetaStuff, Ltd. DOM4J is a registered 459 * trademark of MetaStuff, Ltd. 460 * 461 * 5. Due credit should be given to the DOM4J Project 462 * (http://dom4j.org/). 463 * 464 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS 465 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 466 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 467 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 468 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 469 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 470 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 471 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 472 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 473 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 474 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 475 * OF THE POSSIBILITY OF SUCH DAMAGE. 476 * 477 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. 478 * 479 * $Id: DOMNodeHelper.java,v 1.6 2001/04/10 23:43:44 jstrachan Exp $ 480 */