示例#1
0
  /**
   * Create a new plugin manager.
   *
   * @param pluginType Core type for a plugin.
   * @param pluginCategory Provides a category name to the plugin. Must not be null.
   * @param pluginSuffix Provides a suffix that will be trimmed off when converting to a plugin
   *     name. Can be null.
   * @param classpath Custom class path to search for classes.
   */
  public PluginManager(
      Class pluginType, String pluginCategory, String pluginSuffix, List<URL> classpath) {
    this.pluginCategory = pluginCategory;
    this.pluginSuffix = pluginSuffix;

    this.plugins = new ArrayList<Class<? extends PluginType>>();
    this.interfaces = new ArrayList<Class<? extends PluginType>>();

    Reflections reflections;
    if (classpath == null) {
      reflections = defaultReflections;
    } else {
      addClasspath(classpath);
      reflections =
          new Reflections(
              new ConfigurationBuilder().setUrls(classpath).setScanners(new SubTypesScanner()));
    }

    // Load all classes types filtering them by concrete.
    @SuppressWarnings("unchecked")
    Set<Class<? extends PluginType>> allTypes = reflections.getSubTypesOf(pluginType);
    for (Class<? extends PluginType> type : allTypes) {
      // The plugin manager does not support anonymous classes; to be a plugin, a class must have a
      // name.
      if (JVMUtils.isAnonymous(type)) continue;

      if (JVMUtils.isConcrete(type)) plugins.add(type);
      else interfaces.add(type);
    }

    pluginsByName = new TreeMap<String, Class<? extends PluginType>>();
    for (Class<? extends PluginType> pluginClass : plugins) {
      String pluginName = getName(pluginClass);
      pluginsByName.put(pluginName, pluginClass);
    }

    // sort the plugins so the order of elements is deterministic
    sortPlugins(plugins);
    sortPlugins(interfaces);
  }
示例#2
0
 /**
  * Adds the URL to the system class loader classpath using reflection. HACK: Uses reflection to
  * modify the class path, and assumes loader is a URLClassLoader.
  *
  * @param urls URLs to add to the system class loader classpath.
  */
 private static void addClasspath(List<URL> urls) {
   Set<URL> existing = JVMUtils.getClasspathURLs();
   for (URL url : urls) {
     if (existing.contains(url)) continue;
     try {
       Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
       if (!method.isAccessible()) method.setAccessible(true);
       method.invoke(ClassLoader.getSystemClassLoader(), url);
     } catch (Exception e) {
       throw new ReviewedStingException("Error adding url to the current classloader.", e);
     }
   }
 }
示例#3
0
  static {
    // turn off logging in the reflections library - they talk too much
    Reflections.log = null;

    Set<URL> classPathUrls = new LinkedHashSet<URL>();

    URL cwd;
    try {
      cwd = new File(".").getAbsoluteFile().toURI().toURL();
    } catch (MalformedURLException e) {
      throw new RuntimeException(e);
    }

    // NOTE: Reflections also scans directories for classes.
    // Meanwhile some of the jar MANIFEST.MF Bundle-ClassPath properties contain "."
    // Do NOT let reflections scan the CWD where it often picks up test classes when
    // they weren't explicitly in the classpath, for example the UninstantiableWalker
    for (URL url : JVMUtils.getClasspathURLs()) if (!url.equals(cwd)) classPathUrls.add(url);

    defaultReflections =
        new Reflections(
            new ConfigurationBuilder().setUrls(classPathUrls).setScanners(new SubTypesScanner()));
  }