ReflectiveEnvironmnt#isPackage() now consult a list of classes loaded by given ClassLoader.
authorJan Vrany <jan.vrany@fit.cvut.cz>
Sun, 20 Jul 2014 21:46:44 +0100
changeset 3171 fb5aefff7ae5
parent 3170 770c76797564
child 3172 fb47f223848a
child 3190 603fdba602c4
ReflectiveEnvironmnt#isPackage() now consult a list of classes loaded by given ClassLoader. This is not only faster than searcing the filesystem, but also works with classes that have been generated and loaded on the fly (such as those 'accepted' in a browser)
tools/java/src/stx/libjava/tools/environment/ReflectiveEnvironment.java
--- a/tools/java/src/stx/libjava/tools/environment/ReflectiveEnvironment.java	Sun Jul 20 02:41:14 2014 +0100
+++ b/tools/java/src/stx/libjava/tools/environment/ReflectiveEnvironment.java	Sun Jul 20 21:46:44 2014 +0100
@@ -26,6 +26,7 @@
 public class ReflectiveEnvironment implements INameEnvironment {
 	
 	private static final boolean DEBUG_isPackage = false;
+	private static Field FIELD_ClassLoader_Classes;
 	
 	/** 
 	 * A java.lang.ClassLoader where to search for classes & packages
@@ -39,6 +40,16 @@
 	
 	public TypeRegistry types;
 	
+	static {
+		try {
+			FIELD_ClassLoader_Classes = ClassLoader.class.getDeclaredField("classes");
+			FIELD_ClassLoader_Classes.setAccessible(true);
+		} catch (NoSuchFieldException e) {
+			FIELD_ClassLoader_Classes = null;
+		} catch (SecurityException e) {
+			FIELD_ClassLoader_Classes = null;
+		}
+	}
 			
 	public ReflectiveEnvironment() {
 		 this(new TypeRegistry(), ClassLoader.getSystemClassLoader() );
@@ -174,10 +185,32 @@
 	 * The default package is always assumed to exist.
 	 *
 	 */
+	@SuppressWarnings("unchecked")
 	public boolean isPackage(String packageName, ClassLoader loader) {
 		if (loader == null) {
 			return isPackage(packageName, sun.misc.Launcher.getBootstrapClassPath().getURLs());
 		}
+		if (FIELD_ClassLoader_Classes != null) {
+			int packageNameLen = packageName.length();
+			Vector<Class<?>> classes;
+			try {
+				classes = (Vector<Class<?>>)FIELD_ClassLoader_Classes.get(loader);
+				Iterator<Class<?>> i = classes.iterator();
+				while (i.hasNext()) {					 
+					String className = i.next().getName();
+					int classNameLen = className.length();					
+					if ((classNameLen > packageNameLen) &&
+						(className.charAt(packageNameLen) == '.') &&
+						(className.startsWith(packageName))) {
+						return true;
+					}
+				}				
+			} catch (IllegalArgumentException e) {
+			} catch (IllegalAccessException e) {
+			}
+		}
+			
+		
 		if (loader instanceof URLClassLoader) {
 			if (isPackage(packageName, ((URLClassLoader)loader).getURLs())) {
 				return true;