1   
2   
3   
4   
5   
6   
7   
8   package org.dom4j.dom;
9   
10  import java.util.List;
11  
12  import org.dom4j.Branch;
13  import org.dom4j.CharacterData;
14  import org.dom4j.Document;
15  import org.dom4j.DocumentType;
16  import org.dom4j.Element;
17  import org.dom4j.Node;
18  
19  import org.w3c.dom.DOMException;
20  import org.w3c.dom.NamedNodeMap;
21  import org.w3c.dom.NodeList;
22  
23  /***
24   * <p>
25   * <code>DOMNodeHelper</code> contains a collection of utility methods for use
26   * across Node implementations.
27   * </p>
28   * 
29   * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
30   * @version $Revision: 1.20 $
31   */
32  public class DOMNodeHelper {
33      public static final NodeList EMPTY_NODE_LIST = new EmptyNodeList();
34  
35      protected DOMNodeHelper() {
36      }
37  
38      
39      
40      public static boolean supports(Node node, String feature, String version) {
41          return false;
42      }
43  
44      public static String getNamespaceURI(Node node) {
45          return null;
46      }
47  
48      public static String getPrefix(Node node) {
49          return null;
50      }
51  
52      public static String getLocalName(Node node) {
53          return null;
54      }
55  
56      public static void setPrefix(Node node, String prefix) throws DOMException {
57          notSupported();
58      }
59  
60      public static String getNodeValue(Node node) throws DOMException {
61          return node.getText();
62      }
63  
64      public static void setNodeValue(Node node, String nodeValue)
65              throws DOMException {
66          node.setText(nodeValue);
67      }
68  
69      public static org.w3c.dom.Node getParentNode(Node node) {
70          return asDOMNode(node.getParent());
71      }
72  
73      public static NodeList getChildNodes(Node node) {
74          return EMPTY_NODE_LIST;
75      }
76  
77      public static org.w3c.dom.Node getFirstChild(Node node) {
78          return null;
79      }
80  
81      public static org.w3c.dom.Node getLastChild(Node node) {
82          return null;
83      }
84  
85      public static org.w3c.dom.Node getPreviousSibling(Node node) {
86          Element parent = node.getParent();
87  
88          if (parent != null) {
89              int index = parent.indexOf(node);
90  
91              if (index > 0) {
92                  Node previous = parent.node(index - 1);
93  
94                  return asDOMNode(previous);
95              }
96          }
97  
98          return null;
99      }
100 
101     public static org.w3c.dom.Node getNextSibling(Node node) {
102         Element parent = node.getParent();
103 
104         if (parent != null) {
105             int index = parent.indexOf(node);
106 
107             if (index >= 0) {
108                 if (++index < parent.nodeCount()) {
109                     Node next = parent.node(index);
110 
111                     return asDOMNode(next);
112                 }
113             }
114         }
115 
116         return null;
117     }
118 
119     public static NamedNodeMap getAttributes(Node node) {
120         return null;
121     }
122 
123     public static org.w3c.dom.Document getOwnerDocument(Node node) {
124         return asDOMDocument(node.getDocument());
125     }
126 
127     public static org.w3c.dom.Node insertBefore(Node node,
128             org.w3c.dom.Node newChild, org.w3c.dom.Node refChild)
129             throws DOMException {
130         if (node instanceof Branch) {
131             Branch branch = (Branch) node;
132             List list = branch.content();
133             int index = list.indexOf(refChild);
134 
135             if (index < 0) {
136                 branch.add((Node) newChild);
137             } else {
138                 list.add(index, newChild);
139             }
140 
141             return newChild;
142         } else {
143             throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
144                     "Children not allowed for this node: " + node);
145         }
146     }
147 
148     public static org.w3c.dom.Node replaceChild(Node node,
149             org.w3c.dom.Node newChild, org.w3c.dom.Node oldChild)
150             throws DOMException {
151         if (node instanceof Branch) {
152             Branch branch = (Branch) node;
153             List list = branch.content();
154             int index = list.indexOf(oldChild);
155 
156             if (index < 0) {
157                 throw new DOMException(DOMException.NOT_FOUND_ERR,
158                         "Tried to replace a non existing child " + "for node: "
159                                 + node);
160             }
161 
162             list.set(index, newChild);
163 
164             return oldChild;
165         } else {
166             throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
167                     "Children not allowed for this node: " + node);
168         }
169     }
170 
171     public static org.w3c.dom.Node removeChild(Node node,
172             org.w3c.dom.Node oldChild) throws DOMException {
173         if (node instanceof Branch) {
174             Branch branch = (Branch) node;
175             branch.remove((Node) oldChild);
176 
177             return oldChild;
178         }
179 
180         throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
181                 "Children not allowed for this node: " + node);
182     }
183 
184     public static org.w3c.dom.Node appendChild(Node node,
185             org.w3c.dom.Node newChild) throws DOMException {
186         if (node instanceof Branch) {
187             Branch branch = (Branch) node;
188             org.w3c.dom.Node previousParent = newChild.getParentNode();
189 
190             if (previousParent != null) {
191                 previousParent.removeChild(newChild);
192             }
193 
194             branch.add((Node) newChild);
195 
196             return newChild;
197         }
198 
199         throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
200                 "Children not allowed for this node: " + node);
201     }
202 
203     public static boolean hasChildNodes(Node node) {
204         return false;
205     }
206 
207     public static org.w3c.dom.Node cloneNode(Node node, boolean deep) {
208         return asDOMNode((Node) node.clone());
209     }
210 
211     public static void normalize(Node node) {
212         notSupported();
213     }
214 
215     public static boolean isSupported(Node n, String feature, String version) {
216         return false;
217     }
218 
219     public static boolean hasAttributes(Node node) {
220         if ((node != null) && node instanceof Element) {
221             return ((Element) node).attributeCount() > 0;
222         } else {
223             return false;
224         }
225     }
226 
227     
228     
229     public static String getData(CharacterData charData) throws DOMException {
230         return charData.getText();
231     }
232 
233     public static void setData(CharacterData charData, String data)
234             throws DOMException {
235         charData.setText(data);
236     }
237 
238     public static int getLength(CharacterData charData) {
239         String text = charData.getText();
240 
241         return (text != null) ? text.length() : 0;
242     }
243 
244     public static String substringData(CharacterData charData, int offset,
245             int count) throws DOMException {
246         if (count < 0) {
247             throw new DOMException(DOMException.INDEX_SIZE_ERR,
248                     "Illegal value for count: " + count);
249         }
250 
251         String text = charData.getText();
252         int length = (text != null) ? text.length() : 0;
253 
254         if ((offset < 0) || (offset >= length)) {
255             throw new DOMException(DOMException.INDEX_SIZE_ERR,
256                     "No text at offset: " + offset);
257         }
258 
259         if ((offset + count) > length) {
260             return text.substring(offset);
261         }
262 
263         return text.substring(offset, offset + count);
264     }
265 
266     public static void appendData(CharacterData charData, String arg)
267             throws DOMException {
268         if (charData.isReadOnly()) {
269             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
270                     "CharacterData node is read only: " + charData);
271         } else {
272             String text = charData.getText();
273 
274             if (text == null) {
275                 charData.setText(text);
276             } else {
277                 charData.setText(text + arg);
278             }
279         }
280     }
281 
282     public static void insertData(CharacterData data, int offset, String arg)
283             throws DOMException {
284         if (data.isReadOnly()) {
285             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
286                     "CharacterData node is read only: " + data);
287         } else {
288             String text = data.getText();
289 
290             if (text == null) {
291                 data.setText(arg);
292             } else {
293                 int length = text.length();
294 
295                 if ((offset < 0) || (offset > length)) {
296                     throw new DOMException(DOMException.INDEX_SIZE_ERR,
297                             "No text at offset: " + offset);
298                 } else {
299                     StringBuffer buffer = new StringBuffer(text);
300                     buffer.insert(offset, arg);
301                     data.setText(buffer.toString());
302                 }
303             }
304         }
305     }
306 
307     public static void deleteData(CharacterData charData, int offset, int count)
308             throws DOMException {
309         if (charData.isReadOnly()) {
310             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
311                     "CharacterData node is read only: " + charData);
312         } else {
313             if (count < 0) {
314                 throw new DOMException(DOMException.INDEX_SIZE_ERR,
315                         "Illegal value for count: " + count);
316             }
317 
318             String text = charData.getText();
319 
320             if (text != null) {
321                 int length = text.length();
322 
323                 if ((offset < 0) || (offset >= length)) {
324                     throw new DOMException(DOMException.INDEX_SIZE_ERR,
325                             "No text at offset: " + offset);
326                 } else {
327                     StringBuffer buffer = new StringBuffer(text);
328                     buffer.delete(offset, offset + count);
329                     charData.setText(buffer.toString());
330                 }
331             }
332         }
333     }
334 
335     public static void replaceData(CharacterData charData, int offset,
336             int count, String arg) throws DOMException {
337         if (charData.isReadOnly()) {
338             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
339                     "CharacterData node is read only: " + charData);
340         } else {
341             if (count < 0) {
342                 throw new DOMException(DOMException.INDEX_SIZE_ERR,
343                         "Illegal value for count: " + count);
344             }
345 
346             String text = charData.getText();
347 
348             if (text != null) {
349                 int length = text.length();
350 
351                 if ((offset < 0) || (offset >= length)) {
352                     throw new DOMException(DOMException.INDEX_SIZE_ERR,
353                             "No text at offset: " + offset);
354                 } else {
355                     StringBuffer buffer = new StringBuffer(text);
356                     buffer.replace(offset, offset + count, arg);
357                     charData.setText(buffer.toString());
358                 }
359             }
360         }
361     }
362 
363     
364     
365     public static void appendElementsByTagName(List list, Branch parent,
366             String name) {
367         final boolean isStar = "*".equals(name);
368 
369         for (int i = 0, size = parent.nodeCount(); i < size; i++) {
370             Node node = parent.node(i);
371 
372             if (node instanceof Element) {
373                 Element element = (Element) node;
374 
375                 if (isStar || name.equals(element.getName())) {
376                     list.add(element);
377                 }
378 
379                 appendElementsByTagName(list, element, name);
380             }
381         }
382     }
383 
384     public static void appendElementsByTagNameNS(List list, Branch parent,
385             String namespace, String localName) {
386         final boolean isStarNS = "*".equals(namespace);
387         final boolean isStar = "*".equals(localName);
388 
389         for (int i = 0, size = parent.nodeCount(); i < size; i++) {
390             Node node = parent.node(i);
391 
392             if (node instanceof Element) {
393                 Element element = (Element) node;
394 
395                 if ((isStarNS
396                         || (((namespace == null) 
397                                 || (namespace.length() == 0)) && ((element
398                                 .getNamespaceURI() == null) || (element
399                                 .getNamespaceURI().length() == 0))) 
400                                 || ((namespace != null) && namespace
401                         .equals(element.getNamespaceURI())))
402                         && (isStar || localName.equals(element.getName()))) {
403                     list.add(element);
404                 }
405 
406                 appendElementsByTagNameNS(list, element, namespace, localName);
407             }
408         }
409     }
410 
411     
412     
413     public static NodeList createNodeList(final List list) {
414         return new NodeList() {
415             public org.w3c.dom.Node item(int index) {
416                 if (index >= getLength()) {
417                     
418 
419 
420 
421 
422                     return null;
423                 } else {
424                     return DOMNodeHelper.asDOMNode((Node) list.get(index));
425                 }
426             }
427 
428             public int getLength() {
429                 return list.size();
430             }
431         };
432     }
433 
434     public static org.w3c.dom.Node asDOMNode(Node node) {
435         if (node == null) {
436             return null;
437         }
438 
439         if (node instanceof org.w3c.dom.Node) {
440             return (org.w3c.dom.Node) node;
441         } else {
442             
443             System.out.println("Cannot convert: " + node
444                     + " into a W3C DOM Node");
445             notSupported();
446 
447             return null;
448         }
449     }
450 
451     public static org.w3c.dom.Document asDOMDocument(Document document) {
452         if (document == null) {
453             return null;
454         }
455 
456         if (document instanceof org.w3c.dom.Document) {
457             return (org.w3c.dom.Document) document;
458         } else {
459             
460             notSupported();
461 
462             return null;
463         }
464     }
465 
466     public static org.w3c.dom.DocumentType asDOMDocumentType(DocumentType dt) {
467         if (dt == null) {
468             return null;
469         }
470 
471         if (dt instanceof org.w3c.dom.DocumentType) {
472             return (org.w3c.dom.DocumentType) dt;
473         } else {
474             
475             notSupported();
476 
477             return null;
478         }
479     }
480 
481     public static org.w3c.dom.Text asDOMText(CharacterData text) {
482         if (text == null) {
483             return null;
484         }
485 
486         if (text instanceof org.w3c.dom.Text) {
487             return (org.w3c.dom.Text) text;
488         } else {
489             
490             notSupported();
491 
492             return null;
493         }
494     }
495 
496     public static org.w3c.dom.Element asDOMElement(Node element) {
497         if (element == null) {
498             return null;
499         }
500 
501         if (element instanceof org.w3c.dom.Element) {
502             return (org.w3c.dom.Element) element;
503         } else {
504             
505             notSupported();
506 
507             return null;
508         }
509     }
510 
511     public static org.w3c.dom.Attr asDOMAttr(Node attribute) {
512         if (attribute == null) {
513             return null;
514         }
515 
516         if (attribute instanceof org.w3c.dom.Attr) {
517             return (org.w3c.dom.Attr) attribute;
518         } else {
519             
520             notSupported();
521 
522             return null;
523         }
524     }
525 
526     /***
527      * Called when a method has not been implemented yet
528      * 
529      * @throws DOMException
530      *             DOCUMENT ME!
531      */
532     public static void notSupported() {
533         throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
534                 "Not supported yet");
535     }
536 
537     public static class EmptyNodeList implements NodeList {
538         public org.w3c.dom.Node item(int index) {
539             return null;
540         }
541 
542         public int getLength() {
543             return 0;
544         }
545     }
546 }
547 
548 
549 
550 
551 
552 
553 
554 
555 
556 
557 
558 
559 
560 
561 
562 
563 
564 
565 
566 
567 
568 
569 
570 
571 
572 
573 
574 
575 
576 
577 
578 
579 
580 
581 
582 
583