/* * Copyright 2008 biaoping.yin * * 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.frameworkset.web.listener; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Properties; import org.apache.log4j.Logger; import org.frameworkset.web.servlet.PropertiesDummy; import org.frameworkset.web.servlet.launcher.CustomClassLoader; import org.frameworkset.web.servlet.launcher.CustomJarsLauncher; /** * <p> * Title: ListenerUtil.java * </p> * <p> * Description: * </p> * <p> * bboss workgroup * </p> * <p> * Copyright (c) 2008 * </p> * * @Date 2011-1-5 * @author biaoping.yin * @version 1.0 */ public abstract class JarUtil { private static final Properties defaultStrategies; /** * Name of the class path resource (relative to the DispatcherServlet class) * that defines DispatcherServlet's default strategy names. */ private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties"; private static String[] jarFiles = new String[] { ".jar", ".dll", ".lib", ".so", ".zip" }; private static String[] execludeJarDirs = new String[] { ".svn" }; private static String docbase; private static String customJarsLocation = "/WEB-INF/lib/ext"; private static String[] appServerClassLoader = new String[] { "org.frameworkset.web.servlet.launcher.TomcatWebAppClassLoader", "org.frameworkset.web.servlet.launcher.ApusicWebappClassLoader", "org.frameworkset.web.servlet.launcher.WAS70WebappClassLoader", "org.frameworkset.web.servlet.launcher.ResinWebAppClassLoader", "org.frameworkset.web.servlet.launcher.WeblogicWebAppClassLoader" }; static { // Load default strategy implementations from properties file. // This is currently strictly internal and not meant to be customized // by application developers. try { defaultStrategies = fillProperties(); initAppServerClassLoader(); initDocbase(); String[] jarFiles_ = null; String jarFile = (String) defaultStrategies .getProperty("org.frameworkset.web.servlet.launcher.jarFiles"); if (jarFile != null && !jarFile.trim().equals("")) { jarFile = jarFile.trim(); jarFiles_ = jarFile.split(","); if (jarFiles_.length > 0) { for (int i = 0; i < jarFiles_.length; i++) { jarFiles_[i] = jarFiles_[i].trim(); } jarFiles = jarFiles_; } } String execludeJarDir = (String) defaultStrategies .getProperty("org.frameworkset.web.servlet.launcher.execludejarDirs"); if (execludeJarDir != null && !execludeJarDir.trim().equals("")) { execludeJarDir = execludeJarDir.trim(); String[] execludeJarDirs_ = execludeJarDir.split(","); if (execludeJarDirs_.length > 0) { for (int i = 0; i < execludeJarDirs_.length; i++) { execludeJarDirs_[i] = execludeJarDirs_[i].trim(); } execludeJarDirs = execludeJarDirs_; } } } catch (IOException ex) { throw new IllegalStateException( "Could not load 'DispatcherServlet.properties': " + ex.getMessage()); } } private static void initDocbase() { docbase = defaultStrategies .getProperty("org.frameworkset.web.servlet.launcher.docbase"); System.out .println("get docbase from [org.frameworkset.web.servlet.launcher.docbase]: " + docbase); if (docbase == null || docbase.trim().equals("")) { URL location = (JarUtil.class).getProtectionDomain() .getCodeSource().getLocation(); File appDir = computeApplicationDir(location, new File(".")); docbase = appDir.getParentFile().getPath(); System.out .println("Evalute docbase from Class context: " + docbase); } else { docbase = docbase.trim(); File file = new File(docbase); if (!file.exists()) { System.out.println("Config docbase does not exist: " + docbase + ", Will Get from Class context."); URL location = (JarUtil.class).getProtectionDomain() .getCodeSource().getLocation(); File appDir = computeApplicationDir(location, new File(".")); docbase = appDir.getParentFile().getPath(); System.out.println("Evalute docbase from Class context: " + docbase); } } // org.frameworkset.web.servlet.launcher.docbase customJarsLocation = defaultStrategies .getProperty("org.frameworkset.web.servlet.launcher.customJarsLocation"); System.out .println("Get customJarsLocation from [org.frameworkset.web.servlet.launcher.customJarsLocation]: " + customJarsLocation); if (customJarsLocation == null || customJarsLocation.trim().equals("")) { System.out .println("Get customJarsLocation from [org.frameworkset.web.servlet.launcher.customJarsLocation]: " + customJarsLocation + " default customJarsLocation[/WEB-INF/lib/ext] will be used."); customJarsLocation = "/WEB-INF/lib/ext"; } else { customJarsLocation = customJarsLocation.trim(); } } private static void initAppServerClassLoader() { String appServerClassLoader_ = defaultStrategies .getProperty("org.frameworkset.web.servlet.launcher.CustomClassLoader"); if (appServerClassLoader_ != null) { System.out .println("AppServerClassLoaders:" + appServerClassLoader_); String temp[] = appServerClassLoader_.split(","); for (int i = 0; i < temp.length; i++) { temp[i] = temp[i].trim(); } if (temp.length > 0) { appServerClassLoader = temp; } } } private static File computeApplicationDir(URL location, File defaultDir) { if (location == null) { System.out .println("Warning: Cannot locate the program directory. Assuming default."); return defaultDir; } if (!"file".equalsIgnoreCase(location.getProtocol())) { System.out .println("Warning: Unrecognized location type. Assuming default."); return new File("."); } String file = location.getFile(); // System.out.println("file: .>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" // + file); if (!file.endsWith(".jar") && !file.endsWith(".zip")) { try { // return (new File(URLDecoder.decode(location.getFile(), // "UTF-8"))).getParentFile().getParentFile(); return (new File(URLDecoder.decode(location.getFile(), "UTF-8"))) .getParentFile().getParentFile().getParentFile() .getParentFile().getParentFile().getParentFile(); } catch (UnsupportedEncodingException e) { } System.out .println("Warning: Unrecognized location type. Assuming default."); return new File(location.getFile()); } else { try { File path = null;// new // File(URLDecoder.decode(location.toExternalForm().substring(6), // "UTF-8")).getParentFile(); if (!isLinux()) { path = new File(URLDecoder.decode(location.toExternalForm() .substring(6), "UTF-8")).getParentFile() .getParentFile(); } else { path = new File(URLDecoder.decode(location.toExternalForm() .substring(5), "UTF-8")).getParentFile() .getParentFile(); } // System.out.println("path: " + path.getAbsolutePath()); // System.out.println("location: " + location.getPath()); // System.out.println("external from location: " + // URLDecoder.decode(location.toExternalForm().substring(6), // "UTF-8")); // System.out.println("external from location + 6: " + // URLDecoder.decode(location.toExternalForm(), "UTF-8")); return path; } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out .println("Warning: Unrecognized location type. Assuming default."); return new File(location.getFile()); } public static boolean isJarFile(String name) { for (int i = 0; i < jarFiles.length; i++) { if (name.endsWith(jarFiles[i])) return true; } return false; } public static boolean isExecludeJarDir(String name) { for (int i = 0; i < execludeJarDirs.length; i++) { if (name.equals(execludeJarDirs[i])) return true; } return false; } /** * determine the OS name * * @return The name of the OS */ public static final String getOS() { return System.getProperty("os.name"); } /** * @return True if the OS is a Windows derivate. */ public static final boolean isWindows() { return getOS().startsWith("Windows"); } /** * @return True if the OS is a Linux derivate. */ public static final boolean isLinux() { return getOS().startsWith("Linux"); } private static boolean loaded = false; public static boolean loadCustomJars() { if (loaded) return loaded; try { // Exception e = new // Exception("JarLoadServlet>>>>>>>>>>>>>>>>>>>>>>>>>"); // e.printStackTrace(); // String customJarsLocation = // arg0.getServletContext().getInitParameter("customJarsLocation"); System.out.println("Load custom Jars from Location:" + customJarsLocation + " to " + JarUtil.class.getClassLoader().getClass() .getCanonicalName()); CustomClassLoader classLoader = getDefaultStrategy(JarUtil.class .getClassLoader()); // classLoader.initClassLoader(JarUtil.class.getClassLoader()); CustomJarsLauncher launcher = new CustomJarsLauncher(); launcher.loadFromRepository(classLoader, docbase, customJarsLocation); Logger log = Logger.getLogger(JarUtil.class); return loaded; } catch (Exception e) { e.printStackTrace(); return loaded; } finally { loaded = true; } } /** * Return the default strategy object for the given strategy interface. * <p> * The default implementation delegates to {@link #getDefaultStrategies}, * expecting a single object in the list. * * @param context * the current WebApplicationContext * @param strategyInterface * the strategy interface * @return the corresponding strategy object * * @see #getDefaultStrategies */ protected static CustomClassLoader getDefaultStrategy( ClassLoader classLoader) throws Exception { List<CustomClassLoader> strategies = getDefaultStrategies(classLoader); if (strategies.size() <= 0) { throw new Exception( "DispatcherServlet needs exactly 1 strategy for interface [" + CustomClassLoader.class.getName() + "]"); } return strategies.get(0); } public static InputStream getInputStream(Class clazz) throws IOException { InputStream is = null; is = clazz.getResourceAsStream(DEFAULT_STRATEGIES_PATH); if (is == null) { throw new FileNotFoundException(DEFAULT_STRATEGIES_PATH + " cannot be opened because it does not exist"); } return is; } /** * Create a List of default strategy objects for the given strategy * interface. * <p> * The default implementation uses the "DispatcherServlet.properties" file * (in the same package as the DispatcherServlet class) to determine the * class names. It instantiates the strategy objects through the context's * BeanFactory. * * @param context * the current WebApplicationContext * @param strategyInterface * the strategy interface * @return the List of corresponding strategy objects */ protected static List<CustomClassLoader> getDefaultStrategies( ClassLoader classLoader) { List<CustomClassLoader> strategies = null; if (appServerClassLoader != null) { String[] classNames = appServerClassLoader; // System.out.println(classNames); strategies = new ArrayList(classNames.length); for (int i = 0; i < classNames.length; i++) { String className = classNames[i]; try { System.out.println("Use CustomClassLoader:" + className); Class clazz = Class.forName(className); CustomClassLoader strategy = (CustomClassLoader) clazz .newInstance(); if (strategy.validate(classLoader)) { strategy.initClassLoader(classLoader); strategies.add(strategy); return strategies; } } catch (ClassNotFoundException ex) { // ex.printStackTrace(); continue; } catch (LinkageError ex) { // ex.printStackTrace(); continue; } catch (InstantiationException ex) { // ex.printStackTrace(); continue; } catch (IllegalAccessException ex) { // ex.printStackTrace(); continue; } catch (Exception ex) { // ex.printStackTrace(); continue; } } strategies = Collections.EMPTY_LIST; } else { strategies = Collections.EMPTY_LIST; } return strategies; } /** * Fill the given properties from the given resource. * * @param props * the Properties instance to fill * @param resource * the resource to load from * @throws IOException * if loading failed */ public static Properties fillProperties() throws IOException { InputStream is = getInputStream(PropertiesDummy.class); try { Properties props = new Properties(); props.load(is); return props; } finally { is.close(); } } }