/** * File: PluginStateImpl.java * Date: 19 Aug 2008 * Author: Allan Crooks * * Azureus - a Java Bittorrent client * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program 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 General Public License for more details ( see the COPYING file ). * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.gudy.azureus2.pluginsimpl.local; import java.util.ArrayList; import java.util.List; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.util.Debug; import org.gudy.azureus2.core3.util.FileUtil; import org.gudy.azureus2.plugins.PluginException; import org.gudy.azureus2.plugins.PluginInterface; import org.gudy.azureus2.plugins.PluginState; import org.gudy.azureus2.plugins.UnloadablePlugin; import org.gudy.azureus2.pluginsimpl.local.installer.PluginInstallerImpl; import org.gudy.azureus2.update.UpdaterUtils; public class PluginStateImpl implements PluginState { private PluginInterfaceImpl pi; private PluginInitializer initialiser; private boolean disabled; boolean operational; boolean failed; public PluginStateImpl(PluginInterfaceImpl pi, PluginInitializer initialiser) { this.pi = pi; this.initialiser = initialiser; } public void setLoadedAtStartup(boolean load_at_startup) { String param_name = "PluginInfo." + pi.getPluginID() + ".enabled"; COConfigurationManager.setParameter(param_name, load_at_startup); } public boolean isLoadedAtStartup() { String param_name = "PluginInfo." + pi.getPluginID() + ".enabled"; if (!COConfigurationManager.hasParameter(param_name, false)) { return true; // Load at startup by default. } return COConfigurationManager.getBooleanParameter(param_name); } public boolean hasFailed() { return failed; } public void setDisabled(boolean _disabled) { disabled = _disabled; } public boolean isDisabled() { return disabled; } public boolean isBuiltIn() { String dir = pi.getPluginDirectoryName(); if (dir == null) { return PluginInitializer.isLoadingBuiltin(); } return( dir.length() == 0 || pi.getPluginID().equals( UpdaterUtils.AZUPDATER_PLUGIN_ID ) || pi.getPluginID().equals( UpdaterUtils.AZUPDATERPATCHER_PLUGIN_ID )); } public boolean isMandatory() { if ( pi.getPluginID().equals( UpdaterUtils.AZUPDATER_PLUGIN_ID ) || pi.getPluginID().equals( UpdaterUtils.AZUPDATERPATCHER_PLUGIN_ID )){ return( true ); } String mand = pi.getPluginProperties().getProperty("plugin.mandatory"); return (mand != null && mand.trim().toLowerCase().equals("true")); } void setOperational(boolean b, boolean reloading ) { operational = b; if ( !reloading ){ initialiser.fireOperational( pi, operational ); } } public boolean isOperational() { return operational; } public boolean isShared() { String shared_dir = FileUtil.getApplicationFile("plugins").toString(); String plugin_dir = pi.getPluginDirectoryName(); return plugin_dir.startsWith(shared_dir); } public boolean isInitialisationComplete() { return( initialiser.isInitialisationComplete()); } public void reload() throws PluginException { // we use the "reload" method to load disabled plugins regardless of whether they are // unloadable. If currently disabled then no unloading to do anyway if (isUnloadable() || isOperational()) {unload( true );} initialiser.reloadPlugin(this.pi); } public void uninstall() throws PluginException { PluginInstallerImpl.getSingleton(pi.getPluginManager()).uninstall(this.pi); } public boolean isUnloaded() { return( pi.class_loader == null ); } public void unload() throws PluginException { unload( false ); } protected void unload( boolean for_reload ) throws PluginException { if (!isUnloadable()) { throw new PluginException("Plugin isn't unloadable"); } String dir = pi.getPluginDirectoryName(); // if not dir based then just test this one if (dir == null || dir.length() == 0) { try{ ((UnloadablePlugin)pi.getPlugin()).unload(); }catch( Throwable e ){ Debug.out( "Plugin unload operation failed", e ); } initialiser.unloadPlugin(this.pi); } else { // we must copy the list here as when we unload interfaces they will be // removed from the original list List pis = new ArrayList(PluginInitializer.getPluginInterfaces()); for (int i=0;i<pis.size();i++){ PluginInterfaceImpl pi = (PluginInterfaceImpl)pis.get(i); String other_dir = pi.getPluginDirectoryName(); if (other_dir == null || other_dir.length() == 0) {continue;} if (dir.equals(other_dir)) { try{ ((UnloadablePlugin)pi.getPlugin()).unload(); }catch( Throwable e ){ Debug.out( "Plugin unload operation failed", e ); } initialiser.unloadPlugin( pi ); } } } for (int i=0;i<pi.children.size();i++){ ((PluginStateImpl)((PluginInterface)pi.children.get(i)).getPluginState()).unload( for_reload ); } setOperational(false, for_reload ); pi.destroy(); } public boolean isUnloadable() { String dir = pi.getPluginDirectoryName(); // mechanism to override unloadability boolean disable_unload = pi.getPluginProperties().getProperty("plugin.unload.disabled", "").equalsIgnoreCase("true"); if (disable_unload) {return false;} // if not dir based then just test this one if (dir == null || dir.length() == 0) { return pi.getPlugin() instanceof UnloadablePlugin; } List pis = PluginInitializer.getPluginInterfaces(); for (int i=0;i<pis.size();i++) { PluginInterface pi = (PluginInterface)pis.get(i); String other_dir = pi.getPluginDirectoryName(); if (other_dir == null || other_dir.length() == 0) {continue;} if (dir.equals(other_dir)) { if (!(pi.getPlugin() instanceof UnloadablePlugin)) { return false; } } } for (int i=0;i<pi.children.size();i++){ if (!((PluginInterface)pi.children.get(i)).getPluginState().isUnloadable()){ return false; } } return true; } }