KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > extensions > types > PluginType


1 /*
2  */

3 package com.sslexplorer.extensions.types;
4
5 import java.io.File JavaDoc;
6 import java.io.FileFilter JavaDoc;
7 import java.io.IOException JavaDoc;
8 import java.net.MalformedURLException JavaDoc;
9 import java.net.URL JavaDoc;
10 import java.util.HashMap JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import java.util.Map JavaDoc;
13
14 import javax.servlet.ServletException JavaDoc;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.jdom.Element;
19
20 import com.sslexplorer.boot.ContextHolder;
21 import com.sslexplorer.boot.Util;
22 import com.sslexplorer.core.CoreServlet;
23 import com.sslexplorer.core.CoreUtil;
24 import com.sslexplorer.extensions.ExtensionDescriptor;
25 import com.sslexplorer.extensions.ExtensionException;
26 import com.sslexplorer.extensions.ExtensionType;
27 import com.sslexplorer.security.SessionInfo;
28
29 /**
30  * Extension type that adds a new <i>Plugin</i>
31  *
32  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
33  */

34 public class PluginType implements ExtensionType {
35
36     final static Log log = LogFactory.getLog(PluginType.class);
37
38     /**
39      * Type name
40      */

41     public final static String JavaDoc TYPE = "plugin";
42     
43     // Private statics
44
private static Map JavaDoc<String JavaDoc, Plugin> plugins = new HashMap JavaDoc<String JavaDoc, Plugin>();
45
46     // Private instance variables
47

48     private PluginDefinition def;
49     private Plugin plugin;
50     private boolean classpathAdded;
51
52     /**
53      * Constructor
54      */

55     public PluginType() {
56     }
57     
58     /**
59      * Utility method to get a plugin instance given its Id. <code>null</code>
60      * will be returned if no such plugin exists.
61      *
62      * @param id plugin id
63      * @return plugin
64      */

65     public static Plugin getPlugin(String JavaDoc id) {
66         return plugins.get(id);
67     }
68
69     /*
70      * (non-Javadoc)
71      *
72      * @see com.sslexplorer.extensions.ExtensionType#start(com.sslexplorer.extensions.ExtensionDescriptor,
73      * org.jdom.Element)
74      */

75     public void start(ExtensionDescriptor descriptor, Element element) throws ExtensionException {
76         readConfiguration(descriptor, element);
77         createPlugin();
78         startPlugin(descriptor, element);
79
80     }
81
82     /*
83      * (non-Javadoc)
84      *
85      * @see com.sslexplorer.extensions.ExtensionType#verifyRequiredElements()
86      */

87     public void verifyRequiredElements() throws ExtensionException {
88     }
89
90     /*
91      * (non-Javadoc)
92      *
93      * @see com.sslexplorer.extensions.ExtensionType#isHidden()
94      */

95     public boolean isHidden() {
96         return true;
97     }
98
99     /*
100      * (non-Javadoc)
101      *
102      * @see com.sslexplorer.extensions.ExtensionType#getType()
103      */

104     public String JavaDoc getType() {
105         return TYPE;
106     }
107
108     /*
109      * (non-Javadoc)
110      *
111      * @see com.sslexplorer.extensions.ExtensionType#stop()
112      */

113     public void stop() throws ExtensionException {
114         // TODO remove native dirs and classpath
115

116         if (def != null) {
117             for (URL JavaDoc u : def.getResourceBases()) {
118                 ContextHolder.getContext().removeResourceBase(u);
119             }
120             def.getResourceBases().clear();
121         }
122
123         if (plugin != null) {
124             String JavaDoc tilesConfigFile = plugin.getTilesConfigFile();
125             if (tilesConfigFile != null) {
126                 CoreServlet.getServlet().removeTileConfigurationFile(tilesConfigFile);
127             }
128             plugin.stopPlugin();
129         }
130     }
131
132     public void activate() throws ExtensionException {
133         plugin.activatePlugin();
134     }
135
136     public boolean canStop() throws ExtensionException {
137 // Until struts actions can be unloaded we cannot dynamically stop plugins
138
// return plugin != null ? plugin.canStopPlugin() : true;
139
return false;
140     }
141
142     void readConfiguration(ExtensionDescriptor descriptor, Element element) throws ExtensionException {
143
144         // Plugin name
145
String JavaDoc name = element.getAttributeValue("name");
146         if (name == null || name.equals("")) {
147             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
148                 "The name attribute must be supplied for <plugin> elements (" + descriptor.getApplicationBundle().getFile().getPath() + ").");
149         }
150
151         // Plugin classname
152
String JavaDoc className = element.getAttributeValue("class");
153         if (className == null || className.equals("")) {
154             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
155                 "The class attribute must be supplied for <plugin> elements (" + descriptor.getApplicationBundle().getFile().getPath() + ").");
156         }
157
158         // Order
159
String JavaDoc orderText = element.getAttributeValue("order");
160         int order = 999;
161         if (orderText != null && !orderText.equals("")) {
162             order = Integer.parseInt(orderText);
163         }
164
165         // Optional
166
String JavaDoc dependencies = element.getAttributeValue("dependencies");
167         if (dependencies != null) {
168             log.warn("DEPRECATED. dependencies attribute in plugin definition in "
169                 + descriptor.getApplicationBundle().getFile().getAbsolutePath() + " should now use 'depends'.");
170         } else {
171             dependencies = element.getAttributeValue("depends");
172         }
173
174         def = new PluginDefinition(descriptor);
175
176         // Required
177
def.setName(name);
178         def.setClassName(className);
179
180         // Optional
181
def.setOrder(order);
182
183         /* If this is a dev extension, we generate the paths to add */
184         if(!descriptor.getApplicationBundle().isDevExtension()) {
185             for (Iterator JavaDoc i = element.getChildren().iterator(); i.hasNext();) {
186                 Element el = (Element) i.next();
187                 if (el.getName().equals("classpath")) {
188                     String JavaDoc path = Util.trimmedBothOrBlank(el.getText());
189                     if (!path.equals("")) {
190                         File JavaDoc f = new File JavaDoc(descriptor.getApplicationBundle().getBaseDir(), path);
191                         if (f.exists()) {
192                             try {
193                                 URL JavaDoc u = f.toURL();
194                                 if (log.isInfoEnabled())
195                                     log.info("Adding " + u + " to classpath");
196                                 def.addClassPath(u);
197                             } catch (MalformedURLException JavaDoc murle) {
198                                 throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
199                                     murle, "Invalid classpath.");
200                             }
201                         } else {
202                             if (!"true".equals(System.getProperty("sslexplorer.useDevConfig"))) {
203                                 log.warn("Plugin classpath element " + f.getAbsolutePath() + " does not exist.");
204                             }
205                         }
206                     }
207                 } else if (el.getName().equals("resources")) {
208                     File JavaDoc f = new File JavaDoc(descriptor.getApplicationBundle().getBaseDir(), el.getText());
209                     if (f.exists() && f.isDirectory()) {
210                         try {
211                             def.addResourceBase(f.getCanonicalFile().toURL());
212                         } catch (Exception JavaDoc ex) {
213                             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, ex, "Invalid resource base.");
214                         }
215                     } else {
216                         if (log.isInfoEnabled())
217                             log.info("<resources> element does not point to a valid directory.");
218                     }
219                 } else if (el.getName().equals("native")) {
220                     File JavaDoc f = new File JavaDoc(descriptor.getApplicationBundle().getBaseDir(), el.getText());
221                     if (f.exists() && f.isDirectory()) {
222                         try {
223                             def.addNativeDirectory(f.getCanonicalFile());
224                         } catch (Exception JavaDoc ex) {
225                             throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
226                                 ex, "Invalid native directory.");
227                         }
228                     } else {
229                         if (log.isInfoEnabled())
230                             log.info("<native> element does not point to a valid directory.");
231                     }
232                 } else {
233                     throw new ExtensionException(ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR,
234                         "The <plugin> element only supports the nested <classpath>, <resources> or <native> elements");
235                 }
236             }
237         }
238         
239         /* If the descript was added as a devExtension, then search for and add all
240          * webapps, classpaths and native directories
241          */

242         if(descriptor.getApplicationBundle().isDevExtension()) {
243             File JavaDoc d = new File JavaDoc(new File JavaDoc(System.getProperty("user.dir")).getParentFile(), descriptor.getApplicationBundle().getId());
244             File JavaDoc extensionDir = new File JavaDoc(new File JavaDoc(d, "extensions"), d.getName());
245             File JavaDoc webapp = new File JavaDoc(d, "webapp");
246             File JavaDoc classes = new File JavaDoc(new File JavaDoc(d, "build"), "classes");
247             if (webapp.exists()) {
248                 try {
249                     def.addResourceBase(webapp.toURL());
250                 } catch (MalformedURLException JavaDoc e) {
251                 }
252             }
253             if (classes.exists()) {
254                 try {
255                     def.addClassPath(classes.toURL());
256                 } catch (MalformedURLException JavaDoc e) {
257                 }
258             }
259             File JavaDoc privateDir = new File JavaDoc(extensionDir, "private");
260             if (privateDir.exists()) {
261                 File JavaDoc[] jars = privateDir.listFiles(new FileFilter JavaDoc() {
262                     public boolean accept(File JavaDoc pathname) {
263                         return pathname.getName().toLowerCase().endsWith(".jar");
264                     }
265                 });
266                 for (int idx = 0; jars != null && idx < jars.length; idx++) {
267                     try {
268                         def.addClassPath(jars[idx].toURL());
269                     } catch (MalformedURLException JavaDoc e) {
270                     }
271                 }
272             }
273             File JavaDoc nativeDir = new File JavaDoc(new File JavaDoc(d, "build"), "native");
274             if (nativeDir.exists()) {
275                 try {
276                     def.addNativeDirectory(nativeDir.getCanonicalFile());
277                 }
278                 catch(Exception JavaDoc e) {
279                 }
280             }
281         }
282     }
283
284     synchronized void createPlugin() throws ExtensionException {
285
286         // Add to the classpath and native search path
287
if (!classpathAdded) {
288             for (URL JavaDoc url : def.getClassPath()) {
289                 ContextHolder.getContext().addContextLoaderURL(url);
290             }
291
292             for (Iterator JavaDoc j = def.getNativeDirectories(); j.hasNext();) {
293                 File JavaDoc f = (File JavaDoc) j.next();
294                 try {
295                     CoreUtil.addLibraryPath(f.getAbsolutePath());
296                 } catch (IOException JavaDoc e) {
297                     log.error("Failed to add native directory " + f.getAbsolutePath() + ". The plugin " + def.getName()
298                         + " may not function correctly.", e);
299                 }
300             }
301             classpathAdded = true;
302         }
303
304         ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
305         if (cl == null) {
306             cl = getClass().getClassLoader();
307         }
308
309         try {
310             if(log.isInfoEnabled()) {
311                 log.info("Creating plugin " + def.getClassName());
312             }
313             plugin = (Plugin) Class.forName(def.getClassName(), true, cl).newInstance();
314         } catch (Exception JavaDoc e) {
315             throw new ExtensionException(ExtensionException.FAILED_TO_CREATE_PLUGIN_INSTANCE,
316                 def.getName(),
317                 def.getClassName(),
318                 e.getMessage(),
319                 e);
320         }
321         
322         plugins.put(def.getName(), plugin);
323
324         String JavaDoc resn = plugin.getClass().getName().replace('.', '/') + ".class";
325         if (log.isDebugEnabled())
326             log.debug("Looking for resource " + resn);
327         URL JavaDoc res = plugin.getClass().getClassLoader().getResource(resn);
328         String JavaDoc resource = "";
329         if (res == null)
330             log.error("Could not locate resource " + resn);
331         else {
332
333             String JavaDoc n = res.toExternalForm();
334             if (n.startsWith("jar:file:")) {
335                 n = n.substring(4);
336                 int idx = n.lastIndexOf('!');
337                 if (idx != -1)
338                     n = n.substring(0, idx);
339                 n = n.substring(5);
340                 // Windows path?
341
if (n.startsWith("/") && n.length() > 3 && n.charAt(2) == ':' && Character.isLetter(n.charAt(1))
342                     && n.charAt(3) == '/')
343                     n = n.substring(1);
344                 File JavaDoc f = new File JavaDoc(n);
345                 resource = f.getAbsolutePath();
346             }
347             if (log.isDebugEnabled())
348                 log.debug("Resource is " + resource);
349         }
350     }
351
352     void startPlugin(ExtensionDescriptor descriptor, Element element) throws ExtensionException {
353
354         // Add the resource bases from the plugin
355
for (URL JavaDoc url : def.getResourceBases()) {
356             ContextHolder.getContext().addResourceBase(url);
357         }
358         
359         try {
360             String JavaDoc tilesConfigFile = plugin.getTilesConfigFile();
361             if (tilesConfigFile != null) {
362                 CoreServlet.getServlet().addTileConfigurationFile(tilesConfigFile);
363             }
364             
365             String JavaDoc path = "/WEB-INF/" + def.getDescriptor().getId() + "-struts-config.xml";
366             CoreServlet.getServlet().addStrutsConfig(path);
367             plugin.startPlugin(def, descriptor, element);
368         } catch (ExtensionException e) {
369             // remove the resource bases from the plugin
370
for (URL JavaDoc url : def.getResourceBases()) {
371                 ContextHolder.getContext().removeResourceBase(url);
372             }
373             throw e;
374         } catch (ServletException JavaDoc se) {
375             throw new ExtensionException(ExtensionException.INTERNAL_ERROR, se);
376         }
377     }
378
379     /*
380      * (non-Javadoc)
381      *
382      * @see com.sslexplorer.extensions.ExtensionType#descriptorCreated(org.jdom.Element)
383      */

384     public void descriptorCreated(Element element, SessionInfo session) throws IOException JavaDoc {
385     }
386
387     /* (non-Javadoc)
388      * @see com.sslexplorer.extensions.ExtensionType#getTypeBundle()
389      */

390     public String JavaDoc getTypeBundle() {
391         return "extensions";
392     }
393 }
394
Popular Tags