KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > container > PluginClassLoader


1 /**
2  * $RCSfile: PluginClassLoader.java,v $
3  * $Revision: 1.4 $
4  * $Date: 2005/07/26 21:28:46 $
5  *
6  * Copyright (C) 2004 Jive Software. All rights reserved.
7  *
8  * This software is published under the terms of the GNU Public License (GPL),
9  * a copy of which is included in this distribution.
10  */

11
12 package org.jivesoftware.messenger.container;
13
14 import org.jivesoftware.util.Log;
15
16 import java.io.File JavaDoc;
17 import java.io.FilenameFilter JavaDoc;
18 import java.net.MalformedURLException JavaDoc;
19 import java.net.URL JavaDoc;
20 import java.net.URLClassLoader JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24
25 /**
26  * ClassLoader for plugins. It searches the plugin directory for classes
27  * and JAR files, then constructs a class loader for the resources found.
28  * Resources are loaded as follows:<ul>
29  * <p/>
30  * <li>Any JAR files in the <tt>lib</tt> will be added to the classpath.
31  * <li>Any files in the classes directory will be added to the classpath.
32  * </ul>
33  *
34  * @author Derek DeMoro
35  */

36 class PluginClassLoader {
37
38     private URLClassLoader JavaDoc classLoader;
39     private final List JavaDoc<URL JavaDoc> list = new ArrayList JavaDoc<URL JavaDoc>();
40
41
42     /**
43      * Constructs a plugin loader for the given plugin directory.
44      *
45      * @param pluginDir the plugin directory.
46      * @throws java.lang.SecurityException if the created class loader violates
47      * existing security constraints.
48      */

49     public PluginClassLoader(File JavaDoc pluginDir) throws SecurityException JavaDoc {
50         addDirectory(pluginDir);
51     }
52
53     /**
54      * Adds a directory to the class loader. The {@link #initialize()} method should be called
55      * after adding the directory to make the change take effect.
56      *
57      * @param directory the directory.
58      */

59     public void addDirectory(File JavaDoc directory) {
60         try {
61         File JavaDoc classesDir = new File JavaDoc(directory, "classes");
62         if (classesDir.exists()) {
63             list.add(classesDir.toURL());
64         }
65         File JavaDoc libDir = new File JavaDoc(directory, "lib");
66         File JavaDoc[] jars = libDir.listFiles(new FilenameFilter JavaDoc() {
67             public boolean accept(File JavaDoc dir, String JavaDoc name) {
68                 return name.endsWith(".jar") || name.endsWith(".zip");
69             }
70         });
71         if (jars != null) {
72             for (int i = 0; i < jars.length; i++) {
73                 if (jars[i] != null && jars[i].isFile()) {
74                     list.add(jars[i].toURL());
75                 }
76             }
77         }
78         }
79         catch (MalformedURLException JavaDoc mue) {
80             Log.error(mue);
81         }
82     }
83
84     /**
85      * Adds a URL to the class loader. The {@link #initialize()} method should be called
86      * after adding the URL to make the change take effect.
87      *
88      * @param url the url.
89      */

90     public void addURL(URL JavaDoc url) {
91         list.add(url);
92     }
93
94     /**
95      * Initializes the class loader with all configured classpath URLs. This method
96      * can be called multiple times if the list of URLs changes.
97      */

98     public void initialize(){
99         Iterator JavaDoc urls = list.iterator();
100         URL JavaDoc[] urlArray = new URL JavaDoc[list.size()];
101         for (int i = 0; urls.hasNext(); i++) {
102             urlArray[i] = (URL JavaDoc)urls.next();
103         }
104         classLoader = new URLClassLoader JavaDoc(urlArray, findParentClassLoader());
105     }
106
107     /**
108      * Load a class using this plugin class loader.
109      *
110      * @param name the fully qualified name of the class to load.
111      * @return The module object loaded
112      * @throws ClassNotFoundException if the class could not be loaded by this class loader.
113      * @throws IllegalAccessException if the class constructor was private or protected.
114      * @throws InstantiationException if the class could not be instantiated (initialization error).
115      * @throws SecurityException if the custom class loader not allowed.
116      */

117     public Class JavaDoc loadClass(String JavaDoc name) throws ClassNotFoundException JavaDoc, IllegalAccessException JavaDoc,
118             InstantiationException JavaDoc, SecurityException JavaDoc {
119         return classLoader.loadClass(name);
120     }
121
122     /**
123      * Destroys this class loader.
124      */

125     public void destroy() {
126         classLoader = null;
127     }
128
129     /**
130      * Locates the best parent class loader based on context.
131      *
132      * @return the best parent classloader to use.
133      */

134     private ClassLoader JavaDoc findParentClassLoader() {
135         ClassLoader JavaDoc parent = Thread.currentThread().getContextClassLoader();
136         if (parent == null) {
137             parent = this.getClass().getClassLoader();
138         }
139         if (parent == null) {
140             parent = ClassLoader.getSystemClassLoader();
141         }
142         return parent;
143     }
144 }
Popular Tags