View Javadoc

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 supressStartupFailure = 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.setSupressStartupFailure(supressStartupFailure);
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 supressed.  If it is indicated that startup failure
141 	 * supression is not desired, then startup errors will be thrown directly from calls to
142 	 * load().
143 	 */
144 	public void setSupressStartupFailure(boolean supressStartupFailure) {
145 		this.supressStartupFailure = supressStartupFailure;
146 	}
147 	
148 }