1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.plugin;
17
18 import org.apache.log4j.Logger;
19 import org.kuali.rice.core.api.config.property.Config;
20 import org.kuali.rice.core.api.util.ContextClassLoaderBinder;
21 import org.kuali.rice.core.impl.resourceloader.BaseWrappingResourceLoader;
22 import org.kuali.rice.kew.api.WorkflowRuntimeException;
23
24 import javax.xml.namespace.QName;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28
29
30
31
32
33
34
35
36
37 public class Plugin extends BaseWrappingResourceLoader {
38
39 private static final Logger LOG = Logger.getLogger(Plugin.class);
40 private Config config;
41 private List<PluginListener> pluginListeners = new ArrayList<PluginListener>();
42
43 private boolean supressStartupFailure = true;
44 private boolean started = false;
45 private boolean startupFailure = false;
46
47 public Plugin(QName name, Config config, ClassLoader classLoader) {
48 super(name, classLoader);
49 this.config = config;
50 }
51
52
53
54
55 public synchronized void start() {
56 if (started) {
57 LOG.info(getLogPrefix()+" has already been started.");
58 return;
59 }
60 LOG.info(getLogPrefix()+" Starting...");
61 try {
62 bindThread();
63 try {
64 startupFailure = false;
65 started = true;
66 super.start();
67 LOG.info("Starting plugin listeners");
68 startPluginListeners();
69 } finally {
70 unbindThread();
71 }
72 ClassLoader classLoader = getClassLoader();
73 LOG.info(getLogPrefix()+" ...started." + (classLoader != null ? classLoader.toString() : ""));
74 } catch (Throwable t) {
75 LOG.error(getLogPrefix()+" Failure starting plugin.", t);
76 startupFailure = true;
77 started = true;
78 stop();
79 if (!supressStartupFailure) {
80 if (t instanceof Error) {
81 throw (Error)t;
82 } else if (t instanceof RuntimeException) {
83 throw (RuntimeException)t;
84 }
85 throw new WorkflowRuntimeException("Failed to startup plugin.", t);
86 }
87 }
88 }
89
90
91
92
93 public synchronized void stop() {
94 if (!started) {
95 LOG.info(getLogPrefix()+" has already been stopped.");
96 return;
97 }
98 LOG.info(getLogPrefix()+" Stopping...");
99 bindThread();
100 try {
101 started = false;
102 stopPluginListeners();
103
104 super.stop();
105 } catch (Throwable t) {
106 LOG.error(getLogPrefix()+" Failed when attempting to stop the plugin.", t);
107 } finally {
108 unbindThread();
109 }
110 resetPlugin();
111 LOG.info(getLogPrefix()+" ...stopped.");
112 }
113
114 public boolean isStarted() {
115 return started;
116 }
117
118 public void addPluginListener(PluginListener pluginListener) {
119 pluginListeners.add(pluginListener);
120 }
121
122 public void removePluginListener(PluginListener pluginListener) {
123 pluginListeners.remove(pluginListener);
124 }
125
126 protected void startPluginListeners() {
127 for (Iterator iterator = pluginListeners.iterator(); iterator.hasNext();) {
128 PluginListener listener = (PluginListener) iterator.next();
129 listener.pluginInitialized(this);
130 }
131 }
132
133
134
135
136
137
138 protected void stopPluginListeners() {
139 for (Iterator iterator = pluginListeners.iterator(); iterator.hasNext();) {
140 PluginListener listener = (PluginListener) iterator.next();
141 try {
142 listener.pluginDestroyed(this);
143 } catch (Throwable t) {
144 LOG.error(getLogPrefix()+" Failed when invoking pluginDestroyed on Plugin Listener '"+listener.getClass().getName()+"'.", t);
145 }
146 }
147 }
148
149 public boolean isSupressStartupFailure() {
150 return supressStartupFailure;
151 }
152
153 public void setSupressStartupFailure(boolean supressStartupFailure) {
154 this.supressStartupFailure = supressStartupFailure;
155 }
156
157 public void bindThread() {
158 ContextClassLoaderBinder.bind(getClassLoader());
159 }
160
161 public void unbindThread() {
162 ContextClassLoaderBinder.unbind();
163 }
164
165
166
167
168 private void resetPlugin() {
169 if (!startupFailure) {
170 setClassLoader(null);
171 }
172 pluginListeners.clear();
173 }
174
175 private String getLogPrefix() {
176 return toString();
177 }
178
179 public Config getConfig() {
180 return config;
181 }
182
183 public String toString() {
184 return "[Plugin: " + this.getName() + "]";
185 }
186
187 }