You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oodt.apache.org by ke...@apache.org on 2010/07/15 01:03:30 UTC

svn commit: r964249 [2/2] - /incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/SAXParser.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/SAXParser.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/SAXParser.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/SAXParser.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,321 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements.  See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership.  The ASF licenses this
+// file to you 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 org.apache.oodt.commons.util;
+
+import java.io.IOException;
+import java.util.*;
+import org.xml.sax.*;
+
+/** An XML Simple API for XML (SAX) parser.
+ *
+ * Objects of this class are SAX parsers.
+ *
+ * @author Kelly
+ */
+public class SAXParser {
+	/** Construct a SAX Parser.
+	 */
+	SAXParser(javax.xml.parsers.SAXParser parser) {
+		this.parser = parser;
+	}
+
+	/** Returns a list of features that this parser recognizes.
+	 *
+	 * This method will never return null; if no features are recognized, this
+	 * method will return a zero length array.
+	 *
+	 * @return Recognized features.
+	 */
+	public String[] getFeaturesRecognized() {
+		return EMPTY_STRING_ARRAY;
+	}
+
+	/**
+	 * Returns a list of properties that this parser recognizes.
+	 * This method will never return null; if no properties are
+	 * recognized, this method will return a zero length array.
+	 *
+	 * @return Recognized properties.
+	 */
+	public String[] getPropertiesRecognized() {
+		return EMPTY_STRING_ARRAY;
+	}
+
+	/** Resets the parser. */
+	public void reset() {}
+
+
+	/**
+	 * Set the state of any feature in a SAX2 parser.  The parser
+	 * might not recognize the feature, and if it does recognize
+	 * it, it might not be able to fulfill the request.
+	 *
+	 * @param featureId The unique identifier (URI) of the feature.
+	 * @param state The requested state of the feature (true or false).
+	 *
+	 * @exception SAXNotRecognizedException If the requested feature is
+	 *                                      not known.
+	 * @exception SAXNotSupportedException If the requested feature is
+	 *                                     known, but the requested state
+	 *                                     is not supported.
+	 */
+	public void setFeature(String featureId, boolean state) throws SAXNotRecognizedException, SAXNotSupportedException {
+		throw new SAXNotSupportedException("This parser supports no features");
+	}
+
+	/**
+	 * Query the current state of any feature in a SAX2 parser.  The
+	 * parser might not recognize the feature.
+	 *
+	 * @param featureId The unique identifier (URI) of the feature
+	 *                  being set.
+	 *
+	 * @return The current state of the feature.
+	 *
+	 * @exception SAXNotRecognizedException If the requested feature is
+	 *                                      not known.
+	 */
+	public boolean getFeature(String featureId) throws SAXNotRecognizedException, SAXNotSupportedException {
+		throw new SAXNotSupportedException("This parser supports no features");
+	}
+
+	/**
+	 * Set the value of any property in a SAX2 parser.  The parser
+	 * might not recognize the property, and if it does recognize
+	 * it, it might not support the requested value.
+	 *
+	 * @param propertyId The unique identifier (URI) of the property
+	 *                   being set.
+	 * @param value The value to which the property is being set.
+	 *
+	 * @exception SAXNotRecognizedException If the requested property is
+	 *                                      not known.
+	 * @exception SAXNotSupportedException If the requested property is
+	 *                                     known, but the requested
+	 *                                     value is not supported.
+	 */
+	public void setProperty(String propertyId, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
+		throw new SAXNotSupportedException("This parser supports no properties");
+	}
+
+	/**
+	 * Return the current value of a property in a SAX2 parser.
+	 * The parser might not recognize the property.
+	 *
+	 * @param propertyId The unique identifier (URI) of the property
+	 *                   being set.
+	 *
+	 * @return The current value of the property.
+	 *
+	 * @exception SAXNotRecognizedException If the requested property is
+	 *                                      not known.
+	 *
+	 */
+	public Object getProperty(String propertyId) throws SAXNotRecognizedException, SAXNotSupportedException {
+		throw new SAXNotSupportedException("This parser supports no properties");
+	}
+
+	/**
+	 * Returns true if the specified feature is recognized.
+	 *
+	 */
+	public boolean isFeatureRecognized(String featureId) {
+		return false;
+	}
+
+
+	/**
+	 * Returns true if the specified property is recognized.
+	 *
+	 */
+	public boolean isPropertyRecognized(String propertyId) {
+		return false;
+	}
+
+	/**
+	 * return the locator being used by the parser
+	 *
+	 * @return the parser's active locator
+	 */
+	public final Locator getLocator() {
+		throw new IllegalStateException("This parser doesn't support locators");
+	}
+
+	/**
+	 * Sets the resolver used to resolve external entities. The EntityResolver
+	 * interface supports resolution of public and system identifiers.
+	 *
+	 * @param resolver The new entity resolver. Passing a null value will
+	 *                 uninstall the currently installed resolver.
+	 */
+	public void setEntityResolver(EntityResolver resolver) {
+		try {
+			parser.getXMLReader().setEntityResolver(resolver);
+		} catch (SAXException ignore) {}
+	}
+
+	/**
+	 * Return the current entity resolver.
+	 *
+	 * @return The current entity resolver, or null if none
+	 *         has been registered.
+	 * @see #setEntityResolver
+	 */
+	public EntityResolver getEntityResolver() {
+		throw new IllegalStateException("This parser supports only setting of the entity resolver, not querying");
+	}
+
+	/**
+	 * Sets the error handler.
+	 *
+	 * @param handler The new error handler.
+	 */
+	public void setErrorHandler(ErrorHandler handler) {
+		try {
+			parser.getXMLReader().setErrorHandler(handler);
+		} catch (SAXException ignore) {}
+	}
+
+	/**
+	 * Return the current error handler.
+	 *
+	 * @return The current error handler, or null if none
+	 *         has been registered.
+	 * @see #setErrorHandler
+	 */
+	public ErrorHandler getErrorHandler() {
+		throw new IllegalStateException("This parser supports only setting of the error handler, not querying");
+	}
+
+	/**
+	 * Parses the specified input source.
+	 *
+	 * @param source The input source.
+	 *
+	 * @exception org.xml.sax.SAXException Throws exception on SAX error.
+	 * @exception java.io.IOException Throws exception on i/o error.
+	 */
+	public void parse(InputSource source) throws SAXException, IOException {
+		parser.getXMLReader().parse(source);
+	}
+
+	/**
+	 * Parses the input source specified by the given system identifier.
+	 * <p>
+	 * This method is equivalent to the following:
+	 * <pre>
+	 *     parse(new InputSource(systemId));
+	 * </pre>
+	 *
+	 * @param systemID The input source.
+	 *
+	 * @exception org.xml.sax.SAXException Throws exception on SAX error.
+	 * @exception java.io.IOException Throws exception on i/o error.
+	 */
+	public void parse(String systemID) throws SAXException, IOException {
+		parser.getXMLReader().parse(systemID);
+	}
+
+
+	/**
+	 * Set the locale to use for messages.
+	 *
+	 * @param locale The locale object to use for localization of messages.
+	 *
+	 * @exception SAXException An exception thrown if the parser does not
+	 *                         support the specified locale.
+	 */
+	public void setLocale(Locale locale) throws SAXException {
+		throw new IllegalStateException("This parser doesn't support localized error messages");
+	}
+
+	/**
+	 * Allow an application to register a DTD event handler.
+	 *
+	 * <p>If the application does not register a DTD handler, all DTD
+	 * events reported by the SAX parser will be silently ignored.</p>
+	 *
+	 * <p>Applications may register a new or different handler in the
+	 * middle of a parse, and the SAX parser must begin using the new
+	 * handler immediately.</p>
+	 *
+	 * @param handler The DTD handler.
+	 * @exception java.lang.NullPointerException If the handler 
+	 *            argument is null.
+	 * @see #getDTDHandler
+	 */
+	public void setDTDHandler(DTDHandler handler) {
+		try {
+			parser.getXMLReader().setDTDHandler(handler);
+		} catch (SAXException ignore) {}
+	}
+
+	/**
+	 * Return the current DTD handler.
+	 *
+	 * @return The current DTD handler, or null if none
+	 *         has been registered.
+	 * @see #setDTDHandler
+	 */
+	public DTDHandler getDTDHandler() {
+		try {
+			return parser.getXMLReader().getDTDHandler();
+		} catch (SAXException ex) {
+			throw new IllegalStateException("Unexpected SAXException: " + ex.getMessage());
+		}
+	}
+
+	/**
+	 * Allow an application to register a content event handler.
+	 *
+	 * <p>If the application does not register a content handler, all
+	 * content events reported by the SAX parser will be silently
+	 * ignored.</p>
+	 *
+	 * <p>Applications may register a new or different handler in the
+	 * middle of a parse, and the SAX parser must begin using the new
+	 * handler immediately.</p>
+	 *
+	 * @param handler The content handler.
+	 * @exception java.lang.NullPointerException If the handler 
+	 *            argument is null.
+	 * @see #getContentHandler
+	 */
+	public void setContentHandler(ContentHandler handler) {
+		try {
+			parser.getXMLReader().setContentHandler(handler);
+		} catch (SAXException ignore) {}
+	}
+
+	/**
+	 * Return the current content handler.
+	 *
+	 * @return The current content handler, or null if none
+	 *         has been registered.
+	 * @see #setContentHandler
+	 */
+	public ContentHandler getContentHandler() {
+		try {
+			return parser.getXMLReader().getContentHandler();
+		} catch (SAXException ex) {
+			throw new IllegalStateException("Unexpected SAXException: " + ex.getMessage());
+		}
+
+	}
+
+	private static final String[] EMPTY_STRING_ARRAY = new String[0];
+	private javax.xml.parsers.SAXParser parser;
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/ScreenLogger.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/ScreenLogger.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/ScreenLogger.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/ScreenLogger.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,52 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements.  See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership.  The ASF licenses this
+// file to you 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 org.apache.oodt.commons.util;
+
+import java.io.*;
+import org.apache.oodt.commons.io.*;
+
+/**
+	The <code>ScreenLogger</code> class is intended to be used with the
+	{@link Log} class in order to setup the System.err as a {@link LogListener}.
+
+	@author S. Hardman
+	@version $Revision: 1.1 $
+*/
+public class ScreenLogger extends WriterLogger {
+
+	/**
+		Constructor given no arguments.
+
+		This constructor will specify System.err as the output stream
+		and then call the other constructor with the output stream argument.
+	*/
+	public ScreenLogger () {
+		this(System.err);
+	}
+
+
+	/**
+		Constructor given an output stream.
+
+		This constructor calls the {@link WriterLogger} constructor with the
+		same signature.
+
+		@param outputStream The output stream representing the log destination.
+	*/
+	public ScreenLogger (OutputStream outputStream) {
+		super(outputStream);
+	}
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Utility.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Utility.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Utility.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Utility.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,211 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements.  See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership.  The ASF licenses this
+// file to you 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 org.apache.oodt.commons.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+/** Miscellaneous utilities.
+ *
+ * This class contains various miscellaneous functions as static methods.
+ *
+ * @author Kelly
+ */
+public class Utility {
+	/** Load properties from a resource.
+	 *
+	 * This loads properties from the given resource (relative to the given class)
+	 * into the given properties object.  If any error occurs, this method prints a
+	 * message to stderr but otherwise takes no special action.
+	 *
+	 * <p>You typically use this to merge properties for your application into the
+	 * System properties by calling this method as follows:
+	 * <pre>Utility.loadProperties(System.getProperties(), MyClass.class,
+	 * "MyClass.properties");</pre> This adds the properties from the file
+	 * <code>MyClass.properties</code> (which must exist in the same directory as the
+	 * file <code>MyClass.class</code>, whether in the filesystem or in a jar) into
+	 * the system properties.  You can then fetch these properties from anywhere in
+	 * your program with <code>System.getProperty(String)</code>,
+	 * <code>Integer.getInteger</code>, etc.
+	 *
+	 * <p>You can also use the method to load properties into a newly created
+	 * properties object that you provide.  This keeps your properties separate, but
+	 * then you have to pass a properties object all over the place, and you can't
+	 * take advantage of non-String properties through methods like
+	 * <code>Long#getLong(String)</code>, etc.
+	 *
+	 * @param props The properties object to load.
+	 * @param clazz The class used to locate the resource.
+	 * @param resourceName The name of the resource.
+	 */
+	public static void loadProperties(Properties props, final Class clazz, final String resourceName) {
+		BufferedInputStream in = null;
+		try {
+			in = new BufferedInputStream(clazz.getResourceAsStream(resourceName));
+			props.load(in);
+		} catch (IOException ex) {
+			System.err.println("I/O exception while loading \"" + resourceName + "\": " + ex.getMessage());
+		} finally {
+			if (in != null) try {
+				in.close();
+			} catch (IOException ignore) {}
+		}
+	}
+
+	/** Parse a list.
+	 *
+	 * This yields an iterator created from a list where commas (and optional leading
+	 * and trailing whitespace) separate each element.  Each element will occur only
+	 * once in the iterator regardless of how many times it appeared in the string.
+	 *
+	 * @param list The list to parse.
+	 * @return The iterator over unique elements in the <var>list</var>.
+	 */
+	public static Iterator parseCommaList(final String list) {
+		if (list == null) return new Iterator() {
+			public boolean hasNext() {
+				return false;
+			}
+			public Object next() {
+				throw new java.util.NoSuchElementException("There weren't ANY elements in this iterator, ever");
+			}
+			public void remove() {
+				throw new UnsupportedOperationException("Can't remove elements from this iterator");
+			}
+		};
+		HashSet set = new HashSet();
+		StringTokenizer tokens = new StringTokenizer(list, ",");
+		while (tokens.hasMoreTokens())
+			set.add(tokens.nextToken().trim());
+		return set.iterator();
+	}
+
+	/** Asynchronously redirect an input stream onto an output stream.
+	 *
+	 * The output stream is never closed.
+	 *
+	 * @param in Input stream to redirect.
+	 * @param out Where to redirect <var>in</var>.
+	 */
+	public static void redirect(final InputStream in, final OutputStream out) {
+		new Thread() {
+			public void run() {
+				try {
+					byte[] buf = new byte[1024];
+					for (;;) {
+						int numRead = in.read(buf);
+						if (numRead == -1) {
+							in.close();
+							break;
+						}
+						out.write(buf, 0, numRead);
+					}
+				} catch (IOException ex) {
+					try {
+						in.close();
+					} catch (IOException ignore) {}
+				}
+			}
+		}.start();
+	}
+
+	/** Log statistics on memory to stderr.
+	 *
+	 * @param msg Text to include in log.
+	 */
+	public static void logMemoryStats(String msg) {
+		Runtime rt = Runtime.getRuntime();
+		System.err.println(msg + ": total=" + (rt.totalMemory() / 1024) + "KB, free=" + (rt.freeMemory() / 1024) + "KB");
+	}
+
+	/** Check string s is numeric.  Numeric strings include 5.7, -3.9, 14.981E16, etc.
+         *
+         * @param s Text to be checked.
+	 * @return True is <var>s</var> is a numeric string.
+         */
+	public static boolean isNumeric(String s) {
+                try {
+                        Double.parseDouble(s);
+                } catch (NumberFormatException ex) {
+                         return false;
+                }
+                return true;
+        }
+
+	/**
+	 * Delete a file or directory.  If <var>file</var> references a directory, it
+	 * recursively deletes all the directory tree.
+	 *
+	 * @param file File, directory, or other filesystem artifact to delete.
+	 * @return True if <var>file</var> was deleted, false otherwise.
+	 */
+	public static boolean delete(File file) {
+		if (file.isDirectory()) {
+			File[] entries = file.listFiles();
+			for (int i = 0; i < entries.length; ++i)
+				if (!delete(entries[i]))
+					return false;
+		}
+		return file.delete();
+	}
+
+   /**
+    * This method will escape any single quotes found in the input string
+    * and return the escaped string. This will ready the string for
+    * insertion into a database. The single quote is escaped by inserting
+    * an additional single quote in front of it in the string. If some
+    * considerate developer has already escaped the single quotes in the
+    * input string, this method will essentially do nothing.
+    *
+    * @param inputString The string to be escaped.
+    * @return The escaped string.
+    */
+   public static String escapeSingleQuote(String inputString) {
+
+      int index = inputString.indexOf('\'');
+      if (index == -1) {
+         return (inputString);
+      }
+
+      String outputString = inputString;
+      while (index != -1) {
+
+         // If the single quote is the last character in the string or 
+         // the next character is not another single quote, insert a
+         // single quote in front of the current single quote.
+         if ((index == (outputString.length() - 1)) || (outputString.charAt(index + 1) != '\'')) {
+            outputString = outputString.substring(0, index) + "'" + outputString.substring(index);
+         }
+
+         // If we are not at the end of the string, check for another
+         // single quote.
+         if ((index + 2) <= (outputString.length() - 1)) {
+            index = outputString.indexOf('\'', index + 2);
+         }
+         else {
+            index = -1;
+         }
+      }
+      return (outputString);
+   }
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XML.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XML.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XML.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XML.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements.  See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership.  The ASF licenses this
+// file to you 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.
+//
+// Portions of this code come from the Apache XML Project's Xerces 1.0.3 XML Parser
+// (specifically, the functions escape and getEntityRef).  Apache license applies:
+//
+// The Apache Software License, Version 1.1
+//
+// Copyright (c) 1999 The Apache Software Foundation.  All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+//     conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+//    of conditions and the following disclaimer in the documentation and/or other materials
+//    provided with the distribution.
+//
+// 3. The end-user documentation included with the redistribution, if any, must include
+//    the following acknowledgment:
+//
+//    "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)."
+//
+//    Alternately, this acknowledgment may appear in the software itself,
+//    if and wherever such third-party acknowledgments normally appear.
+//
+// 4. The names "Xerces" and "Apache Software Foundation" must not be used to endorse or
+//    promote products derived from this software without prior written permission. For
+//    written permission, please contact apache@apache.org.
+//
+// 5. Products derived from this software may not be called "Apache", nor may "Apache"
+//    appear in their name, without prior written permission of the Apache Software
+//    Foundation.
+//
+// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
+// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+// ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// $Id: XML.java,v 1.2 2005-05-01 22:49:55 cmattmann Exp $
+
+package org.apache.oodt.commons.util;
+
+import java.io.*;
+import java.util.*;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.OutputKeys;
+
+/** XML services.
+ *
+ * This class provides several XML convenience services and encapsulates the underlying
+ * XML implementation, allowing it to vary without impacting developers.
+ *
+ * @author Kelly
+ */
+public class XML {
+	private static DocumentBuilder getStandardDocumentBuilder() {
+		try {
+			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+			factory.setCoalescing(false);
+			factory.setExpandEntityReferences(false);
+			factory.setIgnoringComments(false);
+			factory.setIgnoringElementContentWhitespace(true);
+			factory.setNamespaceAware(true);
+			factory.setValidating(true);
+			return factory.newDocumentBuilder();
+		} catch (ParserConfigurationException ex) {
+			throw new IllegalStateException("Unexpected ParserConfigurationException: " + ex.getMessage());
+		}
+	}
+
+	/** Get the DOM implementation.
+	 *
+	 * @return The DOM implementation.
+	 */
+	public static DOMImplementation getDOMImplementation() {
+		return getStandardDocumentBuilder().getDOMImplementation();
+	}
+
+	/** Create a DOM document.
+	 *
+	 * @return A new DOM document.
+	 */
+	public static Document createDocument() {
+		return getStandardDocumentBuilder().newDocument();
+	}
+
+	/** Create a DOM parser.
+	 *
+	 * This method creates a new DOM parser that has validation turned on and
+	 * ignorable whitespace not included, and has a default error handler that prints
+	 * error messages and warnings to the standard error stream.
+	 *
+	 * @return A new DOM parser.
+	 */
+	public static DOMParser createDOMParser() {
+		DocumentBuilder builder = getStandardDocumentBuilder();
+		builder.setEntityResolver(ENTERPRISE_ENTITY_RESOLVER);
+		builder.setErrorHandler(new ErrorHandler() {
+			public void error(SAXParseException ex) {
+				System.err.println("Parse error: " + ex.getMessage());
+				ex.printStackTrace();
+			}
+			public void warning(SAXParseException ex) {
+				System.err.println("Parse warning: " + ex.getMessage());
+			}
+			public void fatalError(SAXParseException ex) {
+				System.err.println("Fatal parse error: " + ex.getMessage());
+				ex.printStackTrace();
+			}
+		});
+		return new DOMParser(builder);
+	}
+
+	/** Create a SAX parser.
+	 *
+	 * This method creates a new, default SAX parser.  It's set up with a default
+	 * error handler that just prints messages to the standard error stream.
+	 *
+	 * @return A new SAX parser.
+	 */
+	public static SAXParser createSAXParser() {
+		try {
+			SAXParserFactory factory = SAXParserFactory.newInstance();
+			factory.setNamespaceAware(false);
+			factory.setValidating(false);
+			javax.xml.parsers.SAXParser saxParser = factory.newSAXParser();
+			saxParser.getXMLReader().setEntityResolver(ENTERPRISE_ENTITY_RESOLVER);
+			saxParser.getXMLReader().setErrorHandler(new ErrorHandler() {
+				public void error(SAXParseException ex) {
+					System.err.println("Parse error: " + ex.getMessage());
+				}
+				public void warning(SAXParseException ex) {
+					System.err.println("Parse warning: " + ex.getMessage());
+				}
+				public void fatalError(SAXParseException ex) {
+					System.err.println("Fatal parse error: " + ex.getMessage());
+				}
+			});
+			SAXParser p = new SAXParser(saxParser);
+			return p;
+		} catch (ParserConfigurationException ex) {
+			throw new IllegalStateException("Unexpected ParserConfigurationException: " + ex.getMessage());
+		} catch (SAXException ex) {
+			throw new IllegalStateException("Unexpected SAXException: " + ex.getMessage());
+		}
+	}
+
+	/** Serialize an XML DOM document into a String.
+	 *
+	 * This method takes a DOM document and pretty-prints (or pretty-serializes, in
+	 * XML parlance) it into a string.
+	 *
+	 * @param doc The document.
+	 * @param omitXMLDeclaration True if we should omit the XML declaration, false to keep the XML declaration.
+	 * @return The pretty-serialized, stringified, document.
+	 */
+	public static String serialize(Document doc, boolean omitXMLDeclaration) {
+		StringWriter writer = new StringWriter();
+		try {
+			serialize(doc, writer, omitXMLDeclaration);
+		} catch (IOException cantHappen) {}
+		return writer.getBuffer().toString();
+	}
+
+	/** Serialize an XML DOM document into a String.
+	 *
+	 * This method takes a DOM document and pretty-prints (or pretty-serializes, in
+	 * XML parlance) it into a string.
+	 *
+	 * @param doc The document.
+	 * @return The pretty-serialized, stringified, document.
+	 */
+	public static String serialize(Document doc) {
+		return serialize(doc, /*omitXMLDeclaration*/false);
+	}
+
+	/** Serialize an XML DOM document into a writer.
+	 *
+	 * This method takes a DOM document and pretty-prints (or pretty-serializes, in
+	 * XML parlance) it into a writer.
+	 *
+	 * @param doc The document.
+	 * @param writer Where to write it.
+	 * @param omitXMLDeclaration True if we should omit the XML declaration, false to keep the XML declaration.
+	 * @throws IOException If an I/O error occurs.
+	 */
+	public static void serialize(Document doc, Writer writer, boolean omitXMLDeclaration) throws IOException {
+		try {
+			TransformerFactory factory = TransformerFactory.newInstance();
+			Transformer transformer = factory.newTransformer();
+			
+			//update 05/01/2005
+			//author: Chris Mattmann
+			//set properties to pretty print
+			//and also to include the DOCTYPE when serializing the XML
+			
+			//only set this if it's not null else we get a nice NullPointerException
+			if(doc.getDoctype().getPublicId() != null){
+				transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());			    
+			}
+
+			//only set this if it's not null else we get a nice NullPointerException
+			if(doc.getDoctype().getSystemId() != null){
+				transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());			    
+			}
+
+			transformer.setOutputProperty(OutputKeys.INDENT,"yes");
+			
+			DOMSource source = new DOMSource(doc);
+			StreamResult result = new StreamResult(writer);
+			transformer.transform(source, result);
+		} catch (TransformerConfigurationException ex) {
+			throw new IllegalStateException("Unexpected TransformerConfigurationException: " + ex.getMessage());
+		} catch (TransformerException ex) {
+			throw new IllegalStateException("Unexpected TransformerException: " + ex.getMessage());
+		}
+	}
+
+	/** Serialize an XML DOM document into a writer.
+	 *
+	 * This method takes a DOM document and pretty-prints (or pretty-serializes, in
+	 * XML parlance) it into a writer.
+	 *
+	 * @param doc The document.
+	 * @param writer Where to write it.
+	 * @throws IOException If an I/O error occurs.
+	 */
+	public static void serialize(Document doc, Writer writer) throws IOException {
+		serialize(doc, writer, /*omitXMLDeclaration*/false);
+	}
+
+	/** Parse the given XML document into a DOM tree.
+	 *
+	 * @param inputSource The XML document to parse.
+	 * @return A DOM tree for the given XML document.
+	 * @throws SAXException If a parse error occurs.
+	 * @throws IOException If an I/O error occurs.
+	 */
+	public static Document parse(InputSource inputSource) throws SAXException, IOException {
+		DOMParser parser = XML.createDOMParser();
+		parser.parse(inputSource);
+		return parser.getDocument();
+	}
+
+	/** Parse the given XML document into a DOM tree.
+	 *
+	 * @param string The XML document to parse.
+	 * @return A DOM tree for the given XML document.
+	 * @throws SAXException If a parse error occurs.
+	 */
+	public static Document parse(String string) throws SAXException {
+		Document doc = null;
+		try {
+			DOMParser parser = XML.createDOMParser();
+			StringReader reader = new StringReader(string);
+			InputSource inputSource = new InputSource(reader);
+			doc = parse(inputSource);
+			reader.close();
+		} catch (IOException cantHappen) {
+			cantHappen.printStackTrace();
+			throw new RuntimeException("I/O exception " + cantHappen.getClass().getName()
+				+ " can NOT have happened, yet it did!  Message: " + cantHappen.getMessage());
+		}
+		return doc;
+	}
+
+	/** Parse the given XML document into a DOM tree.
+	 *
+	 * @param reader The XML document to parse.
+	 * @return A DOM tree for the given XML document.
+	 * @throws SAXException If a parse error occurs.
+	 * @throws IOException If an I/O error occurs.
+	 */
+	public static Document parse(Reader reader) throws SAXException, IOException {
+		return parse(new InputSource(reader));
+	}
+
+	/** Parse the given XML document into a DOM tree.
+	 *
+	 * @param inputStream The XML document to parse.
+	 * @return A DOM tree for the given XML document.
+	 * @throws SAXException If a parse error occurs.
+	 * @throws IOException If an I/O error occurs.
+	 */
+	public static Document parse(InputStream inputStream) throws SAXException, IOException {
+		return parse(new InputStreamReader(inputStream));
+	}
+
+	/** Add a repeating child element with text from the given collection to the given node.
+	 *
+	 * For example, if <var>values</var> is a {@link java.util.List} with strings items
+	 * "a", "b", and "c", and <var>name</var> is "value", then the XML document will
+	 * have
+	 * <pre>&lt;value&gt;a&lt;/value&gt;
+	 * &lt;value&gt;b&lt;/value&gt;
+	 * &lt;value&gt;c&lt;/value&gt;</pre>
+	 * appended to <var>node</var>.
+	 *
+	 * @param node Node to which to add child elements.
+	 * @param name Name to give each child element.
+	 * @param values Collection of values to assign to each child element, in iterator order.
+	 * @throws DOMException If a DOM error occurs.
+	 */
+	public static void add(Node node, String name, Collection values) throws DOMException {
+		for (Iterator i = values.iterator(); i.hasNext();)
+			add(node, name, i.next());
+	}
+
+	/** Add a child element with the given text to the given element.
+	 *
+	 * This method modifies your DOM tree so that
+	 * <pre>&lt;node&gt;
+	 *   ...
+	 * &lt;/node&gt;</pre>
+	 * becomes
+	 * <pre>&lt;node&gt;
+	 *   ...
+	 *   &lt;name&gt;text&gt;/name&gt;
+	 * &lt;/node&gt;</pre>
+	 *
+	 * Adding a null <var>name</var> does nothing.  Adding null <var>text</var>
+	 * won't add the element.
+	 *
+	 * @param node Node to which to add a child element.
+	 * @param name Name of the child element to add to <var>node</var>.
+	 * @param text What text the text-node child the child element named <var>name</var> should have.  If null,
+	 * nothing happens.
+	 * @throws DOMException If a DOM error occurs.
+	 */
+	public static void addNonNull(Node node, String name, String text) throws DOMException {
+		if (text == null) return;
+		add(node, name, text);
+	}
+
+	/** Add a child element with the given text to the given element.
+	 *
+	 * This method modifies your DOM tree so that
+	 * <pre>&lt;node&gt;
+	 *   ...
+	 * &lt;/node&gt;</pre>
+	 * becomes
+	 * <pre>&lt;node&gt;
+	 *   ...
+	 *   &lt;name&gt;text&gt;/name&gt;
+	 * &lt;/node&gt;</pre>
+	 *
+	 * Adding a null <var>name</var> does nothing.  Adding null <var>text</var>
+	 * results in an empty <var>name</var> tag.
+	 *
+	 * @param node Node to which to add a child element.
+	 * @param name Name of the child element to add to <var>node</var>.
+	 * @param text What text the text-node child the child element named <var>name</var> should have.
+	 * @throws DOMException If a DOM error occurs.
+	 */
+	public static void add(Node node, String name, String text) throws DOMException {
+		if (name == null) return;
+		if (node == null) throw new IllegalArgumentException("Can't add to a null node");
+		Document doc = node.getOwnerDocument();
+		Element element = doc.createElement(name);
+		if (text != null) element.appendChild(doc.createTextNode(text));
+		node.appendChild(element);
+	}
+
+	/** Add a child element with the string representation of the given
+	 * <var>object</var> to the given <var>node</var>.
+	 *
+	 * This method modifies your DOM tree so that
+	 * <pre>&lt;node&gt;
+	 *   ...
+	 * &lt;/node&gt;</pre>
+	 * becomes
+	 * <pre>&lt;node&gt;
+	 *   ...
+	 *   &lt;name&gt;string-rep&gt;/name&gt;
+	 * &lt;/node&gt;</pre>
+	 *
+	 * Adding a null <var>name</var> does nothing.  Adding null <var>object</var>
+	 * results in an empty <var>name</var> tag.
+	 *
+	 * @param node Node to which to add a child element.
+	 * @param name Name of the child element to add to <var>node</var>.
+	 * @param object The string representation of the object to have as the text-node
+	 * child the child element named <var>name</var>.
+	 * @throws DOMException If a DOM error occurs.
+	 */
+	public static void add(Node node, String name, Object object) throws DOMException {
+		add(node, name, object == null? null : object.toString());
+	}
+
+	/** Get unwrapped text from the given DOM node
+	 *
+	 * This method unwraps any wrapped text.  For example, if the document contains
+	 * <pre>&lt;node&gt;Hello, world.  This is
+	 *    my first document.
+         * &lt;/node&gt;</pre>
+	 * then the node's unwrapped text is
+	 * <pre>Hello, world.  This is my first document.</pre>
+	 * while the {@link #text} method would return the wrapped value
+	 * <pre>Hello, world.  This is
+	 *    my first document.</pre>
+	 *
+	 * <p>In other words, it collects the text nodes under the given node and replaces
+	 * strings of newlines and spaces with a single space.  Unwrapping a null node
+	 * returns a null string.
+	 *
+	 * @param node The node.
+	 * @return The text in its children, unwrapped.
+	 */
+	public static String unwrappedText(Node node) {
+		if (node == null) return null;
+		StringBuffer buffer = new StringBuffer();
+		StringBuffer wrapped = new StringBuffer(text1(node, buffer));
+		boolean newline = false;
+		for (int i = 0; i < wrapped.length(); ++i) {
+			if (newline == false) {
+				if (wrapped.charAt(i) == '\n') {
+					newline = true;
+					wrapped.setCharAt(i, ' ');
+				}
+			} else {
+				if (Character.isWhitespace(wrapped.charAt(i))) {
+					wrapped.deleteCharAt(i);
+					--i;
+				} else
+					newline = false;
+			}
+		}
+		return wrapped.toString().trim();
+	}
+
+	/** Get the text from the given DOM node.
+	 *
+	 * Getting text from a null node gives you a null string.
+	 *
+	 * @param node The node.
+	 * @return The text in its children.
+	 */
+	public static String text(Node node) {
+		// [ return text(node) ]
+		StringBuffer buffer = new StringBuffer();
+		return text1(node, buffer);
+	}
+
+	/** Dump the structure of the DOM tree rooted at the given node to the given writer.
+	 *
+	 * This outputs the tree structure including the type of each node, its name, and
+	 * its value.  Note that for many nodes, the name isn't useful (the name of text
+	 * nodes, for example, is <code>#text</code>), and for many nodes, the value is
+	 * null.
+	 *
+	 * @param writer The writer to which write the tree structure.
+	 * @param node The tree to output.
+	 */
+	public static void dump(PrintWriter writer, Node node) {
+		dump(writer, node, 0);
+	}
+
+	/** Remove all comments from the given document node's subtree.
+	 *
+	 * @param node Node from which to search for comments to nuke.
+	 */
+	public static void removeComments(Node node) {
+		List commentNodes = new ArrayList();
+		findCommentNodes(commentNodes, node);
+		for (Iterator i = commentNodes.iterator(); i.hasNext();) {
+			Node commentNode = (Node) i.next();
+			commentNode.getParentNode().removeChild(commentNode);
+		}
+	}
+
+	/** The resolver for entities for the JPL enterprise. */
+	public static final EntityResolver ENTERPRISE_ENTITY_RESOLVER = new EnterpriseEntityResolver();
+
+	/** An empty XML DOM document.  This is handy for some basic operations, and for
+	 * fetching the DOM implementation.
+	 */
+	public static final Document EMPTY_DOCUMENT = org.apache.oodt.commons.util.XML.createDocument();
+
+	/** Identifies the last printable character in the Unicode range that is supported
+	 * by the encoding used with this serializer.  For 8-bit encodings this will be either
+	 * 0x7E or 0xFF.  For 16-bit encodings this will be 0xFFFF. Characters that are not
+	 * printable will be escaped using character references.
+	 *
+	 * <p>Taken from Xerces 1.0.3.  Apache license applies; see source code for
+	 * license.
+	 *
+	 */
+	private static int LAST_PRINTABLE = 0x7E;
+
+	/** Escapes a string so it may be printed as text content or attribute value. Non
+	 * printable characters are escaped using character references.  Where the format
+	 * specifies a deault entity reference, that reference is used
+	 * (e.g. <code>&amp;lt;</code>).
+	 *
+	 * <p>Taken from Xerces 1.0.3.  Apache license applies; see source code for
+	 * license.
+	 *
+	 * @param source The string to escape
+	 * @return The escaped string
+	 */
+	public static String escape(String source) {
+		StringBuffer    result;
+		int             i;
+		char            ch;
+		String          charRef;
+        
+		result = new StringBuffer(source.length());
+		for (i = 0; i < source.length(); ++i) {
+			ch = source.charAt(i);
+			// If the character is not printable, print as character
+			// reference.  Non printables are below ASCII space but not tab or
+			// line terminator, ASCII delete, or above a certain Unicode
+			// threshold.
+			if ((ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r') || ch > LAST_PRINTABLE || ch == 0xF7)
+				result.append("&#").append(Integer.toString(ch)).append(';');
+			else {
+				// If there is a suitable entity reference for this
+				// character, print it. The list of available entity
+				// references is almost but not identical between XML and
+				// HTML.
+				charRef = getEntityRef(ch);
+				if (charRef == null) result.append(ch);
+				else                 result.append('&').append(charRef).append(';');
+			}
+		}
+		return result.toString();
+	}
+
+	/** Find all comment nodes under the given node and add them to the given list.
+	 *
+	 * @param list List to add to.
+	 * @param node Node to search.
+	 */
+	private static void findCommentNodes(List list, Node node) {
+		if (node.getNodeType() == Node.COMMENT_NODE)
+			list.add(node);
+		else {
+			NodeList children = node.getChildNodes();
+			for (int i = 0; i < children.getLength(); ++i) {
+				findCommentNodes(list, children.item(i));
+			}
+		}
+	}
+
+	/** Get the entity reference for the given character.
+	 *
+	 * Taken from Xerces 1.0.3; see source code for license.
+	 */
+	private static String getEntityRef(char ch) {
+		// Encode special XML characters into the equivalent character references.
+		// These five are defined by default for all XML documents.
+		switch (ch) {
+			case '<':  return "lt";
+			case '>':  return "gt";
+			case '"':  return "quot";
+			case '\'': return "apos";
+			case '&':  return "amp";
+		}
+		return null;
+	}
+
+	/** Get the text from the child node using the given buffer.
+	 *
+	 * @param node The node.
+	 * @param buffer The buffer to use.
+	 * @return The text.
+	 */
+	private static String text1(Node node, StringBuffer buffer) {
+		for (Node ch = node.getFirstChild(); ch != null; ch = ch.getNextSibling()) {
+			if (ch.getNodeType() == Node.ELEMENT_NODE || ch.getNodeType() == Node.ENTITY_REFERENCE_NODE)
+				buffer.append(text(ch));
+			else if (ch.getNodeType() == Node.TEXT_NODE)
+				buffer.append(ch.getNodeValue());
+		}
+		return buffer.toString();
+	}
+
+	/** Dump the structure of the DOM tree rooted at the given node to the given writer,
+	 * indenting the contents.
+	 *
+	 * @param indentAmt The number of spaces to indent the output of this node;
+	 * children are indented two more than this amount.
+	 * @param writer The writer to which write the tree structure.
+	 * @param node The tree to output.
+	 */
+	private static void dump(PrintWriter writer, Node node, int indentAmt) {
+		for (int i = 0; i < indentAmt; ++i)
+			writer.print(' ');
+		writer.println(typeOf(node) + "(" + node.getNodeName() + ", " + node.getNodeValue() + ")");
+		NodeList children = node.getChildNodes();
+		for (int i = 0; i < children.getLength(); ++i)
+			dump(writer, children.item(i), indentAmt + 2);
+	}
+
+	/** Return a human-readable representation of the type of the given node.
+	 *
+	 * For example, an attribute node returns <code>Attribute</code>, while an element
+	 * node returns <code>Element</code>.
+	 *
+	 * @param node The node.
+	 * @return The name of the node's type.
+	 */
+	private static String typeOf(Node node) {
+		switch (node.getNodeType()) {
+			case Node.ATTRIBUTE_NODE:              return "Attribute";
+			case Node.CDATA_SECTION_NODE:          return "CDATA-Section";
+			case Node.COMMENT_NODE:                return "Comment";
+			case Node.DOCUMENT_FRAGMENT_NODE:      return "Document-Fragment";
+			case Node.DOCUMENT_NODE:               return "Document";
+			case Node.DOCUMENT_TYPE_NODE:          return "Document-Type";
+			case Node.ELEMENT_NODE:                return "Element";
+			case Node.ENTITY_NODE:                 return "Entity";
+			case Node.ENTITY_REFERENCE_NODE:       return "Entity-Ref";
+			case Node.NOTATION_NODE:               return "Notation";
+			case Node.PROCESSING_INSTRUCTION_NODE: return "Proc-Instr";
+			case Node.TEXT_NODE:                   return "Text";
+			default:                               return "Unknown!";
+		}
+	}
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPC.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPC.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPC.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPC.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,220 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements.  See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership.  The ASF licenses this
+// file to you 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 org.apache.oodt.commons.util;
+
+import java.io.*;
+import java.util.*;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+/** XML-RPC utilities.
+ *
+ * This class provides several XML-RPC utilities.
+ *
+ * @author Kelly
+ */
+public class XMLRPC {
+	/** Build an XML-RPC method call.
+	 *
+	 * This may throw {@link IllegalArgumentException} if the <var>params</var>
+	 * contains an object that's incompatible with XML-RPC.
+	 *
+	 * @param name Name of the method to call.
+	 * @param params Parameters to pass to the call.
+	 * @return An XML string encapsulationg the call.
+	 * @throws DOMException If we can't construct the call.
+	 */
+	public static byte[] createMethodCall(String name, Collection params) throws DOMException {
+		Document doc = XML.createDocument();
+		Element methodCallElement = doc.createElement("methodCall");
+		doc.appendChild(methodCallElement);
+		XML.add(methodCallElement, "methodName", name);
+		if (params != null && !params.isEmpty()) {
+			Element paramsElement = doc.createElement("params");
+			methodCallElement.appendChild(paramsElement);
+			for (Iterator i = params.iterator(); i.hasNext();)
+				paramsElement.appendChild(createValueElement(doc, i.next()));
+		}
+		return XML.serialize(doc).getBytes();
+	}
+
+	/** Create a &lt;value&gt; element for an XML-RPC method.
+	 *
+	 * This may throw {@link IllegalArgumentException} if the <var>value</var> is
+	 * incompatible with XML-RPC.
+	 *
+	 * @param doc Owning document.
+	 * @param value The value.
+	 * @throws DOMException If we can't construct the &lt;value&gt;.
+	 */
+	private static Element createValueElement(Document doc, Object value) throws DOMException {
+		if (value == null)
+			throw new IllegalArgumentException("Nulls not supported in XML-RPC");
+		Element valueElement = doc.createElement("value");
+		if (value instanceof Integer || value instanceof Short) {
+			XML.add(valueElement, "int", value.toString());
+		} else if (value instanceof Boolean) {
+			XML.add(valueElement, "boolean", ((Boolean) value).booleanValue()? "1" : "0");
+		} else if (value instanceof String) {
+			Element stringElement = doc.createElement("string");
+			valueElement.appendChild(stringElement);
+			stringElement.appendChild(doc.createCDATASection(value.toString()));
+		} else if (value instanceof Float || value instanceof Double) {
+			XML.add(valueElement, "double", value.toString());
+		} else if (value instanceof Date) {
+			XML.add(valueElement, "dateTime.iso8601", ISO8601_FORMAT.format((Date) value));
+		} else if (value instanceof byte[]) {
+			Element base64Element = doc.createElement("base64");
+			valueElement.appendChild(base64Element);
+			base64Element.appendChild(doc.createCDATASection(new String(Base64.encode((byte[])value))));
+		} else if (value instanceof Map) {
+			Element structElement = doc.createElement("struct");
+			valueElement.appendChild(structElement);
+			Map map = (Map) value;
+			for (Iterator i = map.entrySet().iterator(); i.hasNext();) {
+				Element memberElement = doc.createElement("member");
+				valueElement.appendChild(memberElement);
+				Map.Entry entry = (Map.Entry) i.next();
+				if (!(entry.getKey() instanceof String))
+					throw new IllegalArgumentException("Keys in maps for XML-RPC structs must be Strings");
+				XML.add(memberElement, "name", entry.getKey().toString());
+				memberElement.appendChild(createValueElement(doc, entry.getValue()));
+			}
+		} else if (value instanceof Collection) {
+			Element arrayElement = doc.createElement("array");
+			valueElement.appendChild(arrayElement);
+			Element dataElement = doc.createElement("data");
+			arrayElement.appendChild(dataElement);
+			Collection collection = (Collection) value;
+			for (Iterator i = collection.iterator(); i.hasNext();)
+				dataElement.appendChild(createValueElement(doc, i.next()));
+		} else throw new IllegalArgumentException(value.getClass().getName() + " not supported in XML-RPC");
+		return valueElement;
+	}
+
+	/** Parse an XML-RPC method response.
+	 *
+	 * @param response The response data.
+	 * @return The value contained in the <var>response</var>.
+	 * @throws XMLRPCFault If the <var>response</var> contained a fault.
+	 */
+	public static Object parseResponse(byte[] response) throws XMLRPCFault {
+		try {
+			DOMParser parser = XML.createDOMParser();
+			parser.setFeature("http://xml.org/sax/features/validation", false);
+			parser.parse(new InputSource(new ByteArrayInputStream(response)));
+			Document doc = parser.getDocument();
+			doc.normalize();
+			XML.removeComments(doc);
+			Element methodResponseElement = doc.getDocumentElement();
+			if (!"methodResponse".equals(methodResponseElement.getNodeName()))
+				throw new SAXException("Not a <methodResponse> document");
+			Node child = methodResponseElement.getFirstChild();
+			if ("params".equals(child.getNodeName())) {
+				return parseValue(child.getFirstChild().getFirstChild());
+			} else if ("fault".equals(child.getNodeName())) {
+				try {
+					Map map = (Map) parseValue(child.getFirstChild());
+					throw new XMLRPCFault(((Integer) map.get("faultCode")).intValue(),
+						(String) map.get("faultString"));
+				} catch (ClassCastException ex) {
+					throw new SAXException("XML-RPC <fault> invalid");
+				}
+			} else throw new SAXException("XML-RPC response does not contain <params> or <fault>");
+		} catch (SAXException ex) {
+			throw new IllegalArgumentException(ex.getMessage());
+		} catch (IOException ex) {
+			throw new RuntimeException("Unexpected I/O exception that shouldn't happen, but did: " + ex.getMessage());
+		}
+	}
+
+	/** Parse an XML-RPC &lt;value&gt;.
+	 *
+	 * @param node The &lt;value&gt; node.
+	 * @return The Java value of <var>node</var>.
+	 */
+	private static Object parseValue(Node node) {
+		String n = node.getNodeName();
+		if (!"value".equals(n)) throw new IllegalArgumentException("Expecting a <value>, not a <" + n + ">");
+		Node t = node.getFirstChild();
+		n = t.getNodeName();
+
+		// Default if there's no nested element is a String.
+		if (t.getNodeType() == Node.TEXT_NODE || t.getNodeType() == Node.CDATA_SECTION_NODE) {
+			return t.getNodeValue();
+		}
+
+		// Figure out what the type is from the nested element.
+		String txt = XML.unwrappedText(t);
+		if ("i4".equals(n) || "int".equals(n)) {
+			return new Integer(txt);
+		} else if ("boolean".equals(n)) {
+			if ("1".equals(txt))      return new Boolean(true);
+			else if ("0".equals(txt)) return new Boolean(false);
+			else throw new IllegalArgumentException(n + " does not contain a 0 or 1");
+		} else if ("string".equals(n)) {
+			return txt;
+		} else if ("double".equals(n)) {
+			return new Double(txt);
+		} else if ("dateTime.iso8601".equals(n)) {
+			try {
+				return ISO8601_FORMAT.parse(txt);
+			} catch (ParseException ex) {
+				throw new IllegalArgumentException(n + " does not contain an ISO8601 format date/time");
+			}
+		} else if ("base64".equals(n)) {
+			return Base64.decode(txt.getBytes());
+		} else if ("struct".equals(n)) {
+			Map m = new HashMap();
+			NodeList memberNodes = t.getChildNodes();
+			for (int i = 0; i < memberNodes.getLength(); ++i) {
+				Node memberNode = memberNodes.item(i);
+				if (!"member".equals(memberNode.getNodeName()))
+					throw new IllegalArgumentException(n + " contains <" + memberNode.getNodeName()
+						+ ">, not <member>");
+				Node nameNode = memberNode.getFirstChild();
+				if (nameNode == null || !"name".equals(nameNode.getNodeName()))
+					throw new IllegalArgumentException("<member> missing <name> element");
+				Node valueNode = nameNode.getNextSibling();
+				if (valueNode == null || !"value".equals(valueNode.getNodeName()))
+					throw new IllegalArgumentException("<member> missing <value> element");
+				m.put(XML.unwrappedText(nameNode), parseValue(valueNode));
+			}
+			return m;
+		} else if ("array".equals(n)) {
+			Node dataNode = t.getFirstChild();
+			if (dataNode == null || !"data".equals(dataNode.getNodeName()))
+				throw new IllegalArgumentException("<array> missing <data> element");
+			NodeList children = dataNode.getChildNodes();
+			List x = new ArrayList(children.getLength());
+			for (int i = 0; i < children.getLength(); ++i)
+				x.add(parseValue(children.item(i)));
+			return x;
+		} else throw new IllegalArgumentException("Illegal type " + n + " in <value>");
+	}
+
+	/** Constructor that causes a runtime exception since this is a utility class.
+	 */
+	private XMLRPC() {
+		throw new IllegalStateException("Do not construct XMLRPC objects");
+	}
+
+	/** ISO8601 date format for XML-RPC dates. */
+	private static DateFormat ISO8601_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPCFault.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPCFault.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPCFault.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPCFault.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more contributor
+// license agreements.  See the NOTICE.txt file distributed with this work for
+// additional information regarding copyright ownership.  The ASF licenses this
+// file to you 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 org.apache.oodt.commons.util;
+
+import java.io.*;
+import java.util.*;
+import java.text.ParseException;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+/** XML-RPC fault.
+ *
+ * This exception is thrown when a fault is returned from an XML-RPC call.
+ *
+ * @author Kelly
+ */
+public class XMLRPCFault extends Exception {
+	/** Constructor.
+	 *
+	 * @param code Fault code.
+	 * @param string Fault string.
+	 */
+	public XMLRPCFault(int code, String string) {
+		super(code + ": " + string);
+		this.code = code;
+		this.string = string;
+	}
+
+	/** Get the fault code.
+	 *
+	 * @return The fault code.
+	 */
+	public int getCode() {
+		return code;
+	}
+
+	/** Get the fault string.
+	 *
+	 * @return The fault string.
+	 */
+	public String getString() {
+		return string;
+	}
+
+	/** Fault code. */
+	private int code;
+
+	/** Fault string. */
+	private String string;
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/package.html
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/package.html?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/package.html (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/package.html Wed Jul 14 23:03:30 2010
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+  <head>
+    <title>Apache OODT Common Utilities
+    </title>
+  </head>
+  <body>
+    <p>Utility classes for Apache OODT.
+    </p>
+  </body>
+</html>