[jboss-cvs] JBossAS SVN: r60161 - in projects/microcontainer/trunk/container/src: main/org/jboss/config/plugins and 6 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Feb 1 10:33:29 EST 2007


Author: adrian at jboss.org
Date: 2007-02-01 10:33:29 -0500 (Thu, 01 Feb 2007)
New Revision: 60161

Added:
   projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/TypeInfoAttachments.java
   projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/AbstractTypeInfo.java
   projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/support/BeanInfoAnnotation.java
   projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/support/BeanInfoInterface.java
Modified:
   projects/microcontainer/trunk/container/src/main/org/jboss/beans/info/plugins/AbstractBeanInfoFactory.java
   projects/microcontainer/trunk/container/src/main/org/jboss/config/plugins/AbstractConfiguration.java
   projects/microcontainer/trunk/container/src/main/org/jboss/config/spi/Configuration.java
   projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/AnnotationInfoImpl.java
   projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/ClassInfoImpl.java
   projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/InterfaceInfoImpl.java
   projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/javassist/JavassistTypeInfo.java
   projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/DelegateClassInfo.java
   projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/PrimitiveInfo.java
   projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/TypeInfo.java
   projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/test/AbstractBeanInfoTest.java
   projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/test/BeanInfoUnitTestCase.java
Log:
Add support for retrieving BeanInfo from interfaces and annotations.

A bit more refactoring on the internal TypeInfo api to make it easier to maintain
and added some extra helpers like isAnnotation() for easier type checking.
This is one case where I wish java supported multiple inheritance. :-)

Also introduced the notion of caching attachments to types.
This is experimental.

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/beans/info/plugins/AbstractBeanInfoFactory.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/beans/info/plugins/AbstractBeanInfoFactory.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/beans/info/plugins/AbstractBeanInfoFactory.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -132,12 +132,13 @@
                return info;
          }
 
-         if (classInfo.isInterface())
-            throw new IllegalArgumentException(classInfo.getName() + " is an interface");
-
          Set<ConstructorInfo> constructors = getConstructors(classInfo);
          Set<MethodInfo> methods = getMethods(classInfo);
-         Set<PropertyInfo> properties = getProperties(methods);
+         Set<PropertyInfo> properties = null;
+         if (classInfo.isAnnotation())
+            properties = getAnnotationProperties(methods);
+         else
+            properties = getBeanProperties(methods);
          Set<EventInfo> events = getEvents(classInfo);
          
          BeanInfo result = createBeanInfo(classAdapter, properties, constructors, methods, events);
@@ -196,6 +197,7 @@
    protected Set<MethodInfo> getMethods(ClassInfo classInfo)
    {
       HashSet<MethodInfo> result = new HashSet<MethodInfo>();
+      
       while (classInfo != null)
       {
          MethodInfo[] minfos = classInfo.getDeclaredMethods();
@@ -210,16 +212,17 @@
          
          classInfo = classInfo.getSuperclass();
       }
+      
       return result;
    }
    
    /**
-    * Get the properties
+    * Get the properties for a bean
     * 
     * @param methods the methods
     * @return the properties
     */
-   protected Set<PropertyInfo> getProperties(Set<MethodInfo> methods)
+   protected Set<PropertyInfo> getBeanProperties(Set<MethodInfo> methods)
    {
       HashMap<String, MethodInfo> getters = new HashMap<String, MethodInfo>();
       HashMap<String, List<MethodInfo>> setters = new HashMap<String, List<MethodInfo>>();
@@ -311,6 +314,31 @@
    }
    
    /**
+    * Get the properties for an annotation
+    * 
+    * @param methods the methods
+    * @return the properties
+    */
+   protected Set<PropertyInfo> getAnnotationProperties(Set<MethodInfo> methods)
+   {
+      HashSet<PropertyInfo> properties = new HashSet<PropertyInfo>();
+      if (methods != null && methods.isEmpty() == false)
+      {
+         for (MethodInfo method : methods)
+         {
+            TypeInfo returnType = method.getReturnType();
+            TypeInfo[] parameters = method.getParameterTypes();
+            if (parameters.length == 0 && PrimitiveInfo.VOID.equals(returnType) == false)
+            {
+               String name = method.getName();
+               properties.add(new AbstractPropertyInfo(name, name, returnType, method, null, method.getAnnotations()));
+            }
+         }
+      }
+      return properties;
+   }
+   
+   /**
     * Get the events
     * 
     * @param classInfo the class info

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/config/plugins/AbstractConfiguration.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/config/plugins/AbstractConfiguration.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/config/plugins/AbstractConfiguration.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -21,6 +21,8 @@
 */
 package org.jboss.config.plugins;
 
+import java.lang.reflect.Type;
+
 import org.jboss.beans.info.spi.BeanInfo;
 import org.jboss.beans.info.spi.BeanInfoFactory;
 import org.jboss.classadapter.spi.ClassAdapter;
@@ -63,35 +65,40 @@
    {
    }
    
-   public BeanInfo getBeanInfo(String className, ClassLoader cl) throws Throwable
+   public BeanInfo getBeanInfo(String className, ClassLoader cl) throws ClassNotFoundException
    {
       ClassAdapter classAdapter = getClassAdapterFactory().getClassAdapter(className, cl);
       return getBeanInfoFactory().getBeanInfo(classAdapter);
    }
    
-   public BeanInfo getBeanInfo(Class clazz) throws Throwable
+   public BeanInfo getBeanInfo(Class clazz)
    {
       ClassAdapter classAdapter = getClassAdapterFactory().getClassAdapter(clazz);
       return getBeanInfoFactory().getBeanInfo(classAdapter);
    }
    
-   public BeanInfo getBeanInfo(TypeInfo typeInfo) throws Throwable
+   public BeanInfo getBeanInfo(TypeInfo typeInfo)
    {
       ClassAdapter classAdapter = getClassAdapterFactory().getClassAdapter(typeInfo);
       return getBeanInfoFactory().getBeanInfo(classAdapter);
    }
    
-   public ClassInfo getClassInfo(String className, ClassLoader cl) throws Throwable
+   public ClassInfo getClassInfo(String className, ClassLoader cl) throws ClassNotFoundException
    {
       ClassAdapter classAdapter = getClassAdapterFactory().getClassAdapter(className, cl);
       return classAdapter.getClassInfo();
    }
    
-   public ClassInfo getClassInfo(Class clazz) throws Throwable
+   public ClassInfo getClassInfo(Class clazz)
    {
       ClassAdapter classAdapter = getClassAdapterFactory().getClassAdapter(clazz);
       return classAdapter.getClassInfo();
    }
+   
+   public TypeInfo getTypeInfo(Type type)
+   {
+      return getTypeInfoFactory().getTypeInfo(type);
+   }
 
    public TypeInfoFactory getTypeInfoFactory()
    {
@@ -169,12 +176,28 @@
     * Get the BeanInfoFactory
     * 
     * @return the BeanInfoFactory
-    * @throws Throwable for any error
     */
-   protected BeanInfoFactory getBeanInfoFactory() throws Throwable
+   protected BeanInfoFactory getBeanInfoFactory()
    {
       if (beanInfoFactory == null)
-         beanInfoFactory = createDefaultBeanInfoFactory();
+      {
+         try
+         {
+            beanInfoFactory = createDefaultBeanInfoFactory();
+         }
+         catch (RuntimeException e)
+         {
+            throw e;
+         }
+         catch (Error e)
+         {
+            throw e;
+         }
+         catch (Throwable t)
+         {
+            throw new RuntimeException("Error creating bean info factory");
+         }
+      }
       return beanInfoFactory;
    }
 
@@ -182,12 +205,28 @@
     * Get the class adapter factory
     * 
     * @return the ClassAdapterFactory
-    * @throws Throwable for any error
     */
-   protected ClassAdapterFactory getClassAdapterFactory() throws Throwable
+   protected ClassAdapterFactory getClassAdapterFactory()
    {
       if (classAdapterFactory == null)
-         classAdapterFactory = createDefaultClassAdapterFactory();
+      {
+         try
+         {
+            classAdapterFactory = createDefaultClassAdapterFactory();
+         }
+         catch (RuntimeException e)
+         {
+            throw e;
+         }
+         catch (Error e)
+         {
+            throw e;
+         }
+         catch (Throwable t)
+         {
+            throw new RuntimeException("Error creating class adapter");
+         }
+      }
       return classAdapterFactory;
    }
    

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/config/spi/Configuration.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/config/spi/Configuration.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/config/spi/Configuration.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -21,6 +21,8 @@
 */
 package org.jboss.config.spi;
 
+import java.lang.reflect.Type;
+
 import org.jboss.beans.info.spi.BeanInfo;
 import org.jboss.classadapter.spi.DependencyBuilder;
 import org.jboss.joinpoint.spi.JoinpointFactoryBuilder;
@@ -44,27 +46,25 @@
     * @param className the class name
     * @param cl the classloader
     * @return the bean info
-    * @throws Throwable for any error
+    * @throws ClassNotFoundException when the class could not be loaded
     */
-   BeanInfo getBeanInfo(String className, ClassLoader cl) throws Throwable;
+   BeanInfo getBeanInfo(String className, ClassLoader cl) throws ClassNotFoundException;
 
    /**
     * Get the bean info
     * 
     * @param clazz the class
     * @return the bean info
-    * @throws Throwable for any error
     */
-   BeanInfo getBeanInfo(Class clazz) throws Throwable;
+   BeanInfo getBeanInfo(Class clazz);
 
    /**
     * Get the bean info
     * 
     * @param type the type info
     * @return the bean info
-    * @throws Throwable for any error
     */
-   BeanInfo getBeanInfo(TypeInfo type) throws Throwable;
+   BeanInfo getBeanInfo(TypeInfo type);
    
    /**
     * Get the class info for a class
@@ -72,18 +72,26 @@
     * @param className the class name
     * @param cl the classloader
     * @return the class info
-    * @throws Throwable for any error
+    * @throws ClassNotFoundException when the class could not be loaded
     */
-   ClassInfo getClassInfo(String className, ClassLoader cl) throws Throwable;
+   ClassInfo getClassInfo(String className, ClassLoader cl) throws ClassNotFoundException;
    
    /**
     * Get the class info for a class
     * 
     * @param clazz the class
     * @return the class info
-    * @throws Throwable for any error
     */
-   ClassInfo getClassInfo(Class clazz) throws Throwable;
+   ClassInfo getClassInfo(Class clazz);
+   
+   /**
+    * Get the type info for a type
+    * 
+    * @param type the type
+    * @return the type info
+    * @throws IllegalArgumentException for a null type
+    */
+   TypeInfo getTypeInfo(Type type);
 
    /**
     * Get the type info factory

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/AnnotationInfoImpl.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/AnnotationInfoImpl.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/AnnotationInfoImpl.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -58,7 +58,7 @@
     */
    public AnnotationInfoImpl(String name, int modifiers)
    {
-      super(name, modifiers, null);
+      super(name, modifiers);
    }
 
    /**
@@ -85,6 +85,11 @@
       return name;
    }
 
+   public boolean isAnnotation()
+   {
+      return true;
+   }
+   
    public int getModifiers()
    {
       return modifiers;

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/ClassInfoImpl.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/ClassInfoImpl.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/ClassInfoImpl.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -23,7 +23,9 @@
 
 import java.lang.reflect.Array;
 import java.lang.reflect.Modifier;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.Map;
 
 import org.jboss.reflect.spi.ClassInfo;
 import org.jboss.reflect.spi.ConstructorInfo;
@@ -107,6 +109,9 @@
    /** The type info factory */
    protected TypeInfoFactory typeInfoFactory;
 
+   /** The attachments */
+   private transient TypeInfoAttachments attachments;
+
    public TypeInfoFactory getTypeInfoFactory()
    {
       return typeInfoFactory;
@@ -468,6 +473,21 @@
       return getType().isArray();
    }
 
+   public boolean isCollection()
+   {
+      return Collection.class.isAssignableFrom(getType());
+   }
+
+   public boolean isMap()
+   {
+      return Map.class.isAssignableFrom(getType());
+   }
+
+   public boolean isAnnotation()
+   {
+      return getType().isAnnotation();
+   }
+
    public boolean isEnum()
    {
       return getType().isEnum();
@@ -516,6 +536,47 @@
       return this;
    }
 
+   public void setAttachment(String name, Object attachment)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      synchronized (this)
+      {
+         if (attachments == null)
+         {
+            if (attachment == null)
+               return;
+            attachments = new TypeInfoAttachments();;
+         }
+      }
+      if (attachment == null)
+         attachments.removeAttachment(name);
+      else
+         attachments.addAttachment(name, attachment);
+   }
+
+   public <T> T getAttachment(Class<T> expectedType)
+   {
+      if (expectedType == null)
+         throw new IllegalArgumentException("Null expectedType");
+      Object result = getAttachment(expectedType.getName());
+      if (result == null)
+         return null;
+      return expectedType.cast(result);
+   }
+
+   public Object getAttachment(String name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      synchronized (this)
+      {
+         if (attachments == null)
+            return null;
+      }
+      return attachments.getAttachment(name);
+   }
+
    @Override
    protected InheritableAnnotationHolder getSuperHolder()
    {

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/InterfaceInfoImpl.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/InterfaceInfoImpl.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/InterfaceInfoImpl.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -56,6 +56,17 @@
     * 
     * @param name the interface name
     * @param modifiers the interface modifier
+    */
+   public InterfaceInfoImpl(String name, int modifiers)
+   {
+      super(name, modifiers);
+   }
+
+   /**
+    * Create a new InterfaceInfo.
+    * 
+    * @param name the interface name
+    * @param modifiers the interface modifier
     * @param interfaces the interfaces
     */
    public InterfaceInfoImpl(String name, int modifiers, InterfaceInfo[] interfaces)

Added: projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/TypeInfoAttachments.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/TypeInfoAttachments.java	                        (rev 0)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/TypeInfoAttachments.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -0,0 +1,124 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.reflect.plugins;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Future;
+
+/**
+ * TypeInfoAttachments.
+ *
+ * TODO add some security on who can add attachments
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TypeInfoAttachments
+{
+   /** The attachments */
+   private transient Map<String, Object> attachments;
+
+   /**
+    * Set an attachment against the type.
+    * This is useful for caching information against a type.<p>
+    *
+    * If you add a future object, subsequent gets will wait for the result<p>
+    * 
+    * WARNING: Be careful about what you put in here. Don't create
+    * references across classloaders, if you are not sure add a WeakReference
+    * to the information.
+    * 
+    * @param name the name
+    * @param attachment the attachment, pass null to remove an attachment
+    * @throws IllegalArgumentException for a null name
+    */
+   public void addAttachment(String name, Object attachment)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      if (attachment == null)
+         return;
+      synchronized (this)
+      {
+         if (attachments == null)
+            attachments = new HashMap<String, Object>();
+         attachments.put(name, attachment);
+      }
+   }
+
+   /**
+    * Remove an attachment
+    * 
+    * @param name the name
+    * @throws IllegalArgumentException for a null name
+    */
+   public void removeAttachment(String name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      synchronized (this)
+      {
+         if (attachments == null)
+            return;
+         attachments.remove(name);
+      }
+   }
+
+   /**
+    * Get an attachment from the type
+    * 
+    * @param name the name
+    * @return the attachment
+    */
+   public Object getAttachment(String name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      Object result = null;
+      synchronized (this)
+      {
+         if (attachments == null)
+            return null;
+         result = attachments.get(name);
+      }
+      if (result == null)
+         return null;
+      
+      // Special case if the attachment is a future object
+      if (result instanceof Future)
+      {
+         try
+         {
+            return ((Future) result).get();
+         }
+         catch (RuntimeException e)
+         {
+            throw e;
+         }
+         catch (Exception e)
+         {
+            throw new RuntimeException("Error getting attachment from future " + result, e);
+         }
+      }
+      return result;
+   }
+}

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/javassist/JavassistTypeInfo.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/javassist/JavassistTypeInfo.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/reflect/plugins/javassist/JavassistTypeInfo.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -32,6 +32,8 @@
 import javassist.CtField;
 import javassist.CtMethod;
 import javassist.NotFoundException;
+
+import org.jboss.reflect.plugins.TypeInfoAttachments;
 import org.jboss.reflect.plugins.ValueConvertor;
 import org.jboss.reflect.spi.AnnotationValue;
 import org.jboss.reflect.spi.ClassInfo;
@@ -81,6 +83,9 @@
    /** The methods */
    private MethodInfo[] methodArray;
 
+   /** The attachments */
+   private transient TypeInfoAttachments attachments;
+
    /**
     * Create a new JavassistTypeInfo.
     * 
@@ -305,6 +310,21 @@
       return getType().isArray();
    }
 
+   public boolean isCollection()
+   {
+      return Collection.class.isAssignableFrom(getType());
+   }
+
+   public boolean isMap()
+   {
+      return Map.class.isAssignableFrom(getType());
+   }
+
+   public boolean isAnnotation()
+   {
+      return getType().isAnnotation();
+   }
+
    public boolean isEnum()
    {
       return getType().isEnum();
@@ -588,4 +608,44 @@
       return this;
    }
 
+   public void setAttachment(String name, Object attachment)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      synchronized (this)
+      {
+         if (attachments == null)
+         {
+            if (attachment == null)
+               return;
+            attachments = new TypeInfoAttachments();;
+         }
+      }
+      if (attachment == null)
+         attachments.removeAttachment(name);
+      else
+         attachments.addAttachment(name, attachment);
+   }
+
+   public <T> T getAttachment(Class<T> expectedType)
+   {
+      if (expectedType == null)
+         throw new IllegalArgumentException("Null expectedType");
+      Object result = getAttachment(expectedType.getName());
+      if (result == null)
+         return null;
+      return expectedType.cast(result);
+   }
+
+   public Object getAttachment(String name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      synchronized (this)
+      {
+         if (attachments == null)
+            return null;
+      }
+      return attachments.getAttachment(name);
+   }
 }

Added: projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/AbstractTypeInfo.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/AbstractTypeInfo.java	                        (rev 0)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/AbstractTypeInfo.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -0,0 +1,108 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.reflect.spi;
+
+import org.jboss.reflect.plugins.TypeInfoAttachments;
+import org.jboss.util.JBossObject;
+
+/**
+ * AbstractTypeInfo.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractTypeInfo extends JBossObject implements TypeInfo
+{
+   /** The attachments */
+   private transient TypeInfoAttachments attachments;
+
+   public boolean isArray()
+   {
+      return false;
+   }
+
+   public boolean isCollection()
+   {
+      return false;
+   }
+
+   public boolean isMap()
+   {
+      return false;
+   }
+
+   public boolean isAnnotation()
+   {
+      return false;
+   }
+
+   public boolean isEnum()
+   {
+      return false;
+   }
+
+   public boolean isPrimitive()
+   {
+      return false;
+   }
+
+   public void setAttachment(String name, Object attachment)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      synchronized (this)
+      {
+         if (attachments == null)
+         {
+            if (attachment == null)
+               return;
+            attachments = new TypeInfoAttachments();;
+         }
+      }
+      if (attachment == null)
+         attachments.removeAttachment(name);
+      else
+         attachments.addAttachment(name, attachment);
+   }
+
+   public <T> T getAttachment(Class<T> expectedType)
+   {
+      if (expectedType == null)
+         throw new IllegalArgumentException("Null expectedType");
+      Object result = getAttachment(expectedType.getName());
+      if (result == null)
+         return null;
+      return expectedType.cast(result);
+   }
+
+   public Object getAttachment(String name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      synchronized (this)
+      {
+         if (attachments == null)
+            return null;
+      }
+      return attachments.getAttachment(name);
+   }
+}

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/DelegateClassInfo.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/DelegateClassInfo.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/DelegateClassInfo.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -23,7 +23,6 @@
 
 import java.lang.annotation.Annotation;
 
-import org.jboss.util.JBossObject;
 import org.jboss.util.JBossStringBuilder;
 
 /**
@@ -32,7 +31,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class DelegateClassInfo extends JBossObject implements ClassInfo, InterfaceInfo
+public class DelegateClassInfo extends AbstractTypeInfo implements ClassInfo, InterfaceInfo
 {
    /** The serialVersionUID */
    private static final long serialVersionUID = 6830276668550581673L;
@@ -233,16 +232,19 @@
       return delegate.getType();
    }
 
+   @Override
    public boolean isArray()
    {
       return delegate.isArray();
    }
 
+   @Override
    public boolean isEnum()
    {
       return delegate.isEnum();
    }
 
+   @Override
    public boolean isPrimitive()
    {
       return delegate.isPrimitive();

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/PrimitiveInfo.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/PrimitiveInfo.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/PrimitiveInfo.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -22,7 +22,6 @@
 package org.jboss.reflect.spi;
 
 import java.io.ObjectStreamException;
-import java.io.Serializable;
 import java.util.HashMap;
 
 import org.jboss.reflect.plugins.ClassInfoImpl;
@@ -36,7 +35,7 @@
  * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
  * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
  */
-public class PrimitiveInfo implements TypeInfo, Serializable
+public class PrimitiveInfo extends AbstractTypeInfo
 {
    /** serialVersionUID */
    private static final long serialVersionUID = 3256718498443835449L;
@@ -164,16 +163,7 @@
       return ValueConvertor.convertValue(type, value, replaceProperties);
    }
 
-   public boolean isArray()
-   {
-      return false;
-   }
-
-   public boolean isEnum()
-   {
-      return false;
-   }
-
+   @Override
    public boolean isPrimitive()
    {
       return true;
@@ -201,11 +191,19 @@
       return typeInfoFactory;
    }
 
+   @Override
    public String toString()
    {
       return name;
    }
 
+   @Override
+   public String toShortString()
+   {
+      return name;
+   }
+
+   @Override
    public boolean equals(Object obj)
    {
       if (obj == this)
@@ -220,6 +218,7 @@
       return other.ordinal == this.ordinal;
    }
 
+   @Override
    public int hashCode()
    {
       return name.hashCode();

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/TypeInfo.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/TypeInfo.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/reflect/spi/TypeInfo.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -71,6 +71,27 @@
     * @return true when an array
     */
    boolean isArray();
+
+   /**
+    * Whether this type is a collection
+    * 
+    * @return true when a collection
+    */
+   boolean isCollection();
+
+   /**
+    * Whether this type is a map
+    * 
+    * @return true when a map
+    */
+   boolean isMap();
+
+   /**
+    * Whether this type is an annotation
+    * 
+    * @return true when an annotation
+    */
+   boolean isAnnotation();
    
    /**
     * Whether this type is an enum
@@ -122,4 +143,40 @@
     * @return type info factory
     */
    TypeInfoFactory getTypeInfoFactory();
+   
+   /**
+    * Get an attachment from the type
+    * 
+    * @param name the name
+    * @return the attachment
+    */
+   Object getAttachment(String name);
+   
+   /**
+    * Get an attachment from the type,
+    * uses the expected type as both the name
+    * and to cast the resulting object.
+    * 
+    * @param <T> the expected type
+    * @param expectedType the expected type
+    * @return the attachment
+    * @throws ClassCastException when the object is not of the expected type
+    */
+   <T> T getAttachment(Class<T> expectedType);
+   
+   /**
+    * Set an attachment against the type.
+    * This is useful for caching information against a type.<p>
+    *
+    * If you add a future object, subsequent gets will wait for the result<p>
+    * 
+    * WARNING: Be careful about what you put in here. Don't create
+    * references across classloaders, if you are not sure add a WeakReference
+    * to the information.
+    * 
+    * @param name the name
+    * @param attachment the attachment, pass null to remove an attachment
+    * @throws IllegalArgumentException for a null name
+    */
+   void setAttachment(String name, Object attachment);
 }

Added: projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/support/BeanInfoAnnotation.java
===================================================================
--- projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/support/BeanInfoAnnotation.java	                        (rev 0)
+++ projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/support/BeanInfoAnnotation.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -0,0 +1,33 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.beaninfo.support;
+
+/**
+ * BeanInfoInterface.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public @interface BeanInfoAnnotation
+{
+   String something();
+}

Added: projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/support/BeanInfoInterface.java
===================================================================
--- projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/support/BeanInfoInterface.java	                        (rev 0)
+++ projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/support/BeanInfoInterface.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -0,0 +1,33 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.beaninfo.support;
+
+/**
+ * BeanInfoInterface.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface BeanInfoInterface
+{
+   String getSomething();
+}

Modified: projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/test/AbstractBeanInfoTest.java
===================================================================
--- projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/test/AbstractBeanInfoTest.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/test/AbstractBeanInfoTest.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -94,7 +94,8 @@
       Set<ConstructorInfo> actual = beanInfo.getConstructors();
       if (expected.isEmpty())
       {
-         assertEmpty(actual);
+         if (actual != null)
+            assertEmpty(actual);
          return;
       }
       assertNotNull(actual);
@@ -107,7 +108,13 @@
    {
       TypeInfoFactory factory = getTypeInfoFactory();
       Set<MethodInfo> expected = new HashSet<MethodInfo>();
-      for (Method method : clazz.getMethods())
+
+      Method[] methods = null;
+      if (clazz.isAnnotation())
+         methods = clazz.getDeclaredMethods();
+      else
+         methods = clazz.getMethods();
+      for (Method method : methods)
       {
          TypeInfo returnType = factory.getTypeInfo(method.getReturnType());
          Class[] paramClasses = method.getParameterTypes();
@@ -133,7 +140,11 @@
    
    protected void assertBeanProperties(BeanInfo beanInfo, Class<?> clazz) throws Throwable
    {
-      Set<PropertyInfo> expected = getExpectedProperties(clazz);
+      Set<PropertyInfo> expected = null;
+      if (clazz.isAnnotation())
+         expected = getExpectedAnnotationProperties(clazz);
+      else
+         expected = getExpectedProperties(clazz);
       
       Set<PropertyInfo> actual = beanInfo.getProperties();
       if (expected.isEmpty())
@@ -284,6 +295,29 @@
       return properties;
    }
    
+   protected Set<PropertyInfo> getExpectedAnnotationProperties(Class<?> clazz)
+   {
+      TypeInfoFactory factory = getTypeInfoFactory();
+      HashSet<PropertyInfo> properties = new HashSet<PropertyInfo>();
+
+      Method[] methods  = clazz.getDeclaredMethods();
+      for (Method method : methods)
+      {
+         TypeInfo returnType = factory.getTypeInfo(method.getGenericReturnType());
+         Class[] parameters = method.getParameterTypes();
+         if (parameters.length == 0 && PrimitiveInfo.VOID.equals(returnType) == false)
+         {
+            String name = method.getName();
+            ClassInfo declaringType = (ClassInfo) factory.getTypeInfo(method.getDeclaringClass());
+            Set<AnnotationValue> getterAnnotations = getExpectedAnnotations(method.getAnnotations()); 
+            AnnotationValue[] annotations = getterAnnotations.toArray(new AnnotationValue[getterAnnotations.size()]);
+            MethodInfo getter = new MethodInfoImpl(null, name, returnType, new TypeInfo[0], new AnnotationValue[0][], null, method.getModifiers(), declaringType);
+            properties.add(new AbstractPropertyInfo(name, name, returnType, getter, null, annotations));
+         }
+      }
+      return properties;
+   }
+   
    protected static String getUpperPropertyName(String name)
    {
       int start = 3;

Modified: projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/test/BeanInfoUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/test/BeanInfoUnitTestCase.java	2007-02-01 14:22:03 UTC (rev 60160)
+++ projects/microcontainer/trunk/container/src/tests/org/jboss/test/beaninfo/test/BeanInfoUnitTestCase.java	2007-02-01 15:33:29 UTC (rev 60161)
@@ -32,6 +32,7 @@
 import org.jboss.test.beaninfo.support.BeanInfoAnnotatedGetterAndSetterSimpleMerge;
 import org.jboss.test.beaninfo.support.BeanInfoAnnotatedGetterOnly;
 import org.jboss.test.beaninfo.support.BeanInfoAnnotatedSetterOnly;
+import org.jboss.test.beaninfo.support.BeanInfoAnnotation;
 import org.jboss.test.beaninfo.support.BeanInfoBooleanProperties;
 import org.jboss.test.beaninfo.support.BeanInfoConstructors;
 import org.jboss.test.beaninfo.support.BeanInfoDefaultConstructor;
@@ -43,6 +44,7 @@
 import org.jboss.test.beaninfo.support.BeanInfoGetterAndSetter;
 import org.jboss.test.beaninfo.support.BeanInfoGetterOnly;
 import org.jboss.test.beaninfo.support.BeanInfoInconsistentTypes;
+import org.jboss.test.beaninfo.support.BeanInfoInterface;
 import org.jboss.test.beaninfo.support.BeanInfoParameterConstructor;
 import org.jboss.test.beaninfo.support.BeanInfoProperties;
 import org.jboss.test.beaninfo.support.BeanInfoSetterOnly;
@@ -150,6 +152,16 @@
    {
       testBean(BeanInfoAnnotatedGetterAndSetterSimpleMerge.class, new String[] { "something" });
    }
+   
+   public void testBeanInterface() throws Throwable
+   {
+      testBean(BeanInfoInterface.class, new String[] { "something" });
+   }
+   
+   public void testBeanAnnotation() throws Throwable
+   {
+      testBean(BeanInfoAnnotation.class, new String[] { "something" });
+   }
 
    public void testDefaultConstructor() throws Throwable
    {
@@ -225,7 +237,8 @@
          Set<String> expected = new HashSet<String>();
          for (String beanName : beanNames)
             expected.add(beanName);
-         expected.add("class");
+         if (clazz.isInterface() == false)
+            expected.add("class");
          assertEquals(expected, props);
       }
    }




More information about the jboss-cvs-commits mailing list