1 /**
2 * Copyright 2005-2011 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 }