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:02:32 UTC

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

Author: kelly
Date: Wed Jul 14 23:02:32 2010
New Revision: 964248

URL: http://svn.apache.org/viewvc?rev=964248&view=rev
Log:
WIP OODT-15
Import additional OODT commons: enterprise config, server, executables, etc.
(Does anyone use this crap?)

Added:
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Configuration.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfigurationEntityResolver.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfiguredTestCase.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/EDAException.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServer.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServerConfig.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Executable.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Initializer.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/MultiServer.java
    incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Service.java

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Configuration.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Configuration.java?rev=964248&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Configuration.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Configuration.java Wed Jul 14 23:02:32 2010
@@ -0,0 +1,735 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE 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;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.*;
+import org.apache.oodt.commons.util.*;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.NoInitialContextException;
+import java.rmi.registry.Registry;
+import java.util.StringTokenizer;
+
+/** EDA Configuration.
+ *
+ * An object of this class represents the configuration information for the EDA software.
+ *
+ * @author Kelly
+ */
+public class Configuration {
+	/** The singleton configuration. */
+	static Configuration configuration = null;
+
+	/** Name of property that specifies the direcotries that contains XML entities. */
+	public static final String ENTITY_DIRS_PROP = "entity.dirs";
+
+	/** Name of the default config file. */
+	public static final String DEFAULT_CONFIG_FILE = ".edarc.xml";
+
+	/** Alternate config file. */
+	public static final String ALT_CONFIG_FILE = ".oodtrc.xml";
+
+	/** Library-location config file. */
+	public static final File LIB_CONFIG_FILE = new File(System.getProperty("java.home", "/") + File.separator + "lib"
+		+ File.separator + "edarc.xml");
+
+	/** Non-JRE library location of config file. */
+	public static final File ALT_LIB_CONFIG_FILE = new File(System.getProperty("java.home", "/") + File.separator + ".."
+		+ File.separator + "lib" + File.separator + "edarc.xml");
+
+	 /** Get the singleton configuration.
+	  *
+	  * This method returns the singleton configuration object, or creates it if it
+	  * doesn't yet exist.  To create it, it reads the configuration file specified by
+	  * the system property <code>org.apache.oodt.commons.Configuration.url</code> or the file in the
+	  * user's home directory called .edarc.xml if the system property isn't
+	  * specified.  It parses the file and returns a <code>Configuration</code> object
+	  * initialized with the data specified therein.
+	  *
+	  * @throws IOException If reading the configuration file fails.
+	  * @throws SAXException If parsing the configuration file fails.
+	  * @throws MalformedURLException If the URL specification is invalid.
+	  * @return An initialized configuration object.
+	  */
+	 public static Configuration getConfiguration() throws IOException, SAXException, MalformedURLException {
+		 // Got one?  Use it.
+		 if (configuration != null) return configuration;
+
+		 URL url;
+
+		 // First preference: URL via the org.apache.oodt.commons.Configuration.url prop.
+		 String urlString = System.getProperty("org.apache.oodt.commons.Configuration.url");
+		 if (urlString != null) {
+			 url = new URL(urlString);
+		 } else {
+			 File file = null;
+
+			 // Second preference: file via the org.apache.oodt.commons.Configuration.file prop.
+			 String filename = System.getProperty("org.apache.oodt.commons.Configuration.file");
+			 if (filename != null) {
+				 file = new File(filename);
+				 if (!file.exists()) throw new IOException("File " + file + " not found");
+			 } else {
+				 List candidates = new ArrayList();
+
+				 // Third preference: ~/.edarc.xml
+				 File homedir = new File(System.getProperty("user.home", "/"));
+				 File homedirfile = new File(homedir, DEFAULT_CONFIG_FILE);
+				 candidates.add(homedirfile);
+
+				 // Fourth preference: ~/.oodtrc.xml
+				 File alt = new File(homedir, ALT_CONFIG_FILE);
+				 candidates.add(alt);
+
+				 // Fifth and sixth preferences: $EDA_HOME/conf/edarc.xml and $EDA_HOME/etc/edarc.xml
+				 String edaHome = System.getProperty("eda.home");
+				 if (edaHome != null) {
+					 File edaHomeDir = new File(edaHome);
+					 candidates.add(new File(new File(edaHomeDir, "conf"), "edarc.xml"));
+					 candidates.add(new File(new File(edaHomeDir, "etc"), "edarc.xml"));
+				 }
+
+				 // Seventh preference: JAVA_HOME/lib/edarc.xml
+				 candidates.add(LIB_CONFIG_FILE);
+
+				 // Final preference: JAVA_HOME/../lib/edarc.xml (to get out of JRE)
+				 candidates.add(ALT_LIB_CONFIG_FILE);
+
+				 // Now find one.
+				 boolean found = false;
+				 for (Iterator i = candidates.iterator(); i.hasNext();) {
+					 file = (File) i.next();
+					 if (file.exists()) {
+						 found = true;
+						 break;
+					 }
+				 }
+				 if (found && file == alt)
+					 System.err.println("WARNING: Using older config file " + alt + "; rename to "
+						 + homedirfile + " as soon as possible.");
+				 if (!found) {
+					 return getEmptyConfiguration();
+				 }
+			 }
+			 url = file.toURL();
+		 }
+
+		 return getConfiguration(url);
+
+	 }
+
+	/** Get the singleton configuration.
+	 *
+	 * This method returns the singleton configuration object from a 
+	 * specified file url.  It parses the file and returns a <code>Configuration</code> object
+	 * initialized with the data specified therein.  Added by Chris Mattmann 12/05/03.
+	 *
+	 * @throws IOException If an I/O error occurs.
+	 * @return An initialized configuration object.
+	 */
+	public static Configuration getConfiguration(URL configFileUrl) throws SAXException, IOException {
+		synchronized (Configuration.class) {
+			if (configuration == null)
+				configuration = new Configuration(configFileUrl);
+		}
+		return configuration;
+	}
+
+	private static Configuration getEmptyConfiguration() {
+		synchronized (Configuration.class) {
+			if (configuration == null)
+				configuration = new Configuration();
+		}
+		return configuration;
+	}
+
+
+	/** Get the singleton configuration without exception.
+	 *
+	 * This method is identical to {@link #getConfiguration} but traps all checked
+	 * exceptions.  If the configuration can't be read, it returns null.
+	 *
+	 * @return An initialized configuration object, or null if an error occurred.
+	 */
+	public static Configuration getConfigurationWithoutException() {
+		// Got one?  Use it.  Do this out of a try block for performance.
+		if (configuration != null) return configuration;
+
+		// Try to get it.
+		try {
+			return getConfiguration();
+		} catch (RuntimeException ex) {
+			throw ex;
+		} catch (Exception ex) {
+			System.err.println("Exception " + ex.getClass().getName() + " while getting configuration: "
+				+ ex.getMessage());
+			ex.printStackTrace();
+			return null;
+		}
+	}
+
+	Configuration() {
+		serverMgrPort = 7577;
+		nameServerStateFrequency = 6000000;
+		nameServerObjectKey = "StandardNS%20POA";
+		nameServerPort = "10000";
+		nameServerHost = "localhost";
+		nameServerVersion = "1.0";
+		nameServerUsingRIRProtocol = false;
+		webServerDocumentDirectory = new File(System.getProperty("user.home", "/") + "tomcat/webapps/ROOT");
+		webPort = "8080";
+		webHost = "localhost";
+		System.setProperty(WEB_PROTOCOL_PROPERTY, "http");
+		initializeContext();
+	}
+
+	/** Construct a configuration.
+	 *
+	 * @param url The location of the configuration.
+	 * @throws IOException If reading the configuration file fails.
+	 * @throws SAXParseException If parsing the configuration file fails.
+	 */
+	Configuration(URL url) throws IOException, SAXException {
+		this(new InputSource(url.toString()));
+	}
+
+	Configuration(InputSource inputSource) throws IOException, SAXException {
+		String systemID = inputSource.getSystemId();
+		if (systemID == null) inputSource.setSystemId("file:/unknown");
+
+		// Get the document
+		DOMParser parser = XML.createDOMParser();
+		parser.setEntityResolver(new ConfigurationEntityResolver());
+		parser.setErrorHandler(new ErrorHandler() {
+			public void error(SAXParseException ex) throws SAXException {
+				throw ex;
+			}
+			public void warning(SAXParseException ex) {
+				System.err.println("Warning: " + ex.getMessage());
+			}
+			public void fatalError(SAXParseException ex) throws SAXException {
+				System.err.println("Fatal parse error: " + ex.getMessage());
+				throw ex;
+			}
+		});
+		parser.parse(inputSource);
+		Document document = parser.getDocument();
+		XML.removeComments(document);
+		document.normalize();
+		
+		// See if this really is a <configuration> document.
+		if (!document.getDocumentElement().getNodeName().equals("configuration"))
+			throw new SAXException("Configuration " + inputSource.getSystemId() + " is not a <configuration> document");
+
+		NodeList list = document.getDocumentElement().getChildNodes();
+		for (int eachChild = 0; eachChild < list.getLength(); ++eachChild) {
+			Node childNode = list.item(eachChild);
+			if (childNode.getNodeName().equals("webServer")) {
+				NodeList children = childNode.getChildNodes();
+				for (int i = 0; i < children.getLength(); ++i) {
+					Node node = children.item(i);
+					if ("host".equals(node.getNodeName()))
+						webHost = XML.unwrappedText(node);
+					else if ("port".equals(node.getNodeName()))
+						webPort = XML.unwrappedText(node);
+					else if ("dir".equals(node.getNodeName()))
+						webServerDocumentDirectory = new File(XML.unwrappedText(node));
+				}					
+				properties.setProperty("org.apache.oodt.commons.Configuration.webServer.baseURL", getWebServerBaseURL());
+				if (webServerDocumentDirectory == null)
+					webServerDocumentDirectory = new File(System.getProperty("user.home", "/")
+						+ "/dev/htdocs");
+			} else if (childNode.getNodeName().equals("nameServer")) {
+				Element nameServerNode = (Element) childNode;
+				String nameServerStateFrequencyString = nameServerNode.getAttribute("stateFrequency");
+				if (nameServerStateFrequencyString == null || nameServerStateFrequencyString.length() == 0)
+					nameServerStateFrequency = 0;
+				else try {
+					nameServerStateFrequency = Integer.parseInt(nameServerStateFrequencyString);
+				} catch (NumberFormatException ex) {
+					throw new SAXException("Illegal nun-numeric value \"" + nameServerStateFrequencyString
+						+ "\" for stateFrequency attribute");
+				}
+				if (childNode.getFirstChild().getNodeName().equals("rir")) {
+					nameServerUsingRIRProtocol = true;
+					NodeList children = childNode.getFirstChild().getChildNodes();
+					nameServerObjectKey = children.getLength() == 1? XML.unwrappedText(children.item(0)):null;
+				} else {
+					nameServerUsingRIRProtocol = false;
+					nameServerVersion = null;
+					nameServerPort = null;
+					// Must be same as CORBAMgr.NS_OBJECT_KEY:
+					nameServerObjectKey = "StandardNS/NameServer%2DPOA/_root";
+					NodeList children = childNode.getFirstChild().getChildNodes();
+					for (int i = 0; i < children.getLength(); ++i) {
+						Node node = children.item(i);
+						if (node.getNodeName().equals("version"))
+							nameServerVersion = XML.unwrappedText(node);
+						else if (node.getNodeName().equals("host"))
+							nameServerHost = XML.unwrappedText(node);
+						else if (node.getNodeName().equals("port"))
+							nameServerPort = XML.unwrappedText(node);
+						else if (node.getNodeName().equals("objectKey"))
+							nameServerObjectKey = XML.unwrappedText(node);
+					}
+				}
+			} else if (childNode.getNodeName().equals("xml")) {
+				NodeList children = childNode.getChildNodes();
+				for (int i = 0; i < children.getLength(); ++i) {
+					Node xmlNode = children.item(i);
+					if ("entityRef".equals(xmlNode.getNodeName())) {
+						NodeList dirNodes = xmlNode.getChildNodes();
+						StringBuffer refDirs = new StringBuffer(System.getProperty(ENTITY_DIRS_PROP, ""));
+						for (int j = 0; j < dirNodes.getLength(); ++j)
+							refDirs.append(',').append(XML.unwrappedText(dirNodes.item(j)));
+						if (refDirs.length() > 0)
+							System.setProperty(ENTITY_DIRS_PROP, refDirs.charAt(0) == ','?
+								refDirs.substring(1) : refDirs.toString());
+					}
+				}
+			} else if ("serverMgr".equals(childNode.getNodeName())) {
+				serverMgrPort = Integer.parseInt(XML.unwrappedText(childNode.getFirstChild()));
+			} else if (childNode.getNodeName().equals("properties")) {
+				loadProperties(childNode, properties);
+			} else if (childNode.getNodeName().equals("programs")) {
+				NodeList children = childNode.getChildNodes();
+				for (int i = 0; i < children.getLength(); ++i) {
+					// They're all of type execServer---for now.
+					ExecServerConfig esc = new ExecServerConfig(children.item(i));
+					esc.getProperties().setProperty("org.apache.oodt.commons.Configuration.url", inputSource.getSystemId());
+					execServers.add(esc);
+				}
+			}
+		}
+
+		initializeContext();
+	}
+
+	private void initializeContext() {
+		contextEnvironment.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.oodt.commons.object.jndi.ObjectCtxFactory");
+		String registryList = System.getProperty("org.apache.oodt.commons.rmiregistries", System.getProperty("rmiregistries"));
+		if (registryList == null) {
+			String host = System.getProperty("rmiregistry.host", "localhost");
+			int port = Integer.getInteger("rmiregistry.port", Registry.REGISTRY_PORT).intValue();
+			registryList = "rmi://" + host + ":" + port;
+		}
+		contextEnvironment.put("rmiregistries", registryList);
+	}
+
+	/** Serialize this configuration into a serialized XML document.
+	 *
+	 * @return Serialized XML version of this configuration.
+	 * @throws DOMException If an error occurs constructing the XML structure.
+	 */
+	public String toXML() throws DOMException {
+		Document doc = createDocument("configuration");
+		doc.replaceChild(toXML(doc), doc.getDocumentElement());
+		return XML.serialize(doc);
+	}
+
+	/** 
+	 *
+	 * @param document The document to which the XML structure will belong.
+	 * @return The root node representing this configuration.
+	 * @throws DOMException If an error occurs constructing the XML structure.
+	 */
+	public Node toXML(Document document) throws DOMException {
+		// <configuration>
+		Element configurationNode = document.createElement("configuration");
+
+		// <webServer>
+		Element webServerNode = document.createElement("webServer");
+		configurationNode.appendChild(webServerNode);
+
+		// <webServer>
+		//   <host>...</host><port>...</port><dir>...</dir>
+		XML.add(webServerNode, "host", webHost);
+		XML.add(webServerNode, "port", webPort);
+		XML.add(webServerNode, "dir", webServerDocumentDirectory.toString());
+
+		// <nameServer>
+		Element nameServerNode = document.createElement("nameServer");
+		nameServerNode.setAttribute("stateFrequency", String.valueOf(nameServerStateFrequency));
+		configurationNode.appendChild(nameServerNode);
+
+		// <nameServer>
+		//   <rir> or <iiop>
+		if (nameServerUsingRIRProtocol) {
+			Element rirNode = document.createElement("rir");
+			nameServerNode.appendChild(rirNode);
+			if (nameServerObjectKey != null)
+				XML.add(rirNode, "objectKey", nameServerObjectKey);
+		} else {
+			Element iiopNode = document.createElement("iiop");
+			nameServerNode.appendChild(iiopNode);
+			if (nameServerVersion != null)
+				XML.add(iiopNode, "version", nameServerVersion);
+			XML.add(iiopNode, "host", nameServerHost);
+			if (nameServerPort != null)
+				XML.add(iiopNode, "port", nameServerPort);
+			if (nameServerObjectKey != null)
+				XML.add(iiopNode, "objectKey", nameServerObjectKey);
+		}
+
+		// <xml><entityRef><dir>...
+		if (!getEntityRefDirs().isEmpty()) {
+			Element xmlNode = document.createElement("xml");
+			configurationNode.appendChild(xmlNode);
+			Element entityRefNode = document.createElement("entityRef");
+			xmlNode.appendChild(entityRefNode);
+			XML.add(entityRefNode, "dir", getEntityRefDirs());
+		}
+
+		// <serverMgr><port>...
+		if (getServerMgrPort() != 0) {
+			Element serverMgrNode = document.createElement("serverMgr");
+			configurationNode.appendChild(serverMgrNode);
+			XML.add(serverMgrNode, "port", String.valueOf(getServerMgrPort()));
+		}
+
+		// Global <properties>...</properties>
+		if (properties.size() > 0)
+			dumpProperties(properties, configurationNode);
+
+		// <programs>...
+		if (execServers.size() > 0) {
+			Element programsNode = document.createElement("programs");
+			configurationNode.appendChild(programsNode);
+
+			for (Iterator i = execServers.iterator(); i.hasNext();) {
+				ExecServerConfig esc = (ExecServerConfig) i.next();
+				Element execServerNode = document.createElement("execServer");
+				programsNode.appendChild(execServerNode);
+				XML.add(execServerNode, "class", esc.getClassName());
+				XML.add(execServerNode, "objectKey", esc.getObjectKey());
+				XML.add(execServerNode, "host", esc.getPreferredHost().toString());
+				if (esc.getProperties().size() > 0)
+					dumpProperties(esc.getProperties(), execServerNode);
+			}
+		}
+
+		return configurationNode;
+	}
+
+	/** Merge the properties in the configuration into the given properties.
+	 *
+	 * Properties that already exist in the <var>targetProps</var> won't be
+	 * overwritten.
+	 *
+	 * @param targetProps The target properties.
+	 */
+	public void mergeProperties(Properties targetProps) {
+		for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
+			Map.Entry entry = (Map.Entry) i.next();
+			if (!targetProps.containsKey(entry.getKey()))
+				targetProps.put(entry.getKey(), entry.getValue());
+		}
+	}
+
+	/** Get the exec-server configurations.
+	 *
+	 * @return A collection of exec server configurations, each of class {@link ExecServerConfig}.
+	 */
+	public Collection getExecServerConfigs() {
+		return execServers;
+	}
+
+        /** Get the exec-server configurations.
+         *
+         * @param clazz The class of exec servers that will be returned.
+         * @return A collection of exec server configurations, each of class {@link ExecServerConfig}.
+         */
+        public Collection getExecServerConfigs(Class clazz) {
+                String className = clazz.getName();
+                Collection execServerConfigs = new ArrayList();
+                for (Iterator i = execServers.iterator(); i.hasNext();) {
+                        ExecServerConfig exec = (ExecServerConfig) i.next();
+                        if (className.equals(exec.getClassName()))
+                                execServerConfigs.add(exec);
+                }
+                return execServerConfigs;
+        }
+
+        /** Get an exec-server configuration.
+         *
+         * @param objectKey The object key of the Exec Server to retrieve.
+         * @return An {@link ExecServerConfig} or null if object key not found.
+         */
+        public ExecServerConfig getExecServerConfig(String objectKey) {
+                ExecServerConfig execServerConfig = null;
+                for (Iterator i = execServers.iterator(); i.hasNext() && execServerConfig == null;) {
+                        ExecServerConfig exec = (ExecServerConfig) i.next();
+                        if (objectKey.equals(exec.getObjectKey()))
+                                execServerConfig = exec;
+                }
+                return execServerConfig;
+        }
+
+	/** Get the web server base URL.
+	 *
+	 * @return The base web server URL.
+	 */
+	public String getWebServerBaseURL() {
+		String proto = System.getProperty(WEB_PROTOCOL_PROPERTY);
+		if (proto == null) {
+			if ("443".equals(webPort)) proto = "https";
+			else proto = "http";
+		}
+		return proto + "://" + webHost + ":" + webPort;
+	}
+
+	/** Get the web server document directory.
+	 *
+	 * @return The document directory.
+	 */
+	public File getWebServerDocumentDirectory() {
+		return webServerDocumentDirectory;
+	}
+
+	/** Get the name server URL.
+	 *
+	 * @return The name server URL.
+	 */
+	public String getNameServerURL() {
+		return getWebServerBaseURL() + "/ns.ior";
+	}
+
+	/** Get the name server port, if any.
+	 *
+	 * @return The port.
+	 */
+	public String getNameServerPort() {
+		return nameServerPort;
+	}
+
+	/** Get the frequency with which the name server saves its state.
+	 *
+	 * @return The state-save frequency in milliseconds; <= 0 means never save state.
+	 */
+	public int getNameServerStateFrequency() {
+		return nameServerStateFrequency;
+	}
+
+	/** Get the object context.
+	 *
+	 * @return The object context based on this configuration.
+	 * @throws NamingException If the context can't be created.
+	 */
+	public Context getObjectContext() throws NamingException {
+		Context c = null;
+		final String className = (String) contextEnvironment.get(javax.naming.Context.INITIAL_CONTEXT_FACTORY);
+		if (className == null)
+			c = new InitialContext(contextEnvironment);
+		else try {
+			// Work around iPlanet bug.  JNDI uses the thread's context class
+			// loader to load the initial context factory class.  For some
+			// reason, that loader fails to find things in iPlanet's
+			// classpath, such as the EDA initial context factory.  Here, we
+			// cut a new thread and explicitly set its context class loader to
+			// the application class loader.  When JNDI looks up the initial
+			// context factory, the thread's context class loader is the app
+			// class loader, which succeeds.
+			Class clazz = Class.forName(className);
+			final ClassLoader loader = clazz.getClassLoader();
+			InitialContextThread thread = new InitialContextThread(loader);
+			thread.start();
+			try {
+				thread.join();
+			} catch (InterruptedException ex) {
+				throw new NoInitialContextException("Initial context thread interrupted: " + ex.getMessage());
+			}
+			c = thread.getContext();
+			if (c == null)
+				throw thread.getException();
+		} catch (ClassNotFoundException ex) {
+			throw new NoInitialContextException("Class " + className + " not found");
+		}
+		return c;
+	}
+
+	/** Get the entity reference directories.
+	 *
+	 * @return A list of {@link java.lang.String}s naming directories for entity references.
+	 */
+	public List getEntityRefDirs() {
+		List dirs = new ArrayList();
+		for (StringTokenizer t = new StringTokenizer(System.getProperty(ENTITY_DIRS_PROP, ""), ",;|"); t.hasMoreTokens();)
+			dirs.add(t.nextToken());
+		return dirs;
+	}
+
+	/** Get the port number on which the server manager is listening.
+	 *
+	 * @return The port number, or 0 if there is no server manager.
+	 */
+	public int getServerMgrPort() {
+		return serverMgrPort;
+	}
+
+	/** Load the properties described in an XML properties element into the
+	 * given properties object.
+	 *
+	 * @param propertiesNode The XML node which is a <code>&lt;properties&gt;</code> element.
+	 * @param props The properties object to load with properties from <var>propertiesNode</var>.
+	 */
+	static void loadProperties(Node propertiesNode, Properties props) {
+		NodeList children = propertiesNode.getChildNodes();
+		for (int i = 0; i < children.getLength(); i += 2) {
+			String key = XML.unwrappedText(children.item(i));
+			String value = XML.unwrappedText(children.item(i+1));
+			props.setProperty(key, value);
+		}
+	}
+
+	/** Dump the properties from the given properties object in XML form, appending
+	 * them to the given node under a &lt;properties&gt; element.
+	 *
+	 * @param props The properties to dump in XML form.
+	 * @param node The node to which to append the &lt;properties&gt; element.
+	 * @throws DOMException If a DOM error occurs.
+	 */
+	static void dumpProperties(Properties props, Node node) {
+		Element propertiesElement = node.getOwnerDocument().createElement("properties");
+		node.appendChild(propertiesElement);
+		for (Iterator i = props.entrySet().iterator(); i.hasNext();) {
+			Map.Entry entry = (Map.Entry) i.next();
+			XML.add(propertiesElement, "key", (String) entry.getKey());
+			XML.add(propertiesElement, "value", (String) entry.getValue());
+		}
+	}
+
+	/** Create a new XML document with the configuration DTD.
+	 *
+	 * @param name Name to give to the document element.
+	 * @returns An XML DOM document with the doctype and the root document empty element in place.
+	 * @throws DOMException If we can't create the document.
+	 */
+	static Document createDocument(String documentElementName) throws DOMException {
+		DocumentType docType = XML.getDOMImplementation().createDocumentType(documentElementName, DTD_FPI, DTD_URL);
+		Document doc = XML.getDOMImplementation().createDocument(/*namespaceURI*/null, documentElementName, docType);
+		return doc;
+	}
+
+	/** The formal public identifier (FPI) of the configuration document type definition (DTD). */
+	public static final String DTD_FPI = "-//JPL//DTD EDA Configuration 1.0//EN";
+	
+	/** The old formal public identifier (FPI) of the configuration document type definition (DTD). */
+	public static final String DTD_OLD_FPI = "-//JPL//DTD OODT Configuration 1.0//EN";
+
+	/** The system identifier of the configuration document type definition (DTD). */
+	public static final String DTD_URL = "http://oodt.jpl.nasa.gov/edm-commons/Configuration.dtd";
+
+	/** Name of the system property that names the web protocol to use. */
+	public static final String WEB_PROTOCOL_PROPERTY = "org.apache.oodt.commons.Configuration.webProtocol";
+
+	/** Global properties. */
+	private Properties properties = new Properties();
+
+	/** Object context environment. */
+	Hashtable contextEnvironment = new Hashtable();
+
+	/** Exec-servers. */
+	private List execServers = new ArrayList();
+
+	/** Web server host. */
+	private String webHost;
+
+	/** Web server port. */
+	private String webPort;
+
+	/** Web server doc dir. */
+	private File webServerDocumentDirectory;
+
+	/** Name server using rir protocol.
+	 *
+	 * If false, then it's using iiop.
+	 */
+	private boolean nameServerUsingRIRProtocol;
+
+	/** Name server version. */
+	private String nameServerVersion;
+
+	/** Name server host. */
+	private String nameServerHost;
+
+	/** Name server port. */
+	private String nameServerPort;
+
+	/** Name server object key. */
+	private String nameServerObjectKey;
+
+	/** How often the name server saves its state. */
+	private int nameServerStateFrequency;
+
+	/** On what port the server manager will listen. */
+	private int serverMgrPort;
+
+	/** Thread to set a context class loader and get a JNDI initial context. */
+	private class InitialContextThread extends Thread {
+		/** Ctor
+		 *
+		 * @param loader What class loader to use as thread's context class loader.
+		 */
+		public InitialContextThread(ClassLoader loader) {
+			setContextClassLoader(loader);
+		}
+
+		public void run() {
+			try {
+				context = new InitialContext(contextEnvironment);
+			} catch (NamingException ex) {
+				exception = ex;
+			} catch (Throwable t) {
+				System.err.println("Unexpected throwable " + t.getClass().getName() + " getting initial context: "
+					+ t.getMessage());
+				t.printStackTrace();
+			}
+		}
+
+		/** Get the context.
+		 *
+		 * <strong>Warning!</strong> Do not call this method until the thread terminates.
+		 *
+		 * @return The context, or null if the context could not be retrieved.
+		 */
+		public Context getContext() {
+			return context;
+		}
+
+		/** Get any exception.
+		 *
+		 * @return Any exception that occurred while retrieving the context.
+		 */
+		public NamingException getException() {
+			return exception;
+		}
+
+		/** JNDI context. */
+		private Context context;
+
+		/** Any exception. */
+		private NamingException exception;
+	}
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfigurationEntityResolver.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfigurationEntityResolver.java?rev=964248&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfigurationEntityResolver.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfigurationEntityResolver.java Wed Jul 14 23:02:32 2010
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE 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;
+
+import java.io.IOException;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/** XML entity resolver for the configuration file.
+ *
+ * This resolver attempts to use a locally accessible configuration.dtd so that we can
+ * bootstrap enterprise applications without http access.  You see, The config file
+ * specifies the list of entity directories, but the config file itself is an XML document
+ * that refers to its doctype entity.  We therefore resolve the config DTD to a
+ * classpath-acessible copy.
+ *
+ * @author Kelly
+ */
+class ConfigurationEntityResolver implements EntityResolver {
+	public InputSource resolveEntity(String publicID, String systemID) throws SAXException, IOException {
+		if (Configuration.DTD_FPI.equals(publicID) || Configuration.DTD_OLD_FPI.equals(publicID))
+			return new InputSource(Configuration.class.getResourceAsStream("Configuration.dtd"));
+		return null;
+	}
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfiguredTestCase.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfiguredTestCase.java?rev=964248&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfiguredTestCase.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ConfiguredTestCase.java Wed Jul 14 23:02:32 2010
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE 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;
+
+import java.io.BufferedInputStream;
+import junit.framework.TestCase;
+import org.xml.sax.InputSource;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ * Base test case for tests that need the Configuration object.
+ *
+ * @author Kelly
+ */ 
+public abstract class ConfiguredTestCase extends TestCase {
+	/**
+	 * Creates a new {@link ConfiguredTestCase} instance.
+	 *
+	 * @param caseName Case name.
+	 */
+	protected ConfiguredTestCase(String caseName) {
+		super(caseName);
+	}
+	
+	/**
+	 * Set up a test Configuration object.
+	 *
+	 * @throws Exception if an error occurs.
+	 */
+	protected void setUp() throws Exception {
+		super.setUp();
+		if (Configuration.configuration == null) {
+			try {
+				StringReader reader = new StringReader(TSTDOC);
+				InputSource is = new InputSource(reader);
+				is.setEncoding("UTF-8");
+				is.setPublicId("-//JPL//XML EDM Test Configuration 0.0.0//EN");
+				is.setSystemId("internal:test-edarc.xml");
+				Configuration.configuration = new Configuration(is);
+				reader.close();
+			} catch (IOException ex) {
+				ex.printStackTrace();
+				throw new IllegalStateException("Unexpected IOException: " + ex.getMessage());
+			}
+		}
+	}
+
+	/** Test configuration, as a document. */
+	private static final String TSTDOC = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE configuration PUBLIC"
+		+ " \"-//JPL//DTD EDA Configuration 1.0//EN\" \"http://oodt.jpl.nasa.gov/edm-commons/Configuration.dtd\">\n"
+		+ "<configuration><webServer><host>www.jpl.nasa.gov</host><port>81</port><dir>/non/existent/htdocs</dir>"
+		+ "</webServer><nameServer><iiop><version>1</version><host>oodt.jpl.nasa.gov</host><port>82</port>"
+		+ "<objectKey>StandardNS/NameServer%2DPOA/_test</objectKey></iiop></nameServer><ldapServer>"
+		+ "<host>ldap.jpl.nasa.gov</host><port>83</port><managerDN>cn=GeorgeTestostoles,dc=test,dc=zone</managerDN>"
+		+ "<password>h1ghly;s3cr3t</password></ldapServer><xml><parser>crimson</parser><entityRef>"
+		+ "<dir>/non/existent/htdocs/xml</dir><dir>/non/existent/htdocs/dtd</dir></entityRef></xml><serverMgr>"
+		+ "<port>84</port></serverMgr><properties><key>global</key><value>1</value><key>override</key><value>2</value>"
+		+ "</properties><programs><execServer><class>TestServer</class><objectKey>urn:eda:rmi:TestObject</objectKey>"
+		+ "<host>oodt.jpl.nasa.gov</host><properties><key>local</key><value>3</value><key>override</key><value>4</value>"
+		+ "</properties></execServer><client><class>TestClient</class><properties><key>local</key><value>5</value>"
+		+ "<key>override</key><value>6</value></properties></client></programs></configuration>";
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/EDAException.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/EDAException.java?rev=964248&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/EDAException.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/EDAException.java Wed Jul 14 23:02:32 2010
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE 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;
+
+public class EDAException extends Exception {
+	public EDAException(String msg) {
+		super(msg);
+	}
+
+	public EDAException(Throwable cause) {
+		super(cause);
+	}
+
+	public EDAException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+}
+

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServer.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServer.java?rev=964248&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServer.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServer.java Wed Jul 14 23:02:32 2010
@@ -0,0 +1,474 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE 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;
+
+import java.io.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.*;
+import java.rmi.RMISecurityManager;
+import java.util.*;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import org.apache.oodt.commons.io.Log;
+import org.apache.oodt.commons.util.*;
+import org.apache.xmlrpc.XmlRpcClientLite;
+import org.apache.xmlrpc.XmlRpcServer;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+import java.rmi.Remote;
+import java.rmi.server.RemoteStub;
+import java.rmi.server.UnicastRemoteObject;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteRef;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayOutputStream;
+import org.apache.oodt.commons.io.Base64EncodingOutputStream;
+
+/** Server execution program.
+ *
+ * This is an executable class that starts a JPL EDA server.
+ *
+ * @author Kelly
+ */
+public class ExecServer {
+	/** Start a server.
+	 *
+	 * The command-line should have two arguments:
+	 *
+	 * <ol>
+	 *   <li>The fully-qualified class name of the server to execute.</li>
+	 *   <li>The object name of the server to register with the naming service.</li>
+	 * </ol>
+	 *
+	 * @param argv The command-line arguments
+	 */
+	public static void main(String[] argv) {
+		if (argv.length < 2) {
+			System.err.println("Usage: class-name-of-server object-name");
+			System.exit(1);
+		}
+
+		String className = argv[0];
+		String name = argv[1];
+
+		// Enable support of our special URLs, like stdin:
+		System.setProperty("java.protocol.handler.pkgs", "org.apache.oodt.commons.net.protocol");
+
+		try {
+			// Get the configuration.
+			configuration = Configuration.getConfiguration();
+			configuration.mergeProperties(System.getProperties());
+
+			// Set up the logger.
+			LogInit.init(System.getProperties(), name);
+
+			// Run initializers
+			try {
+				runInitializers();
+			} catch (EDAException ex) {
+				ex.printStackTrace();
+				System.exit(1);
+			}
+
+			// Create it.
+			final ExecServer server = new ExecServer(name, className);
+
+			// Print it.
+			if (Boolean.getBoolean(PRINT_IOR_PROPERTY)) {
+				if (server.getServant() instanceof RemoteObject) {
+					RemoteObject remoteObject = (RemoteObject) server.getServant();
+					RemoteStub remoteStub = (RemoteStub) RemoteObject.toStub(remoteObject);
+					RemoteRef ref = remoteStub.getRef();
+					System.out.print("RMI:");
+					System.out.flush();
+					ObjectOutputStream objOut
+						= new ObjectOutputStream(new Base64EncodingOutputStream(System.out));
+					objOut.writeObject(ref);
+					objOut.flush();
+					System.out.println();
+				} else {
+					org.omg.PortableServer.Servant servant=(org.omg.PortableServer.Servant)server.getServant();
+					org.omg.CORBA.ORB orb = servant._orb();
+					System.out.println(orb.object_to_string(servant._this_object(orb)));
+				}
+				System.out.flush();
+			}
+
+			// Bind it.
+			if (!Boolean.getBoolean(DISABLE_BINDING)) {
+				binder = new Binder(name, server);
+				binder.start();
+			}
+
+			// Prepare for the inevitable
+			Runtime.getRuntime().addShutdownHook(new Thread() {
+				public void run() {
+					server.shutdown0();
+				}
+			});
+
+			// We're done here.
+			for (;;) try {
+				Thread.currentThread().join();
+			} catch (InterruptedException ignore) {}
+		} catch (IOException ex) {
+			System.err.println("I/O error during initialization: " + ex.getMessage());
+			ex.printStackTrace();
+		} catch (SAXParseException ex) {
+			System.err.println("Error in the configuration file at line " + ex.getLineNumber() + ", column "
+				+ ex.getColumnNumber() + ": " + ex.getMessage());
+		} catch (SAXException ex) {
+			System.err.println("Error " + ex.getClass().getName() + " while attempting to parse the configuration"
+				+ " file: " + ex.getMessage());
+		} catch (javax.naming.NamingException ex) {
+			System.err.println("Naming/directory error: " + ex.getClass().getName() + ": " + ex.getMessage());
+		} catch (java.lang.reflect.InvocationTargetException ex) {
+			Throwable target = ex.getTargetException();
+			System.err.println("Constructor for \"" + className + "\" threw " + target.getClass().getName() + ": "
+				+ ex.getMessage());
+			target.printStackTrace();
+		} catch (RuntimeException ex) {
+			throw ex;
+		} catch (Exception ex) {
+			System.err.println("Exception " + ex.getClass().getName() + " initializing server \"" + name
+				+ "\" with class \"" + className + "\": " + ex.getMessage());
+			ex.printStackTrace();
+		} 
+		System.exit(1);
+	}
+
+	protected ExecServer(String name) {
+		this.name = name;
+	}
+
+	/** Create a new executable server.
+	 *
+	 * @param name Name of the server
+	 * @param className Name of class that implements the server.
+	 * @throws ClassNotFoundException If the class for <var>className</var> can't be found.
+	 * @throws NoSuchMethodException If the constructor for <var>className</var> taking a single <code>ExecServer</code>
+	 *         can't be found.
+	 * @throws InstantiationException If the class for <var>className</var> is abstract or is an interface.
+	 * @throws IllegalAccessException If the class for <var>className</var> isn't public.
+	 * @throws InvocationTargetException If an exception occurs in the constructor for <var>className</var>.
+	 * @throws DOMException If the server's status document can't be created.
+	 * @throws UnknownHostException If the local host name can't be determined.
+	 */
+	public ExecServer(String name, String className) throws ClassNotFoundException, NoSuchMethodException,
+		InstantiationException, IllegalAccessException, InvocationTargetException, DOMException, UnknownHostException {
+		this.name = name;
+
+		// Find the class and the required constructor.
+		Class clazz = Class.forName(className);
+		Constructor ctor = clazz.getConstructor(new Class[]{ExecServer.class});
+
+		// Invoke the constructor to create the servant.
+		servant = ctor.newInstance(new Object[]{this});
+		Date startDate = new Date();
+
+		// Create the XML-RPC interface to this server.
+		xmlrpcServer = new XmlRpcServer();
+		xmlrpcServer.addHandler("server", this);
+
+		// Create the server status document.
+		DocumentType docType = XML.getDOMImplementation().createDocumentType("server", STATUS_FPI, STATUS_URL);
+		statusDocument = XML.getDOMImplementation().createDocument(/*namespaceURI*/null, "server", docType);
+		Element serverElement = statusDocument.getDocumentElement();
+		XML.add(serverElement, "name", name);
+		XML.add(serverElement, "class", className);
+		XML.add(serverElement, "state", "up");
+		Element startElement = statusDocument.createElement("start");
+		serverElement.appendChild(startElement);
+		Element userElement = statusDocument.createElement("user");
+		startElement.appendChild(userElement);
+		XML.add(userElement, "name", System.getProperty("user.name", "UNKNOWN"));
+		XML.add(userElement, "cwd", System.getProperty("user.dir", "UNKNOWN"));
+		XML.add(userElement, "home", System.getProperty("user.home", "UNKNOWN"));
+		Element dateElement = statusDocument.createElement("date");
+		startElement.appendChild(dateElement);
+		dateElement.setAttribute("ms", String.valueOf(startDate.getTime()));
+		dateElement.appendChild(statusDocument.createTextNode(startDate.toString()));
+		XML.add(startElement, "config", System.getProperty("org.apache.oodt.commons.Configuration.url", "UNKNOWN"));
+		Element hostElement = statusDocument.createElement("host");
+		serverElement.appendChild(hostElement);
+		XML.add(hostElement, "name", InetAddress.getLocalHost().getHostName());
+		Element osElement = statusDocument.createElement("os");
+		hostElement.appendChild(osElement);
+		XML.add(osElement, "name", System.getProperty("os.name", "UNKNOWN"));
+		XML.add(osElement, "version", System.getProperty("os.version", "UNKNOWN"));
+		XML.add(osElement, "arch", System.getProperty("os.arch", "UNKNOWN"));
+		Element vmElement = statusDocument.createElement("vm");
+		serverElement.appendChild(vmElement);
+		XML.add(vmElement, "name", System.getProperty("java.vm.name", "UNKNOWN"));
+		XML.add(vmElement, "version", System.getProperty("java.version", "UNKNOWN"));
+		XML.add(vmElement, "classpath", System.getProperty("java.class.path", "UNKNOWN"));
+		XML.add(vmElement, "extdirs", System.getProperty("java.ext.dirs", "UNKNOWN"));
+		logElement = statusDocument.createElement("log");
+		serverElement.appendChild(logElement);
+	}
+
+	/** Get my name.
+	 *
+	 * @return The name under which I'm registered in teh naming context.
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/** Return the servant for this executable server.
+	 *
+	 * @return The servant.
+	 */
+	public Object getServant() {
+		return servant;
+	}
+
+	/** Control this server.
+	 *
+	 * @param command Command to send to the server.
+	 * @return Results of <var>command</var>.
+	 */
+	public byte[] control(byte[] command) {
+		return xmlrpcServer.execute(new ByteArrayInputStream(command));
+	}
+
+	/** Return the server's class name.
+	 *
+	 * @return Its class name.
+	 */
+	public String getServerClassName() {
+		return className;
+	}
+
+	/** Return status of this server.
+	 *
+	 * @return Its status.
+	 */
+	public String getServerStatus() {
+		// Update the status document with the current log.
+		for (Iterator i = LogInit.MEMORY_LOGGER.getMessages().iterator(); i.hasNext();) {
+			String message = (String) i.next();
+			Element messageElement = statusDocument.createElement("message");
+			messageElement.setAttribute("xml:space", "preserve");
+			messageElement.appendChild(statusDocument.createTextNode(message));
+			logElement.appendChild(messageElement);
+		}
+
+		// Serialize the document.
+		String rc = XML.serialize(statusDocument);
+
+		// Remove all the log messages from the document.
+		NodeList children = logElement.getChildNodes();
+		for (int i = 0; i < children.getLength(); ++i)
+			logElement.removeChild(children.item(i));
+
+		// Return the serialized form, which included the log messages.
+		System.err.println(rc);
+		return rc;
+	}
+
+	/** Set a system property.
+	 *
+	 * This uses the property manager to notify property change listeners.
+	 *
+	 * @param key Property's name.
+	 * @param value New value.
+	 * @return Zero (return required for XML-RPC access).
+	 */
+	public int setSystemProperty(String key, String value) {
+		System.err.println("Setting system property \"" + key + "\" to \"" + value + "\"");
+		PropertyMgr.setProperty(key, value);
+		return 0;
+	}
+
+	/**
+	 * Call the server manager on the local system.
+	 *
+	 * @param port What port on the local system the server manager is listening.
+	 * @param user User name to use for authentication.
+	 * @param password Authenticator for <var>user</var>.
+	 * @param method What method in the server manager to call.
+	 * @param params Parameters to pass to the method named by <var>method</var>.
+	 * @return The return value from the method named by <var>method</var>.
+	 * @throws Exception If any error occurs.
+	 */
+	public Object callLocalServerManager(int port, String user, String password, String method, List params) throws Exception {
+		XmlRpcClientLite local = new XmlRpcClientLite("localhost", port);
+		local.setBasicAuthentication(user, password);
+		return local.execute(method, new Vector(params));
+	}
+
+	/** Shut down and exit.
+	 *
+	 * @return Zero.
+	 */
+	public int shutdown() {
+		// Log it.
+		System.err.println("Received shutdown command");
+
+		// Make sure we actually exit sometime soon.
+		new Thread() {
+			public void run() {
+				try {
+					Thread.sleep(15000);
+				} catch (InterruptedException ignore) {}
+				System.exit(1);
+			}
+		}.start();
+
+		// Clean up.
+		shutdown0();
+
+		// And exit.
+		System.err.println("Calling System.exit with status code 0");
+		System.exit(0);
+		return 0;
+	}
+
+	private void shutdown0() {
+		// Unbind.
+		if (!Boolean.getBoolean(DISABLE_BINDING)) try {
+			binder.stopBinding();
+			Context objectContext = configuration.getObjectContext();
+			objectContext.unbind(getName());
+			objectContext.close();
+		} catch (NamingException ignore) {}
+
+		// Kill the ORB.  YEAH!  KILL IT, KILL IT, KIIIIIIIIIIIIIIL IIIIIIIIT!!!!!!!1
+		try {
+			if (servant instanceof org.omg.PortableServer.Servant) {
+				org.omg.PortableServer.Servant s = (org.omg.PortableServer.Servant) servant;
+				org.omg.CORBA.ORB orb = s._orb();
+				orb.shutdown(false/*=>terminate without waiting for reqs to complete*/);
+			}
+		} catch (Throwable ignore) {}
+	}
+
+	/**
+	 * Binding thread.
+	 */
+	private static class Binder extends Thread {
+		public Binder(String name, ExecServer server) {
+			super("Binder for " + name);
+			setDaemon(true);
+			this.name = name;
+			this.server = server;
+			keepBinding = true;
+		}
+		public void run() {
+			while (shouldKeepBinding()) try {
+				Context objectContext = configuration.getObjectContext();
+				objectContext.rebind(name, server.getServant());
+				objectContext.close();
+			} catch (Throwable ex) {
+				System.err.println("Exception binding at " + new Date() + "; will keep trying...");
+				ex.printStackTrace();
+		        } finally {
+				try {
+					Thread.sleep(REBIND_PERIOD);
+				} catch (InterruptedException ignore) {}
+			}
+		}
+		public synchronized void stopBinding() {
+			keepBinding = false;
+		}
+		private synchronized boolean shouldKeepBinding() {
+			return keepBinding;
+		}
+		private boolean keepBinding;
+		private String name;
+		private ExecServer server;
+	}
+
+	/**
+	 * Run all initializers.
+	 *
+	 * This instantiates and calls the {@link Initializer#initialize} method of each
+	 * initializer specified by class name in a comma separated list of classes in the
+	 * system properties.  The property name is <code>org.apache.oodt.commons.initializers</code>, or
+	 * if not defined, <code>org.apache.oodt.commons.ExecServer.initializers</code>, or if not
+	 * defined, <code>initializers</code>.  And if that one's not defined, then none
+	 * are run.
+	 *
+	 * @throws EDAException if an error occurs.
+	 */
+	public static void runInitializers() throws EDAException {
+		String initList = System.getProperty("org.apache.oodt.commons.initializers",
+			System.getProperty("org.apache.oodt.commons.ExecServer.initializers", System.getProperty("initializers", "")));
+		for (Iterator i = org.apache.oodt.commons.util.Utility.parseCommaList(initList); i.hasNext();) {
+			String iname = (String) i.next();
+			try {
+				Class initClass = Class.forName(iname);
+				Initializer init = (Initializer) initClass.newInstance();
+				init.initialize();
+			} catch (ClassNotFoundException ex) {
+				System.err.println("Initializer \"" + iname + "\" not found; aborting");
+				throw new EDAException(ex);
+			} catch (InstantiationException ex) {
+				System.err.println("Initializer \"" + iname + "\" is abstract; aborting");
+				throw new EDAException(ex);
+			} catch (IllegalAccessException ex) {
+				System.err.println("Initializer \"" + iname + "\" isn't public; aborting");
+				throw new EDAException(ex);
+			} catch (EDAException ex) {
+				System.err.println("Initializer \"" + iname + "\" failed: " + ex.getMessage());
+				throw new EDAException(ex);
+			}
+		}
+	}
+
+	/** The configuration. */
+	private static Configuration configuration;
+
+	/** Object key name. */
+	protected String name;
+
+	/** The servant. */
+	private Object servant;
+
+	/** The server class name. */
+	private String className;
+
+	/** Current binder, if any. */
+	private static Binder binder;
+
+	/** Server's status document. */
+	private Document statusDocument;
+
+	/** The &lt;log&gt; element within the status document. */
+	private Element logElement;
+
+	/** The XML-RPC interface to this server. */
+	private XmlRpcServer xmlrpcServer;
+
+	/** Status DTD formal public identifier. */
+	public static final String STATUS_FPI = "-//JPL//DTD EDA Server Status 1.0";
+	
+	/** Status DTD system identifier. */
+	public static final String STATUS_URL = "http://oodt.jpl.nasa.gov/edm-commons/xml/serverStatus.dtd";
+
+	/** Name of the property that prints the server's IOR or RMI handle. */
+	public static final String PRINT_IOR_PROPERTY = "org.apache.oodt.commons.ExecServer.printIOR";
+
+	/** Name of the property that prevents binding of this object with the naming service. */
+	public static final String DISABLE_BINDING = "org.apache.oodt.commons.ExecServer.disableBinding";
+
+	/** How long to wait before bind attempts, in ms. */
+	private static final long REBIND_PERIOD = Long.getLong("org.apache.oodt.commons.ExecServer.rebindPeriod", 30*60*1000).longValue();
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServerConfig.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServerConfig.java?rev=964248&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServerConfig.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/ExecServerConfig.java Wed Jul 14 23:02:32 2010
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE 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;
+
+import java.io.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.*;
+import org.apache.oodt.commons.util.Documentable;
+import org.apache.oodt.commons.util.XML;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/** Configuration for an EDA exec-server.
+ *
+ * @author Kelly
+ */
+public class ExecServerConfig extends Executable implements Documentable {
+	/** Create an exec-server configuration.
+	 *
+	 * @param className Name of the class to execute.
+	 * @param objectKey Object key under which class will register.
+	 * @param properties Properties for the server.
+	 */
+	public ExecServerConfig(String className, String objectKey, InetAddress preferredHost, Properties properties) {
+		this.className = className;
+		this.objectKey = objectKey;
+		this.preferredHost = preferredHost;
+		this.properties = properties;
+	}
+
+	/** Create an exec-server configuration.
+	 *
+	 * @param xml XML DOM description, must be an &lt;execServer&gt; element.
+	 * @throws SAXException If <var>xml</var> is invalid.
+	 * @throws UnknownHostException If the <var>xml</var> refers to an unknown host name.
+	 */
+	public ExecServerConfig(Node xml) throws SAXException, UnknownHostException {
+		properties = new Properties();
+		preferredHost = org.apache.oodt.commons.net.Net.getLoopbackAddress();
+		NodeList children = xml.getChildNodes();
+		className = XML.unwrappedText(children.item(0));
+		objectKey = XML.unwrappedText(children.item(1));
+		for (int i = 2; i < children.getLength(); ++i) {
+			Node child = children.item(i);
+			String name = child.getNodeName();
+			if ("host".equals(name))
+				preferredHost = InetAddress.getByName(XML.unwrappedText(children.item(2)));
+			else if ("properties".equals(name))
+				Configuration.loadProperties(child, properties);
+			else throw new SAXException("Unknown node " + name + " in exec server XML");
+		}
+	}		
+
+	/** Create an exec-server configuration.
+	 *
+	 * @param xml Serialized XML description.
+	 * @throws SAXException If we can't parse <var>xml</var>.
+	 * @throws UnknownHostException If the <var>xml</var> refers to an unknown host name.
+	 */
+	public ExecServerConfig(String xml) throws SAXException, UnknownHostException {
+		this(XML.parse(xml).getDocumentElement());
+	}
+
+	protected String[] getCommandLine() {
+		String[] commandLine = new String[6 + properties.size()];
+		commandLine[0] = "java";
+		commandLine[1] = "-Xms" + initialHeap;
+		commandLine[2] = "-Xmx" + maxHeap;
+		int index = 3;
+		for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
+			Map.Entry entry = (Map.Entry) i.next();
+			commandLine[index++] = "-D" + entry.getKey() + "=" + entry.getValue();
+		}
+		commandLine[index++] = "org.apache.oodt.commons.ExecServer";
+		commandLine[index++] = className;
+		commandLine[index++] = objectKey;
+		return commandLine;
+	}
+
+	/** Get the class name I'm going to execute.
+	 *
+	 * @return The class name.
+	 */
+	public String getClassName() {
+		return className;
+	}
+
+	/** Get the object key I'm going to use.
+	 *
+	 * @return The object key.
+	 */
+	public String getObjectKey() {
+		return objectKey;
+	}
+
+	/** Get the properties for my process.
+	 *
+	 * @return The properties.
+	 */
+	public Properties getProperties() {
+		return properties;
+	}
+
+	/** Get the preferred host.
+	 *
+	 * @return The host on which this server prefers to run.
+	 */
+	public InetAddress getPreferredHost() {
+		return preferredHost;
+	}
+
+	public int hashCode() {
+		return className.hashCode() ^ objectKey.hashCode() ^ properties.hashCode();
+	}
+
+	public boolean equals(Object rhs) {
+		if (rhs == this) return true;
+		if (rhs == null || !(rhs instanceof ExecServerConfig)) return false;
+		ExecServerConfig obj = (ExecServerConfig) rhs;
+		return className.equals(obj.className) && objectKey.equals(obj.objectKey) && properties.equals(obj.properties);
+	}
+
+	public String toString() {
+		return className + " " + objectKey;
+	}
+
+	public Node toXML(Document doc) throws DOMException {
+		Element execServerElement = doc.createElement("execServer");
+		XML.add(execServerElement, "class", getClassName());
+		XML.add(execServerElement, "objectKey", getObjectKey());
+		XML.add(execServerElement, "preferredHost", getPreferredHost().toString());
+		Configuration.dumpProperties(getProperties(), execServerElement);
+		return execServerElement;
+	}
+
+	/** Yield this exce-server configuration as serialized XML.
+	 *
+	 * @return This object as a string serialized XML document.
+	 * @throws DOMException If we can't create the XML document.
+	 */
+	public String toXML() throws DOMException {
+		Document doc = Configuration.createDocument("execServer");
+		doc.replaceChild(toXML(doc), doc.getDocumentElement());
+		return XML.serialize(doc);
+	}
+
+	/** Class name for the ExecServer to execute. */
+	private String className;
+
+	/** Instance name. */
+	private String objectKey;
+
+	/** Properties for the server. */
+	private Properties properties;
+
+	/** Preferred host. */
+	private InetAddress preferredHost;
+
+	/** Initial heap size. */
+	private static String initialHeap;
+
+	/** Max heap size. */
+	private static String maxHeap;
+
+	/** Initialize the heap sizes. */
+	static {
+		Properties props = new Properties();
+		org.apache.oodt.commons.util.Utility.loadProperties(props, ExecServerConfig.class, "ExecServerConfig.properties");
+		initialHeap = props.getProperty("initialHeap", "32m");
+		maxHeap = props.getProperty("maxHeap", "128m");
+	}
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Executable.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Executable.java?rev=964248&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Executable.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Executable.java Wed Jul 14 23:02:32 2010
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE 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;
+
+import java.io.*;
+import java.util.*;
+
+/** An executable object.
+ *
+ * Objects of this class are programs that can be executed asynchronously.  Their standard
+ * output and standard error streams are shared with the parent process' standard output
+ * and error streams.
+ *
+ * @author Kelly
+ */
+public abstract class Executable {
+	/** Construct an executable.
+	 */
+	public Executable() {}
+
+	/** Get the command-line.
+	 *
+	 * @return Command-line.
+	 */
+	protected abstract String[] getCommandLine();
+
+	/** Start executing this program.
+	 *
+	 * If any error occurs while launching the program, this method notes a message to
+	 * stderr, but otherwise takes no further action.
+	 */
+	public void execute() {
+		// We force program execution to be asynchronous by cutting a new thread.
+		new Thread() {
+			public void run() {
+				try {
+					process = Runtime.getRuntime().exec(getCommandLine());
+					
+					// Read all output (standard and error output)
+					// from the process and pass it to the user.
+					redirect(process.getErrorStream(), System.err);
+					redirect(process.getInputStream(), System.out);
+				} catch (IOException ex) {
+					System.err.println("Can't execute command \"" + getCommandLine()[0] + "\": "
+						+ ex.getMessage());
+				}
+			}
+
+			/** Redirect the given input onto the given output.
+			 *
+			 * @param in The stream to read.
+			 * @param out Where to write it.
+			 */
+			private void redirect(final InputStream in, final OutputStream out) {
+				// Do this in the background, too.
+				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();
+			}
+		}.start();
+
+		// Spin until the process field is set.
+		while (process == null)
+			Thread.yield();
+	}
+
+	/** Wait for the process to terminate.
+	 *
+	 * @throws InterruptedException If the thread waiting for the termination is interrupted.
+	 * @return The exit value of the process.
+	 */
+	public int waitFor() throws InterruptedException {
+		return process.waitFor();
+	}
+
+	/** Terminate this process.
+	 */
+	public void terminate() {
+		process.destroy();
+	}
+
+	/** The process backing this executable. */
+	protected Process process;
+
+}

Added: incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Initializer.java
URL: http://svn.apache.org/viewvc/incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Initializer.java?rev=964248&view=auto
==============================================================================
--- incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Initializer.java (added)
+++ incubator/oodt/trunk/commons/src/main/java/org/apache/oodt/commons/Initializer.java Wed Jul 14 23:02:32 2010
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE 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;
+
+/**
+ * Initializer for an enterprise application.
+ *
+ * @author Kelly
+ * @version $Revision: 1.1.1.1 $
+ */
+public interface Initializer {
+	/**
+	 * Initialize the appliction.
+	 *
+	 * @throws EDAException if an error occurs.
+	 */
+	void initialize() throws EDAException;
+}