/* * Moonlight|3D Copyright (C) 2005 The Moonlight|3D team * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Created on Jan 5, 2005 */ package ml.core.plugins; /** * \package ml.core.plugins * * This is the plugin manager. It is responsible for loading and * unloading all plugins at runtime. * * This package is part of the core program. */ import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import ml.core.State; import ml.core.exceptions.Exception; import ml.core.helper.Property; import ml.core.helper.Value; import ml.core.preferences.PreferencesGroup; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * The plugin manager is responsible for loading and unloading plugins * in the right order. * * @author gregor */ public class Manager { class ClassLoader extends URLClassLoader { public ClassLoader() { super(new URL[0]); } @Override public void addURL(URL url) { super.addURL(url); } } class PluginWrapper { private boolean loaded; private boolean unloadable; private Class pluginClass; private Plugin plugin; private Manager manager; public PluginWrapper(Manager manager, Class pluginClass) { this.manager=manager; this.pluginClass=pluginClass; unloadable=false; } public void instantiate() throws InstantiationException, IllegalAccessException { plugin=(Plugin)pluginClass.newInstance(); } /** * checks, whether the dependencies of the plugin are actually satisfied * @return true, if dependencies are all satisfied, false otherwise */ public boolean hasSatisfiesDependencies() { ArrayList dependencies=plugin.getDependencies(); if(dependencies==null) { return true; } for(int i=0;i dependencies=plugin.getDependencies(); if(dependencies==null) { return true; } if(unloadable) { return false; } for(int i=0;i dependencies=manager.plugins.get(i).plugin.getDependencies(); if(dependencies==null) { continue; } for(int j=0;j plugins; private ClassLoader classLoader; public Manager() { plugins=new ArrayList(); classLoader=new ClassLoader(); // build a preferences group with the additional plugin paths PreferencesGroup pluginPreferences=new PreferencesGroup(); pluginPreferences.setName("Plugins"); Property paths=new Property(pluginPreferences); paths.setName("paths"); paths.setType(Value.Type.StringArray); try { paths.setMaxSize(0); } catch (Exception e) { // this cannot happen here e.printStackTrace(); } State.getInstance().getPreferencesManager().getCurrentPreferences().addPreferencesGroup(pluginPreferences); } /** * tries to load a plugin from a given class name * @param className the name of the class to load as a plugin * @throws Exception */ void getPlugin(String className) throws Exception { try { Class pluginClass=classLoader.loadClass(className); plugins.add(new PluginWrapper(this,pluginClass)); } catch (ClassNotFoundException e) { throw new Exception("failed to load plugin " + className,e); } } private void addToClasspath(String path) { State.getInstance().logger().info("adding to classpath: " + path); try { classLoader.addURL(new URL("file:" + path)); } catch (MalformedURLException e) { // TODO handle exception more appropriately e.printStackTrace(); } } void parsePluginList(File file) throws Exception { try { Document pluginListDoc=DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file.toURI().toString()); Element root=pluginListDoc.getDocumentElement(); NodeList classpathList, pluginList; State.getInstance().logger().info("loading plugins from " + file.toURI().toString()); classpathList=root.getElementsByTagName("classpath"); for(int i=0;i getPluginList() { ArrayList pluginList=new ArrayList(); for(int i=0;i