View Javadoc

1   /***
2    * Copyright 2007 ATG DUST Project
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    * 
7    * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8    * 
9    * Unless required by applicable law or agreed to in writing, software 
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and limitations under the License.
13   */
14  
15  package atg.junit.nucleus;
16  
17  import java.io.File;
18  import java.io.FileInputStream;
19  import java.io.FileNotFoundException;
20  import java.util.Iterator;
21  import java.util.LinkedList;
22  import java.util.List;
23  
24  import org.apache.log4j.Logger;
25  import org.w3c.dom.Document;
26  import org.w3c.dom.Element;
27  import org.w3c.dom.Node;
28  import org.w3c.dom.NodeList;
29  import org.w3c.dom.Text;
30  
31  import atg.nucleus.logging.ApplicationLoggingImpl;
32  import atg.xml.tools.DefaultErrorHandler;
33  import atg.xml.tools.DefaultXMLToolsFactory;
34  import atg.xml.tools.XMLToDOMParser;
35  import atg.xml.tools.XMLToolsFactory;
36  
37  /*** A utility class to help with common XML manipulation functions.
38   *
39   * @version 1.0
40   */
41  public class XmlUtils
42  {
43    
44    private static Logger log = Logger.getLogger(XmlUtils.class);
45        /*** Initializes the XML file to be parsed and gets the Document tree for it.
46         *  @param File the XML file to parse
47         *  @param boolean true if the file should be validated against its DTD; otherwise false.
48         *  @exception FileNotFoundException if the specified file can not be located.
49         *  @exception Exception if an error occurs parsing the file to a DOM.
50         **/
51        public static Document initializeFile( File pXmlFile, boolean pValidateDoc )
52            throws FileNotFoundException, Exception
53        {
54          XMLToolsFactory factory = DefaultXMLToolsFactory.getInstance();
55          XMLToDOMParser parser = factory.createXMLToDOMParser();
56          ApplicationLoggingImpl logger = new ApplicationLoggingImpl( "[UnitTests.base:atg.junit.nucleus.XmlUtils]" );
57          DefaultErrorHandler errorHandler = new DefaultErrorHandler(logger, true, true);
58          return parser.parse(new FileInputStream( pXmlFile ), pValidateDoc, errorHandler);
59        }
60  
61        /*** retrieves the Node(s) represented within the DOM hierarchy at the location
62         *  designated by the 'nested' child nodes.
63         *  @param File the XML document in which to look
64         *  @param boolean true if the file should be validated against its DTD; otherwise false.
65         *  @param String[] the nested child nodes to retrieve. for example, if you specified
66         *  an array { "foo", "bar", "flippy" } this method would return all 'flippy' Nodes for the XML
67         *  document:
68         *  <pre>
69         *    &lt;foo&lt;
70         *      &lt;bar&lt;
71         *        &lt;flippy .../&lt;
72         *        &lt;flippy .../&lt;
73         *      &lt;/bar&lt;
74         *    &lt;/foo&lt;
75         *  </pre>
76         *  @return List the requested child Nodes.  an empty List if no child Nodes exist.
77         *  @exception FileNotFoundException if the specified file can not be located.
78         *  @exception Exception if an error occurs parsing the file to a DOM.
79         */
80        public static List<Node>  getNodes( File pXmlFile, boolean pValidateDoc, String[] pChildren )
81            throws FileNotFoundException, Exception
82        {
83            return getNodes( initializeFile( pXmlFile, pValidateDoc ), pChildren );
84        }
85  
86        /*** retrieves the Node(s) represented within the DOM hierarchy at the location
87         *  designated by the 'nested' child nodes.
88         *  @param Document the XML document parsed to a DOM
89         *  @param String[] the nested child nodes to retrieve. for example, if you specified
90         *  an array { "foo", "bar", "flippy" } this method would return all 'flippy' Nodes for the XML
91         *  document:
92         *  <pre>
93         *    &lt;foo&lt;
94         *      &lt;bar&lt;
95         *        &lt;flippy .../&lt;
96         *        &lt;flippy .../&lt;
97         *      &lt;/bar&lt;
98         *    &lt;/foo&lt;
99         *  </pre>
100        *  @return List the requested child Nodes.  an empty List if no child Nodes exist.
101        *  null if the specified Document was null.
102        */
103       public static List<Node>  getNodes( Document pDocument, String[] pChildren )
104       {
105           if ( pDocument == null ) return null;
106           return getNodes( pDocument.getDocumentElement(), pChildren );
107       }
108 
109       /*** retrieves the Node(s) represented within the DOM hierarchy at the location
110        *  designated by the 'nested' child nodes.
111        *  @param Node the Node at which to start searching
112        *  @param String[] the nested child nodes to retrieve. for example, if you specified
113        *  an array { "foo", "bar", "flippy" } this method would return all 'flippy' Nodes for the XML
114        *  document:
115        *  <pre>
116        *    &lt;foo&lt;
117        *      &lt;bar&lt;
118        *        &lt;flippy .../&lt;
119        *        &lt;flippy .../&lt;
120        *      &lt;/bar&lt;
121        *    &lt;/foo&lt;
122        *  </pre>
123        *  @return List the requested child Nodes.  an empty List if no child Nodes exist.
124        */
125       public static List<Node> getNodes( Node pNode, String[] pChildren ) {
126           List<Node>  nodes = new LinkedList<Node>();
127 
128           if ( pNode == null ) {
129               // do nothing
130           } else if ( pChildren == null || pChildren.length == 0 ) {
131               // if there are no more children, just return this Node
132               nodes.add( pNode );
133           } else {
134               // otherwise recurse and get the children nodes...
135               String[] children = new String[ pChildren.length - 1 ];
136               for ( int j=0; j<children.length; j++ ) { children[j] = pChildren[j+1]; }
137 
138               NodeList nl = ((Element)pNode).getElementsByTagName( pChildren[0] );
139               for ( int i=0; i<nl.getLength(); i++ ) {
140                   nodes.addAll( getNodes(nl.item(i), children) );
141               }
142           }
143           return nodes;
144       }
145 
146       /*** returns the Element NodeList for the specified child of the parent Node.
147        *  @param Node the parent node
148        *  @param String the name of the child node(s)
149        *  @return NodeList the children of the parent Node.  null if pChild or pNode is null.
150        */
151       public static NodeList getNodes( Node pNode, String pChild ) {
152           if ( pNode == null || pChild == null ) return null;
153           return ((Element)pNode).getElementsByTagName( pChild );
154       }
155 
156       /*** Returns the String value of the content of the Node specified.
157        *  @param Node the node whose content to get.
158        *  @return String the value of the content of the Node.  An empty String if the Node
159        *  does not have any content.
160        */
161       public static String getNodeTextValue(Node pElement) {
162         NodeList children = pElement.getChildNodes();
163         StringBuffer sb = new StringBuffer();
164         for (int i = 0; i < children.getLength(); i++) {
165           if (children.item(i) instanceof Text) {
166             Text n = (Text) children.item(i);
167             sb.append(n.getNodeValue());
168           }
169         }
170         String v = sb.toString();
171         return v.toString();
172       }
173 
174       /*** gets the value of the named attribute.
175        *  @param Node the node whose attribute should be retrieved.
176        *  @param String the name of attribute whose value should be retrieved.
177        *  @return String the value of the attribute.  null if the attribute is not defined
178        *  or if a value has not been specified for it. */
179       public static String getAttribute( Node pNode, String pName ) {
180           return getAttribute( pNode, pName, null );
181       }
182 
183       /*** returns the value of the named attribute, or the specified default if the attribute
184        *  value is null.
185        *  @param Node the node whose attribute should be retrieved.
186        *  @param String the name of attribute whose value should be retrieved.
187        *  @param String the default value to return if a value does not exist for the specified
188        *  attribute, or if the specified attribute is not defined in this Node.
189        *  @return String the value of the attribute.  */
190       public static String getAttribute( Node pNode, String pName, String pDefault ) {
191           if ( pNode.getAttributes().getNamedItem(pName) == null ) return pDefault;
192           return pNode.getAttributes().getNamedItem(pName).getNodeValue();
193       }
194 
195       /*** returns the value of the named attribute as an Integer object.
196        *  @param Node the node whose attribute should be retrieved.
197        *  @param String the name of attribute whose value should be retrieved.
198        *  @param String the default value to return if a value does not exist for the specified
199        *  attribute, or if the specified attribute is not defined in this Node.
200        *  @return Integer the value of the attribute. If pAllowNull is true and
201        *  no value is specified for the attribute then null is returned.
202        *  @exception FileFormatException if the value specified by the attribute can not be converted to an Integer,
203        *  or if pAllowNull is false and no value was specified for the attribute. */
204       public static Integer getIntegerAttribute( Node pNode, String pName, boolean pAllowNull )
205           throws FileFormatException
206       {
207           Node n = pNode.getAttributes().getNamedItem( pName );
208           if ( n == null && pAllowNull ) return null;
209           if ( n == null && !pAllowNull ) throw new FileFormatException("No value specified for required attribute '" + pName + "'.");
210           return getIntegerValue( n.getNodeValue(), pName, pAllowNull );
211       }
212 
213       /*** converts the specified String into an Integer.
214        *  @param String the value to convert.
215        *  @param String a descriptor of what the value is for.
216        *  @param boolean true if the input value can be null; otherwise false.
217        *  @return Integer the Integer value of the String input value.
218        *  @exception FileFormatException if the String can not be converted to an Integer or if it is
219        *  null and pAllowNull is false.  */
220       public static Integer getIntegerValue( String pValue, String pDescriptor, boolean pAllowNull )
221           throws FileFormatException
222       {
223           if ( (pValue == null || pValue.trim().length() == 0 ) && pAllowNull ) return null;
224           try {
225             return new Integer( pValue.trim() );
226           } catch (Throwable t) {
227               throw new FileFormatException("Invalid Integer value '" + pValue + "' specified for attribute '" + pDescriptor + "'.");
228           }
229       }
230 
231       /*** returns the value of the named attribute as a Long object.
232        *  @param Node the node whose attribute should be retrieved.
233        *  @param String the name of attribute whose value should be retrieved.
234        *  @param String the default value to return if a value does not exist for the specified
235        *  attribute, or if the specified attribute is not defined in this Node.
236        *  @return Long the value of the attribute. If pAllowNull is true and
237        *  no value is specified for the attribute then null is returned.
238        *  @exception FileFormatException if the value specified by the attribute can not be converted to a Long,
239        *  or if pAllowNull is false and no value was specified for the attribute. */
240       public static Long getLongAttribute( Node pNode, String pName, boolean pAllowNull )
241           throws FileFormatException
242       {
243           Node n = pNode.getAttributes().getNamedItem( pName );
244           if ( n == null && pAllowNull ) return null;
245           if ( n == null && !pAllowNull ) throw new FileFormatException("No value specified for required attribute '" + pName + "'.");
246           return getLongValue( n.getNodeValue(), pName, pAllowNull );
247       }
248 
249       /*** converts the specified String into a Long.
250        *  @param String the value to convert.
251        *  @param String a descriptor of what the value is for.
252        *  @param boolean true if the input value can be null; otherwise false.
253        *  @return Long the Long value of the String input value.
254        *  @exception FileFormatException if the String can not be converted to a Long or if it is
255        *  null and pAllowNull is false.  */
256       public static Long getLongValue( String pValue, String pDescriptor, boolean pAllowNull )
257           throws FileFormatException
258       {
259           if ( (pValue == null || pValue.trim().length() == 0 ) && pAllowNull ) return null;
260           try {
261             return new Long( pValue.trim() );
262           } catch (Throwable t) {
263               throw new FileFormatException("Invalid Long value '" + pValue + "' specified for attribute '" + pDescriptor + "'.");
264           }
265       }
266 
267       /*** returns the value of the named attribute as a boolean.
268        *  @param Node the node whose attribute should be retrieved.
269        *  @param String the name of attribute whose value should be retrieved.
270        *  @param boolean the default value to return if a value does not exist for the specified
271        *  attribute, or if the specified attribute is not defined in this Node.
272        *  @return boolean the value of the attribute. If no value was specified for the
273        *  attribute then the default value is returned.
274        *  @exception FileFormatException if the value specified by the attribute can not be converted to a boolean.
275        */
276       public static boolean getBooleanAttribute( Node pNode, String pName, boolean pDefault )
277           throws FileFormatException
278       {
279           Node n = pNode.getAttributes().getNamedItem( pName );
280           if ( n == null ) return pDefault;
281           return getBooleanValue( n.getNodeValue(), pName, pDefault );
282       }
283 
284       /*** converts the specified value into a boolean.
285        *  @param String the value which should be converted.
286        *  @param String a descriptor of what the value is for.
287        *  @param boolean the default value to return if the specified value is null or empty.
288        *  @return boolean the converted value. If the specified value was null or empty
289        *  then the default value is returned.
290        *  @exception FileFormatException if the specified value can not be converted to a boolean.
291        */
292       public static boolean getBooleanValue( String pValue, String pDescriptor, boolean pDefault )
293           throws FileFormatException
294       {
295           if ( pValue == null || pValue.trim().length() == 0 ) return pDefault;
296           if ( ! pValue.trim().equalsIgnoreCase("true") && ! pValue.trim().equalsIgnoreCase("false") )
297               throw new FileFormatException("Invalid Boolean value '" + pValue + "' specified for attribute '" + pDescriptor +
298                                                    "'. Must be [true|false]");
299           return new Boolean(pValue.trim()).booleanValue();
300       }
301 
302       /*** returns the value of the named attribute as a Boolean object.
303        *  @param Node the node whose attribute should be retrieved.
304        *  @param String the name of attribute whose value should be retrieved.
305        *  @param Boolean the default value to return if a value does not exist for the specified
306        *  attribute, or if the specified attribute is not defined in this Node.
307        *  @return Boolean the value of the attribute. If no value was specified for the
308        *  attribute then the default value is returned.
309        *  @exception FileFormatException if the value specified by the attribute can not be converted to a boolean.
310        */
311       public static Boolean getBooleanAttribute( Node pNode, String pName, Boolean pDefault )
312           throws FileFormatException
313       {
314           Node n = pNode.getAttributes().getNamedItem( pName );
315           if ( n == null ) return pDefault;
316           String v = n.getNodeValue();
317           if ( v == null || v.length() == 0 ) return pDefault;
318           return new Boolean( getBooleanValue( v, pName, true ) );  // the default 'true' passed to this call should not never to be used
319       }
320 
321       /* a main method for testing these functions */
322       public static void main( String[] pArgs ) {
323           String file = "C://temp//registry.xml";
324 		  //String file = "/work/systest/qma/temp/registry.xml";
325           log.info("bea's registry file:=[" + file + "]");
326           String[] children = { "host", "product", "release" };
327           try {
328             List<Node>  nodes = getNodes( new File(file), false, children );
329             if ( nodes == null ) {
330                 System.out.print("Nodes is null.");
331             } else if ( nodes.size() == 0 ) {
332                 System.out.print("Nodes is empty.");
333             } else {
334                 Iterator<Node>  iter = nodes.iterator();
335                 while ( iter.hasNext() ) {
336                     Node n = iter.next();
337                     log.info("Got Node: " + getAttribute(n, "level") + "/" + getAttribute(n,"ServicePackLevel") );
338                 }
339             }
340           } catch (Throwable t) {
341               t.printStackTrace();
342           }
343 
344           log.info("-------------------");
345           log.info("BEA Version: " + atg.junit.nucleus.TestUtils.getBeaVersion() );
346           //System.setProperty("bea.home","c://bea");
347           //log.info("BEA Version: " + atg.junit.nucleus.TestUtils.getBeaVersion() );
348 
349       }
350 }