aboutsummaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/net/java/games/util/Version.java104
-rw-r--r--src/main/java/net/java/games/util/plugins/Plugin.java60
-rw-r--r--src/main/java/net/java/games/util/plugins/PluginLoader.java169
-rw-r--r--src/main/java/net/java/games/util/plugins/Plugins.java251
4 files changed, 584 insertions, 0 deletions
diff --git a/src/main/java/net/java/games/util/Version.java b/src/main/java/net/java/games/util/Version.java
new file mode 100644
index 0000000..62bd4a1
--- /dev/null
+++ b/src/main/java/net/java/games/util/Version.java
@@ -0,0 +1,104 @@
+/*
+* Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* -Redistribution of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* -Redistribution in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* Neither the name of Sun Microsystems, Inc. or the names of contributors may
+* be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* This software is provided "AS IS," without a warranty of any kind.
+* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS
+* LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A
+* RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+* IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT
+* OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
+* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+*
+* You acknowledge that this software is not designed or intended for use in the
+* design, construction, operation or maintenance of any nuclear facility.
+*/
+
+package net.java.games.util;
+
+/**
+ * The version and build number of this implementation.
+ * Version numbers for a release are of the form: w.x.y[-a]-z, where:
+ * <ul>
+ * <li>
+ * w - the major version number of the release. This number should
+ * start at 1. Typically, a bump in the major version number
+ * signifies that the release breaks backwards compatibility
+ * with some older release.
+ * </li>
+ * <li>
+ * x - minor version number. This number starts at 0. A bump in
+ * the minor version number signifies a release that has significant
+ * new functionality.
+ * </li>
+ * <li>
+ * y - minor-minor version number number. This number starts at 0. A
+ * bump in the minor-minor version number signifies that new bug
+ * fixes have been added to the build.
+ * </li>
+ * <li>
+ * a - an optional build designator followed by a digit. Valid build
+ * designators are:
+ * <ul>
+ * <li>alpha</li>
+ * <li>beta</li>
+ * </ul>
+ * </li>
+ * <li>
+ * z - build number. This is used to specify the build number of the
+ * release. This is usually only important to people that use
+ * the daily build of a project. The format is the lower-case
+ * letter 'b' followed by a two digit number.
+ * </li>
+ * </ul>
+ *
+ * For example, the following are all valid version strings:
+ * <ul>
+ * <li>1.1.2-b02</li>
+ * <li>1.3.5-alpha1-b19</li>
+ * <li>4.7.1-beta3-b20</li>
+ * </ul>
+ *
+ */
+public final class Version {
+
+ /**
+ * Private constructor - no need for user to create
+ * an instance of this class.
+ */
+ private Version() {
+ }
+
+ /**
+ * Version string of this build.
+ */
+ private static final String version = "1.0.0-b01";
+
+ /**
+ * Returns the verison string and build number of
+ * this implementation. See the class descritpion
+ * for the version string format.
+ *
+ * @return The version string of this implementation.
+ */
+ public static String getVersion() {
+ return version;
+ }
+}
diff --git a/src/main/java/net/java/games/util/plugins/Plugin.java b/src/main/java/net/java/games/util/plugins/Plugin.java
new file mode 100644
index 0000000..cfb533b
--- /dev/null
+++ b/src/main/java/net/java/games/util/plugins/Plugin.java
@@ -0,0 +1,60 @@
+/*
+ * Plugin.java
+ *
+ * Created on April 18, 2003, 11:29 AM
+ */
+
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+
+package net.java.games.util.plugins;
+
+/** This is a marker interface used to mark plugins in a Jar file
+ * for retrieval by the Plugins class. In order for a class to be
+ * treated as a Plugin the following must be true:
+ *
+ * (1) The name of the class must end with "Plugin".
+ * (ie MedianCutFilterPlugin, DirectInput EnvrionmentPlugin)
+ *
+ * (2) The class must implement the Plugin interface. It can do
+ * so directly, through inheritence of either a superclass
+ * that implements this interface, or through the implementation
+ * of an interface that extends this interface.
+ *
+ *
+ * @author Jeffrey P. Kesselman
+ *
+ */
+public interface Plugin {
+
+}
diff --git a/src/main/java/net/java/games/util/plugins/PluginLoader.java b/src/main/java/net/java/games/util/plugins/PluginLoader.java
new file mode 100644
index 0000000..00545eb
--- /dev/null
+++ b/src/main/java/net/java/games/util/plugins/PluginLoader.java
@@ -0,0 +1,169 @@
+/*
+ * PluginLodaer.java
+ *
+ * Created on April 18, 2003, 11:32 AM
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.util.plugins;
+
+/**
+ *
+ * @author jeff
+ */
+import java.io.*;
+import java.net.*;
+
+/** This class is used internally by the Plugin system.
+ * End users of the system are unlikely to need to be aware
+ * of it.
+ *
+ *
+ * This is the class loader used to keep the namespaces of
+ * different plugins isolated from each other and from the
+ * main app code. One plugin loader is created per Jar
+ * file in the sub-directory tree of the plugin directory.
+ *
+ * In addition to isolating java classes this loader also isolates
+ * DLLs such that plugins with conflicting DLL names may be
+ * used by simply placing the plugin and its associated DLL
+ * in a sub-folder of its own.
+ *
+ * This class also currently implements methods for testing
+ * classes for inheritance of superclasses or interfaces.
+ * This code is genericly useful and should really be moved
+ * to a seperate ClassUtils class.
+ * @author Jeffrey Kesselman
+ */
+public class PluginLoader extends URLClassLoader {
+ static final boolean DEBUG = false;
+ File parentDir;
+ boolean localDLLs = true;
+ /** Creates a new instance of PluginLodaer
+ * If the system property "net.java.games.util.plugins.nolocalnative" is
+ * not set then the laoder will look for requried native libs in the
+ * same directory as the plugin jar. (Useful for handling name
+ * collision between plugins). If it IS set however, then it will
+ * fall back to the default way of loading natives. (Necessary for
+ * Java Web Start.)
+ * @param jf The JarFile to load the Plugins from.
+ * @throws MalformedURLException Will throw this exception if jf does not refer to a
+ * legitimate Jar file.
+ */
+ public PluginLoader(File jf) throws MalformedURLException {
+ super(new URL[] {jf.toURL()},
+ Thread.currentThread().getContextClassLoader());
+ parentDir = jf.getParentFile();
+ if (System.getProperty("net.java.games.util.plugins.nolocalnative")
+ !=null){
+ localDLLs = false;
+ }
+ }
+
+ /** This method is queried by the System.loadLibrary()
+ * code to find the actual native name and path to the
+ * native library to load.
+ *
+ * This subclass implementation of this method ensures that
+ * the native library will be loaded from, and only from,
+ * the parent directory of the Jar file this loader was
+ * created to support. This allows different Plugins
+ * with supporting DLLs of the same name to co-exist, each
+ * in their own subdirectory.
+ *
+ * Setting the global "localDLLs" by setting the property
+ * net.java.games.util.plugins.nolocalnative defeats this behavior.
+ * This is necessary for Java Web Start apps which have strong
+ * restrictions on where and how native libs can be loaded.
+ *
+ * @param libname The JNI name of the native library to locate.
+ * @return Returns a string describing the actual loation of the
+ * native library in the native file system.
+ */
+ protected String findLibrary(String libname){
+ if (localDLLs) {
+ String libpath = parentDir.getPath() + File.separator +
+ System.mapLibraryName(libname);
+ if (DEBUG) {
+ System.out.println("Returning libname of: " + libpath);
+ }
+ return libpath;
+ } else {
+ return super.findLibrary(libname);
+ }
+ }
+
+ /** This function is called as part of scanning the Jar for
+ * plugins. It checks to make sure the class passed in is
+ * a legitimate plugin, which is to say that it meets
+ * the following criteria:
+ *
+ * (1) Is not itself an interface
+ * (2) Implements the Plugin marker interface either directly
+ * or through inheritance.
+ *
+ * interface, either
+ * @param pc The potential plug-in class to vette.
+ * @return Returns true if the class meets the criteria for a
+ * plugin. Otherwise returns false.
+ */
+ public boolean attemptPluginDefine(Class pc){
+ return ((!pc.isInterface()) && classImplementsPlugin(pc));
+ }
+
+ private boolean classImplementsPlugin(Class testClass){
+ if (testClass == null) return false; // end of tree
+ if (DEBUG) {
+ System.out.println("testing class "+testClass.getName());
+ }
+ Class[] implementedInterfaces = testClass.getInterfaces();
+ for(int i=0;i<implementedInterfaces.length;i++){
+ if (DEBUG) {
+ System.out.println("examining interface: "+implementedInterfaces[i]);
+ }
+ if (implementedInterfaces[i]==Plugin.class) {
+ if (DEBUG) {
+ System.out.println("returning true from classImplementsPlugin");
+ }
+ return true;
+ }
+ }
+ for(int i=0;i<implementedInterfaces.length;i++){
+ if (classImplementsPlugin(implementedInterfaces[i])){
+ return true;
+ }
+ }
+ return classImplementsPlugin(testClass.getSuperclass());
+ }
+
+}
diff --git a/src/main/java/net/java/games/util/plugins/Plugins.java b/src/main/java/net/java/games/util/plugins/Plugins.java
new file mode 100644
index 0000000..42f0837
--- /dev/null
+++ b/src/main/java/net/java/games/util/plugins/Plugins.java
@@ -0,0 +1,251 @@
+/*
+ * Plugins.java
+ *
+ * Created on April 18, 2003, 10:57 AM
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.util.plugins;
+
+/**
+ *
+ * @author jeff
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+/** This is the application interface to the Plugin system.
+ * One Plugins object should be created for each plug-in
+ * directory tree root.
+ *
+ * On creation the Plugins object will scan its assigned
+ * directory tree and examine all Jar files in that tree to
+ * see if they qualify as Plug-ins.
+ *
+ * The Plugin classes may then be retrived from the Plugins object by calling
+ * the appropriate get function (see below).
+ *
+ * If a plugin requires a native code library, that library must be present
+ * in the same directory as the plugin Jar file UNLESS the property
+ * "net.java.games.util.plugins.nolocalnative" is set. In that case
+ * it will fall abck to the VM or environment's default way of finding
+ * native libraries. (This is n ecessary for Java Web Start apps.)
+ *
+ */
+public class Plugins {
+ static final boolean DEBUG = true;
+ List pluginList= new ArrayList();
+
+ /** Creates a new instance of Plugins
+ * @param pluginRoot The root od the directory tree to scan for Jars
+ * containing plugins.
+ */
+ public Plugins(File pluginRoot) throws IOException {
+ scanPlugins(pluginRoot);
+ }
+
+ private void scanPlugins(File dir) throws IOException {
+ File[] files = dir.listFiles();
+ if (files == null) {
+ throw new FileNotFoundException("Plugin directory "+dir.getName()+
+ " not found.");
+ }
+ for(int i=0;i<files.length;i++){
+ File f = files[i];
+ if (f.getName().endsWith(".jar")) { // process JAR file
+ processJar(f);
+ } else if (f.isDirectory()) {
+ scanPlugins(f); // recurse
+ }
+ }
+ }
+
+
+ private void processJar(File f) {
+ try {
+ //JarFile jf = new JarFile(f);
+ if (DEBUG) {
+ System.out.println("Scanning jar: "+f.getName());
+ }
+ PluginLoader loader = new PluginLoader(f);
+ JarFile jf = new JarFile(f);
+ for (Enumeration en = jf.entries();en.hasMoreElements();){
+ JarEntry je = (JarEntry)en.nextElement();
+ if (DEBUG) {
+ System.out.println("Examining file : "+je.getName());
+ }
+ if (je.getName().endsWith("Plugin.class")) {
+ if (DEBUG) {
+ System.out.println("Found candidate class: "+je.getName());
+ }
+ String cname = je.getName();
+ cname = cname.substring(0,cname.length()-6);
+ cname = cname.replace('/','.'); // required by JDK1.5
+ Class pc = loader.loadClass(cname);
+ if (loader.attemptPluginDefine(pc)) {
+ if (DEBUG) {
+ System.out.println("Adding class to plugins:"+pc.getName());
+ }
+ pluginList.add(pc);
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /** This method returns all the Plugins found in the
+ * directory passed in at object creation time or any of its
+ * sub-directories.
+ * @return An array of Plugin objects
+ */
+ public Class[] get(){
+ Class[] pluginArray = new Class[pluginList.size()];
+ return (Class[])pluginList.toArray(pluginArray);
+ }
+
+ /** This method returns a sub-list of all the found Plugin
+ * classes that implement <B>any</B> of the passed in set of
+ * Interfaces (either directly or through inheritance.)
+ * @param interfaces A set of interfaces to match against the interfaces
+ * implemented by the plugin classes.
+ * @return The list of plugin classes that implement at least
+ * one member of the passed in set of interfaces.
+ */
+ public Class[] getImplementsAny(Class[] interfaces){
+ List matchList = new ArrayList(pluginList.size());
+ Set interfaceSet = new HashSet();
+ for(int i=0;i<interfaces.length;i++){
+ interfaceSet.add(interfaces[i]);
+ }
+ for(Iterator i = pluginList.iterator();i.hasNext();){
+ Class pluginClass = (Class)i.next();
+ if (classImplementsAny(pluginClass,interfaceSet)){
+ matchList.add(pluginClass);
+ }
+ }
+ Class[] pluginArray = new Class[matchList.size()];
+ return (Class[])matchList.toArray(pluginArray);
+ }
+
+ private boolean classImplementsAny(Class testClass,Set interfaces){
+ if (testClass == null) return false; // end of tree
+ Class[] implementedInterfaces = testClass.getInterfaces();
+ for(int i=0;i<implementedInterfaces.length;i++){
+ if (interfaces.contains(implementedInterfaces[i])) {
+ return true;
+ }
+ }
+ for(int i=0;i<implementedInterfaces.length;i++){
+ if (classImplementsAny(implementedInterfaces[i],interfaces)){
+ return true;
+ }
+ }
+ return classImplementsAny(testClass.getSuperclass(),interfaces);
+ }
+
+ /** This method returns a sub-list of all the found Plugin
+ * classes that implement <B>all</B> of the passed in set of
+ * Interfaces (either directly or through inheritance.)
+ * @param interfaces A set of interfaces to match against the interfaces
+ * implemented by the plugin classes.
+ * @return The list of plugin classes that implement at least
+ * one member of the passed in set of interfaces.
+ */
+ public Class[] getImplementsAll(Class[] interfaces){
+ List matchList = new ArrayList(pluginList.size());
+ Set interfaceSet = new HashSet();
+ for(int i=0;i<interfaces.length;i++){
+ interfaceSet.add(interfaces[i]);
+ }
+ for(Iterator i = pluginList.iterator();i.hasNext();){
+ Class pluginClass = (Class)i.next();
+ if (classImplementsAll(pluginClass,interfaceSet)){
+ matchList.add(pluginClass);
+ }
+ }
+ Class[] pluginArray = new Class[matchList.size()];
+ return (Class[])matchList.toArray(pluginArray);
+ }
+
+ private boolean classImplementsAll(Class testClass,Set interfaces){
+ if (testClass == null) return false; // end of tree
+ Class[] implementedInterfaces = testClass.getInterfaces();
+ for(int i=0;i<implementedInterfaces.length;i++){
+ if (interfaces.contains(implementedInterfaces[i])) {
+ interfaces.remove(implementedInterfaces[i]);
+ if (interfaces.size() == 0) { // found them all
+ return true;
+ }
+ }
+ }
+ for(int i=0;i<implementedInterfaces.length;i++){
+ if (classImplementsAll(implementedInterfaces[i],interfaces)){
+ return true;
+ }
+ }
+ return classImplementsAll(testClass.getSuperclass(),interfaces);
+ }
+
+ /** This method returns a sub-list of all the found Plugin
+ * classes that extend the passed in Class
+ * (either directly or through inheritance.)
+ * @param superclass The class to match.
+ * @return The list of plugin classes that extend the passed
+ * in class.
+ */
+ public Class[] getExtends(Class superclass){
+ List matchList = new ArrayList(pluginList.size());
+ for(Iterator i = pluginList.iterator();i.hasNext();){
+ Class pluginClass = (Class)i.next();
+ if (classExtends(pluginClass,superclass)){
+ matchList.add(pluginClass);
+ }
+ }
+ Class[] pluginArray = new Class[matchList.size()];
+ return (Class[])matchList.toArray(pluginArray);
+ }
+
+ private boolean classExtends(Class testClass,Class superclass){
+ if (testClass == null) { // end of hirearchy
+ return false;
+ }
+ if (testClass == superclass) {
+ return true;
+ }
+ return classExtends(testClass.getSuperclass(),superclass);
+ }
+}