/* * PluginLoader.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST 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 * of the License, or (at your option) any later version. * * BEAST 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 BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.app.plugin; import java.io.File; import java.io.FileFilter; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; public class PluginLoader { public static File getPluginFolder() { String pluginFolderFromProperty = null; try { pluginFolderFromProperty = java.lang.System.getProperty("beast.plugins.dir"); } catch (Exception ex) { // } if (pluginFolderFromProperty != null) { return new File(pluginFolderFromProperty); } final String PLUGIN_FOLDER = "plugins"; final File PLUGIN_FILE = new File(PLUGIN_FOLDER); return PLUGIN_FILE; } public static List<String> getAvailablePlugins(){ List<String> plugins = new ArrayList<String> (); File pluginFile = PluginLoader.getPluginFolder(); Logger.getLogger("dr.app.plugin").info("Looking for plugins in " + pluginFile.getAbsolutePath()); File[] classFolderFiles = pluginFile.listFiles(new FileFilter() { public boolean accept(File pathname) { String name = pathname.getName(); if(!pathname.isDirectory() || name.endsWith("CVS") || name.endsWith(".classes")) return false; File[] directoryContents = pathname.listFiles(new FileFilter() { public boolean accept(File pathname) { String name = pathname.getName(); return name.endsWith(".jar"); } }); return directoryContents.length != 0; } }); if (classFolderFiles != null) { for (File folder : classFolderFiles) { plugins.add(folder.getName()); } } File[] pluginJarFiles = pluginFile.listFiles(new FileFilter() { public boolean accept(File pathname) { return !pathname.isDirectory() && pathname.getAbsolutePath().endsWith(".jar"); } }); if (pluginJarFiles != null) { for (File jarFile : pluginJarFiles) { String name = jarFile.getName(); name =name.substring(0, name.length()- 4); if(! plugins.contains(name)) plugins.add(name); } } return plugins; } public static Plugin loadPlugin(final String pluginName/*, boolean pluginEnabled*/) { //the class loader must still be assigned if the plugin isnt enabled so //documents from that plugin can still be displayed. final String loggerName = "dr.app.plugin"; Logger.getLogger(loggerName).info("Loading plugin " + pluginName); File pluginDir = PluginLoader.getPluginFolder(); File file = new File(pluginDir, pluginName); try { URL[] urls; if (!file.exists()) { Logger.getLogger(loggerName).info("Loading jar file"); file = new File(pluginDir, pluginName + ".jar"); urls = new URL[]{file.toURL()}; } else { File classFiles = new File(pluginDir, "classes"); final boolean classesExist = classFiles.exists(); File[] files = file.listFiles(new FileFilter() { public boolean accept(File pathname) { String name = pathname.getName(); if(!name.endsWith(".jar")) return false; name = name.substring(0, name.length()- 4); return !(name.equals(pluginName) && classesExist); } }); if(files == null) files = new File[0]; int length = files.length+1; if(classesExist) length ++; urls = new URL[length]; int count = 0; if( classesExist ) { urls[ count ++ ] = classFiles.toURL(); } urls[ count ++ ] = file.toURL(); Logger.getLogger(loggerName).info("Adding " + file + " to class path"); for (File jarFile : files) { urls[count++] = jarFile.toURL(); } } final URLClassLoader classLoader = new URLClassLoader(urls); for (URL url : classLoader.getURLs()) { Logger.getLogger(loggerName).info("URL from loader: " + url.toString() + "\n"); } final Class myClass = classLoader.loadClass(pluginName); final Object plugin = myClass.newInstance(); // isn't that covered by the cast failing? if (!(plugin instanceof Plugin)){ throw new Exception("Class should be " + Plugin.class.getName()); } return (Plugin)plugin; } catch (Exception e) { Logger.getLogger(loggerName).severe(e.getMessage()); } return null; } }