📄 standardpluginmanager.java
字号:
/*****************************************************************************
* 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 + -