KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > PluginManager


1 package hudson;
2
3 import hudson.model.Hudson;
4 import hudson.util.Service;
5
6 import javax.servlet.ServletContext JavaDoc;
7 import java.io.File JavaDoc;
8 import java.io.FilenameFilter JavaDoc;
9 import java.io.IOException JavaDoc;
10 import java.io.StringWriter JavaDoc;
11 import java.io.PrintWriter JavaDoc;
12 import java.net.URL JavaDoc;
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Set JavaDoc;
18 import java.util.logging.Level JavaDoc;
19 import java.util.logging.Logger JavaDoc;
20
21 /**
22  * Manages {@link PluginWrapper}s.
23  *
24  * @author Kohsuke Kawaguchi
25  */

26 public final class PluginManager {
27     /**
28      * All discovered plugins.
29      */

30     private final List JavaDoc<PluginWrapper> plugins = new ArrayList JavaDoc<PluginWrapper>();
31
32     /**
33      * All active plugins.
34      */

35     private final List JavaDoc<PluginWrapper> activePlugins = new ArrayList JavaDoc<PluginWrapper>();
36
37     private final List JavaDoc<FailedPlugin> failedPlugins = new ArrayList JavaDoc<FailedPlugin>();
38
39     /**
40      * Plug-in root directory.
41      */

42     public final File JavaDoc rootDir;
43
44     public final ServletContext JavaDoc context;
45
46     /**
47      * {@link ClassLoader} that can load all the publicly visible classes from plugins
48      * (and including the classloader that loads Hudson itself.)
49      *
50      */

51     // implementation is minimal --- just enough to run XStream
52
// and load plugin-contributed classes.
53
public final ClassLoader JavaDoc uberClassLoader = new UberClassLoader();
54
55     public PluginManager(ServletContext JavaDoc context) {
56         this.context = context;
57         rootDir = new File JavaDoc(Hudson.getInstance().getRootDir(),"plugins");
58         if(!rootDir.exists())
59             rootDir.mkdirs();
60
61         File JavaDoc[] archives = rootDir.listFiles(new FilenameFilter JavaDoc() {
62             public boolean accept(File JavaDoc dir, String JavaDoc name) {
63                 return name.endsWith(".hpi") // plugin jar file
64
|| name.endsWith(".hpl"); // linked plugin. for debugging.
65
}
66         });
67
68         if(archives==null) {
69             LOGGER.severe("Hudson is unable to create "+rootDir+"\nPerhaps its security privilege is insufficient");
70             return;
71         }
72         for( File JavaDoc arc : archives ) {
73             try {
74                 PluginWrapper p = new PluginWrapper(this,arc);
75                 plugins.add(p);
76                 if(p.isActive())
77                     activePlugins.add(p);
78             } catch (IOException JavaDoc e) {
79                 failedPlugins.add(new FailedPlugin(arc.getName(),e));
80                 LOGGER.log(Level.SEVERE, "Failed to load a plug-in " + arc, e);
81             }
82         }
83
84         for (PluginWrapper p : activePlugins.toArray(new PluginWrapper[0]))
85             try {
86                 p.load(this);
87             } catch (IOException JavaDoc e) {
88                 failedPlugins.add(new FailedPlugin(p.getShortName(),e));
89                 LOGGER.log(Level.SEVERE, "Failed to load a plug-in " + p.getShortName(), e);
90                 activePlugins.remove(p);
91                 plugins.remove(p);
92             }
93     }
94
95     public List JavaDoc<PluginWrapper> getPlugins() {
96         return plugins;
97     }
98
99     public List JavaDoc<FailedPlugin> getFailedPlugins() {
100         return failedPlugins;
101     }
102
103     public PluginWrapper getPlugin(String JavaDoc shortName) {
104         for (PluginWrapper p : plugins) {
105             if(p.getShortName().equals(shortName))
106                 return p;
107         }
108         return null;
109     }
110
111     /**
112      * Discover all the service provider implementations of the given class,
113      * via <tt>META-INF/services</tt>.
114      */

115     public <T> Collection JavaDoc<Class JavaDoc<? extends T>> discover( Class JavaDoc<T> spi ) {
116         Set JavaDoc<Class JavaDoc<? extends T>> result = new HashSet JavaDoc<Class JavaDoc<? extends T>>();
117
118         for (PluginWrapper p : activePlugins) {
119             Service.load(spi, p.classLoader, result);
120         }
121
122         return result;
123     }
124
125     /**
126      * Orderly terminates all the plugins.
127      */

128     public void stop() {
129         for (PluginWrapper p : activePlugins) {
130             p.stop();
131         }
132     }
133
134     private final class UberClassLoader extends ClassLoader JavaDoc {
135         public UberClassLoader() {
136             super(PluginManager.class.getClassLoader());
137         }
138
139         @Override JavaDoc
140         protected Class JavaDoc<?> findClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
141             // first, use the context classloader so that plugins that are loading
142
// can use its own classloader first.
143
ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
144             if(cl!=null)
145                 try {
146                     return cl.loadClass(name);
147                 } catch(ClassNotFoundException JavaDoc e) {
148                     // not found. try next
149
}
150
151             for (PluginWrapper p : activePlugins) {
152                 try {
153                     return p.classLoader.loadClass(name);
154                 } catch (ClassNotFoundException JavaDoc e) {
155                     //not found. try next
156
}
157             }
158             // not found in any of the classloader. delegate.
159
throw new ClassNotFoundException JavaDoc(name);
160         }
161
162         @Override JavaDoc
163         protected URL JavaDoc findResource(String JavaDoc name) {
164             for (PluginWrapper p : activePlugins) {
165                 URL JavaDoc url = p.classLoader.getResource(name);
166                 if(url!=null)
167                     return url;
168             }
169             return null;
170         }
171     }
172
173     private static final Logger JavaDoc LOGGER = Logger.getLogger(PluginManager.class.getName());
174
175     /**
176      * Remembers why a plugin failed to deploy.
177      */

178     public static final class FailedPlugin {
179         public final String JavaDoc name;
180         public final IOException JavaDoc cause;
181
182         public FailedPlugin(String JavaDoc name, IOException JavaDoc cause) {
183             this.name = name;
184             this.cause = cause;
185         }
186
187         public String JavaDoc getExceptionString() {
188             StringWriter JavaDoc sw = new StringWriter JavaDoc();
189             cause.printStackTrace(new PrintWriter JavaDoc(sw));
190             return sw.toString();
191         }
192     }
193 }
194
Popular Tags