Finds all subclasses of a given class or interface. It will only search within the loaded packages and not the entire classpath. @param parentClass the class for which subclasses are sought @return a list of Class objects.
(Class<?> parentClass)
| 74 | * @return a list of {@link Class} objects. |
| 75 | */ |
| 76 | static public List<Class<?>> findSubclasses(Class<?> parentClass){ |
| 77 | Package[] packages = Package.getPackages(); |
| 78 | List<Class<?>> result = new ArrayList<Class<?>>(); |
| 79 | for(int i = 0; i < packages.length; i++){ |
| 80 | String packageDir = packages[i].getName(); |
| 81 | //look in the file system |
| 82 | if(!packageDir.startsWith("/")) packageDir = "/" + packageDir; |
| 83 | packageDir = packageDir.replace('.', Strings.getPathSep().charAt(0)); |
| 84 | URL packageURL = Gate.getClassLoader().getResource(packageDir); |
| 85 | if(packageURL != null){ |
| 86 | File directory = Files.fileFromURL(packageURL); |
| 87 | if(directory.exists()){ |
| 88 | String [] files = directory.list(); |
| 89 | for (int j=0; j < files.length; j++){ |
| 90 | // we are only interested in .class files |
| 91 | if(files[j].endsWith(".class")){ |
| 92 | // removes the .class extension |
| 93 | String classname = files[j].substring(0, files[j].length() - 6); |
| 94 | try { |
| 95 | // Try to create an instance of the object |
| 96 | Class<?> aClass = Class.forName(packages[i] + "." + classname, |
| 97 | true, Gate.getClassLoader()); |
| 98 | if(parentClass.isAssignableFrom(aClass)) result.add(aClass); |
| 99 | }catch(ClassNotFoundException cnfex){} |
| 100 | } |
| 101 | } |
| 102 | }else{ |
| 103 | //look in jar files |
| 104 | try{ |
| 105 | JarURLConnection conn = (JarURLConnection)packageURL.openConnection(); |
| 106 | String starts = conn.getEntryName(); |
| 107 | JarFile jFile = conn.getJarFile(); |
| 108 | Enumeration<JarEntry> e = jFile.entries(); |
| 109 | while (e.hasMoreElements()){ |
| 110 | String entryname = e.nextElement().getName(); |
| 111 | if (entryname.startsWith(starts) && |
| 112 | //not sub dir |
| 113 | (entryname.lastIndexOf('/')<=starts.length()) && |
| 114 | entryname.endsWith(".class")){ |
| 115 | String classname = entryname.substring(0, entryname.length() - 6); |
| 116 | if (classname.startsWith("/")) classname = classname.substring(1); |
| 117 | classname = classname.replace('/','.'); |
| 118 | try { |
| 119 | // Try to create an instance of the object |
| 120 | Class<?> aClass = Class.forName(packages[i] + "." + classname, |
| 121 | true, Gate.getClassLoader()); |
| 122 | if(parentClass.isAssignableFrom(aClass)) result.add(aClass); |
| 123 | }catch(ClassNotFoundException cnfex){} |
| 124 | } |
| 125 | } |
| 126 | }catch(java.io.IOException ioe){} |
| 127 | } |
| 128 | } |
| 129 | } |
| 130 | return result; |
| 131 | } |
| 132 | |
| 133 | /** |
nothing calls this directly
no test coverage detected