⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plugindiscoverer.java

📁 JGAP(发音"jay-gap")是一款用Java编写的遗传算法包。提供了基本的遗传算法.你可以使用它来解决一些适用于遗传算法解决的问题.
💻 JAVA
字号:
/*
 * This file is part of JGAP.
 *
 * JGAP offers a dual license model containing the LGPL as well as the MPL.
 *
 * For licencing information please see the file license.txt included with JGAP
 * or have a look at the top of class org.jgap.Chromosome which representatively
 * includes the JGAP license policy applicable for any file delivered with JGAP.
 */
package org.jgap.util;

import java.io.*;
import java.util.*;
import java.util.jar.*;

/**
 * This class will (slightly inefficiently) look for all classes that implement
 * a particular interface.  It is useful for plugins.  This is done by looking
 * through the contents of all jar files in the classpath, as well as
 * performing a recursive search for *.class files in the classpath directories
 *
 * This particular class may not work in restrictive ClassLoader environments
 * such as Applets or WebStart.  (It may...but unlikely and untested.)
 *
 * @author Klaus Meffert
 * @since 2.3
 */
public class PluginDiscoverer {
  /** String containing the CVS revision. Read out via reflection!*/
  private final static String CVS_REVISION = "$Revision: 1.5 $";

  private static final boolean DEBUG = false;

  //list of folders in the classpath
  private List m_classpathFolders;

  //list of jars in the classpath
  private List m_classpathJars;

  /**
   * Reads the list of jars and classpath folders into instance variables
   * for later (cached) access.
   *
   * @author Klaus Meffert
   * @since 2.3
   */
  public PluginDiscoverer() {
    String classpath = System.getProperty("java.class.path");
    StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
    m_classpathFolders = new Vector();
    m_classpathJars = new Vector();
    while (st.hasMoreTokens()) {
      String item = st.nextToken();
      File f = new File(item);
      if (item.toLowerCase().endsWith(".jar") && f.isFile()) {
        m_classpathJars.add(item);
      }
      else if (f.isDirectory()) {
        m_classpathFolders.add(item);
      }
    }
  }

  /**
   * Checks if a given class matches a given interface
   * @param interfaceClass The interface we are looking for
   * @param testClass class under test against the interface
   * @return corrected name of matched class, or null if not matching
   *
   * @author Klaus Meffert
   * @since 2.3
   */
  private String checkIfClassMatches(final Class a_interfaceClass,
                                     String a_testClass) {
    // remove trailing dots
    if (a_testClass.toLowerCase().endsWith(".class")) {
      a_testClass = a_testClass.substring(0, a_testClass.length() - 6);
    }
    // replace slashes with dots
    a_testClass = a_testClass.replace('\\', '.').replace('/', '.');
    // remove leading dots
    while (a_testClass.startsWith(".")) {
      a_testClass = a_testClass.substring(1);
    }
    if (a_testClass.indexOf('$') != -1) {
      // don't handle inner/internal classes
      return null;
    }
    try {
      Class testClassObj = Class.forName(a_testClass, false,
                                         this.getClass().getClassLoader());
      if (a_interfaceClass.isAssignableFrom(testClassObj)) {
        if (testClassObj.isInterface()) {
          // no interfaces wanted as result
          return null;
        }
        if ( (testClassObj.getModifiers() & java.lang.reflect.Modifier.ABSTRACT)
            > 0) {
          // no abstract classes wanted as result
          return null;
        }
        return a_testClass;
      }
    }
    catch (UnsatisfiedLinkError ule) {
      if (DEBUG) {
        System.out.println("Unsatisfied link error for class: " + a_testClass);
      }
    }
    catch (IllegalAccessError e) {
      if (DEBUG) {
        System.out.println("Unable to load class: " + a_testClass);
      }
    }
    catch (ClassNotFoundException cnfe) {
      if (DEBUG) {
        System.out.println("Class not found" + a_testClass);
      }
    }
    catch (NoClassDefFoundError nex) {
      if (DEBUG) {
        System.out.println("No class definition found: " + a_testClass);
      }
    }
    return null;
  }

  /**
   * Finds all classes implementing the given interface
   * @param a_fullInterfaceName name of the interface (inclusive package name)
   * to find implementing classes (not abstract) for
   * @return list of class names that implement the given interface
   *
   * @throws ClassNotFoundException
   *
   * @author Klaus Meffert
   * @since 2.4
   */
  public List findImplementingClasses(final String a_fullInterfaceName)
      throws ClassNotFoundException {
    Class interfaceToLookFor = Class.forName(a_fullInterfaceName);
    return findImplementingClasses(interfaceToLookFor);
  }

  /**
   * Finds all classes implementing the given interface
   * @param a_intrface the interface to check against
   * @return list of class names that implement the given interface
   *
   * @author Klaus Meffert
   * @since 2.3
   */
  public List findImplementingClasses(final Class a_intrface) {
    List result = new Vector();
    // Check the jar files
    String s = null;
    try {
      // determine current directory
      File f = new File(".");
      s = f.getCanonicalPath();
    }
    catch (IOException iex) {
      throw new RuntimeException("Unable to determine current directory");
    }
    Iterator i = m_classpathJars.iterator();
    while (i.hasNext()) {
      String filename = (String) i.next();
      // only search for jars in current dir or subdir (otherwise we would scan
      // the whole bunch of system and external library jars, too, and that
      // would be really inperformant)
      if (filename.startsWith(s)) {
        System.err.println(filename);
        try {
          JarFile jar = new JarFile(filename);
          Enumeration item = jar.entries();
          while (item.hasMoreElements()) {
            JarEntry entry = (JarEntry) item.nextElement();
            String name = entry.getName();
            if (name.toLowerCase().endsWith(".class")) {
              String classname = checkIfClassMatches(a_intrface, name);
              if (classname != null) {
                result.add(classname);
              }
            }
          }
        }
        catch (IOException e) {
          System.out.println("Unable to open jar " + filename);
        }
      }
    }
    // Iterate over the classpath folders
    i = m_classpathFolders.iterator();
    while (i.hasNext()) {
      String folder = (String) i.next();
      System.err.println(folder);
      findImplementingClasses0(a_intrface, result, folder, "");
    }
    return result;
  }

  /**
   * Recursive helper method, searching a path recursively for class files
   * conforming to a given interface
   * @param intrface the interface we are looking for
   * @param result container for storing the results
   * @param base base directory
   * @param path current location in the traversal
   *
   * @author Klaus Meffert
   * @since 2.3
   */
  private void findImplementingClasses0(final Class a_intrface,
                                        final List a_result,
                                        final String a_base,
                                        final String a_path) {
    File f = new File(a_base + File.separator + a_path);
    if (!f.isDirectory()) {
      return;
    }
    File[] matches = f.listFiles(new ClassFilter());
    for (int i = 0; i < matches.length; i++) {
      String classname = a_path + File.separator + matches[i].getName();
      classname = checkIfClassMatches(a_intrface, classname);
      if (classname != null) {
        a_result.add(classname);
      }
    }
    matches = f.listFiles(new DirectoryFilter());
    for (int i = 0; i < matches.length; i++) {
      String folder = a_path + File.separator + matches[i].getName();
      findImplementingClasses0(a_intrface, a_result, a_base, folder);
    }
  }

  /**
   * Filter that only matches class files
   */
  public class ClassFilter
      implements FilenameFilter {
    public boolean accept(final File a_dir, final String a_name) {
      return (a_name != null && a_name.toLowerCase().endsWith(".class"));
    }
  }
  /**
   * Filter that only matches subdirectories
   */
  public class DirectoryFilter
      implements FilenameFilter {
    public boolean accept(final File a_dir, final String a_name) {
      return (a_dir != null
              && new File(a_dir.getPath()
                          + File.separator + a_name).isDirectory());
    }
  }
  /**
   * For testing purpose
   * @param args not used
   * @throws Exception in case of any problem
   *
   * @author Klaus Meffert
   * @since 2.3
   */
  public static void main(String[] args)
      throws Exception {
    PluginDiscoverer discoverer = new PluginDiscoverer();
    List plugins = discoverer.findImplementingClasses(
        "org.jgap.INaturalSelector");
    System.out.println();
    int size = plugins.size();
    System.out.println("" + size + " plugin"
                       + (size == 1 ? "" : "s") + " discovered"
                       + (size == 0 ? "" : ":"));
    for (int i = 0; i < size; i++) {
      System.out.println(plugins.get(i));
    }
    System.exit(0);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -