1 package hudson; 2 3 import hudson.model.Hudson; 4 import hudson.util.Service; 5 6 import javax.servlet.ServletContext ; 7 import java.io.File ; 8 import java.io.FilenameFilter ; 9 import java.io.IOException ; 10 import java.io.StringWriter ; 11 import java.io.PrintWriter ; 12 import java.net.URL ; 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.HashSet ; 16 import java.util.List ; 17 import java.util.Set ; 18 import java.util.logging.Level ; 19 import java.util.logging.Logger ; 20 21 26 public final class PluginManager { 27 30 private final List <PluginWrapper> plugins = new ArrayList <PluginWrapper>(); 31 32 35 private final List <PluginWrapper> activePlugins = new ArrayList <PluginWrapper>(); 36 37 private final List <FailedPlugin> failedPlugins = new ArrayList <FailedPlugin>(); 38 39 42 public final File rootDir; 43 44 public final ServletContext context; 45 46 51 public final ClassLoader uberClassLoader = new UberClassLoader(); 54 55 public PluginManager(ServletContext context) { 56 this.context = context; 57 rootDir = new File (Hudson.getInstance().getRootDir(),"plugins"); 58 if(!rootDir.exists()) 59 rootDir.mkdirs(); 60 61 File [] archives = rootDir.listFiles(new FilenameFilter () { 62 public boolean accept(File dir, String name) { 63 return name.endsWith(".hpi") || name.endsWith(".hpl"); } 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 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 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 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 <PluginWrapper> getPlugins() { 96 return plugins; 97 } 98 99 public List <FailedPlugin> getFailedPlugins() { 100 return failedPlugins; 101 } 102 103 public PluginWrapper getPlugin(String shortName) { 104 for (PluginWrapper p : plugins) { 105 if(p.getShortName().equals(shortName)) 106 return p; 107 } 108 return null; 109 } 110 111 115 public <T> Collection <Class <? extends T>> discover( Class <T> spi ) { 116 Set <Class <? extends T>> result = new HashSet <Class <? extends T>>(); 117 118 for (PluginWrapper p : activePlugins) { 119 Service.load(spi, p.classLoader, result); 120 } 121 122 return result; 123 } 124 125 128 public void stop() { 129 for (PluginWrapper p : activePlugins) { 130 p.stop(); 131 } 132 } 133 134 private final class UberClassLoader extends ClassLoader { 135 public UberClassLoader() { 136 super(PluginManager.class.getClassLoader()); 137 } 138 139 @Override 140 protected Class <?> findClass(String name) throws ClassNotFoundException { 141 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 144 if(cl!=null) 145 try { 146 return cl.loadClass(name); 147 } catch(ClassNotFoundException e) { 148 } 150 151 for (PluginWrapper p : activePlugins) { 152 try { 153 return p.classLoader.loadClass(name); 154 } catch (ClassNotFoundException e) { 155 } 157 } 158 throw new ClassNotFoundException (name); 160 } 161 162 @Override 163 protected URL findResource(String name) { 164 for (PluginWrapper p : activePlugins) { 165 URL url = p.classLoader.getResource(name); 166 if(url!=null) 167 return url; 168 } 169 return null; 170 } 171 } 172 173 private static final Logger LOGGER = Logger.getLogger(PluginManager.class.getName()); 174 175 178 public static final class FailedPlugin { 179 public final String name; 180 public final IOException cause; 181 182 public FailedPlugin(String name, IOException cause) { 183 this.name = name; 184 this.cause = cause; 185 } 186 187 public String getExceptionString() { 188 StringWriter sw = new StringWriter (); 189 cause.printStackTrace(new PrintWriter (sw)); 190 return sw.toString(); 191 } 192 } 193 } 194 | Popular Tags |