View Javadoc

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