[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