📄 pluginmanager.java
字号:
// load and cache configuration data for the given interface. private static void configureNamedPlugin(String iname) throws ClassNotFoundException { int found = 0; /** * First load the class map for this interface (if not done yet): * key is [intfc,name], value is class. * There is ALSO a "marker key" of "intfc" by itself to show we * loaded this intfc's configuration. */ if (!namedPluginClasses.containsKey(iname)) { // 1. Get classes named by the configuration. format is: // plugin.named.<INTF> = <CLASS> = <name>, <name> [,] \ // <CLASS> = <name>, <name> [ ... ] String namedVal = ConfigurationManager.getProperty(NAMED_PREFIX+iname); if (namedVal != null) { log.debug("Got Named configuration for interface="+iname+", config="+namedVal); // match "<classname> =" Pattern classnameEqual = Pattern.compile("([\\w\\p{Sc}\\.]+)\\s*\\="); int prevEnd = -1; String prevClassName = null; Matcher classMatcher = classnameEqual.matcher(namedVal); while (classMatcher.find()) { if (prevClassName != null) found += installNamedConfigs(iname, prevClassName, namedVal.substring(prevEnd, classMatcher.start()).trim().split("\\s*,\\s*")); prevClassName = classMatcher.group(1); prevEnd = classMatcher.end(); } if (prevClassName != null) found += installNamedConfigs(iname, prevClassName, namedVal.substring(prevEnd).trim().split("\\s*,\\s*")); } // 2. Get Self-named config entries: // format is plugin.selfnamed.<INTF> = <CLASS> , <CLASS> .. String selfNamedVal = ConfigurationManager.getProperty(SELFNAMED_PREFIX+iname); if (selfNamedVal != null) { String classnames[] = selfNamedVal.split("\\s*,\\s*"); for (int i = 0; i < classnames.length; ++i) { try { Class pluginClass = Class.forName(classnames[i]); String names[] = (String[])pluginClass.getMethod("getPluginNames", null). invoke(null, null); if (names == null || names.length == 0) log.error("Self-named plugin class \""+classnames[i]+"\" returned null or empty name list!"); else found += installNamedConfigs(iname, classnames[i], names); } catch (NoSuchMethodException e) { log.error("Implementation Class \""+classnames[i]+"\" is not a subclass of SelfNamedPlugin, it has no getPluginNames() method."); } catch (Exception e) { log.error("While configuring self-named plugin: " + e.toString()); } } } namedPluginClasses.put(iname, "org.dspace.core.marker"); if (found == 0) log.error("No named plugins found for interface="+iname); } } // add info for a named plugin to cache, under all its names. private static int installNamedConfigs(String iname, String classname, String names[]) throws ClassNotFoundException { int found = 0; for (int i = 0; i < names.length; ++i) { String key = iname+SEP+names[i]; if (namedPluginClasses.containsKey(key)) log.error("Name collision in named plugin, implementation class=\""+classname+ "\", name=\""+names[i]+"\""); else namedPluginClasses.put(key, classname); log.debug("Got Named Plugin, intfc="+iname+", name="+names[i]+", class="+classname); ++found; } return found; } /** * Returns an instance of a plugin that implements the interface * intface and is bound to a name matching name. If there is no * matching plugin, it returns null. The names are matched by * String.equals(). * * @param intfc the interface class of the plugin * @param name under which the plugin implementation is configured. * @return instance of plugin implementation, or null if there is no match or an error. */ public static Object getNamedPlugin(Class intfc, String name) throws PluginInstantiationException { try { String iname = intfc.getName(); configureNamedPlugin(iname); String key = iname + SEP + name; String cname = (String)namedPluginClasses.get(key); if (cname == null) log.warn("Cannot find named plugin for interface="+iname+", name=\""+name+"\""); else { Class pluginClass = Class.forName(cname); if (cacheMe(pluginClass)) { String nkey = pluginClass.getName() + SEP + name; Object cached = namedInstanceCache.get(nkey); if (cached == null) { log.debug("Creating cached instance of: " + cname + " for interface=" + iname + " pluginName=" + name ); cached = pluginClass.newInstance(); if (cached instanceof SelfNamedPlugin) ((SelfNamedPlugin)cached).setPluginInstanceName(name); namedInstanceCache.put(nkey, cached); } return cached; } else { log.debug("Creating UNcached instance of: " + cname + " for interface=" + iname + " pluginName=" + name ); Object result = pluginClass.newInstance(); if (result instanceof SelfNamedPlugin) ((SelfNamedPlugin)result).setPluginInstanceName(name); return result; } } } 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); } return null; } /** * Returns all of the names under which a named plugin implementing * the interface intface can be requested (with getNamedPlugin()). * The array is empty if there are no matches. Use this to populate * a menu of plugins for interactive selection, or to document what * the possible choices are. * <p> * NOTE: The names are NOT returned in any deterministic order. * * @param intfc plugin interface for which to return names. * @return an array of strings with every name; if none are * available an empty array is returned. */ public static String[] getAllPluginNames(Class intfc) { try { String iname = intfc.getName(); configureNamedPlugin(iname); String prefix = iname + SEP; ArrayList result = new ArrayList(); Iterator ki = namedPluginClasses.keySet().iterator(); while (ki.hasNext()) { String key = (String)ki.next(); if (key.startsWith(prefix)) result.add(key.substring(prefix.length())); } if (result.size() == 0) log.error("Cannot find any names for named plugin, interface="+iname); return (String[])result.toArray(new String[result.size()]); } catch (ClassNotFoundException e) { return new String[0]; } } /** * Tells the Plugin Manager to let go of any references to a * reusable plugin, to prevent it from being given out again and to * allow the object to be garbage-collected. Call this when a * plugin instance must be taken out of circulation. * * @param plugin the object to release, must have been created by * <code>getNamedPlugin</code> etc. */ public static void releasePlugin(Object plugin) { forgetInstance(plugin, namedInstanceCache); forgetInstance(plugin, anonymousInstanceCache); } private static void forgetInstance(Object plugin, Map cacheMap) { Collection values = cacheMap.values(); Iterator ci = values.iterator(); while (ci.hasNext()) { Object val = ci.next(); if (val == plugin) values.remove(val); } } /* ----------------------------------------------------------------- * Code to check configuration is all below this line * ----------------------------------------------------------------- */ // true if classname is valid and loadable. private static boolean checkClassname(String iname, String msg) { try { Class intf = Class.forName(iname); return true; } catch (ClassNotFoundException ce) { log.error("No class definition found for "+msg+": \""+iname+"\""); } return false; } // true if classname is loadable AND is subclass of SelfNamedPlugin private static boolean checkSelfNamed(String iname) { try
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -