| /* |
| * 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")); |
| } |
| } |
| } |