[jboss-cvs] JBossAS SVN: r110313 - in projects/jboss-reflect/branches/Branch_2_0/src: main/java/org/jboss/reflect/plugins/javassist and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Jan 10 09:11:03 EST 2011


Author: alesj
Date: 2011-01-10 09:11:03 -0500 (Mon, 10 Jan 2011)
New Revision: 110313

Added:
   projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/support/Obligation.java
   projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/support/UML.java
Modified:
   projects/jboss-reflect/branches/Branch_2_0/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java
   projects/jboss-reflect/branches/Branch_2_0/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfoFactoryImpl.java
   projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/test/AnnotatedClassInfoTest.java
Log:
Port JBREFLECT-139 to 2_0.

Modified: projects/jboss-reflect/branches/Branch_2_0/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java
===================================================================
--- projects/jboss-reflect/branches/Branch_2_0/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java	2011-01-10 14:01:46 UTC (rev 110312)
+++ projects/jboss-reflect/branches/Branch_2_0/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java	2011-01-10 14:11:03 UTC (rev 110313)
@@ -32,7 +32,10 @@
 import java.lang.reflect.TypeVariable;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.jboss.reflect.plugins.AnnotationAttributeImpl;
@@ -63,11 +66,15 @@
  * An introspection type factory.
  *
  * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
+ * @author <a href="mailto:ales.justin at jboss.org">Ales Justin</a>
  */
 public class IntrospectionTypeInfoFactoryImpl extends WeakTypeCache<TypeInfo> implements TypeInfoFactory, AnnotationHelper, ClassInfoHelper
 {
    final static AnnotationValue[] NO_ANNOTATIONS = new AnnotationValue[0];
 
+   /** Tmp invocation results */
+   private static ThreadLocal<Map<Class<?>, TypeInfo>> results = new ThreadLocal<Map<Class<?>, TypeInfo>>();
+
    /**
     * Generate the type info for a class
     *
@@ -422,46 +429,91 @@
 
    protected TypeInfo instantiate(Class<?> clazz)
    {
-      ClassInfoImpl result;
-      if (clazz.isArray())
+      boolean start = false;
+      Map<Class<?>, TypeInfo> tmp = results.get();
+      if (tmp == null)
       {
-         TypeInfo componentType = getTypeInfo(clazz.getComponentType());
-         result = new ArrayInfoImpl(componentType);
+         start = true;
+         tmp = new HashMap<Class<?>, TypeInfo>();
+         results.set(tmp);
       }
-      else if (clazz.isEnum())
+
+      // if we return here, it means we're already in a loop,
+      // hence no need to cleanup
+      TypeInfo cached = tmp.get(clazz);
+      if (cached != null)
+         return cached;
+
+      try
       {
-         EnumInfoImpl enumInfoImpl = new EnumInfoImpl(clazz.getName(), clazz.getModifiers());
-         result = enumInfoImpl;
-         Field[] fields = clazz.getFields();
-         EnumConstantInfoImpl[] constants = new EnumConstantInfoImpl[fields.length];
-         int i = 0;
-         for (Field field : fields)
+         ClassInfoImpl result;
+         if (clazz.isArray())
          {
-            AnnotationValue[] annotations = getAnnotations(field);
-            constants[i++] = new EnumConstantInfoImpl(field.getName(), enumInfoImpl, annotations);
+            TypeInfo componentType = getTypeInfo(clazz.getComponentType());
+            result = new ArrayInfoImpl(componentType);
+            init(result, clazz);
          }
-         enumInfoImpl.setEnumConstants(constants);
-      }
-      else if (clazz.isAnnotation())
-      {
-         result = new AnnotationInfoImpl(clazz.getName(), clazz.getModifiers());
-         Method[] methods = getDeclaredMethods(clazz);
-         AnnotationAttributeImpl[] atttributes = new AnnotationAttributeImpl[methods.length];
-         for (int i = 0 ; i < methods.length ; i++)
+         else if (clazz.isEnum())
          {
-            atttributes[i] = new AnnotationAttributeImpl(methods[i].getName(), getTypeInfo(methods[i].getReturnType()), null);
+            EnumInfoImpl enumInfoImpl = new EnumInfoImpl(clazz.getName(), clazz.getModifiers());
+            result = enumInfoImpl;
+            init(result, clazz);
+
+            Field[] fields = clazz.getFields();
+            List<EnumConstantInfoImpl> constants = new ArrayList<EnumConstantInfoImpl>();
+            for (Field field : fields)
+            {
+               if (field.isEnumConstant())
+               {
+                  AnnotationValue[] annotations = getAnnotations(field);
+                  constants.add(new EnumConstantInfoImpl(field.getName(), enumInfoImpl, annotations));
+               }
+            }
+            enumInfoImpl.setEnumConstants(constants.toArray(new EnumConstantInfoImpl[constants.size()]));
          }
-         ((AnnotationInfoImpl)result).setAttributes(atttributes);
+         else if (clazz.isAnnotation())
+         {
+            result = new AnnotationInfoImpl(clazz.getName(), clazz.getModifiers());
+            init(result, clazz);
+
+            Method[] methods = getDeclaredMethods(clazz);
+            AnnotationAttributeImpl[] atttributes = new AnnotationAttributeImpl[methods.length];
+            for (int i = 0 ; i < methods.length ; i++)
+            {
+               atttributes[i] = new AnnotationAttributeImpl(methods[i].getName(), getTypeInfo(methods[i].getReturnType()), null);
+            }
+            ((AnnotationInfoImpl)result).setAttributes(atttributes);
+         }
+         else
+         {
+            result = new ReflectClassInfoImpl(clazz.getName());
+            init(result, clazz);
+         }
+
+         return result;
       }
-      else
+      finally
       {
-         result = new ReflectClassInfoImpl(clazz.getName());
+         if (start)
+            results.remove();
       }
+   }
+
+   /**
+    * Initialize default configuration.
+    *
+    * @param result the result
+    * @param clazz the class
+    */
+   private void init(ClassInfoImpl result, Class<?> clazz)
+   {
+      Map<Class<?>, TypeInfo> tmp = results.get();
+      tmp.put(clazz, result);
+
       result.setType(clazz);
       result.setTypeInfoFactory(this);
       result.setClassInfoHelper(this);
       result.setAnnotationHelper(this);
-      return result;
    }
 
    protected TypeInfo instantiate(ParameterizedType type)

Modified: projects/jboss-reflect/branches/Branch_2_0/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfoFactoryImpl.java
===================================================================
--- projects/jboss-reflect/branches/Branch_2_0/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfoFactoryImpl.java	2011-01-10 14:01:46 UTC (rev 110312)
+++ projects/jboss-reflect/branches/Branch_2_0/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfoFactoryImpl.java	2011-01-10 14:11:03 UTC (rev 110313)
@@ -23,14 +23,13 @@
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMember;
-import javassist.CtMethod;
-import javassist.CtPrimitiveType;
-import javassist.NotFoundException;
+import javassist.*;
+
 import org.jboss.reflect.plugins.AnnotationAttributeImpl;
 import org.jboss.reflect.plugins.AnnotationHelper;
 import org.jboss.reflect.plugins.AnnotationValueFactory;
@@ -49,12 +48,17 @@
  * A javassist type factory.
  *
  * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
+ * @author <a href="mailto:ales.justin at jboss.org">Ales Justin</a>
  */
 public class JavassistTypeInfoFactoryImpl extends WeakClassCache implements TypeInfoFactory, AnnotationHelper
 {
    static final ClassPool pool = ClassPool.getDefault();
 
    static final AnnotationValue[] NO_ANNOTATIONS = new AnnotationValue[0];
+
+   /** Tmp invocation results */
+   private static ThreadLocal<Map<CtClass, TypeInfo>> results = new ThreadLocal<Map<CtClass, TypeInfo>>();
+
    /**
     * Raise NoClassDefFoundError for javassist not found
     *
@@ -121,19 +125,37 @@
    @SuppressWarnings("unchecked")
    protected Object instantiate(Class clazz)
    {
+      CtClass ctClass = getCtClass(clazz.getName());
+
+      boolean start = false;
+      Map<CtClass, TypeInfo> tmp = results.get();
+      if (tmp == null)
+      {
+         start = true;
+         tmp = new HashMap<CtClass, TypeInfo>();
+         results.set(tmp);
+      }
+
+      // if we return here, it means we're already in a loop,
+      // hence no need to cleanup
+      TypeInfo cached = tmp.get(ctClass);
+      if (cached != null)
+         return cached;
+
       try
       {
-         CtClass ctClass = getCtClass(clazz.getName());
-
-         if (clazz.isArray())
+         if (ctClass.isArray())
          {
-            TypeInfo componentType = getTypeInfo(clazz.getComponentType());
-            return new JavassistArrayInfoImpl(this, ctClass, clazz, componentType);
+            TypeInfo componentType = getTypeInfo(ctClass.getComponentType());
+            TypeInfo result = new JavassistArrayInfoImpl(this, ctClass, clazz, componentType);
+            tmp.put(ctClass, result);
+            return result;
          }
-
-         if (ctClass.isAnnotation())
+         else if (ctClass.isAnnotation())
          {
             JavassistAnnotationInfo result = new JavassistAnnotationInfo(this, ctClass, clazz);
+            tmp.put(ctClass, result);
+
             CtMethod[] methods = ctClass.getDeclaredMethods();
             AnnotationAttributeImpl[] atttributes = new AnnotationAttributeImpl[methods.length];
             for (int i = 0 ; i < methods.length ; i++)
@@ -141,31 +163,44 @@
                atttributes[i] = new AnnotationAttributeImpl(methods[i].getName(), getTypeInfo(methods[i].getReturnType()), null);
             }
             result.setAttributes(atttributes);
+
             return result;
-
          }
          else if (ctClass.isEnum())
          {
             JavassistEnumInfo enumInfo = new JavassistEnumInfo(this, ctClass, clazz);
+            tmp.put(ctClass, enumInfo);
+
             CtField[] fields = ctClass.getFields();
-            EnumConstantInfoImpl[] constants = new EnumConstantInfoImpl[fields.length];
-            int i = 0;
+            List<EnumConstantInfoImpl> constants = new ArrayList<EnumConstantInfoImpl>();
             for (CtField field : fields)
             {
-               AnnotationValue[] annotations = getAnnotations(field);
-               constants[i++] = new EnumConstantInfoImpl(field.getName(), enumInfo, annotations);
+               if (Modifier.isEnum(field.getModifiers()))
+               {
+                  AnnotationValue[] annotations = getAnnotations(field);
+                  constants.add(new EnumConstantInfoImpl(field.getName(), enumInfo, annotations));
+               }
             }
-            enumInfo.setEnumConstants(constants);
+            enumInfo.setEnumConstants(constants.toArray(new EnumConstantInfoImpl[constants.size()]));
+
             return enumInfo;
          }
-
-
-         return new JavassistTypeInfo(this, ctClass, clazz);
+         else
+         {
+            TypeInfo result = new JavassistTypeInfo(this, ctClass, clazz);
+            tmp.put(ctClass, result);
+            return result;
+         }
       }
       catch (NotFoundException e)
       {
          throw new RuntimeException(e);
       }
+      finally
+      {
+         if (start)
+            results.remove();
+      }
    }
 
    /**

Added: projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/support/Obligation.java
===================================================================
--- projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/support/Obligation.java	                        (rev 0)
+++ projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/support/Obligation.java	2011-01-10 14:11:03 UTC (rev 110313)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.test.classinfo.support;
+
+/**
+ * @author <a href="mailto:ales.justin at jboss.org">Ales Justin</a>
+ */
+ at UML(identifier="MD_ObligationCode")
+public enum Obligation
+{
+   CONDITIONAL,
+   @UML(identifier="optional", obligation=CONDITIONAL)
+   OPTIONAL,
+   @UML(identifier="mandatory", obligation=CONDITIONAL)
+   MANDATORY,
+   FORBIDDEN
+}

Added: projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/support/UML.java
===================================================================
--- projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/support/UML.java	                        (rev 0)
+++ projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/support/UML.java	2011-01-10 14:11:03 UTC (rev 110313)
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.test.classinfo.support;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * @author <a href="mailto:ales.justin at jboss.org">Ales Justin</a>
+ */
+ at Documented
+ at Retention(RUNTIME)
+ at Target({TYPE, FIELD, METHOD})
+public @interface UML
+{
+   String identifier();
+
+   Obligation obligation() default Obligation.MANDATORY;
+}

Modified: projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/test/AnnotatedClassInfoTest.java
===================================================================
--- projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/test/AnnotatedClassInfoTest.java	2011-01-10 14:01:46 UTC (rev 110312)
+++ projects/jboss-reflect/branches/Branch_2_0/src/test/java/org/jboss/test/classinfo/test/AnnotatedClassInfoTest.java	2011-01-10 14:11:03 UTC (rev 110313)
@@ -21,6 +21,7 @@
 */ 
 package org.jboss.test.classinfo.test;
 
+import java.lang.annotation.Annotation;
 import java.util.HashSet;
 
 import org.jboss.reflect.spi.AnnotatedInfo;
@@ -42,16 +43,7 @@
 import org.jboss.reflect.spi.TypeInfoFactory;
 import org.jboss.reflect.spi.Value;
 import org.jboss.test.ContainerTest;
-import org.jboss.test.classinfo.support.AnnotatedClass;
-import org.jboss.test.classinfo.support.AnnotatedSubClass;
-import org.jboss.test.classinfo.support.AnotherAnnotation;
-import org.jboss.test.classinfo.support.ComplexAnnotation;
-import org.jboss.test.classinfo.support.ExpectedAnnotations;
-import org.jboss.test.classinfo.support.JDK14ExpectedAnnotations;
-import org.jboss.test.classinfo.support.JDK50ExpectedAnnotations;
-import org.jboss.test.classinfo.support.SimpleAnnotation;
-import org.jboss.test.classinfo.support.TestEnum;
-import org.jboss.test.classinfo.support.ValueAnnotation;
+import org.jboss.test.classinfo.support.*;
 
 /**
  * 
@@ -297,6 +289,14 @@
       checkParameterAnnotations(methods[0].getParameters());
    }
 
+   public void testCycle() throws Throwable
+   {
+      ClassInfo info = getClassInfo(UML.class);
+      Annotation[] annotations = info.getUnderlyingAnnotations();
+      assertNotNull(annotations);
+      assertEquals(3, annotations.length);
+   }
+
    private void checkAnnotations(AnnotatedInfo info, ExpectedComplexAnnotationData expectedComplexAnnotationData)
    {
       AnnotationValue[] annotations = info.getAnnotations();



More information about the jboss-cvs-commits mailing list