[seam-commits] Seam SVN: r12808 - modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Wed May 26 09:06:18 EDT 2010


Author: shane.bryzak at jboss.com
Date: 2010-05-26 09:06:16 -0400 (Wed, 26 May 2010)
New Revision: 12808

Removed:
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util/Reflections.java
Modified:
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util/AnnotatedBeanProperty.java
Log:
more enhancements


Modified: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util/AnnotatedBeanProperty.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util/AnnotatedBeanProperty.java	2010-05-26 11:55:06 UTC (rev 12807)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util/AnnotatedBeanProperty.java	2010-05-26 13:06:16 UTC (rev 12808)
@@ -3,12 +3,15 @@
 import java.beans.Introspector;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 
 /**
  * A convenience class for working with an annotated property (either a field or method) of
- * a JavaBean class.
+ * a JavaBean class.  By providing an isMatch() method in a concrete implementation
+ * of this class, annotations may be matched on their attribute values or other
+ * conditions.
  *  
  * @author Shane Bryzak
  */
@@ -24,20 +27,30 @@
    private boolean isFieldProperty;
    private boolean set = false;
    
-   protected AnnotatedBeanProperty() 
-   {
-      // noop      
-   }
+   private Class<?> targetClass;
+   private Class<T> annotationClass;
+   private boolean scanned = false;
    
+   /**
+    * Default constructor
+    * 
+    * @param cls The class to scan for the property
+    * @param annotationClass The annotation class to scan for. Specified attribute
+    * values may be scanned for by providing an implementation of the isMatch() method. 
+    */
    public AnnotatedBeanProperty(Class<?> cls, Class<T> annotationClass)
    {            
-      scan(cls, annotationClass);
-   }
+      this.targetClass = cls;
+      this.annotationClass = annotationClass;
+   }   
    
-   protected void scan(Class<?> cls, Class<T> annotationClass)
-   {
+   /**
+    * Scans the target class to locate the annotated property
+    */
+   private void scan()
+   {      
       // First check declared fields
-      for (Field f : cls.getDeclaredFields())
+      for (Field f : targetClass.getDeclaredFields())
       {
          if (f.isAnnotationPresent(annotationClass) && 
                isMatch(f.getAnnotation(annotationClass))) 
@@ -50,7 +63,7 @@
       }      
       
       // Then check public fields, in case it's inherited
-      for (Field f : cls.getFields())
+      for (Field f : targetClass.getFields())
       {
          if (f.isAnnotationPresent(annotationClass) &&
                isMatch(f.getAnnotation(annotationClass))) 
@@ -63,7 +76,7 @@
       }
       
       // Then check public methods (we ignore private methods)
-      for (Method m : cls.getMethods())
+      for (Method m : targetClass.getMethods())
       {
          if (m.isAnnotationPresent(annotationClass) &&
                isMatch(m.getAnnotation(annotationClass)))
@@ -82,8 +95,8 @@
             
             if (this.name != null)
             {
-               this.propertyGetter = Reflections.getGetterMethod(cls, this.name);
-               this.propertySetter = Reflections.getSetterMethod(cls, this.name);
+               this.propertyGetter = getGetterMethod(targetClass, this.name);
+               this.propertySetter = getSetterMethod(targetClass, this.name);
                this.propertyType = this.propertyGetter.getGenericReturnType();
                isFieldProperty = false;               
                set = true;
@@ -91,63 +104,246 @@
             else
             {
                throw new IllegalStateException("Invalid accessor method, must start with 'get' or 'is'.  " +
-                     "Method: " + m + " in class: " + cls);
+                     "Method: " + m + " in class: " + targetClass);
             }
          }
       }   
+      
+      scanned = true;
    }
    
+   /**
+    * This method must be provided by a concrete implementation of this class. It
+    * may be used to scan for an annotation with one or more particular attribute
+    * values.  
+    * 
+    * @param annotation The potential match
+    * @return true if the specified annotation is a match
+    */
    protected abstract boolean isMatch(T annotation);
 
-   private void setupFieldProperty(Field propertyField)
+   /**
+    * This method sets the property value for a specified bean to the specified 
+    * value.  The property to be set is either a field or setter method that
+    * matches the specified annotation class and returns true for the isMatch() 
+    * method.
+    * 
+    * @param bean The bean containing the property to set
+    * @param value The new property value
+    * @throws Exception
+    */
+   public void setValue(Object bean, Object value) throws Exception
    {
-      this.propertyField = propertyField;
-      isFieldProperty = true;
-      this.name = propertyField.getName();
-      this.propertyType = propertyField.getGenericType();
-   }
-
-   public void setValue(Object bean, Object value)
-   {
+      if (!scanned) scan();
+      
       if (isFieldProperty)
       {
-         Reflections.setAndWrap(propertyField, bean, value);         
+         setFieldValue(propertyField, bean, value);        
       }
       else
       {
-         Reflections.invokeAndWrap(propertySetter, bean, value);
+         invokeMethod(propertySetter, bean, value);
       }
    }
-   
-   public Object getValue(Object bean)
+    
+   /**
+    * Returns the property value for the specified bean.  The property to be
+    * returned is either a field or getter method that matches the specified
+    * annotation class and returns true for the isMatch() method.
+    * 
+    * @param bean The bean to read the property from
+    * @return The property value
+    * @throws Exception
+    */
+   public Object getValue(Object bean) throws Exception
    {
+      if (!scanned) scan();
+      
       if (isFieldProperty)
       {
-         return Reflections.getAndWrap(propertyField, bean);  
+         return getFieldValue(propertyField, bean);  
       }
       else
       {
-         return Reflections.invokeAndWrap(propertyGetter, bean);
+         return invokeMethod(propertyGetter, bean);
       }
    }
    
+   /**
+    * Returns the name of the property. If the property is a field, then the
+    * field name is returned.  Otherwise, if the property is a method, then the
+    * name that is returned is the getter method name without the "get" or "is"
+    * prefix, and a lower case first letter.
+    * 
+    * @return The name of the property
+    */
    public String getName()
    {
+      if (!scanned) scan();      
       return name;
    }
    
+   /**
+    * Returns the annotation type
+    * 
+    * @return The annotation type
+    */
    public T getAnnotation()
    {
+      if (!scanned) scan();
       return annotation;
    }
    
+   /**
+    * Returns the property type
+    * 
+    * @return The property type
+    */
    public Type getPropertyType()
    {
+      if (!scanned) scan();
       return propertyType;
    }
    
+   /**
+    * Returns true if the property has been successfully located, otherwise
+    * returns false.
+    * 
+    * @return
+    */
    public boolean isSet()
    {
+      if (!scanned) scan();
       return set;
    }
+   
+   private void setupFieldProperty(Field propertyField)
+   {
+      this.propertyField = propertyField;
+      isFieldProperty = true;
+      this.name = propertyField.getName();
+      this.propertyType = propertyField.getGenericType();
+   }   
+   
+   private Object getFieldValue(Field field, Object obj)
+   {
+      try
+      {
+         return field.get(obj);
+      }
+      catch (Exception e)
+      {
+         if (e instanceof RuntimeException)
+         {
+            throw (RuntimeException) e;
+         }
+         else
+         {
+            throw new IllegalArgumentException(
+                  String.format("Exception reading [%s] field from object [%s].",
+                        field.getName(), obj), e);
+         }         
+      }
+   }
+   
+   private void setFieldValue(Field field, Object obj, Object value)
+   {
+      field.setAccessible(true);
+      try
+      {
+         field.set(obj, value);
+      }
+      catch (Exception e)
+      {
+         if (e instanceof RuntimeException)
+         {
+            throw (RuntimeException) e;
+         }
+         else
+         {
+            throw new IllegalArgumentException(
+                  String.format("Exception setting [%s] field on object [%s] to value [%s]",
+                        field.getName(), obj, value), e);
+         }
+      }      
+   }
+   
+   private Object invokeMethod(Method method, Object obj, Object... args) throws Exception
+   {
+      try
+      {
+         return method.invoke(obj, args);
+      }
+      catch (Exception e)
+      {
+         if (e instanceof InvocationTargetException)
+         {
+            InvocationTargetException ite = (InvocationTargetException) e;
+            throw (Exception) ite.getCause();
+         }
+         else if (e instanceof RuntimeException)
+         {
+            throw (RuntimeException) e;
+         }
+         else
+         {
+            StringBuilder sb = null;
+            if (args != null)
+            {
+               sb = new StringBuilder();
+               for (Object arg : args)
+               {
+                  sb.append((sb.length() > 0 ? "," : ":") + arg);
+               }
+            }
+            throw new IllegalArgumentException(
+                  String.format("Exception invoking method [%s] on object [%s], with arguments [%s].",
+                        method.getName(), obj, sb != null ? sb.toString() : ""));            
+         }
+      }   
+   }   
+   
+   private Method getSetterMethod(Class<?> clazz, String name)
+   {
+      Method[] methods = clazz.getMethods();
+      for (Method method: methods)
+      {
+         String methodName = method.getName();
+         if ( methodName.startsWith("set") && method.getParameterTypes().length==1 )
+         {
+            if ( Introspector.decapitalize( methodName.substring(3) ).equals(name) )
+            {
+               return method;
+            }
+         }
+      }
+      throw new IllegalArgumentException("no such setter method: " + clazz.getName() + '.' + name);
+   }
+   
+   private Method getGetterMethod(Class<?> clazz, String name)
+   {
+      Method[] methods = clazz.getMethods();
+      for (Method method: methods)
+      {
+         String methodName = method.getName();
+         if ( method.getParameterTypes().length==0 )
+         {
+            if ( methodName.startsWith("get") )
+            {
+               if ( Introspector.decapitalize( methodName.substring(3) ).equals(name) )
+               {
+                  return method;
+               }
+            }
+            else if ( methodName.startsWith("is") )
+            {
+               if ( Introspector.decapitalize( methodName.substring(2) ).equals(name) )
+               {
+                  return method;
+               }
+            }
+         }
+      }
+      throw new IllegalArgumentException("no such getter method: " + clazz.getName() + '.' + name);
+   }   
 }
\ No newline at end of file

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util/Reflections.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util/Reflections.java	2010-05-26 11:55:06 UTC (rev 12807)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util/Reflections.java	2010-05-26 13:06:16 UTC (rev 12808)
@@ -1,401 +0,0 @@
-package org.jboss.seam.security.util;
-
-import java.beans.Introspector;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-
-public class Reflections
-{
-   
-   public static Object invoke(Method method, Object target, Object... args) throws Exception
-   {
-      try
-      {
-         return method.invoke( target, args );
-      }
-      catch (IllegalArgumentException iae)
-      {
-         String message = "Could not invoke method by reflection: " + toString(method);
-         if (args!=null && args.length>0) 
-         {
-            message += " with parameters: (" + Strings.toClassNameString(", ", args) + ')';
-         }
-         message += " on: " + target.getClass().getName();
-         throw new IllegalArgumentException(message, iae);
-      }
-      catch (InvocationTargetException ite)
-      {
-         if ( ite.getCause() instanceof Exception )
-         {
-            throw (Exception) ite.getCause();
-         }
-         else
-         {
-            throw ite;
-         }
-      }
-   }
-   
-   public static Object get(Field field, Object target) throws Exception
-   {
-      boolean accessible = field.isAccessible();
-      try
-      {
-         field.setAccessible(true);
-         return field.get(target);
-      }
-      catch (IllegalArgumentException iae)
-      {
-         String message = "Could not get field value by reflection: " + toString(field) + 
-            " on: " + target.getClass().getName();
-         throw new IllegalArgumentException(message, iae);
-      }
-      finally
-      {
-         field.setAccessible(accessible);
-      }
-   }
-   
-   public static void set(Field field, Object target, Object value) throws Exception
-   {
-      try
-      {
-         field.set(target, value);
-      }
-      catch (IllegalArgumentException iae)
-      {
-         // target may be null if field is static so use field.getDeclaringClass() instead
-         String message = "Could not set field value by reflection: " + toString(field) +
-            " on: " + field.getDeclaringClass().getName();
-         if (value==null)
-         {
-            message += " with null value";
-         }
-         else
-         {
-            message += " with value: " + value.getClass();
-         }
-         throw new IllegalArgumentException(message, iae);
-      }
-   }
-   
-   public static Object getAndWrap(Field field, Object target)
-   {
-      boolean accessible = field.isAccessible();
-      try
-      {
-         field.setAccessible(true);
-         return get(field, target);
-      }
-      catch (Exception e)
-      {
-         if (e instanceof RuntimeException)
-         {
-            throw (RuntimeException) e;
-         }
-         else
-         {
-            throw new IllegalArgumentException("exception setting: " + field.getName(), e);
-         }
-      }
-      finally
-      {
-         field.setAccessible(accessible);
-      }
-   }
-   
-   public static void setAndWrap(Field field, Object target, Object value)
-   {
-      boolean accessible = field.isAccessible();
-      try
-      {
-         field.setAccessible(true);
-         set(field, target, value);
-      }
-      catch (Exception e)
-      {
-         if (e instanceof RuntimeException)
-         {
-            throw (RuntimeException) e;
-         }
-         else
-         {
-            throw new IllegalArgumentException("exception setting: " + field.getName(), e);
-         }
-      }
-      finally
-      {
-         field.setAccessible(accessible);
-      }
-   }
-   
-   public static Object invokeAndWrap(Method method, Object target, Object... args)
-   {
-      try
-      {
-         return invoke(method, target, args);
-      }
-      catch (Exception e)
-      {
-         if (e instanceof RuntimeException)
-         {
-            throw (RuntimeException) e;
-         }
-         else
-         {
-            throw new RuntimeException("exception invoking: " + method.getName(), e);
-         }
-      }
-   }
-   
-   public static String toString(Method method)
-   {
-      return Strings.unqualify( method.getDeclaringClass().getName() ) + 
-            '.' + 
-            method.getName() + 
-            '(' + 
-            Strings.toString( ", ", method.getParameterTypes() ) + 
-            ')';
-   }
-   
-   public static String toString(Member member)
-   {
-      return Strings.unqualify( member.getDeclaringClass().getName() ) + 
-            '.' + 
-            member.getName();
-   }
-   
-   public static Class classForName(String name) throws ClassNotFoundException
-   {
-      try 
-      {
-         return Thread.currentThread().getContextClassLoader().loadClass(name);
-      }
-      catch (Exception e)
-      {
-         return Class.forName(name);
-      }
-   }
-   
-   /**
-    * Return's true if the class can be loaded using Reflections.classForName()
-    */
-   public static boolean isClassAvailable(String name)
-   {
-      try 
-      {
-         classForName(name);
-      }
-      catch (ClassNotFoundException e) {
-         return false;
-      }
-      return true;
-   }
-
-   public static Class getCollectionElementType(Type collectionType)
-   {
-      if ( !(collectionType instanceof ParameterizedType) )
-      {
-         throw new IllegalArgumentException("collection type not parameterized");
-      }
-      Type[] typeArguments = ( (ParameterizedType) collectionType ).getActualTypeArguments();
-      if (typeArguments.length==0)
-      {
-         throw new IllegalArgumentException("no type arguments for collection type");
-      }
-      Type typeArgument = typeArguments.length==1 ? typeArguments[0] : typeArguments[1]; //handle Maps
-      if (typeArgument instanceof ParameterizedType)
-      {
-         typeArgument = ((ParameterizedType) typeArgument).getRawType();
-      }
-      if ( !(typeArgument instanceof Class) )
-      {
-         throw new IllegalArgumentException("type argument not a class");
-      }
-      return (Class) typeArgument;
-   }
-   
-   public static Class getMapKeyType(Type collectionType)
-   {
-      if ( !(collectionType instanceof ParameterizedType) )
-      {
-         throw new IllegalArgumentException("collection type not parameterized");
-      }
-      Type[] typeArguments = ( (ParameterizedType) collectionType ).getActualTypeArguments();
-      if (typeArguments.length==0)
-      {
-         throw new IllegalArgumentException("no type arguments for collection type");
-      }
-      Type typeArgument = typeArguments[0];
-      if ( !(typeArgument instanceof Class) )
-      {
-         throw new IllegalArgumentException("type argument not a class");
-      }
-      return (Class) typeArgument;
-   }
-   
-   public static Method getSetterMethod(Class clazz, String name)
-   {
-      Method[] methods = clazz.getMethods();
-      for (Method method: methods)
-      {
-         String methodName = method.getName();
-         if ( methodName.startsWith("set") && method.getParameterTypes().length==1 )
-         {
-            if ( Introspector.decapitalize( methodName.substring(3) ).equals(name) )
-            {
-               return method;
-            }
-         }
-      }
-      throw new IllegalArgumentException("no such setter method: " + clazz.getName() + '.' + name);
-   }
-   
-   public static Method getGetterMethod(Class clazz, String name)
-   {
-      Method[] methods = clazz.getMethods();
-      for (Method method: methods)
-      {
-         String methodName = method.getName();
-         if ( method.getParameterTypes().length==0 )
-         {
-            if ( methodName.startsWith("get") )
-            {
-               if ( Introspector.decapitalize( methodName.substring(3) ).equals(name) )
-               {
-                  return method;
-               }
-            }
-            else if ( methodName.startsWith("is") )
-            {
-               if ( Introspector.decapitalize( methodName.substring(2) ).equals(name) )
-               {
-                  return method;
-               }
-            }
-         }
-      }
-      throw new IllegalArgumentException("no such getter method: " + clazz.getName() + '.' + name);
-   }
-   
-   /**
-    * Get all the getter methods annotated with the given annotation. Returns an empty list if
-    * none are found
-    */
-   public static List<Method> getGetterMethods(Class clazz, Class annotation) 
-   {
-      List<Method> methods = new ArrayList<Method>();
-      for (Method method : clazz.getMethods())
-      {
-         if (method.isAnnotationPresent(annotation))
-         {
-            methods.add(method);
-         }
-      }
-      return methods;
-   }
-   
-   public static Field getField(Class clazz, String name)
-   {
-      for ( Class superClass = clazz; superClass!=Object.class; superClass=superClass.getSuperclass() )
-      {
-         try
-         {
-            return superClass.getDeclaredField(name);
-         }
-         catch (NoSuchFieldException nsfe) {}
-      }
-      throw new IllegalArgumentException("no such field: " + clazz.getName() + '.' + name);
-   }
-   
-   /**
-    * Get all the fields which are annotated with the given annotation. Returns an empty list
-    * if none are found
-    */
-   public static List<Field> getFields(Class clazz, Class annotation)
-   {
-      List<Field> fields = new ArrayList<Field>();
-      for (Class superClass = clazz; superClass!=Object.class; superClass=superClass.getSuperclass())
-      {
-         for (Field field : superClass.getDeclaredFields())
-         {
-            if (field.isAnnotationPresent(annotation))
-            {
-               fields.add(field);
-            }
-         }
-      }
-      return fields;
-   }
-
-   public static Method getMethod(Annotation annotation, String name)
-   {
-      try
-      {
-         return annotation.annotationType().getMethod(name);
-      }
-      catch (NoSuchMethodException nsme)
-      {
-         return null;
-      }
-   }
-   
-   public static Method getMethod(Class clazz, String name)
-   {
-      for ( Class superClass = clazz; superClass!=Object.class; superClass=superClass.getSuperclass() )
-      {
-         try
-         {
-            return superClass.getDeclaredMethod(name);
-         }
-         catch (NoSuchMethodException nsme) {}
-      }
-      throw new IllegalArgumentException("no such method: " + clazz.getName() + '.' + name);
-   }
-   
-   /**
-    * Check to see if clazz is an instance of name
-    */
-   public static boolean isInstanceOf(Class clazz, String name)
-   {
-      if (name == null)
-      {
-         throw new IllegalArgumentException("name cannot be null");
-      }
-      for (Class c = clazz; c != Object.class; c = c.getSuperclass())
-      {
-         if (instanceOf(c, name))
-         {
-            return true;
-         }
-      }
-      return false;
-   }
-   
-   private static boolean instanceOf(Class clazz, String name)
-   {  
-      if (name.equals(clazz.getName()))
-      {
-         return true;
-      }
-      else
-      {
-         boolean found = false;
-         Class[] interfaces = clazz.getInterfaces();
-         for (int i = 0; i < interfaces.length && !found; i++)
-         {
-            found = instanceOf(interfaces[i], name);
-         }
-         return found;
-      }
-      
-   }
-
-}



More information about the seam-commits mailing list