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.apache.commons.modeler.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  /***
42   *  Few simple utils to read DOM
43   *
44   * @author Costin Manolache
45   */
46  public class DomUtil {
47      private static org.apache.commons.logging.Log log=
48          org.apache.commons.logging.LogFactory.getLog( DomUtil.class );
49  
50      // -------------------- DOM utils --------------------
51  
52      /*** Get the trimed text content of a node or null if there is no text
53       */
54      public static String getContent(Node n ) {
55          if( n==null ) return null;
56          Node n1=DomUtil.getChild(n, Node.TEXT_NODE);
57  
58          if( n1==null ) return null;
59  
60          String s1=n1.getNodeValue();
61          return s1.trim();
62      }
63  
64      /*** Get the first element child.
65       * @param parent lookup direct childs
66       * @param name name of the element. If null return the first element.
67       */
68      public static Node getChild( Node parent, String name ) {
69          if( parent==null ) return null;
70          Node first=parent.getFirstChild();
71          if( first==null ) return null;
72  
73          for (Node node = first; node != null;
74               node = node.getNextSibling()) {
75              //System.out.println("getNode: " + name + " " + node.getNodeName());
76              if( node.getNodeType()!=Node.ELEMENT_NODE)
77                  continue;
78              if( name != null &&
79                  name.equals( node.getNodeName() ) ) {
80                  return node;
81              }
82              if( name == null ) {
83                  return node;
84              }
85          }
86          return null;
87      }
88  
89      public static String getAttribute(Node element, String attName ) {
90          NamedNodeMap attrs=element.getAttributes();
91          if( attrs==null ) return null;
92          Node attN=attrs.getNamedItem(attName);
93          if( attN==null ) return null;
94          return attN.getNodeValue();
95      }
96  
97      public static void setAttribute(Node node, String attName, String val) {
98          NamedNodeMap attributes=node.getAttributes();
99          Node attNode=node.getOwnerDocument().createAttribute(attName);
100         attNode.setNodeValue( val );
101         attributes.setNamedItem(attNode);
102     }
103     
104     public static void removeAttribute( Node node, String attName ) {
105         NamedNodeMap attributes=node.getAttributes();
106         attributes.removeNamedItem(attName);                
107     }
108     
109     
110     /*** Set or replace the text value 
111      */ 
112     public static void setText(Node node, String val) {
113         Node chld=DomUtil.getChild(node, Node.TEXT_NODE);
114         if( chld == null ) {
115             Node textN=node.getOwnerDocument().createTextNode(val);
116             node.appendChild(textN);
117             return;
118         }
119         // change the value
120         chld.setNodeValue(val);           
121     }
122 
123     /*** Find the first direct child with a given attribute.
124      * @param parent
125      * @param elemName name of the element, or null for any 
126      * @param attName attribute we're looking for
127      * @param attVal attribute value or null if we just want any
128      */ 
129     public static Node findChildWithAtt(Node parent, String elemName,
130                                         String attName, String attVal) {
131         
132         Node child=DomUtil.getChild(parent, Node.ELEMENT_NODE);
133         if( attVal== null ) {
134             while( child!= null &&
135                     ( elemName==null || elemName.equals( child.getNodeName())) && 
136                     DomUtil.getAttribute(child, attName) != null ) {
137                 child=getNext(child, elemName, Node.ELEMENT_NODE );
138             }
139         } else {
140             while( child!= null && 
141                     ( elemName==null || elemName.equals( child.getNodeName())) && 
142                     ! attVal.equals( DomUtil.getAttribute(child, attName)) ) {
143                 child=getNext(child, elemName, Node.ELEMENT_NODE );
144             }
145         }
146         return child;        
147     }    
148     
149 
150     /*** Get the first child's content ( ie it's included TEXT node ).
151      */
152     public static String getChildContent( Node parent, String name ) {
153         Node first=parent.getFirstChild();
154         if( first==null ) return null;
155         for (Node node = first; node != null;
156              node = node.getNextSibling()) {
157             //System.out.println("getNode: " + name + " " + node.getNodeName());
158             if( name.equals( node.getNodeName() ) ) {
159                 return getContent( node );
160             }
161         }
162         return null;
163     }
164 
165     /*** Get the first direct child with a given type
166      */
167     public static Node getChild( Node parent, int type ) {
168         Node n=parent.getFirstChild();
169         while( n!=null && type != n.getNodeType() ) {
170             n=n.getNextSibling();
171         }
172         if( n==null ) return null;
173         return n;
174     }
175 
176     /*** Get the next sibling with the same name and type
177      */
178     public static Node getNext( Node current ) {
179         String name=current.getNodeName();
180         int type=current.getNodeType();
181         return getNext( current, name, type);
182     }
183 
184     /*** Return the next sibling with a given name and type
185      */ 
186     public static Node getNext( Node current, String name, int type) {
187         Node first=current.getNextSibling();
188         if( first==null ) return null;
189 
190         for (Node node = first; node != null;
191              node = node.getNextSibling()) {
192             
193             if( type >= 0 && node.getNodeType() != type ) continue;
194             //System.out.println("getNode: " + name + " " + node.getNodeName());
195             if( name==null )
196                 return node;
197             if( name.equals( node.getNodeName() ) ) {
198                 return node;
199             }
200         }
201         return null;
202     }
203 
204     public static class NullResolver implements EntityResolver {
205         public InputSource resolveEntity (String publicId,
206                                                    String systemId)
207             throws SAXException, IOException
208         {
209             if( log.isTraceEnabled())
210                 log.trace("ResolveEntity: " + publicId + " " + systemId);
211             return new InputSource(new StringReader(""));
212         }
213     }
214 
215     public static void setAttributes( Object o, Node parent)
216     {
217         NamedNodeMap attrs=parent.getAttributes();
218         if( attrs==null ) return;
219 
220         for (int i=0; i<attrs.getLength(); i++ ) {
221             Node n=attrs.item(i);
222             String name=n.getNodeName();
223             String value=n.getNodeValue();
224 
225             if( log.isTraceEnabled() )
226                 log.trace("Attribute " + parent.getNodeName() + " " +
227                             name + "=" + value);
228             try {
229                 IntrospectionUtils.setProperty(o, name, value);
230             } catch( Exception ex ) {
231                 ex.printStackTrace();
232             }
233         }
234     }
235 
236     /*** Read XML as DOM.
237      */
238     public static Document readXml(InputStream is)
239         throws SAXException, IOException, ParserConfigurationException
240     {
241         DocumentBuilderFactory dbf =
242             DocumentBuilderFactory.newInstance();
243 
244         dbf.setValidating(false);
245         dbf.setIgnoringComments(false);
246         dbf.setIgnoringElementContentWhitespace(true);
247         //dbf.setCoalescing(true);
248         //dbf.setExpandEntityReferences(true);
249 
250         DocumentBuilder db = null;
251         db = dbf.newDocumentBuilder();
252         db.setEntityResolver( new NullResolver() );
253 
254         // db.setErrorHandler( new MyErrorHandler());
255 
256         Document doc = db.parse(is);
257         return doc;
258     }
259 
260     public static void writeXml( Node n, OutputStream os )
261             throws TransformerException
262     {
263         TransformerFactory tf=TransformerFactory.newInstance();
264         //identity
265         Transformer t=tf.newTransformer();
266         t.setOutputProperty(OutputKeys.INDENT, "yes");
267         t.transform(new DOMSource( n ), new StreamResult( os ));
268     }
269 }