Java tutorial
/* * Copyright (c) 2008 Massimiliano Ziccardi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package it.jnrpe.plugins.factory; import it.jnrpe.plugins.CPluginProxy; import it.jnrpe.plugins.IPluginInterface; import it.jnrpe.utils.CStreamManager; 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.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.commons.digester.Digester; import org.apache.commons.digester.xmlrules.DigesterLoader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * This class instantiate the plugin classes. * * @author Massimiliano Ziccardi */ public class CPluginFactory { private Log m_Logger = LogFactory.getLog(CPluginFactory.class); private static CPluginFactory m_Instance = null; private Map m_mPlugins = new HashMap(); private class CPluginData { private String m_sClassName = null; private String m_sPluginName = null; private COptions m_opts = null; private String m_sDescription = null; private CPluginData(String sPluginName, String sDescription, String sPluginClassName, COptions opts) { m_sClassName = sPluginClassName; m_sPluginName = sPluginName; m_opts = opts; m_sDescription = sDescription; } public IPluginInterface getPluginInstance() throws PluginInstantiationException { try { //Thread.currentThread().setContextClassLoader(m_classLoader); // BUG #2814844 return (IPluginInterface) CPluginData.class.getClassLoader().loadClass(m_sClassName).newInstance(); } catch (Exception e) { throw new PluginInstantiationException("UNABLE TO INSTANTIATE PLUGIN " + m_sPluginName, e); } } public COptions getOptions() { return m_opts; } public String getDescription() { return m_sDescription; } } /** * Returns an instance of the plugin factory * @return */ public static synchronized CPluginFactory getInstance() { if (m_Instance == null) { m_Instance = new CPluginFactory(); m_Instance.configure(); } return m_Instance; } /** * This method has been created to facilitate plugin testing. * Just call this method, passing the path to your plugin.xml files to get a factory. * Then call the getPlugin method to obtain your plugin instance and call the * execute method to execute it. * * @param sPluginXMLPath The path to your XML file * @return a factory instance * @throws FileNotFoundException * @throws IOException * @throws SAXException */ public static CPluginFactory getInstance(String sPluginXMLPath) throws FileNotFoundException, IOException, SAXException { if (m_Instance == null) { CStreamManager streamMgr = new CStreamManager(); try { m_Instance = new CPluginFactory(); m_Instance.parsePluginXmlFile(streamMgr.getInputStream(new File(sPluginXMLPath))); } finally { streamMgr.closeAll(); } } return m_Instance; } /** * Configures the factory. * * A "jnrpe.plugins.xml" file must be available at classloader's root in order to fetch * plugin definitions. */ private void configure() { try { m_Logger.trace("CONFIGURING PLUGIN FACTORY"); InputStream is = this.getClass().getClassLoader().getResourceAsStream("jnrpe.plugins.xml"); if (is != null) parsePluginXmlFile(is); else m_Logger.warn("PLUGIN DEFINITION FILE NOT FOUND."); } catch (IOException ex) { m_Logger.error("Error " + ex.getMessage(), ex); } catch (SAXException ex) { m_Logger.error("Error " + ex.getMessage(), ex); } } /** * @deprecated */ private void configurePlugins(File fDir) { m_Logger.trace("READING PLUGIN CONFIGURATION FROM DIRECTORY " + fDir.getName()); CStreamManager streamMgr = new CStreamManager(); File[] vfJars = fDir.listFiles(new FileFilter() { public boolean accept(File f) { return f.getName().endsWith(".jar"); } }); // Initializing classloader URL[] urls = new URL[vfJars.length]; URLClassLoader ul = null; for (int j = 0; j < vfJars.length; j++) { try { urls[j] = vfJars[j].toURI().toURL(); } catch (MalformedURLException e) { // should never happen } } ul = URLClassLoader.newInstance(urls); for (int i = 0; i < vfJars.length; i++) { File file = vfJars[i]; try { m_Logger.info("READING PLUGINS DATA IN FILE '" + file.getName() + "'"); ZipInputStream jin = (ZipInputStream) streamMgr .handle(new ZipInputStream(new FileInputStream(file))); ZipEntry ze = null; while ((ze = jin.getNextEntry()) != null) { if (ze.getName().equals("plugin.xml")) { parsePluginXmlFile(jin); break; } } } catch (Exception e) { m_Logger.error("UNABLE TO READ DATA FROM FILE '" + file.getName() + "'. THE FILE WILL BE IGNORED.", e); } finally { streamMgr.closeAll(); } } } private void parsePluginXmlFile(InputStream in) throws IOException, SAXException { CStreamManager streamMgr = new CStreamManager(); m_Logger.trace("PARSING FILE plugin.xml IN JAR FILE."); Digester digester = DigesterLoader.createDigester(new InputSource( streamMgr.handle(this.getClass().getClassLoader().getResourceAsStream("plugin-digester.xml")))); CPluginFactoryConfiguration oConf = (CPluginFactoryConfiguration) digester.parse(in); List vPluginDefs = oConf.getPluginDefinitions(); //for (CPluginDefinition pluginDef : vPluginDefs) for (Iterator iter = vPluginDefs.iterator(); iter.hasNext();) { CPluginDefinition pluginDef = (CPluginDefinition) iter.next(); m_Logger.debug( "FOUND PLUGIN " + pluginDef.getName() + " IMPLEMENTED BY CLASS " + pluginDef.getPluginClass()); m_mPlugins.put(pluginDef.getName(), new CPluginData(pluginDef.getName(), pluginDef.getDescription(), pluginDef.getPluginClass(), pluginDef.getOptions())); } } /** * Instantiates the plugin * @param sPluginName The name of the plugin to be instantiated (as described * in the plugin.xml file). * @return The plugin */ public CPluginProxy getPlugin(String sPluginName) throws PluginInstantiationException { CPluginData pluginData = (CPluginData) m_mPlugins.get(sPluginName); if (pluginData != null) return new CPluginProxy(sPluginName, pluginData.getDescription(), pluginData.getPluginInstance(), pluginData.getOptions()); return null; } public Set getPluginList() { return m_mPlugins.keySet(); } }