View Javadoc

1   /*
2    * Copyright 1999,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.codehaus.xfire.util;
17  
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.io.OutputStream;
21  import java.io.StringReader;
22  
23  import javax.xml.parsers.DocumentBuilder;
24  import javax.xml.parsers.DocumentBuilderFactory;
25  import javax.xml.parsers.ParserConfigurationException;
26  import javax.xml.transform.OutputKeys;
27  import javax.xml.transform.Transformer;
28  import javax.xml.transform.TransformerException;
29  import javax.xml.transform.TransformerFactory;
30  import javax.xml.transform.dom.DOMSource;
31  import javax.xml.transform.stream.StreamResult;
32  
33  import org.w3c.dom.Document;
34  import org.w3c.dom.NamedNodeMap;
35  import org.w3c.dom.Node;
36  import org.xml.sax.EntityResolver;
37  import org.xml.sax.InputSource;
38  import org.xml.sax.SAXException;
39  
40  /***
41   * Few simple utils to read DOM. This is originally from the Jakarta Commons
42   * Modeler.
43   * 
44   * @author Costin Manolache
45   */
46  public class DOMUtils
47  {
48      /***
49       * Get the trimed text content of a node or null if there is no text
50       */
51      public static String getContent(Node n)
52      {
53          if (n == null)
54              return null;
55          Node n1 = DOMUtils.getChild(n, Node.TEXT_NODE);
56  
57          if (n1 == null)
58              return null;
59  
60          String s1 = n1.getNodeValue();
61          return s1.trim();
62      }
63  
64      /***
65       * Get the first element child.
66       * 
67       * @param parent
68       *            lookup direct childs
69       * @param name
70       *            name of the element. If null return the first element.
71       */
72      public static Node getChild(Node parent, String name)
73      {
74          if (parent == null)
75              return null;
76          Node first = parent.getFirstChild();
77          if (first == null)
78              return null;
79  
80          for (Node node = first; node != null; node = node.getNextSibling())
81          {
82              //System.out.println("getNode: " + name + " " +
83              // node.getNodeName());
84              if (node.getNodeType() != Node.ELEMENT_NODE)
85                  continue;
86              if (name != null && name.equals(node.getNodeName()))
87              {
88                  return node;
89              }
90              if (name == null)
91              {
92                  return node;
93              }
94          }
95          return null;
96      }
97  
98      public static String getAttribute(Node element, String attName)
99      {
100         NamedNodeMap attrs = element.getAttributes();
101         if (attrs == null)
102             return null;
103         Node attN = attrs.getNamedItem(attName);
104         if (attN == null)
105             return null;
106         return attN.getNodeValue();
107     }
108 
109     public static void setAttribute(Node node, String attName, String val)
110     {
111         NamedNodeMap attributes = node.getAttributes();
112         Node attNode = node.getOwnerDocument().createAttribute(attName);
113         attNode.setNodeValue(val);
114         attributes.setNamedItem(attNode);
115     }
116 
117     public static void removeAttribute(Node node, String attName)
118     {
119         NamedNodeMap attributes = node.getAttributes();
120         attributes.removeNamedItem(attName);
121     }
122 
123     /***
124      * Set or replace the text value
125      */
126     public static void setText(Node node, String val)
127     {
128         Node chld = DOMUtils.getChild(node, Node.TEXT_NODE);
129         if (chld == null)
130         {
131             Node textN = node.getOwnerDocument().createTextNode(val);
132             node.appendChild(textN);
133             return;
134         }
135         // change the value
136         chld.setNodeValue(val);
137     }
138 
139     /***
140      * Find the first direct child with a given attribute.
141      * 
142      * @param parent
143      * @param elemName
144      *            name of the element, or null for any
145      * @param attName
146      *            attribute we're looking for
147      * @param attVal
148      *            attribute value or null if we just want any
149      */
150     public static Node findChildWithAtt(Node parent, String elemName,
151             String attName, String attVal)
152     {
153 
154         Node child = DOMUtils.getChild(parent, Node.ELEMENT_NODE);
155         if (attVal == null)
156         {
157             while (child != null
158                     && (elemName == null || elemName
159                             .equals(child.getNodeName()))
160                     && DOMUtils.getAttribute(child, attName) != null)
161             {
162                 child = getNext(child, elemName, Node.ELEMENT_NODE);
163             }
164         }
165         else
166         {
167             while (child != null
168                     && (elemName == null || elemName
169                             .equals(child.getNodeName()))
170                     && !attVal.equals(DOMUtils.getAttribute(child, attName)))
171             {
172                 child = getNext(child, elemName, Node.ELEMENT_NODE);
173             }
174         }
175         return child;
176     }
177 
178     /***
179      * Get the first child's content ( ie it's included TEXT node ).
180      */
181     public static String getChildContent(Node parent, String name)
182     {
183         Node first = parent.getFirstChild();
184         if (first == null)
185             return null;
186         for (Node node = first; node != null; node = node.getNextSibling())
187         {
188             //System.out.println("getNode: " + name + " " +
189             // node.getNodeName());
190             if (name.equals(node.getNodeName()))
191             {
192                 return getContent(node);
193             }
194         }
195         return null;
196     }
197 
198     /***
199      * Get the first direct child with a given type
200      */
201     public static Node getChild(Node parent, int type)
202     {
203         Node n = parent.getFirstChild();
204         while (n != null && type != n.getNodeType())
205         {
206             n = n.getNextSibling();
207         }
208         if (n == null)
209             return null;
210         return n;
211     }
212 
213     /***
214      * Get the next sibling with the same name and type
215      */
216     public static Node getNext(Node current)
217     {
218         String name = current.getNodeName();
219         int type = current.getNodeType();
220         return getNext(current, name, type);
221     }
222 
223     /***
224      * Return the next sibling with a given name and type
225      */
226     public static Node getNext(Node current, String name, int type)
227     {
228         Node first = current.getNextSibling();
229         if (first == null)
230             return null;
231 
232         for (Node node = first; node != null; node = node.getNextSibling())
233         {
234 
235             if (type >= 0 && node.getNodeType() != type)
236                 continue;
237             //System.out.println("getNode: " + name + " " +
238             // node.getNodeName());
239             if (name == null)
240                 return node;
241             if (name.equals(node.getNodeName()))
242             {
243                 return node;
244             }
245         }
246         return null;
247     }
248 
249     public static class NullResolver implements EntityResolver
250     {
251         public InputSource resolveEntity(String publicId, String systemId)
252                 throws SAXException, IOException
253         {
254             return new InputSource(new StringReader(""));
255         }
256     }
257 
258     /***
259      * Read XML as DOM.
260      */
261     public static Document readXml(InputStream is) throws SAXException,
262             IOException, ParserConfigurationException
263     {
264         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
265 
266         dbf.setValidating(false);
267         dbf.setIgnoringComments(false);
268         dbf.setIgnoringElementContentWhitespace(true);
269         //dbf.setCoalescing(true);
270         //dbf.setExpandEntityReferences(true);
271 
272         DocumentBuilder db = null;
273         db = dbf.newDocumentBuilder();
274         db.setEntityResolver(new NullResolver());
275 
276         // db.setErrorHandler( new MyErrorHandler());
277 
278         Document doc = db.parse(is);
279         return doc;
280     }
281 
282     public static void writeXml(Node n, OutputStream os)
283             throws TransformerException
284     {
285         TransformerFactory tf = TransformerFactory.newInstance();
286         //identity
287         Transformer t = tf.newTransformer();
288         t.setOutputProperty(OutputKeys.INDENT, "yes");
289         t.transform(new DOMSource(n), new StreamResult(os));
290     }
291 }