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.config.property.ConfigContext;
21 import org.kuali.rice.core.api.util.ClassLoaderUtils;
22 import org.kuali.rice.kew.plugin.PluginUtils.PluginZipFileFilter;
23
24 import java.io.File;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Set;
28
29
30
31
32
33
34
35 public class HotDeployer implements Runnable {
36 private static final Logger LOG = Logger.getLogger(HotDeployer.class);
37
38
39 private PluginRegistry registry;
40 private File sharedPluginDirectory;
41 private List<String> pluginDirectories;
42
43 public HotDeployer(PluginRegistry registry, File sharedPluginDirectory, List<String> pluginDirectories) {
44 this.registry = registry;
45 this.sharedPluginDirectory = sharedPluginDirectory;
46 this.pluginDirectories = pluginDirectories;
47 }
48
49 public synchronized void run() {
50 try {
51 LOG.debug("Checking for added and removed plugins...");
52 Set<PluginEnvironment> removedPlugins = getRemovedPlugins();
53 for (PluginEnvironment pluginContext : removedPlugins) {
54 LOG.info("Detected a removed plugin '" + pluginContext.getPluginName() + "', shutting down plugin.");
55 try {
56 pluginContext.unload();
57 registry.removePluginEnvironment(pluginContext.getPluginName());
58 } catch (Exception e) {
59 LOG.error("Failed to unload plugin '" + pluginContext.getPluginName() + "'", e);
60 }
61 }
62 Set<PluginEnvironment> addedPlugins = getAddedPlugins();
63 for (PluginEnvironment pluginContext : addedPlugins) {
64 try {
65 LOG.info("Detected a new plugin. Loading plugin...");
66 pluginContext.load();
67 LOG.info("...plugin '" + pluginContext.getPluginName() + "' loaded.");
68 } catch (Exception e) {
69
70 String pluginName= "<<unknown>>";
71 if (pluginContext.getPlugin() != null) {
72 pluginName = String.valueOf(pluginContext.getPluginName());
73 }
74 LOG.error("Failed to load plugin '" + pluginName + "'", e);
75 } finally {
76
77
78 registry.addPluginEnvironment(pluginContext);
79 }
80 }
81 } catch (Exception e) {
82 LOG.warn("Failed to check for hot deploy.", e);
83 }
84 }
85
86 protected Set<PluginEnvironment> getRemovedPlugins() {
87 Set<PluginEnvironment> removedPlugins = new HashSet<PluginEnvironment>();
88 for (PluginEnvironment environment : registry.getPluginEnvironments()) {
89 if (environment.getLoader().isRemoved()) {
90 removedPlugins.add(environment);
91 }
92 }
93 return removedPlugins;
94 }
95
96 protected Set<PluginEnvironment> getAddedPlugins() throws Exception {
97 Set<PluginEnvironment> addedPlugins = new HashSet<PluginEnvironment>();
98 Set<File> newPluginZipFiles = new HashSet<File>();
99
100
101
102 for (String pluginDirName : pluginDirectories) {
103 File pluginDir = new File(pluginDirName);
104 if (pluginDir.exists() && pluginDir.isDirectory()) {
105 File[] pluginDirFiles = pluginDir.listFiles(new PluginZipFileFilter());
106 for (File pluginZip : pluginDirFiles) {
107 int indexOf = pluginZip.getName().lastIndexOf(".zip");
108 String pluginName = pluginZip.getName().substring(0, indexOf);
109
110 List<PluginEnvironment> currentEnvironments = registry.getPluginEnvironments();
111 boolean pluginExists = false;
112 for (PluginEnvironment environment : currentEnvironments) {
113 if (environment.getPluginName().equals(pluginName)) {
114 pluginExists = true;
115 break;
116 }
117 }
118 if (!pluginExists) {
119
120 long lastModified1 = pluginZip.lastModified();
121 Thread.sleep(100);
122 long lastModified2 = pluginZip.lastModified();
123 if (lastModified1 == lastModified2) {
124 newPluginZipFiles.add(pluginZip);
125 } else {
126 LOG.warn("Detected that the plugin zip is still being modified, holding off on hot deploy: " + pluginZip.getAbsolutePath());
127 }
128 }
129 }
130 }
131 }
132
133 ClassLoader parentClassLoader = ClassLoaderUtils.getDefaultClassLoader();
134 Config parentConfig = ConfigContext.getCurrentContextConfig();
135 for (File newPluginZipFile : newPluginZipFiles) {
136 PluginLoader loader = new ZipFilePluginLoader(newPluginZipFile, sharedPluginDirectory, parentClassLoader, parentConfig);
137 PluginEnvironment environment = new PluginEnvironment(loader, registry);
138 addedPlugins.add(environment);
139 }
140 return addedPlugins;
141 }
142
143 }