alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

// $Id: ModuleLoader.java,v 1.22 2004/09/11 09:25:58 mvw Exp $
// Copyright (c) 1996-2004 The Regents of the University of California. All
// Rights Reserved. Permission to use, copy, modify, and distribute this
// software and its documentation without fee, and without a written
// agreement is hereby granted, provided that the above copyright notice
// and this paragraph appear in all copies.  This software program and
// documentation are copyrighted by The Regents of the University of
// California. The software program and documentation are supplied "AS
// IS", without any accompanying services from The Regents. The Regents
// does not warrant that the operation of the program will be
// uninterrupted or error-free. The end-user understands that the program
// was developed for research purposes and is advised not to rely
// exclusively on the program for any reason.  IN NO EVENT SHALL THE
// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.


/*
 * ModuleLoader.java
 *
 * Created on June 11, 2001, 6:26 AM
 */

package org.argouml.application.modules;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

import org.apache.log4j.Logger;
import org.argouml.application.api.Argo;
import org.argouml.application.api.ArgoModule;
import org.argouml.application.api.ArgoSingletonModule;
import org.argouml.application.api.Pluggable;
import org.argouml.application.events.ArgoEventPump;
import org.argouml.application.events.ArgoModuleEvent;
import org.argouml.application.security.ArgoJarClassLoader;

/**  Handles loading of modules and plugins for ArgoUML.
 *
 * @author  Will Howery
 * @author  Thierry Lach
 * @since   0.9.4
 */
public class ModuleLoader {
    /**
     * Logger for this class.
     */
    private static final Logger LOG = Logger.getLogger(ModuleLoader.class);

    /** Class file suffix */
    public static final String CLASS_SUFFIX = ".class";

    // String mModulePropertyFile=null;
    private static ModuleLoader singleton = null;

    private ArrayList moduleClasses = null;
    private Vector menuActionList = null;
    private static Hashtable singletons = null;
    private static String argoRoot = null;
    private static String argoHome = null;

    /** Make sure the module loader cannot be instantiated from outside.
     */
    private ModuleLoader() {
        singletons = new Hashtable();
        moduleClasses = new ArrayList();
        menuActionList = new Vector();

	// Use a little trick to find out where Argo is being loaded from.
        String extForm = 
	    org.argouml.application.Main.class.getResource(Argo.ARGOINI)
	        .toExternalForm();
	argoRoot = extForm.substring(0, 
				     extForm.length() - Argo.ARGOINI.length());

	// If it's a jar, clean it up and make it look like a file url
	if (argoRoot.startsWith("jar:")) {
	    argoRoot = argoRoot.substring(4);
	    if (argoRoot.endsWith("!")) {
	        argoRoot = argoRoot.substring(0, argoRoot.length() - 1);
	    }
	}
	if (argoRoot != null) {
	    LOG.info("argoRoot is " + argoRoot);
	    if (argoRoot.startsWith("file:")) {
	        argoHome = new File(argoRoot.substring(5)).getAbsoluteFile()
		    .getParent();
	    }
	    else {
	        argoHome = new File(argoRoot).getAbsoluteFile().getParent();
	    }
	    try {
	        /* JDK 1.2 URLDecoder.decode(String) throws Exception
		 * so we catch it here (and ignore it).
		 * JDK 1.3 and JDK 1.4 do not.
		 */
	        argoHome = java.net.URLDecoder.decode(argoHome);
	    }
	    catch (Exception e) {
		LOG.warn(e);
            }

	    LOG.info("argoHome is " + argoHome);
	}
    }

    /** Get the singleton instance
     * 
     * @return the module loader singleton
     */
    public static ModuleLoader getInstance() {
        if (singleton == null) {
            singleton = new ModuleLoader();
        }
        return singleton;
    }

    /** Load the internal modules.
     */
    public void initialize() {
	loadInternalModules(getClass(), "standard.modules");
	loadModulesFromExtensionDir();
	loadModulesFromClassPathJars();
	loadModulesFromPredefinedLists();
    }

    /** Search for and load modules from predefined places.
     *  Look in the following locations in the following order, using
     *  System.getProperty() to retrieve the values.
     *
     *  Property name
     *  ${user.dir}
     *  ${user.home}
     *  ${java.home}/lib
     */
    public void loadModulesFromPredefinedLists() {
        String fs = System.getProperty("file.separator");

        String[] path =
        {
            System.getProperty("user.dir") + fs + ArgoModule.MODULEFILENAME,
            System.getProperty("user.dir") + fs
                + ArgoModule.MODULEFILENAME_ALTERNATE,
            System.getProperty("user.home") + fs + ArgoModule.MODULEFILENAME,
            System.getProperty("user.home") + fs
                + ArgoModule.MODULEFILENAME_ALTERNATE,
            System.getProperty("java.home") + fs + "lib" + fs
                + ArgoModule.MODULEFILENAME,
            System.getProperty("java.home") + fs + "lib" + fs
                + ArgoModule.MODULEFILENAME_ALTERNATE };

	// Get all of the file paths.  Check if the file exists,
	// is a file (not a directory), and is readable.
	for (int i = 0; i < path.length; i++) {
	    try {
	        File file = new File(path[i]).getCanonicalFile();
	        if (file.exists() && file.isFile() && file.canRead()) {
	            LOG.info ("Loading modules from " + file);
		    loadModules(new FileInputStream(file), file.getPath());
		}
	    }
	    catch (FileNotFoundException fnfe) {
	        // Ignore problem
	        LOG.error ("File not found " + path[i], fnfe);
	    }
	    catch (IOException ioe) {
	        // Ignore problem
	        LOG.error ("IO Exception " + path[i], ioe);
	    }
	}
    }

    /** Check the manifest of a jar file for an argo extension.
     */
    private void processJarFile(ClassLoader classloader, File file) {
	JarFile jarfile = null;
        Manifest manifest = null;
	LOG.info("Opening jar file " + file);
        // try {
	// File file = new File(jarName);
	try {
	    jarfile = new JarFile(file);
	}
	catch (Exception e) {
	    LOG.debug("Unable to open " + file, e);
	}

	if (jarfile != null) {
	    try {
	        manifest = jarfile.getManifest();
	        if (manifest == null) {
	            LOG.debug(file + " does not have a manifest");
	        }
	    }
	    catch (Exception e) {
	        LOG.debug("Unable to read manifest of " + file, e);
		manifest = null;
	    }
	}

	if (manifest != null) {
	    // else {
	    Map entries = manifest.getEntries();
	    Iterator iMap = entries.keySet().iterator();
	    while (iMap.hasNext()) {
                // Look for our specification
                String cname = (String) iMap.next();
                Attributes atrs = manifest.getAttributes(cname);
                String s1 = atrs.getValue(Attributes.Name.SPECIFICATION_TITLE);
                String s2 = atrs.getValue(Attributes.Name.SPECIFICATION_VENDOR);
                
                // TODO:  If we are in jdk1.3 or above, check
                // EXTENSION_NAME.  Otherwise pass the class name.  It's not
                // as good of a check (we might get duplicate modules with
                // the same key), but it's better than nothing.
                
                // String key = atrs.getValue(Attributes.Name.EXTENSION_NAME);
                String key = cname;
                if (Pluggable.PLUGIN_TITLE.equals(s1)
                        && Pluggable.PLUGIN_VENDOR.equals(s2)
                        && key != null
                        && cname.endsWith(CLASS_SUFFIX)) {
                    int classNamelen = cname.length() - CLASS_SUFFIX.length();
                    String className = cname.substring(0, classNamelen);
                    className = className.replace('/', '.');
                    // This load is not secure.
                    loadClassFromLoader(classloader, key, className, false);
                }
	    }
	    // }
	}
	// }
	// catch (Exception e) {
	// // Ignore problem.
	// ArgoModule.cat.debug("Exception", e);
	// }
    }

    /** Search for and load modules from classpath, and from
     *  other places.
     */
    public void loadModulesFromExtensionDir() {
	if (argoHome != null) {
	    if (argoHome.startsWith("file:")) {
	        loadModulesFromNamedDirectory(argoHome.substring(5) 
					      + File.separator + "ext");
	    }
	    else {
	        loadModulesFromNamedDirectory(argoHome 
					      + File.separator + "ext");
	    }

	}
        String extdir = System.getProperty("argo.ext.dir");
	if (extdir != null) {
	    loadModulesFromNamedDirectory(extdir);
	}
    }

    private void loadModulesFromNamedDirectory(String dirname) {
	File extensionDir = new File(dirname);
	if (extensionDir.isDirectory()) {
	    File[] file = extensionDir.listFiles(new JarFileFilter());
	    for (int i = 0; i < file.length; i++) {
		JarFile jarfile = null;
		// Try-catch only the JarFile instantiation so we
		// don't accidentally mask anything in ArgoJarClassLoader
		// or processJarFile.
		try {
		    jarfile = new JarFile(file[i]);
		    if (jarfile != null) {
	                ClassLoader classloader =
			    new ArgoJarClassLoader(file[i].toURL());
	                // ClassLoader classloader = 
			// getClass().getClassLoader();
	                processJarFile(classloader, file[i]);
	                // processJarFile(getClass().getClassLoader(), file[i]);
		    }
		}
		catch (IOException ioe) { }
	    }
	}
    }

    /** Load modules from a jar file
     * 
     * @param filename jar file name to load from
     */
    public void loadModulesFromJar(String filename) {
	if (filename.toLowerCase().endsWith(".jar")) {
	    processJarFile(getClass().getClassLoader(), new File(filename));
	}
    }

    /** Load modules from jars in the class path
     */
    public void loadModulesFromClassPathJars() {
	StringTokenizer st;
	st = new StringTokenizer(System.getProperty("java.class.path"),
	                         System.getProperty("path.separator"));

	while (st.hasMoreTokens()) {
	    String component = st.nextToken();

	    if (component.toLowerCase().endsWith(".jar")) {
	        processJarFile(getClass().getClassLoader(), 
			       new File(component));
	    }

	}

    }

    /** Load modules listed in Argo resources.
     * 
     * @param loaderClass class to retrieve classloader from
     * @param rsrcName resource name to load
     * @return false if the resource is not found
     */
    public boolean loadInternalModules(Class loaderClass, String rsrcName) {
	LOG.info("Loading modules from " + rsrcName);
	// Load the internal modules
	InputStream is =
	    loaderClass.getResourceAsStream(Argo.RESOURCEDIR + rsrcName);
	return (is == null) ? false : loadModules(is, rsrcName);
    }

    /** Load modules from a property file.
     * 
     * The load may be successful even if no modules are loaded.
     * 
     * @param moduleFile name of file
     * @return false if the load succeeded
     */
    public boolean loadModulesFromFile(String moduleFile) {
	LOG.info("Loading modules from " + moduleFile);
        try {
	    return loadModules(new FileInputStream(moduleFile), moduleFile);
	}
	catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private boolean keyAlreadyLoaded(String key) {
        ListIterator iterator = moduleClasses.listIterator();
        while (iterator.hasNext()) {
            Object obj = iterator.next();
            if (obj instanceof ArgoModule)
                if (key.equals(((ArgoModule) obj).getModuleKey()))
		    return true;
	}
	return false;
    }

    private void loadClassFromLoader(ClassLoader classloader,
                                     String key,
				     String classname,
				     boolean secure) {

	LOG.debug("Load key:" + key + " class:" + classname);
	if (keyAlreadyLoaded(key)) return;
    
	Object obj = null;
	try {
            Class moduleClass = classloader.loadClass(classname);
	    //
	    // Allow us to load classes with private constructors
	    //
	    // First get the zero-argument constructor
	    Constructor c = moduleClass.getDeclaredConstructor(new Class[]{});
	    // Tell jre we can get at it even though it may not be public
	    c.setAccessible(true);
	    // Instantiate it
	    obj = c.newInstance(new Object[]{});
	}
	catch (Exception e) {
	    obj = null;
            LOG.error("Could not instantiate module" + classname, e);
	}
        if (obj != null && obj instanceof ArgoModule) {
            ArgoModule aModule = (ArgoModule) obj;
	    if (aModule.getModuleKey().equals(key) || (!secure)) {
                if (aModule.initializeModule()) {
                    LOG.info("Loaded Module: " + aModule.getModuleName());
                    moduleClasses.add(aModule);
		    fireEvent(ArgoModuleEvent.MODULE_LOADED, aModule);
		    if (aModule instanceof ArgoSingletonModule) {
			ArgoSingletonModule sModule =
			    (ArgoSingletonModule) aModule;
		        try {
			    Class moduleType = sModule.getSingletonType();
		            if (!(singletons.containsKey(moduleType))) {
			        requestNewSingleton(moduleType, sModule);
		            }
		        }
		        catch (Exception e) {
		            LOG.debug ("Exception", e);
		        }
		    }
                }
	    }
	    else {
	        LOG.warn ("Key '" + key
			       + "' does not match module key '" 
			       + aModule.getModuleKey() + "'");
	    }
        }
    }

    /** Load modules from an input stream.
     * 
     * The load may be successful even if no modules are loaded.
     * 
     * @param is input stream in property file format
     * @param filename the input stream is from (for reporting purposes)
     * 
     * @return false if the load succeeded
     */
    public boolean loadModules(InputStream is, String filename) {
        try {
	    LineNumberReader lnr =
		new LineNumberReader(new InputStreamReader(is));
	    while (true) {
	        String realLine = lnr.readLine();
		if (realLine == null) return true;
		String line = realLine.trim();
		if (line.length() == 0) continue;
		if (line.charAt(0) == '#') continue;
		if (line.charAt(0) == '!') continue;
		String sKey = "";
		String sClassName = "";
		try {
		    int equalPos = line.indexOf("=");
		    sKey = line.substring(0, equalPos).trim();
		    sClassName = line.substring(equalPos + 1).trim()
		            .replace('/', '.');
		}
		catch (Exception e) {
		    LOG.warn ("Unable to process " + filename
			      + " at line " + lnr.getLineNumber()
			      + " data = '" + realLine + "'");
		    continue;
		}

                try {
                    if (sKey.startsWith("module.")) {
			loadClassFromLoader(getClass().getClassLoader(),
			                    sKey,
					    sClassName,
					    true);
		    }
		} catch (Exception e) {
		    LOG.warn("Could not load Module: " + sKey);
		    LOG.debug("Could not load Module: " + sKey, e);
		}
		sKey = "";
	    }
	}
	catch (Exception e) {
            e.printStackTrace();
	    System.exit(1);
        }
        return false;
    }

    /** Shut down all modules */
    public void shutdown() {
        try {
            ListIterator iterator = moduleClasses.listIterator();
            while (iterator.hasNext()) {
                Object obj = iterator.next();
                if (obj instanceof ArgoModule) {
                    ArgoModule m = (ArgoModule) obj;
                    m.shutdownModule();
                }
            }
        } catch (Exception e) {
            LOG.warn("ModuleLoader.shutdown "
			  + "Error processing Module shutdown:",
			  e);
            e.printStackTrace();
        }

    }

    /** Process all of the modules to add popup actions for the
     * given context.
     * 
     * @param popUpActions vector of actions
     * @param context to filter by
     */
    public void addModuleAction(Vector popUpActions, Object context) {
        try {
            ListIterator iterator = moduleClasses.listIterator();
            while (iterator.hasNext()) {
                Object obj = iterator.next();
                if (obj instanceof ArgoModule) {
                    ArgoModule m = (ArgoModule) obj;
                    m.getModulePopUpActions(popUpActions, context);
                }
            }
        } catch (Exception e) {
            LOG.warn("ModuleLoader.addModuleAction "
			  + "Error processing Module popup actions:",
			  e);
            e.printStackTrace();
        }
    }

    /** Get the list of modules
     * 
     * @return the list of modules.
     */
    public ArrayList getModules() {
        // TODO: change signature to return Collection
	return moduleClasses;
    }

    /** Locates a module by key.
     * 
     * @param key module identifier to find
     * @return a module object or null if not found.
     */
    public Object getModule(String key) {
        ListIterator iterator = moduleClasses.listIterator();
        while (iterator.hasNext()) {
            Object obj = iterator.next();
            if (obj instanceof ArgoModule)
                if (key.equals(((ArgoModule) obj).getModuleKey()))
		    return obj;
	}
	return null;
    }

    /** Activate a loaded module.
     * @param module to activate
     * @return true if the module was activated,
     *         false if not or if it was already active.
     */
    public boolean activateModule(ArgoModule module) {
        return false;
    }

    /** Gets the current singleton of the module type requested.
     *
     * @param moduleClass the class of the module singleton
     * @return null if there is some problem.
     */
    public static ArgoModule getCurrentSingleton(Class moduleClass) {
	try {
	    return (ArgoModule) singletons.get(moduleClass);
	}
	catch (Exception e) {
	    return null;
	}
    }

    /** Requests the passed singleton to become the current singleton
     *  of the module type requested.
     *
     *  Singletons may refuse to be activated.  In this case,
     *  requestNewSingleton returns false and does not deactivate the
     *  current singleton.
     * 
     * @param modClass class which identifies the singleton
     * @param moduleInstance the module to make the singleton
     * @return true if the singleton is activated
     */
    public static boolean requestNewSingleton(Class modClass,
					      ArgoSingletonModule
					              moduleInstance)
    {
	boolean rc = moduleInstance.canActivateSingleton();
	ArgoSingletonModule currentSingleton;
	if (!moduleInstance.canActivateSingleton()) return false;
	try {
	    currentSingleton =
		(ArgoSingletonModule) getCurrentSingleton(modClass);
	    if (currentSingleton.canDeactivateSingleton()) {
		currentSingleton.deactivateSingleton();
		singletons.remove(modClass);
	    }
	    else {
		// The current singleton refused to relinquish control.
		return false;
	    }
	}
	catch (Exception e) {
	    currentSingleton = moduleInstance;
	}
	singletons.put(modClass, currentSingleton);
	currentSingleton.activateSingleton();
	return true;
    }

    /** Returns a plug-in of a given type.
     *
     *  The type of plug-in returned is determined by the class passed.
     *
     *  @param pluginType a Class which extends Pluggable and indicates
     *                    the type of plug-in to return.
     *  @param context   Additional information used to choose between
     *                    plugins.
     *
     *  @return A plug-in class which extends the type of class passed
     *          as the argument or null if there is some problem.
     */
    public Pluggable getPlugin (Class pluginType,
				Object[] context) {
	//  Make sure that we are only looking at real extensions
	if (!(pluginType.getName().startsWith(Pluggable.PLUGIN_PREFIX))) {
	    LOG.warn ("Class " + pluginType.getName()
		      + " is not a core Argo pluggable type.");
	    return null;
	}

	// Check to see that the class is not Pluggable itself
	if (pluginType.equals(Pluggable.class)) {
	    LOG.warn ("This is " + pluginType.getName()
		      + ", it cannot be used here.");
	    return null;
	}

	// TODO:  The vector should be populated from
	//                   the enumeration in FIFO sequence.

	ListIterator iterator = getModules().listIterator();
	while (iterator.hasNext()) {
	    Object module = iterator.next();
	    // if (module.getClass().isAssignableFrom(pluginType))
	    if (classImplements(module, pluginType)) {
		Pluggable pluggable = (Pluggable) module;
		// if (pluggable.isModuleType(pluginType))
		if (context == null) {
		    return pluggable;
		}
		else {
		    if (pluggable.inContext(context)) {
			return pluggable;
		    }
		}
	    }
	}
	return null;

    }

    /** Indicates whether a requested plug-in is available.  This guarantees
     *  not to instantiate the plug-in.
     *
     *  @param pluginType a Class which extends Pluggable and indicates
     *                    the type of plug-in to return.
     *
     *  @param context   Additional information used to choose between
     *                    plugins.
     *
     *  @return A plug-in class which extends the type of class passed
     *          as the argument.
     *
     *
     */
    public boolean hasPlugin (Class pluginType,
			      Object[] context) {
	//  Make sure that we are only looking at real extensions
	if (!(pluginType.getName().startsWith(Pluggable.PLUGIN_PREFIX))) {
	    LOG.warn ("Class " + pluginType.getName()
		      + " is not a core Argo pluggable type.");
	    return false;
	}

	// Check to see that the class implements Pluggable
	if (!(pluginType.isAssignableFrom(Pluggable.class))) {
	    LOG.warn ("Class " + pluginType.getName()
		      + " does not extend Pluggable.");
	    return false;
	}

	// Check to see that the class is not Pluggable itself
	if (pluginType.equals(Pluggable.class)) {
	    LOG.warn ("Class " + pluginType.getName()
		      + " does not extend Pluggable.");
	    return false;
	}

	// TODO:  The vector should be populated from
	//                   the enumeration in FIFO sequence.

	ListIterator iterator = getModules().listIterator();
	while (iterator.hasNext()) {
	    Object element = iterator.next();
	    // if (element.getClass().isAssignableFrom(pluginType))
	    if (classImplements(element, pluginType)) {
		Pluggable module = (Pluggable) element;
		if (context == null) {
		    return true;
		}
		else {
		    if (module.inContext(context)) {
			return true;
		    }
		}
	    }
	}
	return false;
    }


    /** Returns all plug-in of a given type.
     *
     *  The type of plug-in returned is determined by the class passed.
     *
     *  @param pluginType a Class which extends Pluggable and indicates
     *                    the type of plug-in to return.
     *
     *  @param context An object (or null) which allows the plugin to
     *                 determine if it should be included in a list.
     *
     *  @return A Vector containing all the plugins of the type
     *          passed for the passed context, or null if none
     *          are available.
     */
    public ArrayList getPlugins (Class pluginType, Object[] context) {

	if (!(pluginType.getName().startsWith(Pluggable.PLUGIN_PREFIX))) {
	    LOG.warn ("Class " + pluginType.getName()
		      + " is not a core Argo pluggable type.");
	    return null;
	}

	// Check to see that the class is not Pluggable itself
	if (pluginType.equals(Pluggable.class)) {
	    LOG.warn ("This is " + pluginType.getName()
		      + ", it cannot be used here.");
	    return null;
	}

	// TODO:  The vector should be populated from
	//                   the enumeration in FIFO sequence.

	ArrayList results = new ArrayList();
	ListIterator iterator = getModules().listIterator();
	while (iterator.hasNext()) {
	    Object module = iterator.next();
	    try {
		Pluggable pluggable = (Pluggable) module;
		// if (pluggable.isModuleType(pluginType))
		// if (pluggable.getClass().isAssignableFrom(pluginType))
		if (classImplements(module, pluginType)) {
		    if (context == null) {
			results.add(module);
		    }
		    else {
			if (pluggable.inContext(context)) {
			    results.add(module);
			}
		    }
		}
	    }
	    catch (Exception ex) {
		LOG.warn("Exception for " + module, ex);
	    }
	}
	return results;
    }

    /** Returns argo home
     * 
     * @return the argo home directory
     */
    public String getArgoHome() { return argoHome; }

    /** Returns argo root
     * 
     * @return the argo root directory
     */
    public String getArgoRoot() { return argoRoot; }

    private boolean classImplements(Object implementor, Class implemented) {

	if (implemented.isInstance(implementor)) {
	    return true;
	}

	return false;
    }

    class JarFileFilter implements FileFilter {
	public boolean accept(File pathname) {
	    return (pathname.canRead()
		    && pathname.isFile()
		    && pathname.getPath().toLowerCase().endsWith(".jar"));
	}
    }

    private void fireEvent(int eventType,  ArgoModule module) {
	ArgoEventPump.fireEvent(new ArgoModuleEvent(eventType, module));
    }

} /* end class ModuleLoader */

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.