⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 standardpluginmanager.java

📁 java插件系统源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
 * Java Plug-in Framework (JPF)
 * Copyright (C) 2004-2006 Dmitry Olshansky
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *****************************************************************************/
package org.java.plugin.standard;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.java.plugin.JpfException;
import org.java.plugin.PathResolver;
import org.java.plugin.Plugin;
import org.java.plugin.PluginClassLoader;
import org.java.plugin.PluginLifecycleException;
import org.java.plugin.PluginManager;
import org.java.plugin.registry.PluginDescriptor;
import org.java.plugin.registry.PluginFragment;
import org.java.plugin.registry.PluginPrerequisite;
import org.java.plugin.registry.PluginRegistry;
import org.java.plugin.registry.PluginRegistry.RegistryChangeData;
import org.java.plugin.registry.PluginRegistry.RegistryChangeListener;

/**
 * Standard implementation of plug-in manager.
 * @version $Id: StandardPluginManager.java,v 1.13 2006/09/07 18:16:57 ddimon Exp $
 */
public final class StandardPluginManager extends PluginManager {
    Log log = LogFactory.getLog(getClass());

    private final PathResolver pathResolver;
    private final PluginRegistry registry;
    private final PluginLifecycleHandler lifecycleHandler;
    private final Map activePlugins = new HashMap(); // <plugin-id, Plugin>
    private final Set activatingPlugins = new HashSet(); // <plugin-id>
    private final Set badPlugins = new HashSet(); // <plugin-id>
    private final List activationLog = new LinkedList(); // <plugin-id>
    private final Map classLoaders =
        new HashMap(); // <plugin-id, PluginClassLoader>
    private final Set disabledPlugins = new HashSet(); // <plugin-id>
    private final List listeners =
        Collections.synchronizedList(new LinkedList()); // <EventListener>
    private RegistryChangeListener registryChangeListener;
    private Map notRegisteredPluginLocations = new HashMap(); //<URL, URL>

    /**
     * Creates instance of plug-in manager for given registry, path resolver
     * and life cycle handler.
     * @param aRegistry some implementation of plug-in registry interface
     * @param aPathResolver some implementation of path resolver interface
     * @param aLifecycleHandler an implementation of plug-in life cycle handler
     * 
     * @see StandardObjectFactory
     */
    protected StandardPluginManager(final PluginRegistry aRegistry,
            final PathResolver aPathResolver,
            final PluginLifecycleHandler aLifecycleHandler) {
        registry = aRegistry;
        pathResolver = aPathResolver;
        lifecycleHandler = aLifecycleHandler;
        lifecycleHandler.init(this);
        registryChangeListener = new RegistryChangeListener() {
            public void registryChanged(final RegistryChangeData data) {
                registryChangeHandler(data);
            }
        };
        registry.registerListener(registryChangeListener);
    }

    /**
     * @see org.java.plugin.PluginManager#getRegistry()
     */
    public PluginRegistry getRegistry() {
        return registry;
    }

    /**
     * @see org.java.plugin.PluginManager#getPathResolver()
     */
    public PathResolver getPathResolver() {
        return pathResolver;
    }
    
    /**
     * Method to handle plug-in registry change events.
     * @param data registry change data holder
     */
    synchronized void registryChangeHandler(
            final RegistryChangeData data) {
        badPlugins.clear();
        for (Iterator it = data.removedPlugins().iterator(); it.hasNext();) {
            String id = (String) it.next();
            deactivatePlugin(id);
            pathResolver.unregisterContext(id);
        }
        for (Iterator it = registry.getPluginDescriptors().iterator();
                it.hasNext();) {
            PluginDescriptor idt = (PluginDescriptor) it.next();
            URL location =
                (URL) notRegisteredPluginLocations.remove(idt.getLocation());
            if (location != null) {
                pathResolver.registerContext(idt, location);
            }
        }
        for (Iterator it = registry.getPluginFragments().iterator();
                it.hasNext();) {
            PluginFragment idt = (PluginFragment) it.next();
            URL location =
                (URL) notRegisteredPluginLocations.remove(idt.getLocation());
            if (location != null) {
                pathResolver.registerContext(idt, location);
            }
        }
        for (Iterator it = data.modifiedPlugins().iterator(); it.hasNext();) {
            String id = (String) it.next();
            if (activePlugins.containsKey(id)) {
                deactivatePlugin(id);
                try {
                    activatePlugin(id);
                } catch (Exception e) {
                    log.error("failed activating modified plug-in " + id, e); //$NON-NLS-1$
                }
            } else {
                PluginClassLoader clsLoader =
                    (PluginClassLoader) classLoaders.get(id);
                if (clsLoader != null) {
                    notifyClassLoader(clsLoader);
                }
            }
        }
    }
    
    /**
     * Registers plug-ins and their locations with this plug-in manager. You
     * should use this method to register new plug-ins to make them available
     * for activation with this manager instance (compare this to
     * {@link PluginRegistry#register(URL[])} method that just makes plug-in's
     * meta-data available for reading and doesn't "know" where are things
     * actually located).
     * @param locations plug-in locations data
     * @return map where keys are manifest URL's and values are registered
     *         plug-ins or plug-in fragments, URL's for unprocessed manifests
     *         are not included
     * @throws JpfException if given plug-ins can't be registered or published
     *         (optional behavior)
     */
    public Map publishPlugins(final PluginLocation[] locations)
            throws JpfException {
        URL[] manifests = new URL[locations.length];
        for (int i = 0; i < manifests.length; i++) {
            manifests[i] = locations[i].getManifestLocation();
            notRegisteredPluginLocations.put(manifests[i],
                    locations[i].getContextLocation());
        }
        return registry.register(manifests);
    }
    
    /**
     * Looks for plug-in with given ID and activates it if it is not activated
     * yet. Note that this method will never return <code>null</code>.
     * @param id plug-in ID
     * @return found plug-in
     * @throws PluginLifecycleException if plug-in can't be found or activated
     */
    public Plugin getPlugin(final String id) throws PluginLifecycleException {
        Plugin result = (Plugin) activePlugins.get(id);
        if (result != null) {
            return result;
        }
        if (badPlugins.contains(id)) {
            throw new IllegalArgumentException("plug-in " + id //$NON-NLS-1$
                    + " disabled internally as it wasn't properly initialized"); //$NON-NLS-1$
        }
        if (disabledPlugins.contains(id)) {
            throw new IllegalArgumentException("plug-in " + id //$NON-NLS-1$
                    + " disabled externally"); //$NON-NLS-1$
        }
        PluginDescriptor descr = registry.getPluginDescriptor(id);
        if (descr == null) {
            throw new IllegalArgumentException("unknown plug-in ID - " + id); //$NON-NLS-1$
        }
        return activatePlugin(descr);
    }

    /**
     * Activates plug-in with given ID if it is not activated yet.
     * @param id plug-in ID
     * @throws PluginLifecycleException if plug-in can't be found or activated
     */
    public void activatePlugin(final String id)
            throws PluginLifecycleException {
        if (activePlugins.containsKey(id)) {
            return;
        }
        if (badPlugins.contains(id)) {
            throw new IllegalArgumentException("plug-in " + id //$NON-NLS-1$
                    + " disabled internally as it wasn't properly initialized"); //$NON-NLS-1$
        }
        if (disabledPlugins.contains(id)) {
            throw new IllegalArgumentException("plug-in " + id //$NON-NLS-1$
                    + " disabled externally"); //$NON-NLS-1$
        }
        PluginDescriptor descr = registry.getPluginDescriptor(id);
        if (descr == null) {
            throw new IllegalArgumentException("unknown plug-in ID - " + id); //$NON-NLS-1$
        }
        activatePlugin(descr);
    }

    /**
     * Looks for plug-in, given object belongs to.
     * @param obj any object that maybe belongs to some plug-in
     * @return plug-in or <code>null</code> if given object doesn't belong
     *         to any plug-in (possibly it is part of "host" application)
     *         and thus doesn't managed by the Framework directly
     *         or indirectly
     */
    public Plugin getPluginFor(final Object obj) {
        if (obj == null) {
            return null;
        }
        ClassLoader clsLoader;
        if (obj instanceof Class) {
            clsLoader = ((Class) obj).getClassLoader();
        } else if (obj instanceof ClassLoader) {
            clsLoader = (ClassLoader) obj;
        } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -