1 /** 2 * Copyright 2005-2013 The Kuali Foundation 3 * 4 * Licensed under the Educational Community License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.opensource.org/licenses/ecl2.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.kuali.rice.kew.plugin; 17 18 /** 19 * A PluginEnvironment represents a Plugin and the PluginLoader from which it was loaded. 20 * Grouping these together allows us to execute a reload of the Plugin since the Plugin 21 * itself is not responsible for handling how it's own loading or reloading. 22 * 23 * <p>The PluginEnvironment also keeps a reference to the PluginRegistry because this 24 * allows it to add and remove Plugins as child resource loaders of the registry. 25 * 26 * @author Kuali Rice Team (rice.collab@kuali.org) 27 */ 28 public class PluginEnvironment implements Reloadable { 29 30 private boolean loaded = false; 31 private Plugin plugin; 32 private final PluginLoader loader; 33 private final PluginRegistry registry; 34 private boolean suppressStartupFailure = true; 35 36 /** 37 * Constructs an unloaded PluginEnvironment from the given PluginLoader and PluginRegistry. 38 * The environment will not be loaded until the first time that load() is executed. 39 */ 40 public PluginEnvironment(PluginLoader loader, PluginRegistry registry) { 41 this.loader = loader; 42 this.registry = registry; 43 } 44 45 /** 46 * Constructs a PluginEnvironment representing the given loaded Plugin. Environments created 47 * in this manner will indicate that they are loaded from the moment they are constructed. 48 */ 49 public PluginEnvironment(Plugin plugin, PluginLoader loader, PluginRegistry registry) { 50 this(loader, registry); 51 this.plugin = plugin; 52 this.loaded = true; 53 } 54 55 /** 56 * Returns true if this environment has been loaded, false otherwise. If this method returns 57 * false then getPlugin() may return null if the environment was never loaded after construction. 58 */ 59 public boolean isLoaded() { 60 return loaded; 61 } 62 63 /** 64 * Returns a boolean indicating whether or not this PluginEnvironment is truly reloadable. 65 * 66 * This will return false if the Plugin represents a plugin which can not be reloaded. 67 */ 68 public boolean isReloadable() { 69 return true; 70 } 71 72 /** 73 * Indicates whether or not a reload of this environment is needed. If this method 74 * returns true, it should continue to return true until a reload() is executed. 75 */ 76 public synchronized boolean isReloadNeeded() { 77 return loader.isModified(); 78 } 79 80 /** 81 * Reloads the environment by effectively executing an unload() followed by a load(). 82 */ 83 public synchronized void reload() throws Exception { 84 unload(); 85 load(); 86 } 87 88 /** 89 * Loads the plugin from the PluginLoader. This will also start the Plugin and add it 90 * to the PluginRegistry's resoure loaders. 91 */ 92 public synchronized void load() throws Exception { 93 plugin = loader.load(); 94 plugin.setSuppressStartupFailure(suppressStartupFailure); 95 // it's important that the plugin is added to the resource loading system prior to startup because 96 // startup may need to grab services 97 registry.addResourceLoader(plugin); 98 plugin.start(); 99 loaded = true; 100 } 101 102 /** 103 * Unloads the plugin. The effectively shuts the plugin down and removes it from the 104 * PluginRegistry's resource loaders. 105 * @throws Exception 106 */ 107 public synchronized void unload() throws Exception { 108 if (plugin != null) { 109 plugin.stop(); 110 // it's important that the plugin be removed from the resource loading system after shutdown in 111 // case the plugin needs to access the resource loader during shutdown 112 registry.removeResourceLoader(plugin.getName()); 113 } 114 loaded = false; 115 } 116 117 public String getPluginName() { 118 if (getPlugin() != null) { 119 return getPlugin().getName().getLocalPart(); 120 } 121 return loader.getPluginName(); 122 } 123 124 /** 125 * Gets the Plugin represented by this environment. May be null if this environment has not 126 * yet been loaded. 127 */ 128 public Plugin getPlugin() { 129 return plugin; 130 } 131 132 /** 133 * Gets the PluginLoader which loaded the Plugin in this environment. 134 */ 135 public PluginLoader getLoader() { 136 return loader; 137 } 138 139 /** 140 * By default, startup failure is suppressed. If it is indicated that startup failure 141 * suppression is not desired, then startup errors will be thrown directly from calls to 142 * load(). 143 */ 144 public void setSuppressStartupFailure(boolean suppressStartupFailure) { 145 this.suppressStartupFailure = suppressStartupFailure; 146 } 147 148 }