/**
* Copyright 2007 ATG DUST Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package atg.junit.nucleus;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import atg.nucleus.logging.ApplicationLoggingImpl;
import atg.xml.tools.DefaultErrorHandler;
import atg.xml.tools.DefaultXMLToolsFactory;
import atg.xml.tools.XMLToDOMParser;
import atg.xml.tools.XMLToolsFactory;
/** A utility class to help with common XML manipulation functions.
*
* @version 1.0
*/
public class XmlUtils
{
private static Logger log = Logger.getLogger(XmlUtils.class);
/** Initializes the XML file to be parsed and gets the Document tree for it.
* @param File the XML file to parse
* @param boolean true if the file should be validated against its DTD; otherwise false.
* @exception FileNotFoundException if the specified file can not be located.
* @exception Exception if an error occurs parsing the file to a DOM.
**/
public static Document initializeFile( File pXmlFile, boolean pValidateDoc )
throws FileNotFoundException, Exception
{
XMLToolsFactory factory = DefaultXMLToolsFactory.getInstance();
XMLToDOMParser parser = factory.createXMLToDOMParser();
ApplicationLoggingImpl logger = new ApplicationLoggingImpl( "[UnitTests.base:atg.junit.nucleus.XmlUtils]" );
DefaultErrorHandler errorHandler = new DefaultErrorHandler(logger, true, true);
return parser.parse(new FileInputStream( pXmlFile ), pValidateDoc, errorHandler);
}
/** retrieves the Node(s) represented within the DOM hierarchy at the location
* designated by the 'nested' child nodes.
* @param File the XML document in which to look
* @param boolean true if the file should be validated against its DTD; otherwise false.
* @param String[] the nested child nodes to retrieve. for example, if you specified
* an array { "foo", "bar", "flippy" } this method would return all 'flippy' Nodes for the XML
* document:
* <pre>
* <foo<
* <bar<
* <flippy .../<
* <flippy .../<
* </bar<
* </foo<
* </pre>
* @return List the requested child Nodes. an empty List if no child Nodes exist.
* @exception FileNotFoundException if the specified file can not be located.
* @exception Exception if an error occurs parsing the file to a DOM.
*/
public static List<Node> getNodes( File pXmlFile, boolean pValidateDoc, String[] pChildren )
throws FileNotFoundException, Exception
{
return getNodes( initializeFile( pXmlFile, pValidateDoc ), pChildren );
}
/** retrieves the Node(s) represented within the DOM hierarchy at the location
* designated by the 'nested' child nodes.
* @param Document the XML document parsed to a DOM
* @param String[] the nested child nodes to retrieve. for example, if you specified
* an array { "foo", "bar", "flippy" } this method would return all 'flippy' Nodes for the XML
* document:
* <pre>
* <foo<
* <bar<
* <flippy .../<
* <flippy .../<
* </bar<
* </foo<
* </pre>
* @return List the requested child Nodes. an empty List if no child Nodes exist.
* null if the specified Document was null.
*/
public static List<Node> getNodes( Document pDocument, String[] pChildren )
{
if ( pDocument == null ) return null;
return getNodes( pDocument.getDocumentElement(), pChildren );
}
/** retrieves the Node(s) represented within the DOM hierarchy at the location
* designated by the 'nested' child nodes.
* @param Node the Node at which to start searching
* @param String[] the nested child nodes to retrieve. for example, if you specified
* an array { "foo", "bar", "flippy" } this method would return all 'flippy' Nodes for the XML
* document:
* <pre>
* <foo<
* <bar<
* <flippy .../<
* <flippy .../<
* </bar<
* </foo<
* </pre>
* @return List the requested child Nodes. an empty List if no child Nodes exist.
*/
public static List<Node> getNodes( Node pNode, String[] pChildren ) {
List<Node> nodes = new LinkedList<Node>();
if ( pNode == null ) {
// do nothing
} else if ( pChildren == null || pChildren.length == 0 ) {
// if there are no more children, just return this Node
nodes.add( pNode );
} else {
// otherwise recurse and get the children nodes...
String[] children = new String[ pChildren.length - 1 ];
for ( int j=0; j<children.length; j++ ) { children[j] = pChildren[j+1]; }
NodeList nl = ((Element)pNode).getElementsByTagName( pChildren[0] );
for ( int i=0; i<nl.getLength(); i++ ) {
nodes.addAll( getNodes(nl.item(i), children) );
}
}
return nodes;
}
/** returns the Element NodeList for the specified child of the parent Node.
* @param Node the parent node
* @param String the name of the child node(s)
* @return NodeList the children of the parent Node. null if pChild or pNode is null.
*/
public static NodeList getNodes( Node pNode, String pChild ) {
if ( pNode == null || pChild == null ) return null;
return ((Element)pNode).getElementsByTagName( pChild );
}
/** Returns the String value of the content of the Node specified.
* @param Node the node whose content to get.
* @return String the value of the content of the Node. An empty String if the Node
* does not have any content.
*/
public static String getNodeTextValue(Node pElement) {
NodeList children = pElement.getChildNodes();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < children.getLength(); i++) {
if (children.item(i) instanceof Text) {
Text n = (Text) children.item(i);
sb.append(n.getNodeValue());
}
}
String v = sb.toString();
return v.toString();
}
/** gets the value of the named attribute.
* @param Node the node whose attribute should be retrieved.
* @param String the name of attribute whose value should be retrieved.
* @return String the value of the attribute. null if the attribute is not defined
* or if a value has not been specified for it. */
public static String getAttribute( Node pNode, String pName ) {
return getAttribute( pNode, pName, null );
}
/** returns the value of the named attribute, or the specified default if the attribute
* value is null.
* @param Node the node whose attribute should be retrieved.
* @param String the name of attribute whose value should be retrieved.
* @param String the default value to return if a value does not exist for the specified
* attribute, or if the specified attribute is not defined in this Node.
* @return String the value of the attribute. */
public static String getAttribute( Node pNode, String pName, String pDefault ) {
if ( pNode.getAttributes().getNamedItem(pName) == null ) return pDefault;
return pNode.getAttributes().getNamedItem(pName).getNodeValue();
}
/** returns the value of the named attribute as an Integer object.
* @param Node the node whose attribute should be retrieved.
* @param String the name of attribute whose value should be retrieved.
* @param String the default value to return if a value does not exist for the specified
* attribute, or if the specified attribute is not defined in this Node.
* @return Integer the value of the attribute. If pAllowNull is true and
* no value is specified for the attribute then null is returned.
* @exception FileFormatException if the value specified by the attribute can not be converted to an Integer,
* or if pAllowNull is false and no value was specified for the attribute. */
public static Integer getIntegerAttribute( Node pNode, String pName, boolean pAllowNull )
throws FileFormatException
{
Node n = pNode.getAttributes().getNamedItem( pName );
if ( n == null && pAllowNull ) return null;
if ( n == null && !pAllowNull ) throw new FileFormatException("No value specified for required attribute '" + pName + "'.");
return getIntegerValue( n.getNodeValue(), pName, pAllowNull );
}
/** converts the specified String into an Integer.
* @param String the value to convert.
* @param String a descriptor of what the value is for.
* @param boolean true if the input value can be null; otherwise false.
* @return Integer the Integer value of the String input value.
* @exception FileFormatException if the String can not be converted to an Integer or if it is
* null and pAllowNull is false. */
public static Integer getIntegerValue( String pValue, String pDescriptor, boolean pAllowNull )
throws FileFormatException
{
if ( (pValue == null || pValue.trim().length() == 0 ) && pAllowNull ) return null;
try {
return new Integer( pValue.trim() );
} catch (Throwable t) {
throw new FileFormatException("Invalid Integer value '" + pValue + "' specified for attribute '" + pDescriptor + "'.");
}
}
/** returns the value of the named attribute as a Long object.
* @param Node the node whose attribute should be retrieved.
* @param String the name of attribute whose value should be retrieved.
* @param String the default value to return if a value does not exist for the specified
* attribute, or if the specified attribute is not defined in this Node.
* @return Long the value of the attribute. If pAllowNull is true and
* no value is specified for the attribute then null is returned.
* @exception FileFormatException if the value specified by the attribute can not be converted to a Long,
* or if pAllowNull is false and no value was specified for the attribute. */
public static Long getLongAttribute( Node pNode, String pName, boolean pAllowNull )
throws FileFormatException
{
Node n = pNode.getAttributes().getNamedItem( pName );
if ( n == null && pAllowNull ) return null;
if ( n == null && !pAllowNull ) throw new FileFormatException("No value specified for required attribute '" + pName + "'.");
return getLongValue( n.getNodeValue(), pName, pAllowNull );
}
/** converts the specified String into a Long.
* @param String the value to convert.
* @param String a descriptor of what the value is for.
* @param boolean true if the input value can be null; otherwise false.
* @return Long the Long value of the String input value.
* @exception FileFormatException if the String can not be converted to a Long or if it is
* null and pAllowNull is false. */
public static Long getLongValue( String pValue, String pDescriptor, boolean pAllowNull )
throws FileFormatException
{
if ( (pValue == null || pValue.trim().length() == 0 ) && pAllowNull ) return null;
try {
return new Long( pValue.trim() );
} catch (Throwable t) {
throw new FileFormatException("Invalid Long value '" + pValue + "' specified for attribute '" + pDescriptor + "'.");
}
}
/** returns the value of the named attribute as a boolean.
* @param Node the node whose attribute should be retrieved.
* @param String the name of attribute whose value should be retrieved.
* @param boolean the default value to return if a value does not exist for the specified
* attribute, or if the specified attribute is not defined in this Node.
* @return boolean the value of the attribute. If no value was specified for the
* attribute then the default value is returned.
* @exception FileFormatException if the value specified by the attribute can not be converted to a boolean.
*/
public static boolean getBooleanAttribute( Node pNode, String pName, boolean pDefault )
throws FileFormatException
{
Node n = pNode.getAttributes().getNamedItem( pName );
if ( n == null ) return pDefault;
return getBooleanValue( n.getNodeValue(), pName, pDefault );
}
/** converts the specified value into a boolean.
* @param String the value which should be converted.
* @param String a descriptor of what the value is for.
* @param boolean the default value to return if the specified value is null or empty.
* @return boolean the converted value. If the specified value was null or empty
* then the default value is returned.
* @exception FileFormatException if the specified value can not be converted to a boolean.
*/
public static boolean getBooleanValue( String pValue, String pDescriptor, boolean pDefault )
throws FileFormatException
{
if ( pValue == null || pValue.trim().length() == 0 ) return pDefault;
if ( ! pValue.trim().equalsIgnoreCase("true") && ! pValue.trim().equalsIgnoreCase("false") )
throw new FileFormatException("Invalid Boolean value '" + pValue + "' specified for attribute '" + pDescriptor +
"'. Must be [true|false]");
return new Boolean(pValue.trim()).booleanValue();
}
/** returns the value of the named attribute as a Boolean object.
* @param Node the node whose attribute should be retrieved.
* @param String the name of attribute whose value should be retrieved.
* @param Boolean the default value to return if a value does not exist for the specified
* attribute, or if the specified attribute is not defined in this Node.
* @return Boolean the value of the attribute. If no value was specified for the
* attribute then the default value is returned.
* @exception FileFormatException if the value specified by the attribute can not be converted to a boolean.
*/
public static Boolean getBooleanAttribute( Node pNode, String pName, Boolean pDefault )
throws FileFormatException
{
Node n = pNode.getAttributes().getNamedItem( pName );
if ( n == null ) return pDefault;
String v = n.getNodeValue();
if ( v == null || v.length() == 0 ) return pDefault;
return new Boolean( getBooleanValue( v, pName, true ) ); // the default 'true' passed to this call should not never to be used
}
/* a main method for testing these functions */
public static void main( String[] pArgs ) {
String file = "C:\\temp\\registry.xml";
//String file = "/work/systest/qma/temp/registry.xml";
log.info("bea's registry file:=[" + file + "]");
String[] children = { "host", "product", "release" };
try {
List<Node> nodes = getNodes( new File(file), false, children );
if ( nodes == null ) {
System.out.print("Nodes is null.");
} else if ( nodes.size() == 0 ) {
System.out.print("Nodes is empty.");
} else {
Iterator<Node> iter = nodes.iterator();
while ( iter.hasNext() ) {
Node n = iter.next();
log.info("Got Node: " + getAttribute(n, "level") + "/" + getAttribute(n,"ServicePackLevel") );
}
}
} catch (Throwable t) {
t.printStackTrace();
}
log.info("-------------------");
log.info("BEA Version: " + atg.junit.nucleus.TestUtils.getBeaVersion() );
//System.setProperty("bea.home","c:\\bea");
//log.info("BEA Version: " + atg.junit.nucleus.TestUtils.getBeaVersion() );
}
}