Changeset 743
- Timestamp:
- 01/23/14 12:22:39 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/reflection/PackageLoader.java
r570 r743 6 6 import java.net.URI; 7 7 import java.net.URL; 8 import java.net.URL Decoder;8 import java.net.URLConnection; 9 9 import java.util.ArrayList; 10 import java.util.Arrays;11 10 import java.util.Enumeration; 12 11 import java.util.LinkedList; … … 16 15 import java.util.zip.ZipEntry; 17 16 17 18 18 public class PackageLoader { 19 19 20 // The following is adapted from: 21 // http://stackoverflow.com/questions/1456930/how-do-i-read-all-classes-from-a-java-package-in-the-classpath 22 23 public static List<Class<?>> getClassesNew(String packageName) throws ClassNotFoundException { 24 25 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 26 27 ArrayList<String> names = new ArrayList<String>(); 28 ; 29 final ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); 30 31 String realPackageName = packageName; 32 packageName = packageName.replace(".", "/"); 33 URL packageURL = classLoader.getResource(packageName); 34 35 if (packageURL.getProtocol().equals("jar")) { 36 37 // build jar file name, then loop through zipped entries 38 39 String jarFileNameUndecoded = packageURL.getFile(); 40 20 // The following is adapted from: 21 // http://stackoverflow.com/questions/1456930/how-do-i-read-all-classes-from-a-java-package-in-the-classpath 22 23 public static List<Class<?>> getClassesNew(String packageName) 24 throws ClassNotFoundException { 25 26 ClassLoader classLoader = Thread.currentThread() 27 .getContextClassLoader(); 28 29 ArrayList<String> names = new ArrayList<String>(); 30 ; 31 final ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); 32 33 String realPackageName = packageName; 34 packageName = packageName.replace(".", "/"); 35 URL packageURL = classLoader.getResource(packageName); 36 37 if (packageURL.getProtocol().equals("jar")) { 38 39 // build jar file name, then loop through zipped entries 40 41 String jarFileNameUndecoded = packageURL.getFile(); 42 43 try { 44 JarURLConnection ju_connection = (JarURLConnection) packageURL 45 .openConnection(); 46 JarFile jf = ju_connection.getJarFile(); 47 48 Enumeration<JarEntry> jarEntries = jf.entries(); 49 while (jarEntries.hasMoreElements()) { 50 String entryName = jarEntries.nextElement().getName(); 51 52 if (entryName.startsWith(packageName)) { 53 54 if (entryName.endsWith(".class") 55 && !entryName.contains("$")) { 56 57 // Deal with situation where the class found might 58 // be a further sub-package 59 // e.g. for "org.expeditee.action" 60 // there is: 61 // org/expeditee/action/widgets/Chart.class 62 // which would produce a value of 'entryName' as 63 // widgets/Chart.class 64 65 entryName = entryName.substring(0, 66 entryName.length() - 6); // 6 = '.class' 67 entryName = entryName.replace('/', '.'); 68 69 names.add(entryName); 70 classes.add(Class.forName(entryName)); 71 } 72 } 73 } 74 } catch (Exception e) { 75 System.err.println("Failed to decode jar file: " 76 + jarFileNameUndecoded); 77 e.printStackTrace(); 78 } 79 } else if (packageURL.getProtocol().equals("bundleresource")) { 80 try { 81 final URLConnection urlConnection = packageURL.openConnection(); 82 final Class<?> c = urlConnection.getClass(); 83 final java.lang.reflect.Method toInvoke = c.getMethod("getFileURL"); 84 final URL fileURL = (URL)toInvoke.invoke(urlConnection); 85 final File folder = new File(fileURL.getFile()); 86 final List<String> files = findFiles(folder); 87 for (final String s : files) { 88 String entryName = realPackageName + s; 89 if (entryName.endsWith(".class") && !entryName.contains("$")) { 90 entryName = entryName.substring(0, entryName.lastIndexOf('.')); 91 entryName = entryName.replace('/', '.'); 92 names.add(entryName); 41 93 try { 42 String jarFileName = URLDecoder.decode(jarFileNameUndecoded, "UTF-8"); 43 44 JarURLConnection ju_connection = (JarURLConnection) packageURL.openConnection(); 45 JarFile jf = ju_connection.getJarFile(); 46 47 Enumeration<JarEntry> jarEntries = jf.entries(); 48 while (jarEntries.hasMoreElements()) { 49 String entryName = jarEntries.nextElement().getName(); 50 51 if (entryName.startsWith(packageName)) { 52 53 if (entryName.endsWith(".class") && !entryName.contains("$")) { 54 55 // Deal with situation where the class found might be a further sub-package 56 // e.g. for "org.expeditee.action" 57 // there is: org/expeditee/action/widgets/Chart.class 58 // which would produce a value of 'entryName' as widgets/Chart.class 59 60 entryName = entryName.substring(0, entryName.length() - 6); // 6 = '.class' 61 entryName = entryName.replace('/', '.'); 62 63 names.add(entryName); 64 classes.add(Class.forName(entryName)); 65 } 66 } 67 } 68 } catch (Exception e) { 69 System.err.println("Failed to decode jar file: " + jarFileNameUndecoded); 70 e.printStackTrace(); 94 final Class<?> tmpc = Class.forName(entryName); 95 classes.add(tmpc); 96 } catch (NoClassDefFoundError e) { 97 System.err.println("Unable to instantiate class " + entryName); 98 System.err.println(e.getMessage()); 71 99 } 72 } else { 73 // loop through files in classpath 74 75 String packageURLString = packageURL.toString(); 76 try { 77 URI uri = new URI(packageURLString); 78 File folder = new File(uri.getPath()); 79 80 List<String> files = findFiles(folder); 81 for(String s : files) { 82 String entryName = realPackageName + s; 83 84 if (entryName.endsWith(".class") && !entryName.contains("$")) { 85 entryName = entryName.substring(0, entryName.lastIndexOf('.')); 86 entryName = entryName.replace('/', '.'); 87 88 names.add(entryName); 89 classes.add(Class.forName(entryName)); 90 } 91 } 92 } catch (Exception e) { 93 System.err.println("Failed to process file: " + packageURLString); 94 e.printStackTrace(); 100 } 101 } 102 } catch (final Exception e) { 103 System.err.println("Failed to process file: " + packageName); 104 e.printStackTrace(); 105 } 106 } else { 107 // loop through files in classpath 108 109 String packageURLString = packageURL.toString(); 110 try { 111 URI uri = new URI(packageURLString); 112 File folder = new File(uri.getPath()); 113 114 List<String> files = findFiles(folder); 115 for (String s : files) { 116 String entryName = realPackageName + s; 117 118 if (entryName.endsWith(".class") 119 && !entryName.contains("$")) { 120 entryName = entryName.substring(0, 121 entryName.lastIndexOf('.')); 122 entryName = entryName.replace('/', '.'); 123 124 names.add(entryName); 125 classes.add(Class.forName(entryName)); 126 } 127 } 128 } catch (Exception e) { 129 System.err.println("Failed to process file: " 130 + packageURLString); 131 e.printStackTrace(); 132 } 133 } 134 135 return classes; 136 } 137 138 /** 139 * Finds all files in a directory and it's subdirectories 140 * 141 * @param directory 142 * The folder to start in 143 * 144 * @return A list of Strings containing file paths relative to the starting 145 * directory 146 */ 147 private static List<String> findFiles(File directory) { 148 List<String> files = new LinkedList<String>(); 149 for (File f : directory.listFiles()) { 150 if (f.isDirectory()) { 151 for (String s : findFiles(f)) { 152 files.add(f.getName() + "/" + s); 153 } 154 } else { 155 files.add(f.getName()); 156 } 157 } 158 return files; 159 } 160 161 public static List<Class<?>> getClasses(final String pckgname) 162 throws ClassNotFoundException { 163 164 final ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); 165 166 // Must be a forward slash for loading resources 167 final String packagePath = pckgname.replace('.', '/'); 168 169 if (System.getProperty("eclipse.expeditee.home") == null) { 170 final ClassLoader cld = Thread.currentThread() 171 .getContextClassLoader(); 172 if (cld == null) { 173 throw new ClassNotFoundException("Can't get class loader."); 174 } 175 URL resource = null; 176 try { 177 final Enumeration<URL> resources = cld 178 .getResources(packagePath); 179 while (resources.hasMoreElements()) { 180 URL url = resources.nextElement(); 181 resource = url; 182 } 183 } catch (IOException e) { 184 System.err 185 .println("A IO Error has occured when trying to use the ContextClassLoader" 186 + System.getProperty("line.separator") 187 + "Are you running from within Eclipse? (or just not with Jar) Then make sure your" 188 + " 'eclipse.expeditee.home' property is set correctly. It is currently: '" 189 + System.getProperty("eclipse.expeditee.home") 190 + "'" 191 + System.getProperty("line.separator") 192 + "You can set it by adding a VM argument. " 193 + "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn"); 194 e.printStackTrace(); 195 } 196 if (resource == null) { 197 throw new ClassNotFoundException("No resource for " 198 + packagePath); 199 } 200 final File directory = new File(resource.getFile()); 201 202 final int splitPoint = directory.getPath().indexOf('!'); 203 if (splitPoint > 0) { 204 String jarName = directory.getPath().substring( 205 "file:".length(), splitPoint); 206 // Windows HACK 207 if (jarName.indexOf(":") >= 0) 208 jarName = jarName.substring(1); 209 210 if (jarName.indexOf("%20") > 0) { 211 jarName = jarName.replace("%20", " "); 212 } 213 // System.out.println("JarName:" + jarName); 214 try { 215 final JarFile jarFile = new JarFile(jarName); 216 final Enumeration<?> entries = jarFile.entries(); 217 while (entries.hasMoreElements()) { 218 final ZipEntry entry = (ZipEntry) entries.nextElement(); 219 final String className = entry.getName(); 220 if (className.startsWith(packagePath)) { 221 if (className.endsWith(".class") 222 && !className.contains("$")) { 223 // The forward slash below is a forwards slash 224 // for 225 // both windows and linux 226 227 String class_forname = className.substring(0, 228 className.length() - 6); 229 class_forname = class_forname.replace('/', '.'); 230 231 classes.add(Class.forName(class_forname)); 232 } 95 233 } 96 } 97 98 return classes; 234 } 235 try { 236 jarFile.close(); 237 } catch (IOException e) { 238 System.err 239 .println("Error attempting to close Jar file"); 240 e.printStackTrace(); 241 } 242 } catch (IOException e) { 243 System.err.println("Error Instantiating Jar File Object"); 244 e.printStackTrace(); 245 } 246 } else { 247 248 System.err 249 .println("A Error has occured when trying to use a Jar file to find actions or agents." 250 + System.getProperty("line.separator") 251 + "Are you running from within Eclipse? (or just not with Jar) Then make sure your" 252 + " 'eclipse.expeditee.home' property is set correctly. It is currently: '" 253 + System.getProperty("eclipse.expeditee.home") 254 + "'" 255 + System.getProperty("line.separator") 256 + "You can set it by adding a VM argument. " 257 + "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn"); 258 } 259 } else { 260 String eclipse_expeditee_home = System.getProperty( 261 "eclipse.expeditee.home", ""); 262 String full_package_path = eclipse_expeditee_home + File.separator 263 + "bin" + File.separator + packagePath; 264 265 final File directory = new File(full_package_path); 266 267 if (directory.exists()) { 268 // Get the list of the files contained in the package 269 String[] files = directory.list(); 270 for (int i = 0; i < files.length; i++) { 271 // we are only interested in .class files 272 if (files[i].endsWith(".class") && !files[i].contains("$") 273 && !files[i].equals("Actions.class")) { 274 // removes the .class extension 275 classes.add(Class.forName(pckgname 276 + files[i].substring(0, files[i].length() - 6))); 277 } 278 } 279 } else { 280 throw new ClassNotFoundException("The package '" + pckgname 281 + "' in the directory '" + directory 282 + "' does not appear to be a valid package"); 283 } 99 284 } 100 101 /** 102 * Finds all files in a directory and it's subdirectories 103 * 104 * @param directory The folder to start in 105 * 106 * @return A list of Strings containing file paths relative to the starting directory 107 */ 108 private static List<String> findFiles(File directory) { 109 List<String> files = new LinkedList<String>(); 110 for(File f : directory.listFiles()) { 111 if(f.isDirectory()) { 112 for(String s : findFiles(f)) { 113 files.add(f.getName() + "/" + s); 114 } 115 } else { 116 files.add(f.getName()); 117 } 118 } 119 return files; 120 } 121 122 public static List<Class<?>> getClasses(final String pckgname) throws ClassNotFoundException { 123 124 final ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); 125 126 // Must be a forward slash for loading resources 127 final String packagePath = pckgname.replace('.', '/'); 128 129 if (System.getProperty("eclipse.expeditee.home") == null) { 130 final ClassLoader cld = Thread.currentThread().getContextClassLoader(); 131 if (cld == null) { 132 throw new ClassNotFoundException("Can't get class loader."); 133 } 134 URL resource = null; 135 try { 136 final Enumeration<URL> resources = cld.getResources(packagePath); 137 while (resources.hasMoreElements()) { 138 URL url = resources.nextElement(); 139 resource = url; 140 } 141 } catch (IOException e) { 142 System.err.println("A IO Error has occured when trying to use the ContextClassLoader" 143 + System.getProperty("line.separator") 144 + "Are you running from within Eclipse? (or just not with Jar) Then make sure your" 145 + " 'eclipse.expeditee.home' property is set correctly. It is currently: '" 146 + System.getProperty("eclipse.expeditee.home") + "'" + System.getProperty("line.separator") 147 + "You can set it by adding a VM argument. " 148 + "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn"); 149 e.printStackTrace(); 150 } 151 if (resource == null) { 152 throw new ClassNotFoundException("No resource for " + packagePath); 153 } 154 final File directory = new File(resource.getFile()); 155 156 final int splitPoint = directory.getPath().indexOf('!'); 157 if (splitPoint > 0) { 158 String jarName = directory.getPath().substring("file:".length(), splitPoint); 159 // Windows HACK 160 if (jarName.indexOf(":") >= 0) 161 jarName = jarName.substring(1); 162 163 if (jarName.indexOf("%20") > 0) { 164 jarName = jarName.replace("%20", " "); 165 } 166 // System.out.println("JarName:" + jarName); 167 try { 168 final JarFile jarFile = new JarFile(jarName); 169 final Enumeration<?> entries = jarFile.entries(); 170 while (entries.hasMoreElements()) { 171 final ZipEntry entry = (ZipEntry) entries.nextElement(); 172 final String className = entry.getName(); 173 if (className.startsWith(packagePath)) { 174 if (className.endsWith(".class") && !className.contains("$")) { 175 // The forward slash below is a forwards slash for 176 // both windows and linux 177 178 String class_forname = className.substring(0, className.length() - 6); 179 class_forname = class_forname.replace('/', '.'); 180 181 classes.add(Class.forName(class_forname)); 182 } 183 } 184 } 185 try { 186 jarFile.close(); 187 } catch (IOException e) { 188 System.err.println("Error attempting to close Jar file"); 189 e.printStackTrace(); 190 } 191 } catch (IOException e) { 192 System.err.println("Error Instantiating Jar File Object"); 193 e.printStackTrace(); 194 } 195 } else { 196 197 System.err.println("A Error has occured when trying to use a Jar file to find actions or agents." 198 + System.getProperty("line.separator") 199 + "Are you running from within Eclipse? (or just not with Jar) Then make sure your" 200 + " 'eclipse.expeditee.home' property is set correctly. It is currently: '" 201 + System.getProperty("eclipse.expeditee.home") + "'" + System.getProperty("line.separator") 202 + "You can set it by adding a VM argument. " 203 + "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn"); 204 } 205 } else { 206 String eclipse_expeditee_home = System.getProperty("eclipse.expeditee.home", ""); 207 String full_package_path = eclipse_expeditee_home + File.separator + "bin" + File.separator + "src" 208 + File.separator + packagePath; 209 210 final File directory = new File(full_package_path); 211 212 if (directory.exists()) { 213 // Get the list of the files contained in the package 214 String[] files = directory.list(); 215 for (int i = 0; i < files.length; i++) { 216 // we are only interested in .class files 217 if (files[i].endsWith(".class") && !files[i].contains("$") && !files[i].equals("Actions.class")) { 218 // removes the .class extension 219 classes.add(Class.forName(pckgname + files[i].substring(0, files[i].length() - 6))); 220 } 221 } 222 } else { 223 throw new ClassNotFoundException("The package '" + pckgname + "' in the directory '" + directory 224 + "' does not appear to be a valid package"); 225 } 226 } 227 return classes; 228 } 285 return classes; 286 } 229 287 230 288 }
Note:
See TracChangeset
for help on using the changeset viewer.