New 'Which' service; factory-driven service to provide

EnvironmentCheck-like utility with easy expandability and reporting


git-svn-id: https://svn.apache.org/repos/asf/xml/commons/trunk@225939 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
curcuru 2001-12-11 17:42:50 +00:00
parent 0451fd50ef
commit acbc352fdf
16 changed files with 2919 additions and 0 deletions

11
java/src/manifest.which Normal file
View File

@ -0,0 +1,11 @@
Manifest-Version: 1.0
Created-By: 1.2.2 (Sun Microsystems Inc.)
Main-Class: org.apache.env.Which
Name: org/apache/env
Comment: xml-commons Which environment checking utility
Implementation-Title: org.apache.env.Which
Implementation-Version: 1.0
Implementation-Vendor: Apache Software Foundation
Implementation-URL: http://xml.apache.org/commons/

404
java/src/org/apache/env/Which.java vendored Normal file
View File

@ -0,0 +1,404 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
/**
* General environment checking and version finding service.
*
* <p>Which is the command line interface to the org.apache.env
* package. Simply put, it provides a simplistic
* check of a user's actual environment for debugging and
* product support purposes by detecting the specific versions
* of commonly installed classes in the environment.</p>
*
* <p>Which and related service classes provide a framework for
* looking for version information and passing it around in
* hashtables. Users can plug in their own implementations of
* WhichProject classes to get custom version info about any
* product.</p>
*
* <p>One important usage note: you must call Which (or subclasses)
* <b>in the environment that you wish to check</b>. I.e. if you
* have a problem with a command line tool, then call Which from
* the same command line environment. If you have a problem with a
* servlet, you <b>must</b> call Which.blah() from your servlet as
* it's installed in an actual container.</p>
*
* <p>Usage-command line:
* <code>
* java org.apache.env.Which [project;WhichProject] [-options]
* </code></p>
*
* <p>Usage-from program:
* <code>
* int status = org.apache.env.Which.which(hash, projects, options);
* </code></p>
*
* <p>Original credit to org.apache.xalan.xslt.EnvironmentCheck</p>
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public class Which
{
/**
* Command line runnability.
* @param args command line args
*/
public static void main(String[] args)
{
// Create instance and have it run
Which app = new Which();
app.doMain(args);
}
/**
* Instance worker method to handle main().
* @param args command line args
*/
public void doMain(String[] args)
{
// Instance method to run from command line
if (!parseArgs(args))
{
outWriter.println(usage());
outWriter.println("Bad argument or help (?) asked for, aborting");
return;
}
Hashtable hash = new Hashtable();
// Grab info on all projects...
int status = which(hash, projectsBuf.toString(), optionsBuf.toString());
// ...then report it to a writer
reportProjectsInfo(hash, optionsBuf.toString(), status, outWriter);
}
/**
* Which - get all info.
* Worker method called from doMain or suitable for calling
* from other programs.
*
* @param hash to put information in
* @param projects to get information about
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int which(Hashtable hash, String projects, String options)
{
if (null == hash)
hash = new Hashtable();
getGeneralInfo(hash, optionsBuf.toString());
int status = getProjectsInfo(hash, projects, options);
hash.put("Which" + WhichConstant.TAG_STATUS,
WhichConstant.ITEM_DESC[status]);
return status;
}
/**
* Grab a couple of generally useful items, like classpath,
* java version, version of this file, etc..
*
* @param hash to put information in
* @param projects to get information about
*/
public void getGeneralInfo(Hashtable hash, String options)
{
hash.put("Which" + WhichConstant.TAG_VERSION, getVersion());
WhichJar.getClasspathInfo(hash, options);
try
{
hash.put("java" + WhichConstant.TAG_VERSION, System.getProperty("java.version"));
hash.put("java.runtime.name", System.getProperty("java.runtime.name"));
hash.put("file.encoding", System.getProperty("file.encoding"));
hash.put("java.vendor", System.getProperty("java.vendor"));
hash.put("os.name", System.getProperty("os.name"));
}
catch (Exception e)
{
hash.put("Which" + WhichConstant.TAG_ERROR, "Accessing System.getProperty(...) threw: " + e.toString());
}
}
/**
* Get information from various project's WhichProject impls.
*
* <p>Each project's info is put into a subhash.
* Note: if projects is null, we use DEFAULT_PROJECTS.</p>
*
* @param hash to put information in
* @param projects to get information about
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getProjectsInfo(Hashtable hash, String projects,
String options)
{
if (null == hash)
hash = new Hashtable();
if ((null == projects) || (projects.length() < 1))
{
projects = DEFAULT_PROJECTS;
hash.put("Which.special-note",
"No -projects provided, using DEFAULT_PROJECTS");
}
// For each listed project, find it's whicher
// and ask it to fill in hash
int retVal = WhichConstant.ITEM_UNKNOWN;
StringTokenizer st = new StringTokenizer(projects, SEPARATOR);
while (st.hasMoreTokens())
{
String projName = st.nextToken();
// Each project has it's info put in a subhashtable
try
{
Hashtable subHash = new Hashtable();
WhichProject proj = WhichFactory.newWhichProject(projName,
options);
int tmpRetVal = proj.getInfo(subHash, options);
hash.put(projName + WhichConstant.TAG_HASHINFO, subHash);
retVal = Math.max(tmpRetVal, retVal);
}
catch (Exception e)
{
// oops, couldn't get asked for project; report error
hash.put(projName
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR],
"newWhichProject threw: " + e.toString());
retVal = Math.max(WhichConstant.ITEM_ERROR, retVal);
}
}
return retVal;
}
/**
* Print information from which() into the PrintWriter.
*
* <p>Simplistic implementation to report to a writer.</p>
*
* @param hash to get info from (may have subhashtables)
* @param options to apply like strict or verbose
* @param status from finding version info
* @param out PrintWriter to send Properties.list()-like
* output to
*/
public void reportProjectsInfo(Hashtable hash, String options,
int status, PrintWriter out)
{
reportHashtable(hash, "Which report", out);
}
/**
* Print information from a hashtable into the PrintWriter.
*
* <p>Provides a pre-order traversal where the parent hash
* has it's output dumped before recursing to any child
* sub hashes. Sorta looks like Properties.list() output.</p>
*
* @param hash to get info from (may have subhashtables)
* @param name to print as header for this hash
* @param out PrintWriter to send Properties.list()-like
* output to
*/
protected void reportHashtable(Hashtable hash, String name,
PrintWriter out)
{
out.println("#---- BEGIN: " + name);
if (null == hash)
return;
Enumeration enum = hash.keys();
Vector v = new Vector();
while (enum.hasMoreElements())
{
Object key = enum.nextElement();
String keyStr = key.toString();
Object item = hash.get(key);
if (item instanceof Hashtable)
{
// Ensure a pre-order traversal
v.addElement(keyStr);
v.addElement((Hashtable) item);
}
else
{
out.println(keyStr + "=" + item);
}
}
enum = v.elements();
while (enum.hasMoreElements())
{
String n = (String) enum.nextElement();
Hashtable h = (Hashtable) enum.nextElement();
reportHashtable(h, n, out);
}
out.println("#---- END: " + name);
}
/**
* Return our usage statement.
* @return String of our usage
*/
protected String usage()
{
return "Which: find classes and jars in your environment\n"
+ "usage: java org.apache.env.Which [-options] [project;org.MyWhichProject]\n";
}
/**
* Parse commandline args, return false if help asked for.
*
* @param args array of commandline args
* @return true if OK, false if error/usage/help needed
*/
protected boolean parseArgs(String[] args)
{
final String OPTION_PREFIX = "-";
final String OPTION_HELP = "?";
// Parse args into instance vars, return false if fatal error
int numArgs = args.length;
for (int k = 0; k < numArgs; k++)
{
// if any arg asks for help return false
if (args[k].indexOf(OPTION_HELP) > -1)
{
return false;
}
// if any arg starts with -, add to optionsBuf
if (args[k].startsWith(OPTION_PREFIX))
{
optionsBuf.append(args[k]);
optionsBuf.append(SEPARATOR);
}
// else it's a project, add to projects
else
{
projectsBuf.append(args[k]);
projectsBuf.append(SEPARATOR);
}
}
return true;
}
/**
* Get simple version info about org.apache.env.Which and
* related classes.
* @return String of our file version
*/
public static String getVersion()
{
return "Which.java:($Revision$) " + WhichJar.getVersion();
}
/** Generic ';' separator for various items. */
public static final String SEPARATOR = ";";
/** Default set of projects to use if none provided. */
public static final String DEFAULT_PROJECTS =
"XmlCommons;Xerces;Xalan;Crimson;Ant";
/** optionsBuf. */
protected StringBuffer optionsBuf = new StringBuffer(); // various internal options
/** projectsBuf. */
protected StringBuffer projectsBuf = new StringBuffer(); // various projects we're asked to 'which'
/** outWriter. */
protected PrintWriter outWriter = new PrintWriter(System.out, true); // where we send output
}

126
java/src/org/apache/env/WhichAnt.java vendored Normal file
View File

@ -0,0 +1,126 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.Hashtable;
/**
* Get Version information about jakarta-ant.
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public class WhichAnt implements WhichProject
{
/** Our project name. */
public static final String SERVICE_NAME = "Ant";
/** The Ant implementation jar. */
private static final String ANT_JARNAME = "ant.jar";
/** The Ant 1.x version class. */
private static final String ANT_VERSION_CLASS =
"org.apache.tools.ant.Main";
/** The Ant 1.x version class. */
private static final String ANT_VERSION_METHOD = "getAntVersion";
/**
* Calls getAntVersion and looks for ant.jar.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getInfo(Hashtable hash, String options)
{
if (null == hash)
hash = new Hashtable();
// Try to find Ant-specific classes
int antFound = WhichConstant.ITEM_NOTFOUND;
try
{
final Class noArgs[] = new Class[0];
Class clazz = WhichClass.findClass(ANT_VERSION_CLASS, options);
Method method = clazz.getMethod(ANT_VERSION_METHOD, noArgs);
Object returnValue = method.invoke(null, new Object[0]);
hash.put(SERVICE_NAME + WhichConstant.TAG_VERSION,
(String) returnValue);
antFound = WhichConstant.ITEM_OK;
}
catch (Exception e3)
{
hash.put(SERVICE_NAME + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]);
antFound = WhichConstant.ITEM_NOTFOUND;
}
// Try to find the jar in the classpath, etc.
int jarRetVal = WhichJar.searchClasspaths(hash, ANT_JARNAME, options);
return Math.max(jarRetVal, antFound);
}
}

141
java/src/org/apache/env/WhichClass.java vendored Normal file
View File

@ -0,0 +1,141 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.lang.reflect.Method;
import org.apache.env.WhichConstant;
/**
* Class finding service.
* This effectively replaces Class.forName() calls in this package.
* Similar to code in javax.xml.*.FactoryFinder. Options included
* for future use; they could specify something like
* LOCAL_CLASSLOADER_ONLY for servlet environments, etc.
*
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public abstract class WhichClass // Prevent instantiation; only provide static services
{
/**
* Worker method to load a class.
* Factor out loading classes for future use and JDK differences.
* Similar to javax.xml.*.FactoryFinder
*
* @param className name of class to load from
* an appropriate classLoader
* @param options currently unused
* @return the class asked for
*
* @throws ClassNotFoundException
*/
public static Class findClass(String className, String options)
throws ClassNotFoundException
{
ClassLoader classLoader = WhichClass.findClassLoader(options);
if (classLoader == null)
{
return Class.forName(className);
}
else
{
return classLoader.loadClass(className);
}
}
/**
* Worker method to figure out which ClassLoader to use.
* For JDK 1.2 and later use the context ClassLoader.
* Similar to javax.xml.*.FactoryFinder
*
* @param options currently unused
* @return the appropriate ClassLoader
*
* @throws ClassNotFoundException
*/
protected static ClassLoader findClassLoader(String options)
throws ClassNotFoundException
{
ClassLoader classLoader = null;
Method m = null;
try
{
m = Thread.class.getMethod("getContextClassLoader", null);
}
catch (NoSuchMethodException nsme)
{
// Assume that we are running JDK 1.1, use the current ClassLoader
return WhichClass.class.getClassLoader();
}
try
{
return (ClassLoader) m.invoke(Thread.currentThread(), null);
}
catch (Exception e)
{
throw new RuntimeException(e.toString());
}
}
}

View File

@ -0,0 +1,150 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
/**
* Simple static constants used throughout org.apache.env package.
*
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public abstract class WhichConstant
{
/** Item is Unknown, or don't care. */
public static final int ITEM_UNKNOWN = 0;
/** Item is Provably a shipped version. */
public static final int ITEM_SHIPPED = 1;
/** Item is Version appears to be OK. */
public static final int ITEM_OK = 2;
/** Item is Item was not found, but might be ok. */
public static final int ITEM_NOTFOUND = 3;
/** Item is Possible problem. */
public static final int ITEM_WARNING = 4;
/** Item is Definite problem. */
public static final int ITEM_ERROR = 5;
/** Descriptive strings for ITEM_ constants; keep in sync. */
public static final String[] ITEM_DESC =
{
/* Keep in sync with above ITEM_* constants */
".unknown",
".shipped-version",
".ok-present",
".not-found",
".warning",
".error"
};
/** Tag denoting version info follows. */
public static final String TAG_VERSION = ".version";
/** Tag denoting a generic error occoured. */
public static final String TAG_ERROR = ".error";
/** Tag denoting a subhash of information is here. */
public static final String TAG_HASHINFO = ".hashinfo";
/** Tag denoting the path to a file (.jar, etc.). */
public static final String TAG_PATH = ".path";
/** Tag denoting the status of a WhichProject hash. */
public static final String TAG_STATUS = ".status";
/** Strict option asks Whichers to return an error if
* required classes, etc. are not found. */
public static final String OPTION_STRICT = "strict";
/** Verbose option asks Whichers to return extra info. */
public static final String OPTION_VERBOSE = "verbose";
/**
* Check if options include strict.
*
* @param options from your method
* @return true if OPTION_STRICT is present
*/
public static boolean isStrict(String options)
{
if (null == options)
return false;
return (options.indexOf(OPTION_STRICT) > -1);
}
/**
* Check if options include verbose.
*
* @param options from your method
* @return true if OPTION_VERBOSE is present
*/
public static boolean isVerbose(String options)
{
if (null == options)
return false;
return (options.indexOf(OPTION_VERBOSE) > -1);
}
}

View File

@ -0,0 +1,128 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.Hashtable;
/**
* Get Version information about xml-crimson.
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public class WhichCrimson implements WhichProject
{
/** Our project name. */
public static final String SERVICE_NAME = "Crimson";
/** The Crimson-J implementation jar. */
private static final String CRIMSON_JARNAME = "crimson.jar";
/** The Crimson-J 1.x version class. */
private static final String CRIMSON1_VERSION_CLASS =
"org.apache.crimson.parser.Parser2";
/** The Crimson-J 1.x version field. */
private static final String CRIMSON1_VERSION_FIELD =
"unknown-what-is-correct-way-to-find-version";
/**
* Detects if Parser2 is present and looks for crimson.jar.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getInfo(Hashtable hash, String options)
{
if (null == hash)
hash = new Hashtable();
int crimson1found = WhichConstant.ITEM_UNKNOWN;
// Look for Crimson-J 1.x
try
{
Class clazz = WhichClass.findClass(CRIMSON1_VERSION_CLASS,
options);
// Found Crimson-J 1.x, note that it's present
//@todo actually find how to lookup Crimson version info
hash.put(SERVICE_NAME + WhichConstant.TAG_VERSION,
"present-unknown-version");
crimson1found = WhichConstant.ITEM_OK;
}
catch (Exception e1)
{
hash.put(SERVICE_NAME + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]);
crimson1found = WhichConstant.ITEM_NOTFOUND;
}
// Try to find jar in the classpath, etc.
int jarRetVal = WhichJar.searchClasspaths(hash, CRIMSON_JARNAME,
options);
return Math.max(jarRetVal, crimson1found);
}
}

View File

@ -0,0 +1,209 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* Simple factory class for WhichProject implementations.
* A list of 'installed' WhichProject impls is kept in our matching
* org/apache/env/WhichFactory.properties file.
*
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public abstract class WhichFactory // prevent instantiation; provide static services only
{
/** org.apache.env.Which, prepended to unknown projectnames. */
public static final String DEFAULT_WHICHCLASS = "org.apache.env.Which";
/** 'WhichFactory'. */
public static final String SERVICE_NAME = "WhichFactory";
/**
* Factory method to get a WhichProject implementation for the name.
* <p>Returns a WhichProject using the name as an FQCN; or looks
* up the name in WhichFactory.properties; or assuming it's
* a simple name and appends DEFAULT_WHICHCLASS on the front.</p>
*
* @param name FQCN, simple name, or installed name of a
* WhichProject implementation class
* @param options to use when getting the class
* @return a WhichProject object
*
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static WhichProject newWhichProject(String name, String options)
throws ClassNotFoundException, InstantiationException,
IllegalAccessException //@todo change to catch and return null instead?
{
Class clazz;
try
{
// Assume it's a FQCN first...
clazz = WhichClass.findClass(name, options);
}
catch (ClassNotFoundException cnfe)
{
try
{
// ...then try installedWhichers...
String implName = installedWhichers.getProperty(name);
// Note this is inefficient to simply let it throw
// cnfe2 if we get null back, but it does work
if (null == implName)
throw new ClassNotFoundException();
clazz = WhichClass.findClass(implName, options);
}
catch (ClassNotFoundException cnfe2)
{
// ...otherwise it's a shortname of just the project name
clazz = WhichClass.findClass(DEFAULT_WHICHCLASS + name,
options);
}
}
if (null == clazz)
throw new ClassNotFoundException(name); //@todo add description
return (WhichProject) clazz.newInstance();
}
/** org/apache/env/WhichFactory.properties. */
private static final String WHICHFACTORY_PROPS =
"org/apache/env/WhichFactory.properties";
/** List of 'installed' WhichProject implementations. */
protected static Properties installedWhichers = new Properties(); // must be initialized
static // static initializer for the class
{
// Load each of the lists of .jar files
loadWhichInstall(installedWhichers, WHICHFACTORY_PROPS);
}
;
/**
* Loads our installedWhichers from WHICHFACTORY_PROPS.
*
* @param table Properties block to load
* @param tableURL name of .properties file to load
*/
private static void loadWhichInstall(Properties table, String tableURL)
{
if (null == table)
table = new Properties();
try
{
InputStream is = null;
try
{
final Class[] NO_CLASSES = new Class[0];
final Object[] NO_OBJS = new Object[0];
Method getCCL =
Thread.class.getMethod("getContextClassLoader",
NO_CLASSES);
if (getCCL != null)
{
ClassLoader contextClassLoader =
(ClassLoader) getCCL.invoke(Thread.currentThread(),
NO_OBJS);
is = contextClassLoader.getResourceAsStream(tableURL);
}
}
catch (Exception e)
{ /*no-op */
}
if (null == is)
{
is = WhichJar.class.getResourceAsStream("/" + tableURL);
}
table.load(is);
is.close();
}
catch (Exception e)
{
// Leave table as-is; presumably it's null
System.err.println(SERVICE_NAME + " loadJarTable threw: "
+ e.toString());
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,31 @@
# Used by org.apache.env.WhichFactory
# Maps a simple name to a FQCN of a WhichProject implementation
# xml.apache.org common projects
commons=org.apache.env.WhichXmlCommons
Commons=org.apache.env.WhichXmlCommons
xml-commons=org.apache.env.WhichXmlCommons
XmlCommons=org.apache.env.WhichXmlCommons
xalan=org.apache.env.WhichXalan
Xalan=org.apache.env.WhichXalan
xml-xalan=org.apache.env.WhichXalan
xerces=org.apache.env.WhichXerces
Xerces=org.apache.env.WhichXerces
xml-xerces=org.apache.env.WhichXerces
crimson=org.apache.env.WhichCrimson
Crimson=org.apache.env.WhichCrimson
xml-crimson=org.apache.env.WhichCrimson
# jakarta.apache.org common projects
ant=org.apache.env.WhichAnt
Ant=org.apache.env.WhichAnt
jakarta-ant=org.apache.env.WhichAnt
# External projects
saxon=org.apache.env.WhichSaxon
Saxon=org.apache.env.WhichSaxon

481
java/src/org/apache/env/WhichJar.java vendored Normal file
View File

@ -0,0 +1,481 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
/**
* Static worker methods to find version info about jars and classpaths.
*
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public abstract class WhichJar // prevent instantiation; provide static services only
{
/**
* Generic worker method to print out java.class.path,
* sun.boot.class.path, and java.ext.dirs.
*
* @param hash to put information in
* @param options to apply like strict or verbose
*/
public static void getClasspathInfo(Hashtable hash, String options)
{
hash.put("java.class.path", System.getProperty("java.class.path"));
hash.put("sun.boot.class.path",
System.getProperty("sun.boot.class.path"));
hash.put("java.ext.dirs", System.getProperty("java.ext.dirs"));
}
/** SERVICE_NAME. */
public static final String SERVICE_NAME = "WhichJar";
/**
* Search all applicable classpath-like items for the named jar.
* Looks in each classpath (and bootclasspath, and ext dirs)
* for the jar and reports info about it.
*
* @param hash to put information in
* @param jarName to look for
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public static int searchClasspaths(Hashtable hash, String jarName,
String options)
{
int retVal1 = searchPath(hash, "java.class.path", jarName, options);
int retVal2 = searchPath(hash, "sun.boot.class.path", jarName,
options);
int retVal3 = searchDirs(hash, "java.ext.dirs", jarName, options);
// Only return error info if options are strict
if (WhichConstant.isStrict(options))
{
return Math.max(retVal1, Math.max(retVal2, retVal3));
}
else
{
// Otherwise return generic OK status
return WhichConstant.ITEM_OK;
}
}
/**
* Search a classpath path for the named jar.
*
* @param hash to put information in
* @param pathName to get from System.getProperty()
* @param jarName to look for, <b>case-insensitive</b>
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public static int searchPath(Hashtable hash, String pathName,
String jarName, String options)
{
// Grab the actual path from the System
String path = System.getProperty(pathName);
StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
int retVal = WhichConstant.ITEM_UNKNOWN;
boolean jarFound = false;
while (st.hasMoreTokens())
{
// Compare as lower case to avoid case problems
// NOTE: we are case-insensitive!
String jarURI = st.nextToken().toLowerCase();
// If a path entry contains our jarName, process it
if (jarURI.indexOf(jarName) > -1)
{
File jarFile = new File(jarURI);
// If the actual file exists, log info about it...
if (jarFile.exists())
{
// ...but if it's *already* been found, log that too
if (jarFound)
{
Hashtable h = new Hashtable();
int multipleStatus = WhichConstant.isStrict(options)
? WhichConstant.ITEM_ERROR
: WhichConstant.ITEM_UNKNOWN;
h.put(jarName
+ WhichConstant.ITEM_DESC[multipleStatus], "jar on classpath multiple times!");
retVal = Math.max(retVal,
getInfo(h, jarFile, options));
retVal = Math.max(retVal, multipleStatus);
hash.put(pathName + "." + jarName
+ WhichConstant.TAG_HASHINFO, h);
//@todo ERROR CASE: if found more than twice, we will overwrite this existing hash entries here - add a postfix?
}
else
{
retVal = Math.max(retVal,
getInfo(hash, jarFile, options));
jarFound = true;
}
}
// ...if not, log it as missing
else
{
hash.put(
jarName
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_WARNING],
"classpath entry [" + jarURI
+ "] does not exist on disk!");
retVal = Math.max(retVal,
WhichConstant.isStrict(options)
? WhichConstant.ITEM_WARNING
: WhichConstant.ITEM_NOTFOUND);
}
} // end of for
} // end of while
return retVal;
}
/**
* Search a list of paths for the named jar.
*
* @param hash to put information in
* @param pathName to get from System.getProperty()
* @param jarName to look for, <b>case-insensitive</b>
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public static int searchDirs(Hashtable hash, String pathName,
String jarName, String options)
{
// Grab the actual path(s) from the System
String path = System.getProperty(pathName);
StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
int retVal = WhichConstant.ITEM_UNKNOWN;
// Search each dir and compile status
while (st.hasMoreTokens())
{
String dir = st.nextToken().toLowerCase();
retVal = Math.max(retVal, searchDir(hash, dir, jarName, options));
}
return retVal;
}
/**
* Search a single directory for the named jar.
*
* @param hash to put information in
* @param dir name of directory
* @param jarName to look for, <b>case-insensitive</b>
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public static int searchDir(Hashtable hash, String dir, String jarName,
String options)
{
// Ensure the directory exists
File searchDir = new File(dir);
if (!searchDir.exists())
{
int retVal = WhichConstant.isStrict(options)
? WhichConstant.ITEM_ERROR
: WhichConstant.ITEM_UNKNOWN;
hash.put(SERVICE_NAME + "searchDir"
+ WhichConstant.ITEM_DESC[retVal],
"searchDir does not exist: " + dir);
return retVal;
}
// Find the jar file if it exists there
File jarFile = new File(searchDir, jarName);
return getInfo(hash, jarFile, options);
}
/**
* Get version information about a specific .jar file.
* Current implementation simply checks the file size in bytes
* of the .jar file and does a lookup in WhichJar.properties
* to get a description of officially shipped .jars.
* //@todo future versions should also lookup manifest
* version info from .jar files (but remember to provide
* fallbacks since we must also run on JDK 1.1.8!).
*
* @param hash to put information in
* @param jarName of the .jar file
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public static int getInfo(Hashtable hash, File jarFile, String options)
{
// Check various error conditions first
if (null == hash)
{
hash = new Hashtable();
}
if (null == jarFile)
{
hash.put(
SERVICE_NAME
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR], "getInfo() called on null jarFile");
return WhichConstant.ITEM_ERROR;
}
// Simplistic implementation: simply look up info about the
// size of the actual .jar file in our tables
// Note: may be replaced in the future to actually look up
// info in the .jar's manifest file as well
//@todo should use URLConnection or something to
// be able to do http: etc.
String jarName = jarFile.getName();
if (jarFile.exists())
{
try
{
hash.put(jarName + WhichConstant.TAG_PATH,
jarFile.getAbsolutePath());
String tmpInfo = getJarInfo(jarName, jarFile.length());
if (null == tmpInfo)
{
hash.put(jarName
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_OK],
"not from an official release, size:"
+ jarFile.length());
return WhichConstant.ITEM_OK;
}
else
{
hash.put(
jarName
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_SHIPPED], tmpInfo);
return WhichConstant.ITEM_SHIPPED;
}
}
catch (Exception e)
{
hash.put(jarName
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR],
jarFile.getAbsolutePath() + " threw: "
+ e.toString());
return WhichConstant.ITEM_ERROR;
}
}
else // of if(jarFile.exists())
{
int retVal = WhichConstant.isStrict(options)
? WhichConstant.ITEM_ERROR
: WhichConstant.ITEM_UNKNOWN;
hash.put(jarName + WhichConstant.ITEM_DESC[retVal],
jarFile.getAbsolutePath() + " does not exist");
return retVal;
}
}
/**
* Get version information about a specific .jar file.
* Lookup the size/jarname pair in WhichJar.properties.
*
* @param hash to put information in
* @param jarName of the .jar file
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
private static String getJarInfo(String jarName, long jarSize)
{
if (null == jarSizeTable)
return null;
final String SIZE_SEPARATOR = ".";
return jarSizeTable.getProperty(String.valueOf(jarSize)
+ SIZE_SEPARATOR + jarName);
}
/**
* Grab the bare filename off a path or URI.
*
* @param URI original URI or path
* @return just the bare filename after last separator
*/
private static String getFilename(String URI)
{
if (null == URI)
return null;
final String URL_SEPARATOR = "/";
return URI.substring(URI.lastIndexOf(URL_SEPARATOR));
}
/** 'org/apache/env/WhichJar.properties'. */
private static final String WHICHJAR_PROPS =
"org/apache/env/WhichJar.properties";
/** A Properties block of known officially shipped .jar names/sizes. */
protected static Properties jarSizeTable = new Properties(); // must be initialized
static // static initializer for the class
{
// Load each of the lists of .jar files
loadJarTable(jarSizeTable, WHICHJAR_PROPS);
}
;
/**
* Loads our jarSizeTable from WHICHJAR_PROPS.
*
* @param table Properties block to load
* @param tableURL name of .properties file to load
*/
private static void loadJarTable(Properties table, String tableURL)
{
if (null == table)
table = new Properties();
try
{
InputStream is = null;
try
{
final Class[] NO_CLASSES = new Class[0];
final Object[] NO_OBJS = new Object[0];
Method getCCL =
Thread.class.getMethod("getContextClassLoader",
NO_CLASSES);
if (getCCL != null)
{
ClassLoader contextClassLoader =
(ClassLoader) getCCL.invoke(Thread.currentThread(),
NO_OBJS);
is = contextClassLoader.getResourceAsStream(tableURL);
}
}
catch (Exception e)
{ /*no-op */
}
if (null == is)
{
is = WhichJar.class.getResourceAsStream("/" + tableURL);
}
table.load(is);
is.close();
}
catch (Exception e)
{
// Leave table as-is; presumably it's null
System.err.println(SERVICE_NAME + " loadJarTable threw: "
+ e.toString());
e.printStackTrace();
}
}
/**
* Get our file version info.
* @return String of our file version
*/
public static String getVersion()
{
return "WhichJar.java:($Revision$)";
}
}

View File

@ -0,0 +1,80 @@
# Used by org.apache.env.WhichJar
# Format: NNNN.jarname.jar=description
# Where: NNNN is actual size in bytes of jarname.jar
# from an *officially shipped* version
# xml-xalan releases
857192.xalan.jar=from xalan-j_1_1
440237.xalan.jar=from xalan-j_1_2
436094.xalan.jar=from xalan-j_1_2_1
426249.xalan.jar=from xalan-j_1_2_2
702536.xalan.jar=from xalan-j_2_0_0
720930.xalan.jar=from xalan-j_2_0_1
732330.xalan.jar=from xalan-j_2_1_0
872241.xalan.jar=from xalan-j_2_2_D10
882739.xalan.jar=from xalan-j_2_2_D11
892188.xalan.jar=from xalan-j_2_2_D13
897409.xalan.jar=from xalan-j_2_2_D14
857171.xalan.jar=from lotusxsl-j_1_0_1
802165.xalan.jar=from lotusxsl-j_2_0_0
857692.xalan.jar=from lotusxsl-j_2_2
424490.xalan.jar=from Xerces Tools releases - ERROR.DO NOT USE!
92409.xml-apis.jar=from xalan-j_2_2_D13
93717.xml-apis.jar=from xalan-j_2_2_D14
# xml-xerces releases
1591855.xerces.jar=from xalan-j_1_1 from xerces-1...
1498679.xerces.jar=from xalan-j_1_2 from xerces-1_2_0.bin
1484896.xerces.jar=from xalan-j_1_2_1 from xerces-1_2_1.bin
804460.xerces.jar=from xalan-j_1_2_2 from xerces-1_2_2.bin
1499244.xerces.jar=from xalan-j_2_0_0 from xerces-1_2_3.bin
1605266.xerces.jar=from xalan-j_2_0_1 from xerces-1_3_0.bin
904030.xerces.jar=from xalan-j_2_1_0 from xerces-1_4.bin
1190776.xerces.jar=from lotusxsl_1_0_1 apparently-from xerces-1_0_3.bin
1489400.xerces.jar=from lotusxsl-j_2_0_0 from XML4J-3_1_1
1787796.xerces.jar=from lotusxsl-j_2_2 or xerces-1_4_1.bin
904030.xerces.jar=from xerces-1_4_0.bin
1802885.xerces.jar=from xerces-1_4_2.bin
1808883.xerces.jar=from xalan-j_2_2_D10,D11,D12 or xerces-1_4_3.bin
1803877.xerces.jar=from XML4J-3_2_1
1812019.xerces.jar=from xalan-j_2_2_D14 or xerces-1_4_4.bin
1734594.xerces.jar=from Xerces-J-bin.2.0.0.beta3
# xml-crimson and JAXP or related releases
5618.jaxp.jar=from jaxp1.0.1
136133.parser.jar=from jaxp1.0.1
28404.jaxp.jar=from jaxp-1.1
187162.crimson.jar=from jaxp-1.1
801714.xalan.jar=from jaxp-1.1
196399.crimson.jar=from crimson-1.1.1
33323.jaxp.jar=from crimson-1.1.1 or jakarta-ant-1.4.1b1
152717.crimson.jar=from crimson-1.1.2beta2
206384.crimson.jar=from crimson-1.1.3 or jakarta-ant-1.4.1b1
136198.parser.jar=from jakarta-ant-1.3 or 1.2
5537.jaxp.jar=from jakarta-ant-1.3 or 1.2
88143.xml-apis.jar=from crimson-1.1.2beta2
# lotusxsl releases (from xml-xalan releases)
120274.lotusxsl.jar=from lotusxsl-0_16_4
120293.lotusxsl.jar=from lotusxsl-0_16_5
283777.lotusxsl.jar=from lotusxsl-0_17_2
305577.lotusxsl.jar=from lotusxsl-0_17_3
304500.lotusxsl.jar=from lotusxsl-0_17_4
714959.lotusxsl.jar=from lotusxsl-0_18_1
717674.lotusxsl.jar=from lotusxsl-0_18_2
752343.lotusxsl.jar=from lotusxsl-0_18_3
907101.lotusxsl.jar=from lotusxsl-0_18_4
# jakarta-ant releases
330479.ant.jar=from jakarta-ant-1.2-bin
295934.ant.jar=from jakarta-ant-1.3-bin
417114.ant.jar=from jakarta-ant-1.4.1b1-bin
# other projects/releases

View File

@ -0,0 +1,80 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.util.Hashtable;
/**
* Simple interface for getting version info about a project.
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public interface WhichProject
{
/**
* Get basic or extended info about a project.
* Override to gather whatever version or configuration
* information is useful about your project or product
* and pass it back in the hashtable.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getInfo(Hashtable hash, String options);
}

125
java/src/org/apache/env/WhichSaxon.java vendored Normal file
View File

@ -0,0 +1,125 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.Hashtable;
/**
* Get Version information about Saxon from http://saxon.sourceforge.net/.
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public class WhichSaxon implements WhichProject
{
/** Our project name. */
public static final String SERVICE_NAME = "Saxon";
/** The Saxon implementation jar. */
private static final String SAXON_JARNAME = "saxon.jar";
/** The Saxon version class. */
private static final String SAXON_VERSION_CLASS = "com.icl.saxon.Version";
/** The Saxon version method. */
private static final String SAXON_VERSION_METHOD = "getVersion"; // String getVersion()
/**
* Calls Version.getVersion and looks for saxon.jar.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getInfo(Hashtable hash, String options)
{
if (null == hash)
hash = new Hashtable();
int returnVal = WhichConstant.ITEM_UNKNOWN;
try
{
final Class noArgs[] = new Class[0];
Class clazz = WhichClass.findClass(SAXON_VERSION_CLASS, options);
Method method = clazz.getMethod(SAXON_VERSION_METHOD, noArgs);
Object returnValue = method.invoke(null, new Object[0]);
hash.put(SERVICE_NAME + WhichConstant.TAG_VERSION,
(String) returnValue);
returnVal = WhichConstant.ITEM_OK;
}
catch (Exception e3)
{
hash.put(SERVICE_NAME + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]);
returnVal = WhichConstant.ITEM_NOTFOUND;
}
// Try to find xalan.jar in the classpath, etc.
int jarRetVal = WhichJar.searchClasspaths(hash, SAXON_JARNAME,
options);
return Math.max(jarRetVal, returnVal);
}
}

202
java/src/org/apache/env/WhichXalan.java vendored Normal file
View File

@ -0,0 +1,202 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.Hashtable;
/**
* Get Version information about xml-xalan.
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public class WhichXalan implements WhichProject
{
/** Our project name. */
public static final String SERVICE_NAME = "Xalan";
/** The Xalan-J implementation jar. */
private static final String XALAN_JARNAME = "xalan.jar";
/** The Xalan-J xml-apis jar. */
private static final String XMLAPIS_JARNAME = "xml-apis.jar";
/** The Xalan-J 1.x version class. */
private static final String XALAN1_VERSION_CLASS =
"org.apache.xalan.xslt.XSLProcessorVersion";
/** The Xalan-J 2.0, 2.1 version class. */
private static final String XALAN2_VERSION_CLASS =
"org.apache.xalan.processor.XSLProcessorVersion";
/** The Xalan-J 2.2+ version class. */
private static final String XALAN2_2_VERSION_CLASS =
"org.apache.xalan.Version";
/** The Xalan-J 2.2+ version method. */
private static final String XALAN2_2_VERSION_METHOD = "getVersion";
/**
* Finds version information from Xalan-J 1.x, 2.x, 2.2+, and
* looks for xalan.jar and xml-apis.jar. Only looks for 1.x
* classes for information; does not report status on them.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getInfo(Hashtable hash, String options)
{
if (null == hash)
hash = new Hashtable();
// Try to find Xalan-specific classes
try
{
// Attempt to find Xalan-J 1.x only as a historical
// note; do not report on success/failure of this
Class clazz = WhichClass.findClass(XALAN1_VERSION_CLASS, options);
// Found Xalan-J 1.x, grab it's version fields
StringBuffer buf = new StringBuffer();
Field f = clazz.getField("PRODUCT");
buf.append(f.get(null));
buf.append(';');
f = clazz.getField("LANGUAGE");
buf.append(f.get(null));
buf.append(';');
f = clazz.getField("S_VERSION");
buf.append(f.get(null));
buf.append(';');
hash.put(SERVICE_NAME + "1" + WhichConstant.TAG_VERSION,
buf.toString());
}
catch (Exception e1)
{
hash.put(SERVICE_NAME + "1" + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]);
}
int xalan2found = WhichConstant.ITEM_UNKNOWN;
int xalan22found = WhichConstant.ITEM_UNKNOWN;
try
{
// NOTE: This is the old Xalan 2.0, 2.1, 2.2 version class,
Class clazz = WhichClass.findClass(XALAN2_VERSION_CLASS, options);
// Found Xalan-J 2.x, grab it's version fields
StringBuffer buf = new StringBuffer();
Field f = clazz.getField("S_VERSION");
buf.append(f.get(null));
hash.put(SERVICE_NAME + "2x" + WhichConstant.TAG_VERSION,
buf.toString());
xalan2found = WhichConstant.ITEM_OK;
}
catch (Exception e2)
{
hash.put(SERVICE_NAME + "2x" + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]);
xalan2found = WhichConstant.ITEM_NOTFOUND;
}
try
{
// NOTE: This is the new Xalan 2.2 and up version class,
final Class noArgs[] = new Class[0];
Class clazz = WhichClass.findClass(XALAN2_2_VERSION_CLASS,
options);
Method method = clazz.getMethod(XALAN2_2_VERSION_METHOD, noArgs);
Object returnValue = method.invoke(null, new Object[0]);
hash.put(SERVICE_NAME + "22+" + WhichConstant.TAG_VERSION,
(String) returnValue);
xalan22found = WhichConstant.ITEM_OK;
}
catch (Exception e3)
{
hash.put(SERVICE_NAME + "22+" + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]);
xalan22found = WhichConstant.ITEM_NOTFOUND;
}
// Try to find xalan.jar in the classpath, etc.
int jarRetVal = WhichJar.searchClasspaths(hash, XALAN_JARNAME,
options);
int ignoreThisReturnValue = WhichJar.searchClasspaths(hash,
XMLAPIS_JARNAME, options);
return Math.max(jarRetVal, Math.max(xalan2found, xalan22found));
}
}

164
java/src/org/apache/env/WhichXerces.java vendored Normal file
View File

@ -0,0 +1,164 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.Hashtable;
/**
* Get Version information about xml-xerces.
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public class WhichXerces implements WhichProject
{
/** Our project name. */
public static final String SERVICE_NAME = "Xerces";
/** The Xerces-J implementation jar. */
private static final String XERCES_JARNAME = "xerces.jar";
/** The Xerces-J 2.x xmlParserAPIs jar. */
private static final String PARSERAPIS_JARNAME = "xmlParserAPIs.jar";
/** The Xerces-J 1.x version class. */
private static final String XERCES1_VERSION_CLASS =
"org.apache.xerces.framework.Version";
/** The Xerces-J 1.x version field. */
private static final String XERCES1_VERSION_FIELD = "fVersion";
/** The Xerces-J 2.x version class. */
private static final String XERCES2_VERSION_CLASS =
"org.apache.xerces.impl.Version";
/** The Xerces-J 2.x version field. */
private static final String XERCES2_VERSION_FIELD = "fVersion";
/**
* Gets version information for Xerces-J 1.x and 2.x,
* and looks for xerces.jar and xmlParserAPIs.jar.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getInfo(Hashtable hash, String options)
{
if (null == hash)
hash = new Hashtable();
int xerces1found = WhichConstant.ITEM_UNKNOWN;
int xerces2found = WhichConstant.ITEM_UNKNOWN;
// Look for Xerces-J 1.x
try
{
Class clazz = WhichClass.findClass(XERCES1_VERSION_CLASS,
options);
// Found Xerces-J 1.x, grab it's version field
Field f = clazz.getField(XERCES1_VERSION_FIELD);
String buf = (String) f.get(null);
hash.put(SERVICE_NAME + "1" + WhichConstant.TAG_VERSION, buf);
xerces1found = WhichConstant.ITEM_OK;
}
catch (Exception e1)
{
hash.put(SERVICE_NAME + "1" + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]);
xerces1found = WhichConstant.ITEM_NOTFOUND;
}
// Look for Xerces-J 2.x
try
{
Class clazz = WhichClass.findClass(XERCES2_VERSION_CLASS,
options);
// Found Xerces-J 1.x, grab it's version field
Field f = clazz.getField(XERCES2_VERSION_FIELD);
String buf = (String) f.get(null);
hash.put(SERVICE_NAME + "2" + WhichConstant.TAG_VERSION, buf);
xerces2found = WhichConstant.ITEM_OK;
}
catch (Exception e1)
{
hash.put(SERVICE_NAME + "2" + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]);
xerces2found = WhichConstant.ITEM_NOTFOUND;
}
// Try to find xerces.jar in the classpath, etc.
int jarRetVal = WhichJar.searchClasspaths(hash, XERCES_JARNAME,
options);
int ignoreThisReturnValue = WhichJar.searchClasspaths(hash,
PARSERAPIS_JARNAME, options);
return Math.max(jarRetVal, Math.max(xerces1found, xerces1found));
}
}

View File

@ -0,0 +1,415 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, International
* Business Machines Corporation., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.env;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.Hashtable;
/**
* Get Version information about xml-commons code.
* @author shane_curcuru@us.ibm.com
* @version $Id$
*/
public class WhichXmlCommons implements WhichProject
{
/** Our project name. */
public static final String SERVICE_NAME = "XmlCommons";
/** The xml-commons external standards jar. */
private static final String XMLCOMMONS_JARNAME = "xml-apis.jar";
/** The xml-commons external standards version class. */
private static final String XMLCOMMONS_VERSION_CLASS =
"org.apache.xmlcommons.Version";
/** The xml-commons external standards version method. */
private static final String XMLCOMMONS_VERSION_METHOD = "getVersion"; // String getVersion()
/**
* Gets information on external standards code in xml-commons
* project; finds the xml-commons version as well as the
* approximate versions of JAXP, DOM and SAX. Looks for the
* default xml-apis.jar with external standards code.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getInfo(Hashtable hash, String options)
{
if (null == hash)
hash = new Hashtable();
// Get info about xml-commons project itself, including xml-apis.jar
int status = getXmlCommonsInfo(hash, options);
// Just determine JAXP version present...
status = Math.max(status, getJAXPInfo(hash, options));
// Just determine SAX version present...
status = Math.max(status, getSAXInfo(hash, options));
// Just determine DOM version present...
status = Math.max(status, getDOMInfo(hash, options));
return status;
}
/**
* Calls xmlcommons.Version.getVersion and looks for xml-apis.jar.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getXmlCommonsInfo(Hashtable hash, String options)
{
int status = WhichConstant.ITEM_UNKNOWN;
try
{
final Class noArgs[] = new Class[0];
Class clazz = WhichClass.findClass(XMLCOMMONS_VERSION_CLASS,
options);
Method method = clazz.getMethod(XMLCOMMONS_VERSION_METHOD,
noArgs);
Object returnValue = method.invoke(null, new Object[0]);
hash.put(SERVICE_NAME + WhichConstant.TAG_VERSION,
(String) returnValue);
status = WhichConstant.ITEM_OK;
}
catch (Exception e)
{
hash.put(SERVICE_NAME + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]);
status = WhichConstant.ITEM_NOTFOUND;
}
// Try to find appropriate jar in the classpath, etc.
int jarStatus = WhichJar.searchClasspaths(hash, XMLCOMMONS_JARNAME,
options);
return Math.max(jarStatus, status);
}
/**
* Gets JAXP version info and looks for jaxp.jar.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getJAXPInfo(Hashtable hash, String options)
{
final String INFONAME = SERVICE_NAME + ".jaxp";
int status = WhichConstant.ITEM_UNKNOWN;
Class jaxpClazz = null;
try
{
final Class noArgs[] = new Class[0];
jaxpClazz =
WhichClass.findClass("javax.xml.parsers.DocumentBuilder",
options);
Method method = jaxpClazz.getMethod("getDOMImplementation",
noArgs);
// If we succeeded, we at least have JAXP 1.1 available
hash.put(INFONAME + WhichConstant.TAG_VERSION, "1.1");
status = WhichConstant.ITEM_SHIPPED;
}
catch (Exception e)
{
if (null != jaxpClazz)
{
// We must have found the class itself, just not the
// method, so we (probably) have JAXP 1.0.1
hash.put(INFONAME + WhichConstant.TAG_VERSION,
"apparently-JAXP-1.0.1"
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR]);
status = WhichConstant.ITEM_ERROR;
}
else
{
// We couldn't even find the class, and don't have
// any JAXP support at all, or only have the
// transform half of it
hash.put(INFONAME + WhichConstant.TAG_VERSION,
"JAXP-nowhere"
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR]);
status = WhichConstant.ITEM_ERROR;
}
}
// Try to find older jaxp.jar in the classpath, etc.
int ignored = WhichJar.searchClasspaths(hash, "jaxp.jar", options);
return status;
}
/**
* Gets SAX version info and looks for sax.jar.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getSAXInfo(Hashtable hash, String options)
{
final String INFONAME = SERVICE_NAME + ".sax";
int status = WhichConstant.ITEM_UNKNOWN;
Class saxClazz = null;
final String SAX_VERSION1_CLASS = "org.xml.sax.Parser";
final String SAX_VERSION1_METHOD = "parse"; // String
final String SAX_VERSION2BETA_CLASS = "org.xml.sax.XMLReader";
final String SAX_VERSION2BETA_METHOD = "parse"; // String
final String SAX_VERSION2_CLASS =
"org.xml.sax.helpers.AttributesImpl";
final String SAX_VERSION2_METHOD = "setAttributes"; // Attributes
final Class oneStringArg[] = { java.lang.String.class };
try
{
final Class attributesArg[] = {
WhichClass.findClass("org.xml.sax.Attributes", options) };
saxClazz = WhichClass.findClass(SAX_VERSION2_CLASS, options);
Method method = saxClazz.getMethod(SAX_VERSION2_METHOD,
attributesArg);
// If we succeeded, we at least have SAX 2.0 final available
hash.put(INFONAME + WhichConstant.TAG_VERSION, "2.0");
status = WhichConstant.ITEM_SHIPPED;
}
catch (Exception e)
{
try
{
saxClazz = WhichClass.findClass(SAX_VERSION2BETA_CLASS,
options);
Method method = saxClazz.getMethod(SAX_VERSION2BETA_METHOD,
oneStringArg);
// If we succeeded, we have SAX 2.0 beta2 available,
// which isn't recommended but should be OK
hash.put(
INFONAME + WhichConstant.TAG_VERSION,
"2.0beta2"
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_WARNING]);
status = WhichConstant.ITEM_OK;
}
catch (Exception e2)
{
try
{
saxClazz = WhichClass.findClass(SAX_VERSION1_CLASS,
options);
Method method = saxClazz.getMethod(SAX_VERSION1_METHOD,
oneStringArg);
// If we succeeded, we have SAX 1.0 available,
// which probably will not work
hash.put(
INFONAME + WhichConstant.TAG_VERSION,
"1.x"
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR]);
status = WhichConstant.ITEM_ERROR;
}
catch (Exception e3)
{
// No SAX classes available anywhere
hash.put(
INFONAME + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR]);
status = WhichConstant.ITEM_ERROR;
}
}
}
// Try to find older sax.jar in the classpath, etc.
int ignored = WhichJar.searchClasspaths(hash, "sax.jar", options);
return status;
}
/**
* Gets DOM version info and looks for dom.jar.
*
* @param hash to put information in
* @param options to apply like strict or verbose
* @return status information from WhichConstant
*/
public int getDOMInfo(Hashtable hash, String options)
{
final String INFONAME = SERVICE_NAME + ".dom";
int status = WhichConstant.ITEM_UNKNOWN;
Class domClazz = null;
final String DOM_LEVEL2_CLASS = "org.w3c.dom.Document";
final String DOM_LEVEL2_METHOD = "createElementNS"; // String, String
final String DOM_LEVEL2WD_CLASS = "org.w3c.dom.Node";
final String DOM_LEVEL2WD_METHOD = "supported"; // String, String
final String DOM_LEVEL2FD_CLASS = "org.w3c.dom.Node";
final String DOM_LEVEL2FD_METHOD = "isSupported"; // String, String
final Class twoStringArgs[] = { java.lang.String.class,
java.lang.String.class };
try
{
domClazz = WhichClass.findClass(DOM_LEVEL2_CLASS, options);
Method method = domClazz.getMethod(DOM_LEVEL2_METHOD,
twoStringArgs);
// If we succeeded, we have loaded interfaces from a
// level 2 DOM somewhere
hash.put(INFONAME + WhichConstant.TAG_VERSION, "2.0");
status = WhichConstant.ITEM_SHIPPED;
}
catch (Exception e)
{
try
{
// Check for the working draft version, which is
// commonly found, but won't work anymore
domClazz = WhichClass.findClass(DOM_LEVEL2WD_CLASS, options);
Method method = domClazz.getMethod(DOM_LEVEL2WD_METHOD,
twoStringArgs);
// If we succeeded, we have loaded interfaces from a
// level 2 DOM somewhere
hash.put(INFONAME + WhichConstant.TAG_VERSION,
"2.0wd"
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR]);
status = WhichConstant.ITEM_ERROR;
}
catch (Exception e2)
{
try
{
// Check for the final draft version, which also
// won't work anymore
domClazz = WhichClass.findClass(DOM_LEVEL2FD_CLASS,
options);
Method method = domClazz.getMethod(DOM_LEVEL2FD_METHOD,
twoStringArgs);
// If we succeeded, we have loaded interfaces from a
// level 2 DOM somewhere
hash.put(
INFONAME + WhichConstant.TAG_VERSION,
"2.0fd"
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR]);
status = WhichConstant.ITEM_ERROR;
}
catch (Exception e3)
{
// No DOM classes available anywhere
hash.put(
INFONAME + WhichConstant.TAG_VERSION,
WhichConstant.ITEM_DESC[WhichConstant.ITEM_NOTFOUND]
+ WhichConstant.ITEM_DESC[WhichConstant.ITEM_ERROR]);
status = WhichConstant.ITEM_ERROR;
}
}
}
//@todo load an actual DOM implmementation and query it as well
//@todo load an actual DOM implmementation and check if
// isNamespaceAware() == true, which is needed to parse
// xsl stylesheet files into a DOM
// Try to find older dom.jar in the classpath, etc.
int ignored = WhichJar.searchClasspaths(hash, "dom.jar", options);
return status;
}
}

172
java/which.xml Normal file
View File

@ -0,0 +1,172 @@
<?xml version="1.0"?>
<!--
Build file for org.apache.env.Which service. No dependencies.
@author shane_curcuru@us.ibm.com
-->
<project default="all">
<!-- Name and version information -->
<property name="name" value="xml-commons"/>
<property name="version" value="1.0"/>
<!-- Name and version of the project -->
<property name="project.name" value="${name}-${version}"/>
<!-- Allow properties following these statements to be overridden -->
<!-- Note that all of these don't have to exist. They've just been defined
incase they are used. -->
<property file="build.properties"/>
<property file=".ant.properties"/>
<property file="${user.home}/.ant.properties"/>
<property file="default.properties"/>
<!-- Location of where to put our build output -->
<property name="tmp.dir" value="."/>
<!-- Build directory -->
<property name="build.dir" value="${tmp.dir}/build"/>
<property name="build.classes.dir" value="${build.dir}/classes"/>
<property name="docs.dir" value="${build.dir}"/>
<property name="docs.java.dir" value="${docs.dir}/javadocs"/>
<property name="docs.user.dir" value="${docs.dir}/docs"/>
<property name="docs.printer.dir" value="${docs.dir}/printer"/>
<!-- Source constants and directories -->
<property name="src.dir" value="src" />
<property name="env.subdir" value="org/apache/env" />
<property name="env.jar.location" value="${build.dir}" />
<property name="env.jar.name" value="which.jar" />
<property name="env.jar" value="${env.jar.location}/${env.jar.name}" />
<!-- Test results directory -->
<property name="check.dir" value="${tmp.dir}/${project.name}/check"/>
<!-- Build properties -->
<property name="build.debug" value="on"/>
<property name="build.deprecation" value="on"/>
<property name="build.optimize" value="off"/>
<!-- Document constants -->
<property name="company.name" value="Apache"/>
<property name="copyright.date" value="2001"/>
<property name="copyright.message"
value="Copyright &#169; ${copyright.date} ${company.name}. All Rights Reserved."/>
<!-- Time stamp patterns -->
<property name="timestamp.distname.pattern" value="yyyy-mm-dd"/>
<!-- Public Targets -->
<target name="main"
depends="all, check"
description="Alias for all, check."/>
<target name="all"
depends="jar"
description="This is the default target. Compiles the program.">
</target>
<target name="compile" depends="init"
description="Compile all classes">
<javac srcdir="${src.dir}" destdir="${build.classes.dir}"
includes="${env.subdir}/*.java" />
</target>
<target name="jar" depends="compile"
description="Jar all classes">
<copy todir="${build.classes.dir}">
<fileset dir="${src.dir}" includes="**/*.properties"/>
</copy>
<jar jarfile="${env.jar}" manifest="${src.dir}/manifest.which" basedir="${build.classes.dir}" />
</target>
<target name="install">
<echo message="${name} currently doesn&apos;t support install."/>
</target>
<target name="uninstall">
<echo message="${name} currently doesn&apos;t support uninstall."/>
</target>
<target name="clean"
description="Deletes all files that are generated by the build.">
<delete>
<fileset dir="${build.dir}"/>
</delete>
</target>
<target name="distclean"
depends="clean"
description="Deletes all files that a left from clean and returns the project to its distributed state.">
</target>
<target name="docs"
depends="javadocs, printerdocs"
description="Generates all documentation for a project.">
<echo message="${name} currently doesn&apos;t have any user documents."/>
</target>
<target name="javadocs"
depends="init"
description="Generates the JavaDocs for the project.">
<mkdir dir="${docs.java.dir}"/>
<javadoc packagenames="org.apache.env"
sourcepath="${src.dir}"
destdir="${docs.java.dir}"
author="true"
version="true"
use="true"
windowtitle="${name} API"
doctitle="${name}"
bottom="${copyright.message}">
</javadoc>
</target>
<target name="printerdocs"
depends="init"
description="Generates a printer friendly version of the documentation.">
<echo message="${name} currently doesn&apos;t have any user documents in a printable format."/>
</target>
<target name="dist"
depends="all, docs"
description="Generates all the artifacts used for a distribution.">
<echo message="${name} currently doesn&apos;t support &apos;dist&apos;."/>
</target>
<target name="test"
depends="check"
description="Alias for check">
</target>
<target name="check"
depends="jar"
description="Compile and execute any tests.">
<echo message="BEGIN Simple test: just call Which (manual verification required)."/>
<java classname="org.apache.env.Which">
<classpath>
<pathelement location="${env.jar}"/>
</classpath>
</java>
<echo message="END Simple test: just call Which (manual verification required)."/>
</target>
<!-- Internal Targets -->
<target name="init">
<!-- This target should initialise things like timestamps and set
available properties. -->
<echo message="Building ${name} (version: ${version}) Buildfile: $Revision$."/>
<mkdir dir="${build.classes.dir}" />
<mkdir dir="${docs.java.dir}" />
<mkdir dir="${docs.user.dir}" />
<tstamp>
<format property="timestamp.distname" pattern="${timestamp.distname.pattern}"/>
</tstamp>
</target>
<!-- Project specific Targets -->
</project>