View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.ws.commons.schema.utils;
21  
22  import org.w3c.dom.*;
23  
24  import java.lang.reflect.Method;
25  import java.lang.reflect.InvocationTargetException;
26  
27  /**
28   * Some useful utility methods.
29   * This class was modified in Xerces2 with a view to abstracting as
30   * much as possible away from the representation of the underlying
31   * parsed structure (i.e., the DOM).  This was done so that, if Xerces
32   * ever adopts an in-memory representation more efficient than the DOM
33   * (such as a DTM), we should easily be able to convert our schema
34   * parsing to utilize it.
35   *
36   * @version $ID DOMUtil
37   */
38  public class DOMUtil {
39  
40      //
41      // Constructors
42      //
43  
44      /**
45       * This class cannot be instantiated.
46       */
47      protected DOMUtil() {
48      }
49  
50      //
51      // Public static methods
52      //
53  
54      /**
55       * Finds and returns the first child element node.
56       */
57      public static Element getFirstChildElement(Node parent) {
58  
59          // search for node
60          Node child = parent.getFirstChild();
61          while (child != null) {
62              if (child.getNodeType() == Node.ELEMENT_NODE) {
63                  return (Element) child;
64              }
65              child = child.getNextSibling();
66          }
67  
68          // not found
69          return null;
70  
71      } // getFirstChildElement(Node):Element
72  
73      /**
74       * Finds and returns the last child element node.
75       */
76      public static Element getLastChildElement(Node parent) {
77  
78          // search for node
79          Node child = parent.getLastChild();
80          while (child != null) {
81              if (child.getNodeType() == Node.ELEMENT_NODE) {
82                  return (Element) child;
83              }
84              child = child.getPreviousSibling();
85          }
86  
87          // not found
88          return null;
89  
90      } // getLastChildElement(Node):Element
91  
92  
93      /**
94       * Finds and returns the next sibling element node.
95       */
96      public static Element getNextSiblingElement(Node node) {
97  
98          // search for node
99          Node sibling = node.getNextSibling();
100         while (sibling != null) {
101             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
102                 return (Element) sibling;
103             }
104             sibling = sibling.getNextSibling();
105         }
106 
107         // not found
108         return null;
109 
110     } // getNextSiblingElement(Node):Element
111 
112     /**
113      * Finds and returns the first child node with the given name.
114      */
115     public static Element getFirstChildElement(Node parent, String elemName) {
116 
117         // search for node
118         Node child = parent.getFirstChild();
119         while (child != null) {
120             if (child.getNodeType() == Node.ELEMENT_NODE) {
121                 if (child.getNodeName().equals(elemName)) {
122                     return (Element) child;
123                 }
124             }
125             child = child.getNextSibling();
126         }
127 
128         // not found
129         return null;
130 
131     } // getFirstChildElement(Node,String):Element
132 
133     /**
134      * Finds and returns the last child node with the given name.
135      */
136     public static Element getLastChildElement(Node parent, String elemName) {
137 
138         // search for node
139         Node child = parent.getLastChild();
140         while (child != null) {
141             if (child.getNodeType() == Node.ELEMENT_NODE) {
142                 if (child.getNodeName().equals(elemName)) {
143                     return (Element) child;
144                 }
145             }
146             child = child.getPreviousSibling();
147         }
148 
149         // not found
150         return null;
151 
152     } // getLastChildElement(Node,String):Element
153 
154     /**
155      * Finds and returns the next sibling node with the given name.
156      */
157     public static Element getNextSiblingElement(Node node, String elemName) {
158 
159         // search for node
160         Node sibling = node.getNextSibling();
161         while (sibling != null) {
162             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
163                 if (sibling.getNodeName().equals(elemName)) {
164                     return (Element) sibling;
165                 }
166             }
167             sibling = sibling.getNextSibling();
168         }
169 
170         // not found
171         return null;
172 
173     } // getNextSiblingdElement(Node,String):Element
174 
175     /**
176      * Finds and returns the first child node with the given qualified name.
177      */
178     public static Element getFirstChildElementNS(Node parent,
179                                                  String uri, String localpart) {
180 
181         // search for node
182         Node child = parent.getFirstChild();
183         while (child != null) {
184             if (child.getNodeType() == Node.ELEMENT_NODE) {
185                 String childURI = child.getNamespaceURI();
186                 if (childURI != null && childURI.equals(uri) &&
187                         child.getLocalName().equals(localpart)) {
188                     return (Element) child;
189                 }
190             }
191             child = child.getNextSibling();
192         }
193 
194         // not found
195         return null;
196 
197     } // getFirstChildElementNS(Node,String,String):Element
198 
199     /**
200      * Finds and returns the last child node with the given qualified name.
201      */
202     public static Element getLastChildElementNS(Node parent,
203                                                 String uri, String localpart) {
204 
205         // search for node
206         Node child = parent.getLastChild();
207         while (child != null) {
208             if (child.getNodeType() == Node.ELEMENT_NODE) {
209                 String childURI = child.getNamespaceURI();
210                 if (childURI != null && childURI.equals(uri) &&
211                         child.getLocalName().equals(localpart)) {
212                     return (Element) child;
213                 }
214             }
215             child = child.getPreviousSibling();
216         }
217 
218         // not found
219         return null;
220 
221     } // getLastChildElementNS(Node,String,String):Element
222 
223     /**
224      * Finds and returns the next sibling node with the given qualified name.
225      */
226     public static Element getNextSiblingElementNS(Node node,
227                                                   String uri, String localpart) {
228 
229         // search for node
230         Node sibling = node.getNextSibling();
231         while (sibling != null) {
232             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
233                 String siblingURI = sibling.getNamespaceURI();
234                 if (siblingURI != null && siblingURI.equals(uri) &&
235                         sibling.getLocalName().equals(localpart)) {
236                     return (Element) sibling;
237                 }
238             }
239             sibling = sibling.getNextSibling();
240         }
241 
242         // not found
243         return null;
244 
245     } // getNextSiblingdElementNS(Node,String,String):Element
246 
247     /**
248      * Finds and returns the first child node with the given name.
249      */
250     public static Element getFirstChildElement(Node parent, String elemNames[]) {
251 
252         // search for node
253         Node child = parent.getFirstChild();
254         while (child != null) {
255             if (child.getNodeType() == Node.ELEMENT_NODE) {
256                 for (int i = 0; i < elemNames.length; i++) {
257                     if (child.getNodeName().equals(elemNames[i])) {
258                         return (Element) child;
259                     }
260                 }
261             }
262             child = child.getNextSibling();
263         }
264 
265         // not found
266         return null;
267 
268     } // getFirstChildElement(Node,String[]):Element
269 
270     /**
271      * Finds and returns the last child node with the given name.
272      */
273     public static Element getLastChildElement(Node parent, String elemNames[]) {
274 
275         // search for node
276         Node child = parent.getLastChild();
277         while (child != null) {
278             if (child.getNodeType() == Node.ELEMENT_NODE) {
279                 for (int i = 0; i < elemNames.length; i++) {
280                     if (child.getNodeName().equals(elemNames[i])) {
281                         return (Element) child;
282                     }
283                 }
284             }
285             child = child.getPreviousSibling();
286         }
287 
288         // not found
289         return null;
290 
291     } // getLastChildElement(Node,String[]):Element
292 
293     /**
294      * Finds and returns the next sibling node with the given name.
295      */
296     public static Element getNextSiblingElement(Node node, String elemNames[]) {
297 
298         // search for node
299         Node sibling = node.getNextSibling();
300         while (sibling != null) {
301             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
302                 for (int i = 0; i < elemNames.length; i++) {
303                     if (sibling.getNodeName().equals(elemNames[i])) {
304                         return (Element) sibling;
305                     }
306                 }
307             }
308             sibling = sibling.getNextSibling();
309         }
310 
311         // not found
312         return null;
313 
314     } // getNextSiblingdElement(Node,String[]):Element
315 
316     /**
317      * Finds and returns the first child node with the given qualified name.
318      */
319     public static Element getFirstChildElementNS(Node parent,
320                                                  String[][] elemNames) {
321 
322         // search for node
323         Node child = parent.getFirstChild();
324         while (child != null) {
325             if (child.getNodeType() == Node.ELEMENT_NODE) {
326                 for (int i = 0; i < elemNames.length; i++) {
327                     String uri = child.getNamespaceURI();
328                     if (uri != null && uri.equals(elemNames[i][0]) &&
329                             child.getLocalName().equals(elemNames[i][1])) {
330                         return (Element) child;
331                     }
332                 }
333             }
334             child = child.getNextSibling();
335         }
336 
337         // not found
338         return null;
339 
340     } // getFirstChildElementNS(Node,String[][]):Element
341 
342     /**
343      * Finds and returns the last child node with the given qualified name.
344      */
345     public static Element getLastChildElementNS(Node parent,
346                                                 String[][] elemNames) {
347 
348         // search for node
349         Node child = parent.getLastChild();
350         while (child != null) {
351             if (child.getNodeType() == Node.ELEMENT_NODE) {
352                 for (int i = 0; i < elemNames.length; i++) {
353                     String uri = child.getNamespaceURI();
354                     if (uri != null && uri.equals(elemNames[i][0]) &&
355                             child.getLocalName().equals(elemNames[i][1])) {
356                         return (Element) child;
357                     }
358                 }
359             }
360             child = child.getPreviousSibling();
361         }
362 
363         // not found
364         return null;
365 
366     } // getLastChildElementNS(Node,String[][]):Element
367 
368     /**
369      * Finds and returns the next sibling node with the given qualified name.
370      */
371     public static Element getNextSiblingElementNS(Node node,
372                                                   String[][] elemNames) {
373 
374         // search for node
375         Node sibling = node.getNextSibling();
376         while (sibling != null) {
377             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
378                 for (int i = 0; i < elemNames.length; i++) {
379                     String uri = sibling.getNamespaceURI();
380                     if (uri != null && uri.equals(elemNames[i][0]) &&
381                             sibling.getLocalName().equals(elemNames[i][1])) {
382                         return (Element) sibling;
383                     }
384                 }
385             }
386             sibling = sibling.getNextSibling();
387         }
388 
389         // not found
390         return null;
391 
392     } // getNextSiblingdElementNS(Node,String[][]):Element
393 
394     /**
395      * Finds and returns the first child node with the given name and
396      * attribute name, value pair.
397      */
398     public static Element getFirstChildElement(Node parent,
399                                                String elemName,
400                                                String attrName,
401                                                String attrValue) {
402 
403         // search for node
404         Node child = parent.getFirstChild();
405         while (child != null) {
406             if (child.getNodeType() == Node.ELEMENT_NODE) {
407                 Element element = (Element) child;
408                 if (element.getNodeName().equals(elemName) &&
409                         element.getAttribute(attrName).equals(attrValue)) {
410                     return element;
411                 }
412             }
413             child = child.getNextSibling();
414         }
415 
416         // not found
417         return null;
418 
419     } // getFirstChildElement(Node,String,String,String):Element
420 
421     /**
422      * Finds and returns the last child node with the given name and
423      * attribute name, value pair.
424      */
425     public static Element getLastChildElement(Node parent,
426                                               String elemName,
427                                               String attrName,
428                                               String attrValue) {
429 
430         // search for node
431         Node child = parent.getLastChild();
432         while (child != null) {
433             if (child.getNodeType() == Node.ELEMENT_NODE) {
434                 Element element = (Element) child;
435                 if (element.getNodeName().equals(elemName) &&
436                         element.getAttribute(attrName).equals(attrValue)) {
437                     return element;
438                 }
439             }
440             child = child.getPreviousSibling();
441         }
442 
443         // not found
444         return null;
445 
446     } // getLastChildElement(Node,String,String,String):Element
447 
448     /**
449      * Finds and returns the next sibling node with the given name and
450      * attribute name, value pair. Since only elements have attributes,
451      * the node returned will be of type Node.ELEMENT_NODE.
452      */
453     public static Element getNextSiblingElement(Node node,
454                                                 String elemName,
455                                                 String attrName,
456                                                 String attrValue) {
457 
458         // search for node
459         Node sibling = node.getNextSibling();
460         while (sibling != null) {
461             if (sibling.getNodeType() == Node.ELEMENT_NODE) {
462                 Element element = (Element) sibling;
463                 if (element.getNodeName().equals(elemName) &&
464                         element.getAttribute(attrName).equals(attrValue)) {
465                     return element;
466                 }
467             }
468             sibling = sibling.getNextSibling();
469         }
470 
471         // not found
472         return null;
473 
474     } // getNextSiblingElement(Node,String,String,String):Element
475 
476     /**
477      * Returns the concatenated child text of the specified node.
478      * This method only looks at the immediate children of type
479      * <code>Node.TEXT_NODE</code> or the children of any child
480      * node that is of type <code>Node.CDATA_SECTION_NODE</code>
481      * for the concatenation.
482      *
483      * @param node The node to look at.
484      */
485     public static String getChildText(Node node) {
486 
487         // is there anything to do?
488         if (node == null) {
489             return null;
490         }
491 
492         // concatenate children text
493         StringBuffer str = new StringBuffer();
494         Node child = node.getFirstChild();
495         while (child != null) {
496             short type = child.getNodeType();
497             if (type == Node.TEXT_NODE) {
498                 str.append(child.getNodeValue());
499             } else if (type == Node.CDATA_SECTION_NODE) {
500                 str.append(getChildText(child));
501             }
502             child = child.getNextSibling();
503         }
504 
505         // return text value
506         return str.toString();
507 
508     } // getChildText(Node):String
509 
510     // return the name of this element
511     public static String getName(Node node) {
512         return node.getNodeName();
513     } // getLocalName(Element):  String
514 
515     /**
516      * returns local name of this element if not null, otherwise
517      * returns the name of the node
518      */
519     public static String getLocalName(Node node) {
520         String name = node.getLocalName();
521         return (name != null) ? name : node.getNodeName();
522     } // getLocalName(Element):  String
523 
524     public static Element getParent(Element elem) {
525         Node parent = elem.getParentNode();
526         if (parent instanceof Element)
527             return (Element) parent;
528         return null;
529     } // getParent(Element):Element
530 
531     // get the Document of which this Node is a part
532     public static Document getDocument(Node node) {
533         return node.getOwnerDocument();
534     } // getDocument(Node):Document
535 
536     // return this Document's root node
537     public static Element getRoot(Document doc) {
538         return doc.getDocumentElement();
539     } // getRoot(Document(:  Element
540 
541     // some methods for handling attributes:
542 
543     // return the right attribute node
544     public static Attr getAttr(Element elem, String name) {
545         return elem.getAttributeNode(name);
546     } // getAttr(Element, String):Attr
547 
548     // return the right attribute node
549     public static Attr getAttrNS(Element elem, String nsUri,
550                                  String localName) {
551         return elem.getAttributeNodeNS(nsUri, localName);
552     } // getAttrNS(Element, String):Attr
553 
554     // get all the attributes for an Element
555     public static Attr[] getAttrs(Element elem) {
556         NamedNodeMap attrMap = elem.getAttributes();
557         Attr[] attrArray = new Attr[attrMap.getLength()];
558         for (int i = 0; i < attrMap.getLength(); i++)
559             attrArray[i] = (Attr) attrMap.item(i);
560         return attrArray;
561     } // getAttrs(Element):  Attr[]
562 
563     // get attribute's value
564     public static String getValue(Attr attribute) {
565         return attribute.getValue();
566     } // getValue(Attr):String
567 
568     // It is noteworthy that, because of the way the DOM specs
569     // work, the next two methods return the empty string (not
570     // null!) when the attribute with the specified name does not
571     // exist on an element.  Beware!
572 
573     // return the value of the attribute of the given element
574     // with the given name
575     public static String getAttrValue(Element elem, String name) {
576         return elem.getAttribute(name);
577     } // getAttr(Element, String):Attr
578 
579     // return the value of the attribute of the given element
580     // with the given name
581     public static String getAttrValueNS(Element elem, String nsUri,
582                                         String localName) {
583         return elem.getAttributeNS(nsUri, localName);
584     } // getAttrValueNS(Element, String):Attr
585 
586     // return the namespace URI
587     public static String getNamespaceURI(Node node) {
588         return node.getNamespaceURI();
589     }
590 
591     public static String getInputEncoding(Document doc) {
592         try {
593             Method m = Document.class.getMethod("getInputEncoding", new Class[]{});
594             return (String) m.invoke(doc, new Object[]{});
595         } catch (Exception e) {
596             return "UTF-8";
597         }
598     }
599 } // class XUtil