/*
* ClasspathUtils.java
*
* Copyright 2001-2004 The Apache Software Foundation.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.axis.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileFilter;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import org.apache.axis.AxisProperties;
import org.apache.axis.MessageContext;
import org.apache.axis.transport.http.HTTPConstants;
/**
* Utility class for constructing the classpath
*/
public class ClasspathUtils {
/**
* Expand a directory path or list of directory paths (File.pathSeparator
* delimited) into a list of file paths of all the jar files in those
* directories.
*
* @param dirPaths The string containing the directory path or list of
* directory paths.
* @return The file paths of the jar files in the directories. This is an
* empty string if no files were found, and is terminated by an
* additional pathSeparator in all other cases.
*/
public static String expandDirs(String dirPaths) {
StringTokenizer st = new StringTokenizer(dirPaths, File.pathSeparator);
StringBuffer buffer = new StringBuffer();
while (st.hasMoreTokens()) {
String d = st.nextToken();
File dir = new File(d);
if (dir.isDirectory()) {
File[] files = dir.listFiles(new JavaArchiveFilter());
for (int i = 0; i < files.length; i++) {
buffer.append(files[i]).append(File.pathSeparator);
}
}
}
return buffer.toString();
}
/**
* Check if this inputstream is a jar/zip
* @param is
* @return true if inputstream is a jar
*/
public static boolean isJar(InputStream is) {
try {
JarInputStream jis = new JarInputStream(is);
if (jis.getNextEntry() != null) {
return true;
}
} catch (IOException ioe) {
}
return false;
}
/**
* Get the default classpath from various thingies in the message context
* @param msgContext
* @return default classpath
*/
public static String getDefaultClasspath(MessageContext msgContext) {
StringBuffer classpath = new StringBuffer();
ClassLoader cl = Thread.currentThread().getContextClassLoader();
fillClassPath(cl, classpath);
// Just to be safe (the above doesn't seem to return the webapp
// classpath in all cases), manually do this:
String webBase = (String) msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION);
if (webBase != null) {
classpath.append(webBase + File.separatorChar + "classes" +
File.pathSeparatorChar);
try {
String libBase = webBase + File.separatorChar + "lib";
File libDir = new File(libBase);
String[] jarFiles = libDir.list();
for (int i = 0; i < jarFiles.length; i++) {
String jarFile = jarFiles[i];
if (jarFile.endsWith(".jar")) {
classpath.append(libBase +
File.separatorChar +
jarFile +
File.pathSeparatorChar);
}
}
} catch (Exception e) {
// Oh well. No big deal.
}
}
// axis.ext.dirs can be used in any appserver
getClassPathFromDirectoryProperty(classpath, "axis.ext.dirs");
// classpath used by Jasper
getClassPathFromProperty(classpath, "org.apache.catalina.jsp_classpath");
// websphere stuff.
getClassPathFromProperty(classpath, "ws.ext.dirs");
getClassPathFromProperty(classpath, "com.ibm.websphere.servlet.application.classpath");
// java class path
getClassPathFromProperty(classpath, "java.class.path");
// Load jars from java external directory
getClassPathFromDirectoryProperty(classpath, "java.ext.dirs");
// boot classpath isn't found in above search
getClassPathFromProperty(classpath, "sun.boot.class.path");
return classpath.toString();
}
/**
* Add all files in the specified directory to the classpath
* @param classpath
* @param property
*/
private static void getClassPathFromDirectoryProperty(StringBuffer classpath, String property) {
String dirs = AxisProperties.getProperty(property);
String path = null;
try {
path = ClasspathUtils.expandDirs(dirs);
} catch (Exception e) {
// Oh well. No big deal.
}
if (path != null) {
classpath.append(path);
classpath.append(File.pathSeparatorChar);
}
}
/**
* Add a classpath stored in a property.
* @param classpath
* @param property
*/
private static void getClassPathFromProperty(StringBuffer classpath, String property) {
String path = AxisProperties.getProperty(property);
if (path != null) {
classpath.append(path);
classpath.append(File.pathSeparatorChar);
}
}
/**
* Walk the classloader hierarchy and add to the classpath
* @param cl
* @param classpath
*/
private static void fillClassPath(ClassLoader cl, StringBuffer classpath) {
while (cl != null) {
if (cl instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) cl).getURLs();
for (int i = 0; (urls != null) && i < urls.length; i++) {
String path = urls[i].getPath();
//If it is a drive letter, adjust accordingly.
if (path.length() >= 3 && path.charAt(0) == '/' && path.charAt(2) == ':')
path = path.substring(1);
classpath.append(URLDecoder.decode(path));
classpath.append(File.pathSeparatorChar);
// if its a jar extract Class-Path entries from manifest
File file = new File(urls[i].getFile());
if (file.isFile()) {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
if (isJar(fis)) {
JarFile jar = new JarFile(file);
Manifest manifest = jar.getManifest();
if (manifest != null) {
Attributes attributes = manifest.getMainAttributes();
if (attributes != null) {
String s = attributes.getValue(Attributes.Name.CLASS_PATH);
String base = file.getParent();
if (s != null) {
StringTokenizer st = new StringTokenizer(s, " ");
while (st.hasMoreTokens()) {
String t = st.nextToken();
classpath.append(base + File.separatorChar + t);
classpath.append(File.pathSeparatorChar);
}
}
}
}
}
} catch (IOException ioe) {
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException ioe2) {
}
}
}
}
}
}
cl = cl.getParent();
}
}
/**
* Filter for zip/jar
*/
private static class JavaArchiveFilter implements FileFilter {
public boolean accept(File file) {
String name = file.getName().toLowerCase();
return (name.endsWith(".jar") || name.endsWith(".zip"));
}
}
}
|