/* * Copyright 2007 Sun Microsystems, Inc. * * This file is part of jVoiceBridge. * * jVoiceBridge is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation and distributed hereunder * to you. * * jVoiceBridge is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Sun designates this particular file as subject to the "Classpath" * exception as provided by Sun in the License file that accompanied this * code. */ package com.sun.voip.server; import com.sun.voip.Logger; import java.net.URL; import java.net.URLClassLoader; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; public class ModuleLoader extends URLClassLoader { private List<Class<?>> moduleClasses = new ArrayList<Class<?>>(); /* * modPath is a list of paths to jar files. * Each path element in the list is separated by path.separator */ public ModuleLoader(String modPath) throws IOException { super(new URL[0]); loadModules(modPath); initializeModules(); } public void loadModules(String modPath) throws IOException { String[] path = modPath.split( System.getProperty("path.separator")); for (int i = 0; i < path.length; i++) { Logger.writeFile("Searching for modules in " + path[i]); File f = new File(path[i]); String[] fileList = f.list(); if (fileList == null) { Logger.writeFile("module path '" + path[i] + "' " + "is not a directory. Ignoring."); continue; } for (int j = 0; j < fileList.length; j++) { String dirEntry = fileList[j]; // next directory entry if (dirEntry.equals(".") || dirEntry.equals("..")) { continue; // skip these } String dir = path[i] + dirEntry + System.getProperty("file.separator"); if (new File(dir).isDirectory()) { /* * Recurively load jar files in subdirectories */ loadModules(dir); continue; } if (dirEntry.indexOf(".jar") < 0) { if (Logger.logLevel >= Logger.LOG_INFO) { Logger.println("Skipping non-jar file " + dirEntry); } continue; } dirEntry = path[i] + dirEntry; Logger.println("Processing jar file " + dirEntry); try { addURL(new File(dirEntry).toURI().toURL()); loadBridgeModule(dirEntry); //if (loadBridgeModule(dirEntry) == false) { // loadNonBridgeModule(dirEntry); //} } catch (IOException e) { Logger.println("Can't read jar file: " + dirEntry); continue; } } } } private void initializeModules() throws IOException { for (Class<?> c : moduleClasses) { if (Logger.logLevel >= Logger.LOG_INFO) { Logger.println("initializeModule " + c.getName()); } try { c.newInstance(); } catch (Exception ex) { Logger.exception("Error instantiating " + c, ex); continue; } } } /* * The manifest must have an attribute with the name Bridge-Module-Info. * The value has the following format: * * <classname>,<classname> ... * * where classname is the class to instiate. */ private boolean loadBridgeModule(String dirEntry) throws IOException { JarFile jarFile = new JarFile(dirEntry); Manifest manifest = null; try { manifest = jarFile.getManifest(); } catch (IOException e) { Logger.println("can't read manifest in " + jarFile); return false; } if (manifest == null) { if (Logger.logLevel >= Logger.LOG_INFO) { Logger.println("no manifest in " + jarFile); } return false; } String[] classList = null; Attributes attributes = manifest.getMainAttributes(); if (attributes == null) { if (Logger.logLevel >= Logger.LOG_INFO) { Logger.println("No attributes in " + dirEntry); } return false; } String attributeValues = attributes.getValue("Bridge-Module-Info"); if (attributeValues == null) { if (Logger.logLevel >= Logger.LOG_INFO) { Logger.println("No attribute values in: " + dirEntry); } return false; } String[] moduleValues = attributeValues.split(","); for (int i = 0; i < moduleValues.length; i++) { addModule(moduleValues[i].trim()); } return true; } private void addModule(String className) { Class c; try { if (Logger.logLevel >= Logger.LOG_INFO) { Logger.println("Looking for class " + className); } c = loadClass(className); } catch (ClassNotFoundException e) { Logger.println("ClassNotFoundException: '" + className + "'"); return; } moduleClasses.add(c); return; } private void loadNonBridgeModule(String dirEntry) throws IOException { JarFile jarFile = new JarFile(dirEntry); Enumeration entries = jarFile.entries(); if (entries == null) { Logger.println("No entries in jarFile: " + dirEntry); return; } while (entries.hasMoreElements()) { JarEntry jarEntry = (JarEntry) entries.nextElement(); String className = jarEntry.getName(); int ix; if ((ix = className.indexOf(".class")) < 0) { if (Logger.logLevel >= Logger.LOG_INFO) { Logger.println("Skipping non-class entry in jarFile: " + className); } continue; } className = className.replaceAll(".class", ""); className = className.replaceAll("/", "."); try { if (Logger.logLevel >= Logger.LOG_INFO) { Logger.println("Looking for class '" + className + "'"); } loadClass(className); // load the class } catch (ClassNotFoundException e) { Logger.println("ClassNotFoundException: '" + className + "'"); } } } }