Author: tchemit Date: 2011-02-18 11:10:44 +0100 (Fri, 18 Feb 2011) New Revision: 2223 Url: http://nuiton.org/repositories/revision/jaxx/2223 Log: Anomalie #1346: Java file parsing is done twice Evolution #1347: Improve classDescriptor loading (try also to obtain constructors if possible) Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/java/JavaFile.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptor.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorHelper.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorResolver.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/resolvers/ClassDescriptorResolverFromJavaClass.java trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/resolvers/ClassDescriptorResolverFromJaxxFile.java trunk/jaxx-compiler/src/test/java/jaxx/compiler/reflect/ClassDescriptorTest.java trunk/jaxx-compiler/src/test/java/jaxx/compiler/reflect/MyClass.java Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/java/JavaFile.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/java/JavaFile.java 2011-02-18 10:09:07 UTC (rev 2222) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/java/JavaFile.java 2011-02-18 10:10:44 UTC (rev 2223) @@ -62,6 +62,8 @@ private List<JavaMethod> methods = new ArrayList<JavaMethod>(); + private List<JavaMethod> constructors = new ArrayList<JavaMethod>(); + private List<JavaFile> innerClasses = new ArrayList<JavaFile>(); private String superClass; @@ -284,8 +286,15 @@ } + if (returnType == null) { - methods.add(method); + // this is a constructor + constructors.add(method); + } else { + + // this is a mreal method + methods.add(method); + } } public void addField(JavaField field) { @@ -385,7 +394,7 @@ if (field.hasInitializerTypes()) { String code = simplifyCode(field.getInitializer(), field.getInitializerTypes()); if (log.isDebugEnabled()) { - log.debug("Use simplify text : "+code); + log.debug("Use simplify text : " + code); } field.setInitializer(code); } @@ -455,4 +464,7 @@ } } + public List<JavaMethod> getConstructors() { + return constructors; + } } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptor.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptor.java 2011-02-18 10:09:07 UTC (rev 2222) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptor.java 2011-02-18 10:10:44 UTC (rev 2223) @@ -55,12 +55,16 @@ private ClassLoader classLoader; + private MethodDescriptor[] constructorDescriptors; + private MethodDescriptor[] methodDescriptors; private FieldDescriptor[] fieldDescriptors; protected FieldDescriptor[] declaredFieldDescriptors; + protected final ClassDescriptorHelper.ResolverType resolverType; + public abstract MethodDescriptor getDeclaredMethodDescriptor( String name, ClassDescriptor... parameterTypes) throws NoSuchMethodException; @@ -68,7 +72,8 @@ public abstract FieldDescriptor getDeclaredFieldDescriptor( String name) throws NoSuchFieldException; - protected ClassDescriptor(String name, + protected ClassDescriptor(ClassDescriptorHelper.ResolverType resolverType, + String name, String packageName, String superclass, String[] interfaces, @@ -77,10 +82,11 @@ String componentType, JAXXObjectDescriptor jaxxObjectDescriptor, ClassLoader classLoader, + MethodDescriptor[] constructorDescriptors, MethodDescriptor[] methodDescriptors, FieldDescriptor[] fieldDescriptors) { this( - name, + resolverType, name, packageName, superclass, interfaces, @@ -89,6 +95,7 @@ componentType, jaxxObjectDescriptor, classLoader, + constructorDescriptors, methodDescriptors, fieldDescriptors, null @@ -96,6 +103,7 @@ } protected ClassDescriptor( + ClassDescriptorHelper.ResolverType resolverType, String name, String packageName, String superclass, @@ -105,9 +113,11 @@ String componentType, JAXXObjectDescriptor jaxxObjectDescriptor, ClassLoader classLoader, + MethodDescriptor[] constructorDescriptors, MethodDescriptor[] methodDescriptors, FieldDescriptor[] fieldDescriptors, FieldDescriptor[] declaredFieldDescriptors) { + this.resolverType = resolverType; this.name = name; this.packageName = packageName; this.superclass = superclass; @@ -117,11 +127,17 @@ this.componentType = componentType; this.jaxxObjectDescriptor = jaxxObjectDescriptor; this.classLoader = classLoader; + this.constructorDescriptors= constructorDescriptors; this.methodDescriptors = methodDescriptors; this.fieldDescriptors = fieldDescriptors; this.declaredFieldDescriptors = declaredFieldDescriptors; } + + public ClassDescriptorHelper.ResolverType getResolverType() { + return resolverType; + } + public String getName() { return name; } @@ -164,6 +180,10 @@ return classLoader; } + public MethodDescriptor[] getConstructorDescriptors() { + return constructorDescriptors; + } + public MethodDescriptor[] getMethodDescriptors() { return methodDescriptors; } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorHelper.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorHelper.java 2011-02-18 10:09:07 UTC (rev 2222) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorHelper.java 2011-02-18 10:10:44 UTC (rev 2223) @@ -38,13 +38,14 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; -import java.util.TreeMap; /** * Mirrors the class <code>java.lang.ClassLoader</code>. JAXX uses <code>ClassDescriptor</code> instead of <code>Class</code> @@ -62,19 +63,33 @@ /** Logger */ private static final Log log = LogFactory.getLog(ClassDescriptorHelper.class); + /** + * Constants to define who load a {@link ClassDescriptor}. + * <p/> + * This will be usefull in some case (for consturctor for example when some + * descriptors are not fully loaded... + * + * @since 2.4 + */ + public enum ResolverType { + JAVA_CLASS, + JAVA_FILE, + JAXX_FILE + } + private static boolean SHOW_LOADING = log.isDebugEnabled(); private static Map<String, ClassDescriptor> descriptors = new HashMap<String, ClassDescriptor>(); - private static Map<String, ClassDescriptorResolver> descriptorResolvers; + private static Map<ResolverType, ClassDescriptorResolver> descriptorResolvers; - protected static Map<String, ClassDescriptorResolver> getDescriptorResolvers() { + protected static Map<ResolverType, ClassDescriptorResolver> getDescriptorResolvers() { if (descriptorResolvers == null) { - descriptorResolvers = new TreeMap<String, ClassDescriptorResolver>(); - descriptorResolvers.put(ClassDescriptorResolverFromJaxxFile.class.getSimpleName(), new ClassDescriptorResolverFromJaxxFile()); - descriptorResolvers.put(ClassDescriptorResolverFromJavaFile.class.getSimpleName(), new ClassDescriptorResolverFromJavaFile()); - descriptorResolvers.put(ClassDescriptorResolverFromJavaClass.class.getSimpleName(), new ClassDescriptorResolverFromJavaClass()); + descriptorResolvers = new EnumMap<ResolverType, ClassDescriptorResolver>(ResolverType.class); + descriptorResolvers.put(ResolverType.JAVA_CLASS, new ClassDescriptorResolverFromJavaClass()); + descriptorResolvers.put(ResolverType.JAVA_FILE, new ClassDescriptorResolverFromJavaFile()); + descriptorResolvers.put(ResolverType.JAXX_FILE, new ClassDescriptorResolverFromJaxxFile()); } return descriptorResolvers; } @@ -151,7 +166,7 @@ log.info("from JAXXFile " + file.getJaxxFile()); } result = getClassDescriptor0( - ClassDescriptorResolverFromJaxxFile.class, + ResolverType.JAXX_FILE, className, file.getJAXXFileURL(), classLoader @@ -201,7 +216,7 @@ } result = getClassDescriptor0( - ClassDescriptorResolverFromJavaFile.class, + ResolverType.JAVA_FILE, className, javaFile, classLoader @@ -220,7 +235,7 @@ } result = getClassDescriptor0( - ClassDescriptorResolverFromJavaClass.class, + ResolverType.JAVA_CLASS, className, classFile, classLoader @@ -241,21 +256,20 @@ } protected static ClassDescriptor getClassDescriptor0( - Class<? extends ClassDescriptorResolver> resolverType, + ResolverType resolverType, String className, URL source, ClassLoader classLoader) throws ClassNotFoundException { if (log.isDebugEnabled()) { log.debug("Loading class descriptor for [" + className + - "] with " + resolverType.getSimpleName()); + "] with " + resolverType); } - Map<String, ClassDescriptorResolver> resolvers = + Map<ResolverType, ClassDescriptorResolver> resolvers = getDescriptorResolvers(); - ClassDescriptorResolver resolver = - resolvers.get(resolverType.getSimpleName()); + ClassDescriptorResolver resolver = resolvers.get(resolverType); resolver.setClassLoader(classLoader); @@ -475,6 +489,24 @@ ); } + public static MethodDescriptor createMethodDescriptor(Constructor<?> javaMethod, + ClassLoader classLoader) { + String methodName = javaMethod.getName(); + int modifiers = javaMethod.getModifiers(); + String returnType = null; + Class<?>[] javaParameters = javaMethod.getParameterTypes(); + String[] parameters = new String[javaParameters.length]; + for (int i = 0; i < parameters.length; i++) { + parameters[i] = javaParameters[i].getName(); + } + return new MethodDescriptor(methodName, + modifiers, + returnType, + parameters, + classLoader + ); + } + public static FieldDescriptor createFieldDescriptor(Field javaField, ClassLoader classLoader) { String fieldName = javaField.getName(); Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorResolver.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorResolver.java 2011-02-18 10:09:07 UTC (rev 2222) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/ClassDescriptorResolver.java 2011-02-18 10:10:44 UTC (rev 2223) @@ -29,7 +29,7 @@ /** * Contract of a resolver of class descriptor. * <p/> - * The unique method {@link #resolvDescriptor(String,URL)} will returns the + * The unique method {@link #resolvDescriptor(String, URL)} will returns the * descriptor if can be found. * * @author tchemit <chemit@codelutin.com> @@ -39,6 +39,16 @@ private ClassLoader classLoader; + private ClassDescriptorHelper.ResolverType resolverType; + + protected ClassDescriptorResolver(ClassDescriptorHelper.ResolverType resolverType) { + this.resolverType = resolverType; + } + + public ClassDescriptorHelper.ResolverType getResolverType() { + return resolverType; + } + public ClassLoader getClassLoader() { return classLoader; } Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/resolvers/ClassDescriptorResolverFromJavaClass.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/resolvers/ClassDescriptorResolverFromJavaClass.java 2011-02-18 10:09:07 UTC (rev 2222) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/resolvers/ClassDescriptorResolverFromJavaClass.java 2011-02-18 10:10:44 UTC (rev 2223) @@ -33,6 +33,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URL; @@ -49,6 +50,10 @@ private static final Log log = LogFactory.getLog(ClassDescriptorResolverFromJavaClass.class); + public ClassDescriptorResolverFromJavaClass() { + super(ClassDescriptorHelper.ResolverType.JAVA_CLASS); + } + @Override public ClassDescriptor resolvDescriptor(String className, URL source) throws ClassNotFoundException { @@ -74,6 +79,14 @@ boolean isArray = javaClass.isArray(); String componentTypeName = isArray ? javaClass.getComponentType().getName() : null; ClassLoader classLoader = javaClass.getClassLoader(); + Constructor<?>[] javaConstructors = javaClass.getConstructors(); + MethodDescriptor[] constructors = new MethodDescriptor[javaConstructors.length]; + for (int i = 0; i < constructors.length; i++) { + constructors[i] = ClassDescriptorHelper.createMethodDescriptor( + javaConstructors[i], + javaClass.getClassLoader() + ); + } Method[] javaMethods = javaClass.getMethods(); MethodDescriptor[] methods = new MethodDescriptor[javaMethods.length]; for (int i = 0; i < methods.length; i++) { @@ -106,13 +119,14 @@ componentTypeName, jaxxObjectDescriptor, classLoader, + constructors, methods, fields ); } - private static class JavaClassClassDescriptor extends ClassDescriptor { + private class JavaClassClassDescriptor extends ClassDescriptor { private final Class<?> javaClass; @@ -127,9 +141,11 @@ String componentTypeName, JAXXObjectDescriptor jaxxObjectDescriptor, ClassLoader classLoader, + MethodDescriptor[] constructors, MethodDescriptor[] methods, FieldDescriptor[] fields) { super( + ClassDescriptorResolverFromJavaClass.this.getResolverType(), name, packageName, superclassName, @@ -139,6 +155,7 @@ componentTypeName, jaxxObjectDescriptor, classLoader, + constructors, methods, fields ); Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/resolvers/ClassDescriptorResolverFromJaxxFile.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/resolvers/ClassDescriptorResolverFromJaxxFile.java 2011-02-18 10:09:07 UTC (rev 2222) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/reflect/resolvers/ClassDescriptorResolverFromJaxxFile.java 2011-02-18 10:10:44 UTC (rev 2223) @@ -41,6 +41,7 @@ import java.lang.reflect.Modifier; import java.net.URL; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; @@ -59,6 +60,10 @@ private static final Log log = LogFactory.getLog(ClassDescriptorResolverFromJaxxFile.class); + public ClassDescriptorResolverFromJaxxFile() { + super(ClassDescriptorHelper.ResolverType.JAXX_FILE); + } + @Override public ClassDescriptor resolvDescriptor(String className, URL source) throws ClassNotFoundException { @@ -67,7 +72,7 @@ JAXXCompiler compiler = engine.getJAXXCompiler(className); SymbolTable symbolTable = compiler.getSymbolTable(); - + if (symbolTable == null) { throw new CompilerException("Internal error: no symbol table was generated for class '" + className + "'"); } @@ -78,7 +83,16 @@ ClassLoader classLoader = getClassLoader(); - ClassDescriptor superclass = ClassDescriptorHelper.getClassDescriptor(symbolTable.getSuperclassName(), classLoader); + ClassDescriptor superclass = + ClassDescriptorHelper.getClassDescriptor( + symbolTable.getSuperclassName(), classLoader); + // tchemit 2011-02-18 Be ware!!! + // this is nearly impossible to obtain consturctors from symbol table. + // let says for the moment this data is not available here and must be found in other places... + // Anyway, the only reason of finding constructor is when we want to generate a jaxx file + // If it inheritate from another jaxx file, we will mkae sure order is ok for this... + + List<MethodDescriptor> constructors = new ArrayList<MethodDescriptor>(); List<MethodDescriptor> publicMethods = symbolTable.getScriptMethods(); List<FieldDescriptor> publicFields = symbolTable.getScriptFields(); //List<MethodDescriptor> declaredMethods = new ArrayList<MethodDescriptor>(publicMethods); @@ -131,23 +145,26 @@ packageName, interfaces, classLoader, + constructors.toArray(new MethodDescriptor[constructors.size()]), publicMethods.toArray(new MethodDescriptor[publicMethods.size()]), publicFields.toArray(new FieldDescriptor[publicFields.size()]) ); } - private static class JaxxFileClassDescriptor extends ClassDescriptor { + private class JaxxFileClassDescriptor extends ClassDescriptor { private final JAXXCompiler compiler; public JaxxFileClassDescriptor(JAXXCompiler compiler, - String className, - String packageName, - Set<String> interfaces, - ClassLoader classLoader, - MethodDescriptor[] publicMethods, - FieldDescriptor[] publicFields) { - super(className, + String className, + String packageName, + Set<String> interfaces, + ClassLoader classLoader, + MethodDescriptor[] constructors, + MethodDescriptor[] publicMethods, + FieldDescriptor[] publicFields) { + super(ClassDescriptorResolverFromJaxxFile.this.getResolverType(), + className, packageName, compiler.getSymbolTable().getSuperclassName(), interfaces.toArray(new String[interfaces.size()]), @@ -156,6 +173,7 @@ null, null, classLoader, + constructors, publicMethods, publicFields ); Modified: trunk/jaxx-compiler/src/test/java/jaxx/compiler/reflect/ClassDescriptorTest.java =================================================================== --- trunk/jaxx-compiler/src/test/java/jaxx/compiler/reflect/ClassDescriptorTest.java 2011-02-18 10:09:07 UTC (rev 2222) +++ trunk/jaxx-compiler/src/test/java/jaxx/compiler/reflect/ClassDescriptorTest.java 2011-02-18 10:10:44 UTC (rev 2223) @@ -25,12 +25,30 @@ package jaxx.compiler.reflect; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import org.junit.Test; public class ClassDescriptorTest { + @BeforeClass + public static void before() { + ClassDescriptorHelper.setShowLoading(true); + } + + @AfterClass + public static void after() { + ClassDescriptorHelper.setShowLoading(true); + } + /*@Test public void testGetClassDescriptor() throws Exception { ClassDescriptorHelper.getClassDescriptor("jaxx.runtime.swing.navigation.tree.NavigationTreeModel.NavigationTreeNode"); @@ -65,13 +83,7 @@ @Test(expected = ClassNotFoundException.class) public void testWrongCase() throws ClassNotFoundException { - //try { - //ClassDescriptor object = ClassDescriptorHelper.getClassDescriptor("jaxx.junit.classdescriptortest", getClass().getClassLoader()); - // fail("Found descriptor using wrong case: " + object); - //} - //catch (ClassNotFoundException e) { - //} } @Test @@ -81,4 +93,57 @@ ClassDescriptor objectArray = ClassDescriptorHelper.getClassDescriptor(Object[].class); assertNotNull(objectArray); } + + @Test + public void testConstructorFromClass() throws ClassNotFoundException, MalformedURLException { + String className = MyClass.class.getName(); + ClassDescriptor descriptor = ClassDescriptorHelper.getClassDescriptor(className); + ClassLoader classLoader = getClass().getClassLoader(); + assertNotNull(descriptor); + assertEquals(ClassDescriptorHelper.ResolverType.JAVA_CLASS, descriptor.getResolverType()); + MethodDescriptor[] constructorDescriptors = descriptor.getConstructorDescriptors(); + assertNotNull(constructorDescriptors); + assertEquals(2, constructorDescriptors.length); + } + + @Test + public void testConstructorFromJavaFile() throws ClassNotFoundException, MalformedURLException { + String className = MyClass.class.getName(); + ClassLoader classLoader = getClass().getClassLoader(); + + + File testSourceDir = new File(getBasedir(), "src" + File.separator + "test" + File.separator + "java"); + + ClassLoader myClassLoader = new URLClassLoader(new URL[]{testSourceDir.toURI().toURL()}, classLoader); + + URL javaFileUrl = ClassDescriptorHelper.getURL(myClassLoader, className, "java"); + assertNotNull(javaFileUrl); + + ClassDescriptor descriptorFromFile = ClassDescriptorHelper.getClassDescriptor0( + ClassDescriptorHelper.ResolverType.JAVA_FILE, + className, + javaFileUrl, + myClassLoader + ); + assertNotNull(descriptorFromFile); + MethodDescriptor[] constructorDescriptorsfromFile = descriptorFromFile.getConstructorDescriptors(); + assertNotNull(constructorDescriptorsfromFile); + assertEquals(2, constructorDescriptorsfromFile.length); + } + + + static File basedir; + + public static File getBasedir() { + if (basedir == null) { + String tmp = System.getProperty("basedir"); + if (tmp == null) { + tmp = new File("").getAbsolutePath(); + } + basedir = new File(tmp); + + } + return basedir; + } + } Modified: trunk/jaxx-compiler/src/test/java/jaxx/compiler/reflect/MyClass.java =================================================================== --- trunk/jaxx-compiler/src/test/java/jaxx/compiler/reflect/MyClass.java 2011-02-18 10:09:07 UTC (rev 2222) +++ trunk/jaxx-compiler/src/test/java/jaxx/compiler/reflect/MyClass.java 2011-02-18 10:10:44 UTC (rev 2223) @@ -42,6 +42,14 @@ public String myPublicStringField; + public MyClass() { + } + + public MyClass(String myProtectedStringField, String myPublicStringField) { + this.myProtectedStringField = myProtectedStringField; + this.myPublicStringField = myPublicStringField; + } + @Override public void myMethod() { }
participants (1)
-
tchemit@users.nuiton.org