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 [1/2] - /incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/

Author: kelly
Date: Wed Jul 14 23:03:30 2010
New Revision: 964249

URL: http://svn.apache.org/viewvc?rev=964249&view=rev
Log:
WIP OODT-15
Import OODT Commons Utilties: entity resolver, CacheMap, various XML (and XMLRPC) utilities, logging crap, etc.

Added:
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Base64.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/CacheMap.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DOMParser.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DateConvert.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Documentable.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/EnterpriseEntityResolver.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/FileLogger.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/JDBC_DB.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LDAP.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogEventMultiplexer.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogInit.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/MemoryLogger.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/PropertyMgr.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/SAXParser.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/ScreenLogger.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Utility.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XML.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPC.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/XMLRPCFault.java
    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/Base64.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Base64.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Base64.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Base64.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,213 @@
+// 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.*;
+
+/** Base 64 encoding and decoding.
+ *
+ * This class provides methods for RFC-1521 specified "base 64" encoding and decoding of
+ * arbitrary data.  Pass a byte array into the {@link #encode} method and you'll get a
+ * byte array result where all of the bytes are printable ASCII values.  Pass that result
+ * into {@link #decode} and you'll get your original byte array.
+ *
+ * <p>Sincere thanks to Tom Daley for providing a sample encoder algorithm and a great
+ * explanation of how RFC-1521 is supposed to work.
+ *
+ * @author Kelly
+ */
+public class Base64 {
+	/** Encode into base 64.
+	 *
+	 * Encode the given data into RFC-1521 base 64.  Encoding a null array gives a
+	 * null result.
+	 *
+	 * @param data The data to encode.
+	 * @return Base-64 encoded <var>data</var>.
+	 */
+	public static byte[] encode(final byte[] data) {
+		return encode(data, 0, data.length);
+	}
+
+	/** Encode into base 64.
+	 *
+	 * Encode the given data into RFC-1521 base 64.  Encoding a null array gives a
+	 * null result.  Start encoding at the given offset and go for the given amount of
+	 * bytes.
+	 *
+	 * @param data The data to encode.
+	 * @param offset Where to start looking for data to encode.
+	 * @param length How much data to encode.
+	 * @return Base-64 encoded <var>data</var>
+	 */
+	public static byte[] encode(final byte[] data, int offset, int length) {
+		if (data == null) return null;
+		if (offset < 0 || offset > data.length)
+			throw new IndexOutOfBoundsException("Can't encode at index " + offset + " which is beyond array bounds 0.."
+				+ data.length);
+		if (length < 0) throw new IllegalArgumentException("Can't encode a negative amount of data");
+		if (offset + length > data.length)
+			throw new IndexOutOfBoundsException("Can't encode beyond right edge of array");
+		
+		int i, j;
+		byte dest[] = new byte[((length+2)/3)*4];
+
+		// Convert groups of 3 bytes into 4.
+		for (i = 0 + offset, j = 0; i < offset + length - 2; i += 3) {
+			dest[j++] = (byte) ((data[i] >>> 2) & 077);
+			dest[j++] = (byte) ((data[i+1] >>> 4) & 017 | (data[i] << 4) & 077);
+			dest[j++] = (byte) ((data[i+2] >>> 6) & 003 | (data[i+1] << 2) & 077);
+			dest[j++] = (byte) (data[i+2] & 077);
+		}
+
+		// Convert any leftover bytes.
+		if (i < offset + length) {
+			dest[j++] = (byte) ((data[i] >>> 2) & 077);
+			if (i < offset + length - 1) {
+				dest[j++] = (byte) ((data[i+1] >>> 4) & 017 | (data[i] << 4) & 077);
+				dest[j++] = (byte) ((data[i+1] << 2) & 077);
+			} else
+				dest[j++] = (byte) ((data[i] << 4) & 077);
+		}
+
+		// Now, map those onto base 64 printable ASCII.
+		for (i = 0; i <j; i++) {
+			if      (dest[i] < 26)  dest[i] = (byte)(dest[i] + 'A');
+			else if (dest[i] < 52)  dest[i] = (byte)(dest[i] + 'a'-26);
+			else if (dest[i] < 62)  dest[i] = (byte)(dest[i] + '0'-52);
+			else if (dest[i] < 63)  dest[i] = (byte) '+';
+			else                    dest[i] = (byte) '/';
+		}
+
+		// Pad the result with and we're done.
+		for (; i < dest.length; i++) dest[i] = (byte) '=';
+		return dest;
+	}
+
+	/** Decode from base 64.
+	 *
+	 * Decode the given RFC-1521 base 64 encoded bytes into the original data they
+	 * represent.  Decoding null data gives a null result.
+	 *
+	 * @param data Base-64 encoded data to decode.
+	 * @return Decoded <var>data</var>.
+	 */
+	public static byte[] decode(final byte[] data) {
+		return decode(data, 0, data.length);
+	}
+
+	/** Decode from base 64.
+	 *
+	 * Decode the given RFC-1521 base 64 encoded bytes into the original data they
+	 * represent.  Decoding null data gives a null result.
+	 *
+	 * @param data Base-64 encoded data to decode.
+	 * @param offset Where to start looking for data to decode.
+	 * @param length How much data to decode.
+	 * @return Decoded <var>data</var>.
+	 */
+	public static byte[] decode(final byte[] data, int offset, int length) {
+		if (data == null) return null;
+		if (offset < 0 || offset >= data.length)
+			throw new IndexOutOfBoundsException("Can't decode at index " + offset + " which is beyond array bounds 0.."
+				+ (data.length-1));
+		if (length < 0) throw new IllegalArgumentException("Can't decode a negative amount of data");
+		if (offset + length > data.length)
+			throw new IndexOutOfBoundsException("Can't decode beyond right edge of array");
+
+		// Ignore any padding at the end.
+		int tail = offset + length - 1;
+		while (tail >= offset && data[tail] == '=')
+			--tail;
+		byte dest[] = new byte[tail + offset + 1 - length/4];
+
+		// First, convert from base-64 ascii to 6 bit bytes.
+		for (int i = offset; i < offset+length; i++) {
+			if      (data[i] == '=') data[i] = 0;
+			else if (data[i] == '/') data[i] = 63;
+			else if (data[i] == '+') data[i] = 62;
+			else if (data[i] >= '0' && data[i] <= '9')
+				data[i] = (byte)(data[i] - ('0' - 52));
+			else if (data[i] >= 'a'  &&  data[i] <= 'z')
+				data[i] = (byte)(data[i] - ('a' - 26));
+			else if (data[i] >= 'A'  &&  data[i] <= 'Z')
+				data[i] = (byte)(data[i] - 'A');
+		}
+
+		// Map those from 4 6-bit byte groups onto 3 8-bit byte groups.
+		int i, j;
+		for (i = 0 + offset, j = 0; j < dest.length - 2; i += 4, j += 3) {
+			dest[j]   = (byte) (((data[i] << 2) & 255) | ((data[i+1] >>> 4) & 003));
+			dest[j+1] = (byte) (((data[i+1] << 4) & 255) | ((data[i+2] >>> 2) & 017));
+			dest[j+2] = (byte) (((data[i+2] << 6) & 255) | (data[i+3] & 077));
+		}
+
+		// And get the leftover ...
+		if (j < dest.length)
+			dest[j] = (byte) (((data[i] << 2) & 255) | ((data[i+1] >>> 4) & 003));
+		if (++j < dest.length)
+			dest[j] = (byte) (((data[i+1] << 4) & 255) | ((data[i+2] >>> 2) & 017));
+
+		// That's it.
+		return dest;
+	}
+
+	/** This class provides namespace for utility methods and shouldn't be instantiated.
+	 */
+	private Base64() {
+		throw new IllegalStateException(getClass().getName() + " should not be instantiated");
+	}
+
+	/** Command-line runner that encodes or decodes.
+	 *
+	 * @param argv Command-line arguments.
+	 */
+	public static void main(String[] argv) throws Exception {
+		if (argv.length < 1 || argv.length > 2) {
+			System.err.println("Usage: encode|decode [file]");
+			System.exit(1);
+		}
+		boolean encode = true;
+		if ("encode".equals(argv[0]))
+			encode = true;
+		else if ("decode".equals(argv[0]))
+			encode = false;
+		else {
+			System.err.println("Specify either \"encode\" or \"decode\"");
+			System.exit(1);
+		}
+		InputStream source = argv.length == 2? new BufferedInputStream(new FileInputStream(argv[1])) : System.in;
+		InputStream in;
+		OutputStream out;
+		if (encode) {
+			in = source;
+			out = new Base64EncodingOutputStream(System.out);
+		} else {
+			in = new Base64DecodingInputStream(source);
+			out = System.out;
+		}
+		byte[] buf = new byte[512];
+		int numRead;
+		while ((numRead = in.read(buf)) != -1)
+			out.write(buf, 0, numRead);
+		in.close();
+		out.close();
+		System.exit(0);
+	}
+}
+
+			

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/CacheMap.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/CacheMap.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/CacheMap.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/CacheMap.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,228 @@
+// 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.util.*;
+
+// Definitions for intended functions:
+//
+// DEFN size(x) = The size of an object x, usually by the size(), length(), or getLength()
+//                methods defined for x.
+// NFED
+//
+// DEFN keys(x) = Set of keys from map x.
+// NFED
+//
+// DEFN dup(x) = Duplicate of object x.
+// NFED
+//
+// DEFN presence(x, y) = True if (x, z) or (z, x) exists in map y for any z.
+// NFED
+//
+// DEFN advance(x, y) = sequence y such that object x in y is moved to the front of the
+//                      sequence, or y if x is not an element of x.
+// NFED
+//
+// DEFN value(v, y) = value v of (k, v) mapping in y.
+// NFED
+//
+// A cache-map Z is a triple (c, C, M) such that c is the capacity, C is an ordered
+// sequence of n keys = {k_0, k_1, ..., k_(n-1)}, and M is a set of mappings (k, v) such
+// that k is the for value v, and all k's are unique.  For all k_i in C, there exists
+// (k_i, v_i) in M.  size(Z) = size(C) = size(M) <= c.  The most recently used v is at the
+// head of C, and the least recently used is at the tail.  When a new (k_new, v_new) is
+// added to Z, C = {k_new, k_0, ..., k_(n-1)} and if size(C) >= c, the previous k_(n-1) is
+// removed from C and M; and M = M U (k_new, v_new).
+
+
+/** A cache map is a map with a built-in cache.
+ *
+ * It operates in all ways like a regular {@link java.util.Map}, except that you can store
+ * only a limited number of entries.  After adding an entry that exceeds the size of the
+ * cache, the map ejects the least recently used entry.
+ *
+ * @author Kelly
+ */
+public class CacheMap implements Map {
+	/** Create a cache map with a default capacity of 5 entries.
+	 */
+	public CacheMap() {
+		// FXN: [ c, C, M := 5, {}, {} ]
+		this(DEFAULT_CAPACITY);
+	}
+
+	/** Create a cache map with the given capacity.
+	 *
+	 * @param capacity How big the cache is.
+	 */
+	public CacheMap(int capacity) {
+		// FXN: [ c, C, M := capacity, {}, {} ]
+
+		if (capacity < 0)
+			throw new IllegalArgumentException("Can't have a negative size " + capacity + " cache map");
+		this.capacity = capacity;
+	}
+
+	/** Get the cache map's capacity.
+	 *
+	 * @return Its capacity.
+	 */
+	public int getCapacity() {
+		return capacity;
+	}
+
+	/** Create a cache map from the given map, having the capacity of the given map.
+	 *
+	 * @param map The map to copy.
+	 */
+	public CacheMap(Map map) {
+		// FXN: [ c, C, M := size(map), keys(map), dup(map) ]
+
+		this.capacity = map.size();
+		putAll(map);
+	}
+
+	public int size() {
+		// FXN: [ return value := size(M) ]
+		return map.size();
+	}
+
+	public boolean isEmpty() {
+		// FXN: [ return value := size(M) = 0? ]
+		return map.size() == 0;
+	}
+
+	/** Returns true if there's a mapping for the specified key in the cache map.
+	 *
+	 * This method does not otherwise affect the cache.
+	 *
+	 * @param key Key to check.
+	 * @return True if the cache map contains a mapping for the <var>key</var>.
+	 */
+	public boolean containsKey(Object key) {
+		// FXN: [ return value := presence(key, M) ]
+		return (map.containsKey(key));
+	}
+
+	/** Returns true if there's a mapping for the specified value in the cache map.
+	 *
+	 * This method does not otherwise affect the cache.
+	 *
+	 * @param value Value to check.
+	 * @return True if the cache map contains a mapping for the <var>value</var>.
+	 */
+	public boolean containsValue(Object value) {
+		// FXN: [ return value := presence(value, M) ]
+		return map.containsValue(value);
+	}
+
+	public Object get(Object key) {
+		// FXN: [ key in M -> C, return value := advance(key, C), value(key, M)
+		//      | true     -> C, return value := C, null ]
+
+		advance(key);
+		return map.get(key);
+	}
+
+	public Object put(Object key, Object value) {
+		// FXN: [ key in M -> C, M, return value := advance(key, C), M U (key, value), value(key, M)
+		//      | size(C) < c -> C, M, return value := key || C, M U (key, value), null
+		//      | true -> C, M, return value := key || {k_i | k elem C, 0 <= i <= c - 2},
+		//                                      (M U (key, value)) - (k_(c-1), v), null ]
+
+		Object old = map.put(key, value);
+		if (old != null) {
+			advance(key);
+			return old;
+		}
+
+		cache.addFirst(key);
+		if (cache.size() > capacity)
+			map.remove(cache.removeLast());
+		return null;
+	}
+	
+	public Object remove(Object key) {
+		// FXN: [ key in M -> C, M, return value := C - key, M - (key, v), v
+		//      | true -> return value := null ]
+
+		if (!map.containsKey(key))
+			return null;
+		cache.remove(key);
+		return map.remove(key);
+	}
+
+	public void putAll(Map t) {
+		// FXN: [ C, M := (keys(t) || C)[0..(c-1)], { (k_i, v_i) | k_i elem of (keys(t) || C)[0..(c-1)]} ]
+		for (Iterator i = t.entrySet().iterator(); i.hasNext();) {
+			Map.Entry entry = (Map.Entry) i.next();
+			put(entry.getKey(), entry.getValue());
+		}
+	}
+
+	public void clear() {
+		cache.clear();
+		map.clear();
+	}
+
+	public Set keySet() {
+		throw new UnsupportedOperationException("Not implemented for CacheMap");
+	}
+	public Collection values() {
+		throw new UnsupportedOperationException("Not implemented for CacheMap");
+	}
+	public Set entrySet() {
+		throw new UnsupportedOperationException("Not implemented for CacheMap");
+	}
+
+	public boolean equals(Object rhs) {
+		if (rhs == this) return true;
+		if (rhs == null || !(rhs instanceof CacheMap)) return false;
+		CacheMap obj = (CacheMap) rhs;
+		return obj.cache.equals(cache);
+	}
+
+	public int hashCode() {
+		return cache.hashCode();
+	}
+
+	/** Advance the given key to the front of the cache.
+	 *
+	 * If the key isn't in the cache, leave the cache alone.
+	 *
+	 * @param key The key to advance.
+	 */
+	private void advance(Object key) {
+		// FXN: [ C = advance(key, C) ]
+
+		boolean present = cache.remove(key);
+		if (!present) return;
+		cache.addFirst(key);
+	}
+
+	/** What the default capacity of a cache map is. */
+	private static final int DEFAULT_CAPACITY = 5;
+
+	/** The cache (C). */
+	private LinkedList cache = new LinkedList();
+
+	/** The map (M). */
+	private Map map = new HashMap();
+
+	/** The capacity of this cache map (c). */
+	private int capacity;
+}
+

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DOMParser.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DOMParser.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DOMParser.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DOMParser.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,263 @@
+// 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.*;
+import org.w3c.dom.*;
+import javax.xml.parsers.DocumentBuilder;
+
+/** An XML Document Object Model parser.
+ *
+ * Objects of this class are DOM parsers.
+ *
+ * @author Kelly
+ */
+public class DOMParser {
+	/** Construct the DOM Parser.
+	 */
+	DOMParser(DocumentBuilder builder) {
+		this.builder = builder;
+	}
+
+	/** Get the document.
+	 *
+	 * @return The document.
+	 */
+	public Document getDocument() {
+		if (document == null)
+			throw new IllegalStateException("Must parse something first");
+		return document;
+	}
+
+	/** 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() throws Exception {
+		document = null;
+	}
+
+	/** Resets or copies the parser. */
+	public void resetOrCopy() throws Exception {
+		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("Locators ar enot supported");
+	}
+
+	/**
+	 * 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) {
+		builder.setEntityResolver(resolver);
+	}
+
+	/**
+	 * 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("The resolver can only be set, not queried");
+	}
+
+	/**
+	 * Sets the error handler.
+	 *
+	 * @param handler The new error handler.
+	 */
+	public void setErrorHandler(ErrorHandler handler) {
+		builder.setErrorHandler(handler);
+	}
+
+	/**
+	 * 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("The error handler can only be set, not queried");
+	}
+
+	/**
+	 * 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 {
+		document = builder.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 {
+		document = builder.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 does not support localized error messages");
+	}
+
+	private static final String[] EMPTY_STRING_ARRAY = new String[0];
+	private Document document;
+	private DocumentBuilder builder;
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DateConvert.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DateConvert.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DateConvert.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/DateConvert.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,396 @@
+// 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.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+	The <code>DateConvert</code> class is intended to provide date/time
+	conversion and parse routines. For a description of the syntax of the
+	format strings see {@link SimpleDateFormat}.
+
+	@author S. Hardman
+	@version $Revision: 1.1.1.1 $
+ */
+public class DateConvert {
+
+	/**
+		The number of milliseconds in a minute.
+	*/
+	private final static long MS_IN_MINUTE = 60000;
+
+	/**
+		The number of milliseconds in an hour.
+	*/
+	private final static long MS_IN_HOUR = 3600000;
+
+	/**
+		The number of milliseconds in a day.
+	*/
+	private final static long MS_IN_DAY = 86400000;
+
+	/**
+		The format string representing the ISO 8601 format. The format
+		is close to CCSDS ASCII Time Code A. 
+	*/
+	private final static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
+
+	/**
+		The format string representing the CCSDS ASCII Time Code B format
+		excluding the trailing "Z".
+	*/
+	private final static String DOY_FORMAT = "yyyy-DDD'T'HH:mm:ss.SSS";
+
+	/**
+		The format string representing the EDA time stamp format.
+	*/
+	private final static String TS_FORMAT = "yyyyMMddHHmmssSSS";
+
+	/**
+		The format string representing the DBMS format.
+	*/
+	private final static String DBMS_FORMAT = "dd-MMM-yyyy HH:mm:ss";
+
+	/**
+		The format string representing the Year-Month-Day format.
+	*/
+	private final static String YMD_FORMAT = "yyyy-MM-dd";
+
+
+	/**
+		Constructor given no arguments.
+
+		This is a static-only class that may not be instantiated.
+
+		@throws IllegalStateException If the class is instantiated.
+	*/
+	public DateConvert() throws IllegalStateException {
+		throw new IllegalStateException("Instantiation of this class is not allowed.");
+	}
+
+
+	/**
+		Format the given date and return the resulting string in ISO 8601 format.
+
+		The format is as follows: "yyyy-MM-dd'T'HH:mm:ss.SSS[Z|[+|-]HH:mm]".
+
+		@param inputDate The date to be converted into string format.
+		@return The formatted date/time string.
+	*/
+	public static String isoFormat(Date inputDate) {
+
+		// Setup the date format and convert the given date.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(ISO_FORMAT);
+		String dateString = dateFormat.format(inputDate);
+
+		// Determine the time zone and concatenate the time zone designator
+		// onto the formatted date/time string.
+		TimeZone tz = dateFormat.getTimeZone();
+		String tzName = tz.getDisplayName();
+		if (tzName.equals("Greenwich Mean Time")) {
+			dateString = dateString.concat("Z");
+		}
+		else {
+			// Determine the hour offset. Add an hour if daylight savings
+			// is in effect.
+			long tzOffsetMS = tz.getRawOffset();
+			long tzOffsetHH = tzOffsetMS / MS_IN_HOUR;
+			if (tz.inDaylightTime(inputDate)) {
+				tzOffsetHH = tzOffsetHH + 1;
+			}
+			String hourString = String.valueOf(Math.abs(tzOffsetHH));
+			if (hourString.length() == 1) {
+				hourString = "0" + hourString;
+			}
+
+			// Determine the minute offset.
+			long tzOffsetMMMS = tzOffsetMS % MS_IN_HOUR;
+			long tzOffsetMM = 0;
+			if (tzOffsetMMMS != 0) {
+				tzOffsetMM = tzOffsetMMMS / MS_IN_MINUTE;
+			}
+			String minuteString = String.valueOf(tzOffsetMM);
+			if (minuteString.length() == 1) {
+				minuteString = "0" + minuteString;
+			}
+
+			// Determine the sign of the offset.
+			String sign = "-";
+			if (String.valueOf(tzOffsetMS).indexOf("+") != -1) {
+				sign = "+";
+			}
+
+			dateString = dateString.concat(sign + hourString + ":" + minuteString);
+		}
+
+		return(dateString);
+	}
+
+
+	/**
+		Parse the given date/time string in ISO 8601 format and return the
+		resulting <code>Date</code> object.
+
+		The format is as follows: "yyyy-MM-dd'T'HH:mm:ss.SSS[Z|[+|-]HH:mm]".
+
+		@param inputString The string to be parsed.
+		@return The resulting Date object.
+		@throws ParseException If the string does not match the date/time
+		format.
+	*/
+	public static Date isoParse(String inputString) throws ParseException {
+
+		// Setup the date format.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(ISO_FORMAT);
+		dateFormat.setLenient(false);
+
+		// The length of the input string should be at least 24 characters.
+		if (inputString.length() < 24) {
+			throw new ParseException("An exception occurred because the input date/time string was not at least 24 characters in length.", inputString.length());
+		}
+
+		// Evaluate the the specified offset and set the time zone.
+		String offsetString = inputString.substring(23);
+		if (offsetString.equals("Z")) {
+			dateFormat.setTimeZone(TimeZone.getTimeZone("Greenwich Mean Time"));
+		}
+		else if (offsetString.startsWith("-") || offsetString.startsWith("+")) {
+			SimpleDateFormat offsetFormat = new SimpleDateFormat();
+			if (offsetString.length() == 3) {
+				offsetFormat.applyPattern("HH");
+			}
+			else if (offsetString.length() == 6) {
+				offsetFormat.applyPattern("HH:mm");
+			}
+			else {
+				throw new ParseException("An exception occurred because the offset portion was not the valid length of 3 or 6 characters.", 25);
+			}
+
+			// Validate the given offset.
+			offsetFormat.setLenient(false);
+			Date offsetDate = offsetFormat.parse(offsetString.substring(1));
+
+			// Set the time zone with the validated offset.
+			dateFormat.setTimeZone(TimeZone.getTimeZone("GMT" + offsetString));
+		}
+		else {
+			throw new ParseException("An exception occurred because the offset portion of the input date/time string was not 'Z' or did not start with '+' or '-'.", 24);
+		}
+
+		// Parse the given string.
+		Date parseDate = dateFormat.parse(inputString);
+
+		return(parseDate);
+	}
+
+
+	/**
+		Format the given date and return the resulting string in CCSDS
+		ASCII Time Code B format.
+
+		The format is as follows: "yyyy-DDD'T'HH:mm:ss.SSS".
+
+		@param inputDate The date to be converted into string format.
+		@return The formatted date/time string.
+	*/
+	public static String doyFormat(Date inputDate) {
+
+		// Setup the date format and convert the given date.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(DOY_FORMAT);
+		String dateString = dateFormat.format(inputDate);
+
+		return(dateString);
+	}
+
+
+	/**
+		Parse the given date/time string in CCSDS ASCII Time Code B format
+		and return the resulting <code>Date</code> object.
+
+		The format is as follows: "yyyy-DDD'T'HH:mm:ss.SSS".
+
+		@param inputString The string to be parsed.
+		@return The resulting Date object.
+		@throws ParseException If the string does not match the date/time
+		format.
+	*/
+	public static Date doyParse(String inputString) throws ParseException {
+
+		// Setup the date format and parse the given string.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(DOY_FORMAT);
+		dateFormat.setLenient(false);
+		Date parseDate = dateFormat.parse(inputString);
+
+		return(parseDate);
+	}
+
+
+	/**
+		Format the given date and return the resulting string in a timestamp
+		format.
+
+		The format is as follows: "yyyyMMddHHmmssSSS".
+
+		@param inputDate The date to be converted into string format.
+		@return The formatted date/time string.
+	*/
+	public static String tsFormat(Date inputDate) {
+
+		// Setup the date format and convert the given date.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(TS_FORMAT);
+		String dateString = dateFormat.format(inputDate);
+
+		return(dateString);
+	}
+
+
+	/**
+		Parse the given date/time string in timestamp format
+		and return the resulting <code>Date</code> object.
+
+		The format is as follows: "yyyyMMddHHmmssSSS".
+
+		@param inputString The string to be parsed.
+		@return The resulting Date object.
+		@throws ParseException If the string does not match the date/time
+		format.
+	*/
+	public static Date tsParse(String inputString) throws ParseException {
+
+		// Setup the date format and parse the given string.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(TS_FORMAT);
+		dateFormat.setLenient(false);
+		Date parseDate = dateFormat.parse(inputString);
+
+		return(parseDate);
+	}
+
+
+	/**
+		Format the given date and return the resulting string in a DBMS
+		format.
+
+		The format is as follows: "dd-MMM-yyyy HH:mm:ss".
+
+		@param inputDate The date to be converted into string format.
+		@return The formatted date/time string.
+	*/
+	public static String dbmsFormat(Date inputDate) {
+
+		// Setup the date format and convert the given date.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(DBMS_FORMAT);
+		String dateString = dateFormat.format(inputDate);
+
+		return(dateString);
+	}
+
+
+	/**
+		Parse the given date/time string in DBMS format
+		and return the resulting <code>Date</code> object.
+
+		The format is as follows: "dd-MMM-yyyy HH:mm:ss".
+
+		@param inputString The string to be parsed.
+		@return The resulting Date object.
+		@throws ParseException If the string does not match the date/time
+		format.
+	*/
+	public static Date dbmsParse(String inputString) throws ParseException {
+
+		// Setup the date format and parse the given string.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(DBMS_FORMAT);
+		dateFormat.setLenient(false);
+		Date parseDate = dateFormat.parse(inputString);
+
+		return(parseDate);
+	}
+
+
+	/**
+		Format the given date and return the resulting string in a
+		year-month-day format.
+
+		The format is as follows: "yyyy-MM-dd".
+
+		@param inputDate The date to be converted into string format.
+		@return The formatted date/time string.
+	*/
+	public static String ymdFormat(Date inputDate) {
+
+		// Setup the date format and convert the given date.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(YMD_FORMAT);
+		String dateString = dateFormat.format(inputDate);
+
+		return(dateString);
+	}
+
+
+	/**
+		Parse the given date/time string in year-month-day format
+		and return the resulting <code>Date</code> object.
+
+		The format is as follows: "yyyy-MM-dd".
+
+		@param inputString The string to be parsed.
+		@return The resulting Date object.
+		@throws ParseException If the string does not match the date/time
+		format.
+	*/
+	public static Date ymdParse(String inputString) throws ParseException {
+
+		// Setup the date format and parse the given string.
+		SimpleDateFormat dateFormat = new SimpleDateFormat(YMD_FORMAT);
+		dateFormat.setLenient(false);
+		Date parseDate = dateFormat.parse(inputString);
+
+		return(parseDate);
+	}
+
+
+	/**
+		Get the number of milliseconds in a minute.
+
+		@return The number of milliseconds in a minute.
+	*/
+	public static long getMsecsInMinute() {
+		return(MS_IN_MINUTE);
+	}
+
+
+	/**
+		Get the number of milliseconds in an hour.
+
+		@return The number of milliseconds in an hour.
+	*/
+	public static long getMsecsInHour() {
+		return(MS_IN_HOUR);
+	}
+
+
+	/**
+		Get the number of milliseconds in a day.
+
+		@return The number of milliseconds in a day.
+	*/
+	public static long getMsecsInDay() {
+		return(MS_IN_DAY);
+	}
+}
+

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Documentable.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Documentable.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Documentable.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/Documentable.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,36 @@
+// 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 org.w3c.dom.*;
+
+/** A documentable object.
+ *
+ * An object that exhibits this interface can be documented, in XML, as a DOM node.
+ *
+ * @author Kelly.
+ */
+public interface Documentable {
+	/** Document (aka serialize) this object into an XML DOM node.
+	 *
+	 * @param doc What document will own the node.
+	 * @return This object as an XML DOM node.
+	 * @throws DOMException If an error occurs while creating the DOM structure.
+	 */
+	Node toXML(Document doc) throws DOMException;
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/EnterpriseEntityResolver.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/EnterpriseEntityResolver.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/EnterpriseEntityResolver.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/EnterpriseEntityResolver.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,159 @@
+// 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.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+import java.io.InputStreamReader;
+
+/** XML entity resolver for enterprise applications.
+ *
+ * This resolver attempts to retrieves entities from local sources before deferring to the
+ * default parser's entity resolver.
+ *
+ * @author Kelly
+ */
+public class EnterpriseEntityResolver implements EntityResolver {
+	/** Mapping of public identifiers to known file names. */
+	static Map entities;
+
+	/** Initialize the class by reading the entites.xml file. */
+	static {
+		entities = new HashMap();
+		try {
+			SAXParserFactory factory = SAXParserFactory.newInstance();
+			factory.setNamespaceAware(false);
+			factory.setValidating(true);
+			javax.xml.parsers.SAXParser p = factory.newSAXParser();
+			p.parse(new InputSource(EnterpriseEntityResolver.class.getResourceAsStream("entities.xml")),
+				new DefaultHandler() {
+					private StringBuffer token = new StringBuffer();
+					private String pi;
+					public void characters(char[] ch, int start, int length) {
+						token.append(ch, start, length);
+					}
+					public void endElement(String ns, String name, String qual) {
+						if ("pi".equals(qual))
+							pi = token.toString().trim();
+						else if ("filename".equals(qual)) {
+							entities.put(pi, token.toString().trim());
+						}
+						token.delete(0, token.length());
+					}
+				});
+		} catch (ParserConfigurationException ex) {
+			throw new IllegalStateException("Unexpected ParserConfigurationException: " + ex.getMessage());
+		} catch (SAXParseException ex) {
+			System.err.println("Error parsing entities.xml at line " + ex.getLineNumber() + ", column "
+				+ ex.getColumnNumber() + "; ignoring entity lookup");
+		} catch (SAXException ex) {
+			System.err.println("Exception parsing entities.xml: " + ex.getMessage() + "; ignoring entity lookup");
+		} catch (IOException ex) {
+			System.err.println("I/O error reading entities.xml: " + ex.getMessage() + "; ignoring entity lookup");
+		}
+	}
+
+	public InputSource resolveEntity(String publicID, String systemID) throws SAXException, IOException {
+		String filename = computeFilename(publicID, systemID);
+		if (filename == null) return null;
+
+		// Resolve it using class loader first.  Any DTD in the toplevel directory
+		// of any jar present to the application is a potential source.
+		InputStream in = getClass().getResourceAsStream("/" + filename);
+		if (in != null)
+			return new InputSource(new BufferedReader(new InputStreamReader(in)));
+
+		// OK, try the filesystem next.  You can control what directories get
+		// searched by setting the entity.dirs property.
+		File file = findFile(getEntityRefDirs(System.getProperty("entity.dirs", "")), filename);
+		if (file != null) try {
+			return new InputSource(new BufferedReader(new FileReader(file)));
+		} catch (IOException ignore) {}
+
+		// No luck either way.
+		return null;
+	}
+
+	/** Compute the possible filename from public and system identifiers.
+	 *
+	 * This attempts to map the public ID to a known file based on a table (see
+	 * <code>entity.xml</code>).  If that doesn't work, then it will use the
+	 * file part of the system ID.  If there's no file part, it returns null.
+	 *
+	 * @param publicID The public identifier.
+	 * @param systemID The system identifier.
+	 * @return A file computed from <var>publicID</var> and <var>systemID</var>.
+	 */
+	static String computeFilename(String publicID, String systemID) {
+		String name = (String) entities.get(publicID);
+		if (name == null) try {
+			URL url = new URL(systemID);
+			File file = new File(url.getFile());
+			name = file.getName();
+		} catch (MalformedURLException ignore) {}
+		return name;
+	}
+
+	/**
+	 * Get a list of entity directories from the given string specification.
+	 *
+	 * @param spec Directory names separated by commas.
+	 * @return a {@link List} of those directory names.
+	 */
+	static List getEntityRefDirs(String spec) {
+		List dirs = new ArrayList();
+		for (StringTokenizer t = new StringTokenizer(spec, ",;|"); t.hasMoreTokens();)
+			dirs.add(t.nextToken());
+		return dirs;
+	}
+
+	/** Find a file under a list of directories.
+	 * 
+	 * @param dirs List of {@link java.lang.String} directory names.
+	 * @param filename Name of the file to find under one of the directories named in <var>dirs</var>.
+	 * @return The first path to the file named by <var>filename</var> under a directory in <var>dirs</var>,
+	 * or null if no directory in <var>dirs</var> contains a file named <var>filename</var>.
+	 */
+	static File findFile(List dirs, String filename) {
+		for (Iterator i = dirs.iterator(); i.hasNext();) {
+			File potentialFile = new File((String) i.next(), filename);
+			if (potentialFile.isFile()) return potentialFile;
+		}
+		return null;
+	}
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/FileLogger.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/FileLogger.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/FileLogger.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/FileLogger.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,68 @@
+// 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 org.apache.oodt.commons.io.*;
+import org.apache.oodt.commons.util.*;
+
+/**
+	The <code>FileLogger</code> class is intended to be used with the
+	{@link Log} class in order to setup a log file as a {@link LogListener}.
+
+	@author S. Hardman
+	@version $Revision: 1.1 $
+*/
+public class FileLogger extends WriterLogger {
+
+	/**
+		Constructor given no arguments.
+
+		This constructor will create a new log file or append to an existing
+		log file if the specified file exists. The constructor will then call
+		the other constructor with the output stream argument. This constructor
+		utilizes two system properties for specifying the path and name of the
+		log file. They are as follows:
+
+		<p>org.apache.oodt.commons.util.FileLogger.path - If specified, this is the directory where
+			the log file will be found or created, otherwise the local directory
+			will be utilized.
+
+		<p>org.apache.oodt.commons.util.FileLogger.name - If specified, this is the name of the log
+			file to be found or created, otherwise the name will be as follows:
+			"eda_yyyymmddhhmmssSSS.log".
+
+		@throws FileNotFoundException If the file cannot be opened for any
+			reason.
+	*/
+	public FileLogger () throws FileNotFoundException {
+		this(new FileOutputStream(System.getProperty("org.apache.oodt.commons.util.FileLogger.path", ".") + "/" + System.getProperty("org.apache.oodt.commons.util.FileLogger.name", "eda_" + DateConvert.tsFormat(new Date()) + ".log"), true));
+	}
+
+
+	/**
+		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 FileLogger (OutputStream outputStream) {
+		super(outputStream);
+	}
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/JDBC_DB.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/JDBC_DB.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/JDBC_DB.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/JDBC_DB.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,441 @@
+// 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.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+import java.util.Properties;
+
+/**
+	This class is a wrapper for JDBC.
+
+	@author D. Crichton
+	@version $Revision: 1.3 $
+*/
+public class JDBC_DB
+{
+	Properties serverProps;
+	Connection connect;
+	String sql_command;
+	Statement stmt;
+	ResultSet rs;
+	ResultSetMetaData rs_meta;
+	int affected;
+	boolean more_rows;
+	boolean keep_connect_open;
+	private boolean autoCommitMode = false;
+	public final String TO_DATE_FORMAT = "DD-MM-YYYY HH24:MI:SS";
+
+	/******************************************************************
+	**
+	** JDBC_DB
+	**
+	** Constructor method will create class instance and load the
+	** Oracle DB driver
+	**
+	*******************************************************************/
+
+	public  JDBC_DB(
+			java.util.Properties sys_props) throws SQLException
+	{
+			String  classname;
+
+			serverProps = sys_props;
+			keep_connect_open = true;
+
+	}
+
+	public  JDBC_DB(
+			java.util.Properties sys_props,
+			Connection srv_connect) throws SQLException
+	{
+			String  classname;
+
+			serverProps = sys_props;
+			connect = srv_connect;
+
+			if (srv_connect == null) {
+				keep_connect_open  = false;
+			} else {
+				keep_connect_open = true;
+			}
+	}
+
+	public void setAutoCommitMode(boolean autoCommitMode) {
+		this.autoCommitMode = autoCommitMode;
+	}
+
+	/******************************************************************
+	**
+	** openConnection
+	**
+	** Open a connection to the database.
+	**
+	*******************************************************************/
+	public void openConnection() throws SQLException
+
+	{
+		openConnection(serverProps.getProperty("org.apache.oodt.commons.util.JDBC_DB.user", "unknown"),
+			serverProps.getProperty("org.apache.oodt.commons.util.JDBC_DB.password"),
+			serverProps.getProperty("org.apache.oodt.commons.util.JDBC_DB.database"));
+	}
+
+
+	public void openConnection(
+		String username,
+		String password,
+		String database) throws SQLException
+	{
+		String url, classname;
+
+		if (stmt != null)
+			stmt.close();
+
+		if (rs != null)
+			rs.close();
+
+		if (keep_connect_open)
+			return;
+
+		if (connect != null)
+			connect.close();
+
+
+		rs_meta = null;
+		connect = null;
+		stmt = null;
+		rs = null;
+
+		Properties props = new Properties();
+		props.put("user", username);
+
+		if (password != null)
+			props.put("password", password);
+
+
+		classname = serverProps.getProperty("org.apache.oodt.commons.util.JDBC_DB.driver", "oracle.jdbc.driver.OracleDriver");
+		try {
+			System.err.println("Attempting to load class " + classname);
+			Class.forName(classname);
+			System.err.println("Loaded " + classname);
+		} catch (ClassNotFoundException e) {
+			System.err.println("Can't load JDBC driver \"" + classname + "\": " + e.getMessage());
+			e.printStackTrace();
+		}
+		url = serverProps.getProperty("org.apache.oodt.commons.util.JDBC_DB.url", "jdbc:oracle:@");
+		try {
+			if (database != null) {
+				System.err.println("Connecting to url+database combo: " + url + database);
+				connect = DriverManager.getConnection(url+database, props);
+			} else {
+				System.err.println("Connecting to full url: " + url);
+				connect = DriverManager.getConnection(url, props);
+			}
+		} catch (SQLException e) {
+			System.err.println("SQL Exception during connection creation: " + e.getMessage());
+			e.printStackTrace();
+			while (e != null) {
+				System.err.println(e.getMessage());
+				e = e.getNextException();
+			}
+		}
+
+		connect.setAutoCommit(autoCommitMode);
+
+	}
+
+
+	/******************************************************************
+	**
+	** closeConnection
+	**
+	** Close a connection to the database.
+	**
+	*******************************************************************/
+
+	public void closeConnection() {
+		try {
+			if (rs != null) {
+				rs.close();
+			}
+			if (stmt != null) {
+				stmt.close();
+			}
+			if (keep_connect_open) {
+				return;
+			}
+			if (connect != null) {
+				connect.close();
+			}
+			connect = null;
+			rs = null;
+			stmt = null;
+		} catch (SQLException e) {
+			System.err.println("Ignoring database close connection exception");
+			//System.err.println("Ignoring exception " + e.getClass().getName() + ": " + e.getMessage());
+			//e.printStackTrace();
+		}
+	}
+
+	/******************************************************************
+	**
+	** executeSQLCommand
+	**
+	** Send an SQL command to the DBMS to be executed.
+	**
+	*******************************************************************/
+
+	public void executeSQLCommand(String cmd) throws SQLException
+	{
+
+
+		/*
+		** Get the string, and create the statement
+		*/
+		sql_command = cmd;
+
+		if (stmt!=null)
+			stmt.close();
+
+		if (connect == null) openConnection();
+		if (connect == null) {
+			keep_connect_open = false;
+			openConnection();
+		}
+		if (connect == null)
+			throw new IllegalStateException("Connection is null!!!");
+		
+		if (connect.isClosed()) {
+			connect = null;
+			keep_connect_open = false;
+			openConnection();
+		}
+		if (connect == null)
+			throw new IllegalStateException("Connection is still null!!!");
+		if (connect.isClosed())
+			throw new IllegalStateException("Connection got closed!");
+
+		stmt = connect.createStatement();
+		affected = stmt.executeUpdate(sql_command);
+	}
+
+	/******************************************************************
+	**
+	** executeQuery
+	**
+	** Send an SQL query to the DBMS to be executed.
+	**
+	*******************************************************************/
+	public ResultSet executeQuery(String cmd) throws SQLException
+	{
+		sql_command = cmd;
+
+
+		if (stmt!=null)
+			stmt.close();
+
+		if (connect == null) openConnection();
+		if (connect == null) {
+			keep_connect_open = false;
+			openConnection();
+		}
+		if (connect == null)
+			throw new IllegalStateException("Connection is null!!!");
+		
+		if (connect.isClosed()) {
+			connect = null;
+			keep_connect_open = false;
+			openConnection();
+		}
+		if (connect == null)
+			throw new IllegalStateException("Connection is still null!!!");
+		if (connect.isClosed())
+			throw new IllegalStateException("Connection got closed!");
+
+
+		//long time0 = System.currentTimeMillis();
+		stmt = connect.createStatement();
+		//long time = System.currentTimeMillis();
+		//System.err.println("###### Creating a new statement: " + (time - time0));
+		//time0 = time;
+
+		if (rs!=null)
+			rs.close();
+
+		rs = stmt.executeQuery(sql_command);
+		//time = System.currentTimeMillis();
+		//System.err.println("###### Executing the query: " + (time - time0));
+
+		if (rs == null)
+		{
+			return(null);
+		}
+
+		return(rs);
+
+
+	}
+
+	/******************************************************************
+	**
+	** getCount
+	**
+	** Will return a count when user passes sting select count(*) from ...
+	**
+	*******************************************************************/
+	public int getCount(String cmd) throws SQLException
+	{
+		sql_command = cmd;
+		int count;
+
+
+		if (stmt!=null)
+			stmt.close();
+
+		stmt = connect.createStatement();
+
+		if (rs!=null)
+			rs.close();
+
+		rs = stmt.executeQuery(sql_command);
+
+		if (rs == null)
+		{
+			return(0);
+		}
+
+		count = 0;
+
+		while (rs.next())
+		{
+			count = rs.getInt(1);
+		}
+
+		stmt.close();
+		rs.close();
+
+
+		return(count);
+
+
+	}
+	/******************************************************************
+	**
+	** commit
+	**
+	**
+	**
+	*******************************************************************/
+	public void commit() throws SQLException
+	{
+		connect.commit();
+	}
+
+	/******************************************************************
+	**
+	** rollback
+	**
+	**
+	**
+	*******************************************************************/
+	public void rollback()
+	{
+		try
+		{
+			if (connect != null)
+				connect.rollback();
+		}
+
+		catch (SQLException e)
+		{
+
+		}
+	}
+
+	 protected void finalize() throws Throwable
+	{
+		try
+		{
+			if ((connect != null) && (!keep_connect_open))
+			{
+				connect.close();
+
+			}
+
+			if (rs != null)
+			{
+				rs.close();
+			}
+
+			if (stmt != null)
+			{
+				stmt.close();
+			}
+
+		}
+		catch (SQLException e)
+		{
+		}
+	}
+
+	/******************************************************************
+	**
+	** Convert Date to string in format for
+	** Oracle TO_DATE processing - DD-MM-YY HH24:MI:SS
+	**
+	**
+	*******************************************************************/
+
+
+	public String toDateStr(java.util.Date inDate)
+	{
+
+		String outDate;
+/*
+		outDate = Integer.toString(inDate.getDate()) + "-" +
+			   Integer.toString(inDate.getMonth() + 1) + "-" +
+			   Integer.toString(inDate.getYear()) + " " +
+			   Integer.toString(inDate.getHours()) + ":" +
+			   Integer.toString(inDate.getMinutes()) + ":" +
+			   Integer.toString(inDate.getSeconds());
+		return(outDate);
+*/
+
+		SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
+		String dateStr = fmt.format(inDate);
+
+		return dateStr;
+
+
+	}
+
+	public Connection getConnection() throws SQLException
+	{
+		if (connect == null) openConnection();
+		if (connect == null) {
+			keep_connect_open = false;
+			openConnection();
+		}
+		if (connect == null)
+			throw new IllegalStateException("getConnection can't get a connection pointer");
+		return(connect);
+	}
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LDAP.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LDAP.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LDAP.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LDAP.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,58 @@
+// 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.*;
+
+/** LDAP services.
+ *
+ * This class provides LDAP convenience services.
+ *
+ * @author Kelly
+ */
+public class LDAP {
+	/** Convert the given string into an LDAP-safe query string.
+	 *
+	 * This method escapes certain characters that are special in LDAP query strings.
+	 *
+	 * @return An escaped, LDAP-safe string.
+	 */
+	public static String toLDAPString(String str) {
+		StringBuffer result = new StringBuffer();
+		for (int i = 0; i < str.length(); ++i) {
+			char ch = str.charAt(i);
+			switch (ch) {
+				case '*':
+					result.append("\\2a");
+					break;
+				case '(':
+					result.append("\\28");
+					break;
+				case ')':
+					result.append("\\29");
+					break;
+				case '\\':
+					result.append("\\5c");
+					break;
+				default:
+					result.append(ch);
+					break;
+			}
+		}
+		return result.toString();
+	}
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogEventMultiplexer.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogEventMultiplexer.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogEventMultiplexer.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogEventMultiplexer.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,76 @@
+// 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.beans.PropertyChangeEvent;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.oodt.commons.io.LogEvent;
+import org.apache.oodt.commons.io.LogListener;
+
+/** Multiplexer for logging events.
+ *
+ * @author Kelly
+ */
+public class LogEventMultiplexer implements LogListener {
+	/** Add an event listener.
+	 *
+	 * @param listener Listener to add.
+	 */
+	public void addListener(LogListener listener) {
+		listeners.add(listener);
+	}
+
+	/** Remove an event listener.
+	 *
+	 * @param listener Listener to remove.
+	 */
+	public void removeListener(LogListener listener) {
+		listeners.remove(listener);
+	}
+
+	public void messageLogged(LogEvent event) {
+		for (Iterator i = listeners.iterator(); i.hasNext();) {
+			LogListener listener = (LogListener) i.next();
+			listener.messageLogged(event);
+		}
+	}
+
+	public void streamStarted(LogEvent event) {
+		for (Iterator i = listeners.iterator(); i.hasNext();) {
+			LogListener listener = (LogListener) i.next();
+			listener.streamStarted(event);
+		}
+	}
+
+	public void streamStopped(LogEvent event) {
+		for (Iterator i = listeners.iterator(); i.hasNext();) {
+			LogListener listener = (LogListener) i.next();
+			listener.streamStopped(event);
+		}
+	}
+
+	public void propertyChange(PropertyChangeEvent event) {
+		for (Iterator i = listeners.iterator(); i.hasNext();) {
+			LogListener listener = (LogListener) i.next();
+			listener.propertyChange(event);
+		}
+	}
+
+	/** List of listeners to which I multiplex events. */
+	private List listeners = new ArrayList();
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogInit.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogInit.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogInit.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/LogInit.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,120 @@
+// 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.util.*;
+import org.apache.oodt.commons.io.*;
+import java.beans.PropertyChangeEvent;
+
+/**
+	The <code>LogInit</code> class is intended to be used to initialize
+	the logging capability implemented by the {@link Log} class.
+
+	Maybe someday the <code>init</code> method will become part of the 
+	{@link Log} class.
+
+	@author S. Hardman
+	@version $Revision: 1.1.1.1 $
+	@see Log
+*/
+public class LogInit {
+
+	/**
+		Constructor given no arguments.
+
+		This is a static-only class that may not be instantiated.
+
+		@throws IllegalStateException If the class is instantiated.
+	*/
+	public LogInit() throws IllegalStateException {
+		throw new IllegalStateException("LogInit(): Instantiation of this class is not allowed.");
+	}
+
+
+	/**
+		Initialize the logging capability as specified in the configuration.
+
+		@param props The system properties.
+		@param source The default source to be included in messages.
+		@throws Exception If the logging capability cannot be initialized.
+	*/
+	public static void init(Properties props, String source) throws Exception {
+		// Set up the log event pipeline: filter -> multiplexer -> memory
+		// log/user-specified log.  First the multiplexer.
+		LogEventMultiplexer mux = new LogEventMultiplexer();
+
+		// One destination out of the multiplexer is the in-memory round-robin logger.
+		mux.addListener(MEMORY_LOGGER);
+
+		// Another destination is any user-specified logger.
+		String userSpecifiedListener = props.getProperty("org.apache.oodt.commons.util.LogInit.listener");
+		if (userSpecifiedListener != null)
+			mux.addListener((LogListener) Class.forName(userSpecifiedListener).newInstance());
+
+		// Ahead of the multiplexer is the filter.
+		String categoryList = props.getProperty("org.apache.oodt.commons.util.LogInit.categories", "");
+		StringTokenizer tokens = new StringTokenizer(categoryList);
+		Object[] categories = new Object[tokens.countTokens()];
+		for (int i = 0; i < categories.length; ++i)
+			categories[i] = tokens.nextToken();
+		EnterpriseLogFilter filter = new EnterpriseLogFilter(mux, true, categories);
+		Log.addLogListener(filter);
+
+		// And set the source label.
+		Log.setDefaultSource(source);
+	}
+
+	/** Log filter that uses strings as category objects.
+	 */
+	public static class EnterpriseLogFilter extends LogFilter {
+		/** Construct an EnterpriseLogFilter.
+		 *
+		 * @param listener What object will get filtered log messages.
+		 * @param passThrough If true, pass messages through by default and filter out the
+		 * specified <var>categories</var> of messages. If false, filter out messages by
+		 * default and pass through the specified <var>categories</var>.
+		 * @param categories Categories of messages to filter out (if
+		 * <var>passThrough</var> is true) or to pass through (if <var>passThrough</var>
+		 * is false).
+		 */
+		public EnterpriseLogFilter(LogListener listener, boolean passThrough, Object[] categories) {
+			super(listener, passThrough, categories);
+			PropertyMgr.addPropertyChangeListener(this);
+		}
+
+		/** Update the list of categories to either pass-through or filter out.
+		 *
+		 * @param event Property change event.
+		 */
+		public void propertyChange(PropertyChangeEvent event) {
+			String key = event.getPropertyName();
+			if ("org.apache.oodt.commons.util.LogInit.categories".equals(key)) {
+				String categoriesList = (String) event.getNewValue();
+				categories.clear();
+				if (categoriesList != null) {
+					StringTokenizer tokens = new StringTokenizer(categoriesList);
+					categories.put(tokens.nextToken(), DUMMY);
+				}
+				Log.get("Info").println("Enterprise log now filtering out " + (categoriesList == null?
+					"all categories of messages" : "messages in categories " + categoriesList));
+			}
+		}
+	}
+
+	/** The single memory logger for an application. */
+	public static final MemoryLogger MEMORY_LOGGER = new MemoryLogger();
+}
+

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/MemoryLogger.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/MemoryLogger.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/MemoryLogger.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/MemoryLogger.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,100 @@
+// 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.beans.PropertyChangeEvent;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Iterator;
+import org.apache.oodt.commons.io.LogListener;
+import org.apache.oodt.commons.io.LogEvent;
+
+/** In-memory logger.
+ *
+ * This logger maintains log messages in memory.
+ *
+ * @author Kelly
+ */
+public class MemoryLogger implements LogListener {
+	/** Create a memory logger.
+	 *
+	 * The size of the message cache comes from the system property <code>org.apache.oodt.commons.util.MemoryLogger.size</code>,
+	 * or {@link #DEF_SIZE} if that property isn't specified.
+	 */
+	public MemoryLogger() {
+		this(Integer.getInteger("org.apache.oodt.commons.util.MemoryLogger.size", DEF_SIZE).intValue());
+	}
+
+	/** Create a memory logger.
+	 *
+	 * @param size Size of the message cache.
+	 */
+	public MemoryLogger(int size) {
+		this.size = size;
+	}
+
+	/** Get the list of messages logged so far.
+	 *
+	 * This returns a list of {@link String}s in time order.
+	 *
+	 * @return A list of message strings.
+	 */
+	public List getMessages() {
+		return (List) messages.clone();
+	}
+
+	/** Get the maximum size of the cache.
+	 *
+	 * @return The maximum size of the cache.
+	 */
+	public int getSize() {
+		return size;
+	}
+
+	/** Set the maximum size of the cache.
+	 *
+	 * @param size The new maximum cache size.
+	 */
+	public void setSize(int size) {
+		if (size < 0) throw new IllegalArgumentException("Log cache size can't be negative");
+		int delta = this.size - size;
+		this.size = size;
+		if (delta <= 0) return;
+		if (messages.size() < size) return;
+		while (delta-- > 0)
+			messages.removeFirst();
+	}
+
+	public void streamStarted(LogEvent ignore) {}
+	public void streamStopped(LogEvent ignore) {}
+	public void propertyChange(PropertyChangeEvent ignore) {}
+
+	public void messageLogged(LogEvent event) {
+		messages.add(DateConvert.isoFormat(event.getTimestamp()) + " " + event.getSource() + " " + event.getCategory()
+			+ ": " + event.getMessage());
+		if (messages.size() > size)
+			messages.removeFirst();
+	}
+
+	/** The list of messages. */
+	private LinkedList messages = new LinkedList();
+
+	/** Maximum size of message cache. */
+	private int size;
+
+	/** The default size of the message cache, 32. */
+	public static final int DEF_SIZE = 32;
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/PropertyMgr.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/PropertyMgr.java?rev=964249&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/PropertyMgr.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/util/PropertyMgr.java Wed Jul 14 23:03:30 2010
@@ -0,0 +1,61 @@
+// 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.util.*;
+import java.beans.*;
+
+/** Property manager manages updates to properties.
+ *
+ * @author Kelly
+ */
+public class PropertyMgr {
+	/** Add a listener for property changes.
+	 *
+	 * @param listener Listener to add.
+	 */
+	public static void addPropertyChangeListener(PropertyChangeListener listener) {
+		listeners.add(listener);
+	}
+
+	/** Remove a listener's interest in property changes.
+	 *
+	 * @param listener Listener to remove.
+	 */
+	public static void removePropertyChangeListener(PropertyChangeListener listener) {
+		listeners.remove(listener);
+	}
+
+	/** Set a property and notify listeners.
+	 *
+	 * @param key Property's name.
+	 * @param value New property's value.
+	 */
+	public static void setProperty(String key, String value) {
+		String oldValue = System.getProperty(key);
+		System.setProperty(key, value);
+		if (!listeners.isEmpty()) {
+			PropertyChangeEvent event = new PropertyChangeEvent(System.getProperties(), key, oldValue, value);
+			for (Iterator i = listeners.iterator(); i.hasNext();) {
+				PropertyChangeListener listener = (PropertyChangeListener) i.next();
+				listener.propertyChange(event);
+			}
+		}
+	}
+
+	/** Property change listeners. */
+	private static List listeners = new ArrayList();
+}