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