/**
* 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;
}
}