1 package org.columba.core.plugin; 19 20 import java.io.File ; 21 import java.lang.reflect.Constructor ; 22 import java.net.MalformedURLException ; 23 import java.net.URL ; 24 import java.util.List ; 25 import java.util.Vector ; 26 27 import org.columba.api.plugin.ExtensionMetadata; 28 import org.columba.api.plugin.IExtension; 29 import org.columba.api.plugin.IExtensionInterface; 30 import org.columba.api.plugin.PluginException; 31 import org.columba.api.plugin.PluginMetadata; 32 import org.columba.core.logging.Logging; 33 import org.columba.core.main.Main; 34 35 41 public class Extension implements IExtension { 42 43 private static final String FILE_PLUGIN_JAR = "plugin.jar"; 44 45 private static final java.util.logging.Logger LOG = java.util.logging.Logger 46 .getLogger("org.columba.core.plugin"); 47 48 private ExtensionMetadata metadata; 49 50 private PluginMetadata pluginMetadata; 51 52 private boolean internalPlugin; 53 54 private IExtensionInterface cachedInstance; 55 56 60 private boolean enabled = true; 61 62 67 public Extension(ExtensionMetadata metadata, boolean internal) { 68 this.metadata = metadata; 69 70 internalPlugin = internal; 71 } 72 73 79 public Extension(PluginMetadata pluginMetadata, ExtensionMetadata metadata) { 80 this.metadata = metadata; 81 this.pluginMetadata = pluginMetadata; 82 83 internalPlugin = false; 84 } 85 86 89 public ExtensionMetadata getMetadata() { 90 return metadata; 91 } 92 93 96 public IExtensionInterface instanciateExtension(Object [] arguments) 97 throws PluginException { 98 99 if (!enabled) 100 throw new PluginException("Extension <" + getMetadata().getId() 101 + "> was disabled due to a former instanciation error"); 102 103 String id = null; 104 File pluginDirectory = null; 105 106 String className = metadata.getClassname(); 107 108 if (pluginMetadata != null) { 109 id = pluginMetadata.getId(); 110 pluginDirectory = pluginMetadata.getDirectory(); 112 } 113 114 IExtensionInterface plugin = null; 115 116 if ((metadata.isSingleton()) && (cachedInstance != null)) { 118 plugin = cachedInstance; 119 120 } else { 121 122 try { 123 124 if (isInternal()) 125 126 plugin = instanciateJavaClass(className, arguments); 128 129 else { 130 134 139 141 152 plugin = instanciateExternalJavaClass(arguments, 154 pluginDirectory, className); 155 156 } 157 158 if (metadata.isSingleton()) 160 cachedInstance = plugin; 161 162 } catch (Exception e) { 163 logErrorMessage(e); 164 165 enabled = false; 167 168 throw new PluginException(this, e); 169 } catch (Error e) { 170 logErrorMessage(e); 171 172 enabled = false; 174 175 throw new PluginException(this, e); 176 } 177 178 } 179 return plugin; 180 } 181 182 185 private void logErrorMessage(Throwable e) { 186 if (e.getCause() != null) { 187 LOG.severe(e.getCause().getMessage()); 188 if (Logging.DEBUG) 189 e.getCause().printStackTrace(); 190 } else { 191 LOG.severe(e.getMessage()); 192 if (Logging.DEBUG) 193 e.printStackTrace(); 194 } 195 } 196 197 212 private IExtensionInterface instanciateExternalJavaClass( 213 Object [] arguments, File pluginDirectory, String className) 214 throws Exception { 215 IExtensionInterface plugin; 216 URL [] urls = null; 217 218 String jarFilename = Extension.FILE_PLUGIN_JAR; 220 221 try { 222 urls = getURLs(pluginDirectory, jarFilename); 223 } catch (MalformedURLException e) { 224 e.printStackTrace(); 226 } 227 228 238 Main.mainClassLoader.addURLs(urls); 240 241 243 ExternalClassLoader loader = new ExternalClassLoader(urls, 245 Main.mainClassLoader); 246 plugin = (IExtensionInterface) loader.instanciate(className, 247 arguments); 248 249 return plugin; 250 } 251 252 private IExtensionInterface instanciateJavaClass(String className, 253 Object [] arguments) throws Exception { 254 255 if (className == null) 256 throw new IllegalArgumentException ("className == null"); 257 258 IExtensionInterface plugin = null; 259 260 ClassLoader loader = Main.mainClassLoader; 262 263 Class actClass; 264 265 actClass = loader.loadClass(className); 266 267 if ((arguments == null) || (arguments.length == 0)) { 273 274 plugin = (IExtensionInterface) actClass.newInstance(); 275 276 } else { 277 Constructor constructor; 278 279 constructor = ClassLoaderHelper 280 .findConstructor(arguments, actClass); 281 282 if (constructor == null) { 284 LOG.severe("Couldn't find constructor for " + className 285 + " with matching argument-list: "); 286 for (int i = 0; i < arguments.length; i++) { 287 LOG.severe("argument[" + i + "]=" + arguments[i]); 288 } 289 290 return null; 291 } else { 292 293 plugin = (IExtensionInterface) constructor 294 .newInstance(arguments); 295 296 } 297 298 } 299 300 return plugin; 301 } 302 303 306 public boolean isInternal() { 307 return internalPlugin; 308 } 309 310 313 public String toString() { 314 StringBuffer buf = new StringBuffer (); 315 buf.append("id=" + metadata.getId()); 316 buf.append("class=" + metadata.getClassname()); 317 318 return buf.toString(); 319 } 320 321 333 private URL [] getURLs(File file, String jarFile) 334 throws MalformedURLException { 335 if (file == null) 336 throw new IllegalArgumentException ("file == null"); 337 if (jarFile == null) 338 throw new IllegalArgumentException ("jarFile == null"); 339 340 List urlList = new Vector (); 341 342 String path = file.getPath(); 344 345 if (jarFile != null) { 346 URL jarURL = new File (file, jarFile).toURL(); 347 urlList.add(jarURL); 348 } 349 350 URL newURL = new File (path).toURL(); 351 urlList.add(newURL); 352 353 356 File lib = new File (file, "lib"); 357 358 if (lib.exists()) { 359 File [] libList = lib.listFiles(); 360 361 for (int i = 0; i < libList.length; i++) { 362 File f = libList[i]; 363 364 if (f.getName().endsWith(".jar")) { 365 urlList.add(f.toURL()); 367 } else if (f.isDirectory()) { 368 urlList.add(f.toURL()); 369 } 370 } 371 } 372 373 URL [] url = new URL [urlList.size()]; 374 375 for (int i = 0; i < urlList.size(); i++) { 376 url[i] = (URL ) urlList.get(i); 377 } 378 379 if (Logging.DEBUG) { 380 for (int i = 0; i < url.length; i++) { 381 LOG.finest("url[" + i + "]=" + url[i]); 382 } 383 } 384 385 return url; 386 } 387 388 public void setInternal(boolean internal) { 389 this.internalPlugin = internal; 390 } 391 392 398 public boolean isEnabled() { 399 return false; 401 } 402 403 } 404 | Popular Tags |