📄 pluginmanager.java
字号:
/* * PluginManager.java * * Version: $Revision: 1.2 $ * * Date: $Date: 2006/03/17 16:16:35 $ * * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts * Institute of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Hewlett-Packard Company nor the name of the * Massachusetts Institute of Technology nor the names of their * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */package org.dspace.core;import java.util.Map;import java.util.HashMap;import java.util.HashSet;import java.util.Enumeration;import java.util.List;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import java.util.regex.Pattern;import java.util.regex.Matcher;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Array;import java.io.BufferedReader;import java.io.FileReader;import java.io.File;import java.io.IOException; import org.apache.log4j.Logger;/** * The Plugin Manager is a very simple component container. It creates and * organizes components (plugins), and helps select a plugin in the cases * where there are many possible choices. It also gives some limited * control over the lifecycle of a plugin. It manages three different types * (usage patterns) of plugins: * <p> * <ol><li> Singleton Plugin * <br> There is only one implementation class for the plugin. It is indicated * in the configuration. This type of plugin chooses an implementations of * a service, for the entire system, at configuration time. Your * application just fetches the plugin for that interface and gets the * configured-in choice. * * <p><li> Sequence Plugins * <br> You need a sequence or series of plugins, to implement a mechanism like * StackableAuthenticationMethods or a pipeline, where each plugin is * called in order to contribute its implementation of a process to the * whole. * <p><li> Named Plugins * <br> Use a named plugin when the application has to choose one plugin * implementation out of many available ones. Each implementation is bound * to one or more names (symbolic identifiers) in the configuration. * </ol><p> * The name is just a <code>String</code> to be associated with the * combination of implementation class and interface. It may contain * any characters except for comma (,) and equals (=). It may contain * embedded spaces. Comma is a special character used to separate * names in the configuration entry. * * @author Larry Stone * @version $Revision: 1.2 $ * @see SelfNamedPlugin */public class PluginManager{ /** log4j category */ private static Logger log = Logger.getLogger(PluginManager.class); /** * Prefixes of names of properties to look for in DSpace Configuration */ private static final String SINGLE_PREFIX = "plugin.single."; private static final String SEQUENCE_PREFIX = "plugin.sequence."; private static final String NAMED_PREFIX = "plugin.named."; private static final String SELFNAMED_PREFIX = "plugin.selfnamed."; private static final String REUSABLE_PREFIX = "plugin.reusable."; // Separator character (from perl $;) to make "two dimensional" // hashtable key out of interface classname and plugin name; // this character separates the words. private static final String SEP = "\034"; // Map of plugin class to "reusable" metric (as Boolean, must be Object) // Key is Class, value is Boolean (true by default). private static HashMap cacheMeCache = new HashMap(); // Predicate -- whether or not to cache this class. Ironically, // the cacheability information is itself cached. private static boolean cacheMe(Class implClass) { if (cacheMeCache.containsKey(implClass)) { return ((Boolean)cacheMeCache.get(implClass)).booleanValue(); } else { String key = REUSABLE_PREFIX+implClass.getName(); boolean reusable = ConfigurationManager.getBooleanProperty(key, true); cacheMeCache.put(implClass, new Boolean(reusable)); return reusable; } } /** * Returns an instance of the singleton (single) plugin implementing * the given interface. There must be exactly one single plugin * configured for this interface, otherwise the * <code>PluginConfigurationError</code> is thrown. * <p> * Note that this is the only "get plugin" method which throws an * exception. It is typically used at initialization time to set up * a permanent part of the system so any failure is fatal. * * @param interfaceClass interface Class object * @return instance of plugin * @throws PluginConfigurationError */ public static Object getSinglePlugin(Class interfaceClass) throws PluginConfigurationError, PluginInstantiationException { String iname = interfaceClass.getName(); // configuration format is prefix.<interface> = <classname> String classname = ConfigurationManager.getProperty(SINGLE_PREFIX+iname); if (classname != null) return getAnonymousPlugin(classname.trim()); else throw new PluginConfigurationError("No Single Plugin configured for interface \""+iname+"\""); } // cache of config data for Sequence Plugins; format its // <interface-name> -> [ <classname>.. ] (value is Array) private static HashMap sequenceConfig = new HashMap(); /** * Returns instances of all plugins that implement the interface * intface, in an Array. Returns an empty array if no there are no * matching plugins. * <p> * The order of the plugins in the array is the same as their class * names in the configuration's value field. * * @param intfc interface for which to find plugins. * @return an array of plugin instances; if none are * available an empty array is returned. */ public static Object[] getPluginSequence(Class intfc) throws PluginInstantiationException { // cache the configuration for this interface after grovelling it once: // format is prefix.<interface> = <classname> String iname = intfc.getName(); String classname[] = null; if (!sequenceConfig.containsKey(iname)) { String val = ConfigurationManager.getProperty(SEQUENCE_PREFIX+iname); if (val == null) { log.warn("No Configuration entry found for Sequence Plugin interface="+iname); return new Object[0]; } classname = val.split("\\s*,\\s*"); sequenceConfig.put(iname, classname); } else classname = (String[])sequenceConfig.get(iname); Object result[] = (Object[])Array.newInstance(intfc, classname.length); for (int i = 0; i < classname.length; ++i) { log.debug("Adding Sequence plugin for interface= "+iname+", class="+classname[i]); result[i] = getAnonymousPlugin(classname[i]); } return result; } // Map of cached (reusable) single plugin instances - class -> instance. private static HashMap anonymousInstanceCache = new HashMap(); // Get possibly-cached plugin instance for un-named plugin, // this is shared by Single and Sequence plugins. private static Object getAnonymousPlugin(String classname) throws PluginInstantiationException { try { Class pluginClass = Class.forName(classname); if (cacheMe(pluginClass)) { Object cached = anonymousInstanceCache.get(pluginClass); if (cached == null) { cached = pluginClass.newInstance(); anonymousInstanceCache.put(pluginClass, cached); } return cached; } else return pluginClass.newInstance(); } catch (ClassNotFoundException e) { throw new PluginInstantiationException("Cannot load plugin class: " + e.toString(), e); } catch (InstantiationException e) { throw new PluginInstantiationException(e); } catch (IllegalAccessException e) { throw new PluginInstantiationException(e); } } // Map of named plugin classes, [intfc,name] -> class // Also contains intfc -> "marker" to mark when interface has been loaded. private static HashMap namedPluginClasses = new HashMap(); // Map of cached (reusable) named plugin instances, [class,name] -> instance private static HashMap namedInstanceCache = new HashMap();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -