Author: pete.muir(a)jboss.org
Date: 2010-06-01 12:34:09 -0400 (Tue, 01 Jun 2010)
New Revision: 6371
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/AbstractBeanProperty.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/AnnotatedBeanProperty.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/FieldProperty.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/MethodProperty.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Properties.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Property.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/TypeAnnotatedBeanProperty.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/TypedBeanProperty.java
Removed:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AbstractBeanProperty.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AnnotatedBeanProperty.java
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/TypedBeanProperty.java
Log:
tidy up on properties stuff
Deleted:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AbstractBeanProperty.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AbstractBeanProperty.java 2010-06-01
13:58:26 UTC (rev 6370)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AbstractBeanProperty.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -1,365 +0,0 @@
-package org.jboss.weld.extensions.util;
-
-import java.beans.Introspector;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-
-/**
- * Base class for bean property wrappers
- *
- * @author Shane Bryzak
- */
-public class AbstractBeanProperty
-{
- /**
- * Subclasses should provide an implementation of FieldMatcher to determine
- * whether a Field contains the bean property
- */
- interface FieldMatcher
- {
- boolean matches(Field f);
- }
-
- /**
- * Subclasses should provide an implementation of MethodMatcher to determine
- * whether a method provides the bean property
- */
- interface MethodMatcher
- {
- boolean matches(Method m);
- }
-
- /**
- * Property field
- */
- private Field propertyField;
-
- /**
- * Property getter method
- */
- private Method propertyGetter;
-
- /**
- * Property setter method
- */
- private Method propertySetter;
-
- /**
- * Property name
- */
- private String name;
-
- /**
- * Flag indicating whether the bean property value is contained in a field
- */
- private boolean isFieldProperty;
-
- /**
- * Flag indicating whether the property exists
- */
- private boolean exists = false;
-
- private Type propertyType;
-
- private FieldMatcher fieldMatcher;
-
- private MethodMatcher methodMatcher;
-
- /**
- *
- * @param targetClass
- */
- public AbstractBeanProperty(Class<?> targetClass, FieldMatcher fieldMatcher,
- MethodMatcher methodMatcher)
- {
- this.fieldMatcher = fieldMatcher;
- this.methodMatcher = methodMatcher;
-
- // First check declared fields
- for (Field f : targetClass.getDeclaredFields())
- {
- if (fieldMatcher.matches(f))
- {
- setupFieldProperty(f);
- exists = true;
- return;
- }
- }
-
- // Then check public fields, in case it's inherited
- for (Field f : targetClass.getFields())
- {
- if (fieldMatcher.matches(f))
- {
- setupFieldProperty(f);
- exists = true;
- return;
- }
- }
-
- // Then check public methods (we ignore private methods)
- for (Method m : targetClass.getMethods())
- {
- if (methodMatcher.matches(m))
- {
- String methodName = m.getName();
-
- if ( m.getName().startsWith("get") )
- {
- this.name = Introspector.decapitalize( m.getName().substring(3) );
- }
- else if ( methodName.startsWith("is") )
- {
- this.name = Introspector.decapitalize( m.getName().substring(2) );
- }
-
- if (this.name != null)
- {
- this.propertyGetter = getGetterMethod(targetClass, this.name);
- this.propertySetter = getSetterMethod(targetClass, this.name);
- this.propertyType = this.propertyGetter.getGenericReturnType();
- isFieldProperty = false;
- exists = true;
- }
- else
- {
- throw new IllegalStateException("Invalid accessor method, must start
with 'get' or 'is'. " +
- "Method: " + m + " in class: " + targetClass);
- }
- }
- }
- }
-
- public FieldMatcher getFieldMatcher()
- {
- return fieldMatcher;
- }
-
- public MethodMatcher getMethodMatcher()
- {
- return methodMatcher;
- }
-
- private void setupFieldProperty(Field propertyField)
- {
- this.propertyField = propertyField;
- isFieldProperty = true;
- this.name = propertyField.getName();
- this.propertyType = propertyField.getGenericType();
- }
-
- /**
- * 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
- {
- if (isFieldProperty)
- {
- setFieldValue(propertyField, bean, value);
- }
- else
- {
- invokeMethod(propertySetter, bean, value);
- }
- }
-
- /**
- * 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 (isFieldProperty)
- {
- return getFieldValue(propertyField, bean);
- }
- else
- {
- return invokeMethod(propertyGetter, bean);
- }
- }
-
- /**
- * Returns the property type
- *
- * @return The property type
- */
- public Type getPropertyType()
- {
- return propertyType;
- }
-
- /**
- * Returns true if the property has been successfully located, otherwise
- * returns false.
- *
- * @return
- */
- public boolean exists()
- {
- return exists;
- }
-
- /**
- * 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()
- {
- return name;
- }
-
- private Object getFieldValue(Field field, Object obj)
- {
- field.setAccessible(true);
- try
- {
- return field.get(obj);
- }
- catch (IllegalAccessException e)
- {
- throw new RuntimeException(buildGetFieldValueErrorMessage(field, obj), e);
- }
- catch (NullPointerException ex)
- {
- NullPointerException ex2 = new NullPointerException(
- buildGetFieldValueErrorMessage(field, obj));
- ex2.initCause(ex.getCause());
- throw ex2;
- }
- }
-
- private String buildGetFieldValueErrorMessage(Field field, Object obj)
- {
- return String.format("Exception reading [%s] field from object [%s].",
- field.getName(), obj);
- }
-
- private void setFieldValue(Field field, Object obj, Object value)
- {
- field.setAccessible(true);
- try
- {
- field.set(obj, value);
- }
- catch (IllegalAccessException e)
- {
- throw new RuntimeException(buildSetFieldValueErrorMessage(field, obj, value),
e);
- }
- catch (NullPointerException ex)
- {
- NullPointerException ex2 = new NullPointerException(
- buildSetFieldValueErrorMessage(field, obj, value));
- ex2.initCause(ex.getCause());
- throw ex2;
- }
- }
-
- private String buildSetFieldValueErrorMessage(Field field, Object obj, Object value)
- {
- return String.format("Exception setting [%s] field on object [%s] to value
[%s]",
- field.getName(), obj, value);
- }
-
- private Object invokeMethod(Method method, Object obj, Object... args)
- {
- try
- {
- return method.invoke(obj, args);
- }
- catch (IllegalAccessException ex)
- {
- throw new RuntimeException(buildInvokeMethodErrorMessage(method, obj, args),
ex);
- }
- catch (IllegalArgumentException ex)
- {
- throw new IllegalArgumentException(buildInvokeMethodErrorMessage(method, obj,
args), ex.getCause());
- }
- catch (InvocationTargetException ex)
- {
- throw new RuntimeException(buildInvokeMethodErrorMessage(method, obj, args),
ex);
- }
- catch (NullPointerException ex)
- {
- NullPointerException ex2 = new
NullPointerException(buildInvokeMethodErrorMessage(method, obj, args));
- ex2.initCause(ex.getCause());
- throw ex2;
- }
- catch (ExceptionInInitializerError e)
- {
- throw new RuntimeException(buildInvokeMethodErrorMessage(method, obj, args),
e);
- }
- }
-
- private String buildInvokeMethodErrorMessage(Method method, Object obj, Object...
args)
- {
- StringBuilder message = new StringBuilder(String.format(
- "Exception invoking method [%s] on object [%s], using arguments
[",
- method.getName(), obj));
- if (args != null) for (int i = 0; i < args.length; i++) message.append((i > 0
? "," : "") + args[i]);
- message.append("]");
- return message.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);
- }
-}
Deleted:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AnnotatedBeanProperty.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AnnotatedBeanProperty.java 2010-06-01
13:58:26 UTC (rev 6370)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AnnotatedBeanProperty.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -1,108 +0,0 @@
-package org.jboss.weld.extensions.util;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-/**
- * A convenience class for working with an annotated property (either a field or
- * method) of a JavaBean class. By providing an overridden annotationMatches()
- * method in a subclass, annotations may be matched on their attribute values or
- * other conditions.
- *
- * @author Shane Bryzak
- */
-public class AnnotatedBeanProperty<T extends Annotation> extends
AbstractBeanProperty
-{
- private T annotation;
-
- public interface AnnotationMatcher
- {
- boolean matches(Annotation annotation);
- }
-
- private static class DefaultAnnotationMatcher implements AnnotationMatcher
- {
- public boolean matches(Annotation annotation)
- {
- return true;
- }
- }
-
- private static final AnnotationMatcher defaultMatcher = new
DefaultAnnotationMatcher();
-
- private static class AnnotatedMatcher implements FieldMatcher, MethodMatcher
- {
- private Class<? extends Annotation> annotationClass;
- private AnnotationMatcher matcher;
- private Annotation match;
-
- public AnnotatedMatcher(Class<? extends Annotation> annotationClass,
- AnnotationMatcher matcher)
- {
- this.annotationClass = annotationClass;
- this.matcher = matcher;
- }
-
- public boolean matches(Field f)
- {
- if (f.isAnnotationPresent(annotationClass) &&
- matcher.matches(f.getAnnotation(annotationClass)))
- {
- this.match = f.getAnnotation(annotationClass);
- return true;
- }
- return false;
- }
-
- public boolean matches(Method m)
- {
- if (m.isAnnotationPresent(annotationClass) &&
- matcher.matches(m.getAnnotation(annotationClass)))
- {
- this.match = m.getAnnotation(annotationClass);
- return true;
- }
- return false;
- }
-
- public Annotation getMatch()
- {
- return match;
- }
- }
-
- /**
- * 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.
- */
- @SuppressWarnings("unchecked")
- public AnnotatedBeanProperty(Class<?> cls, Class<T> annotationClass,
- AnnotationMatcher annotationMatcher)
- {
- super(cls, new AnnotatedMatcher(annotationClass, annotationMatcher != null ?
annotationMatcher : defaultMatcher),
- new AnnotatedMatcher(annotationClass, annotationMatcher != null ?
annotationMatcher : defaultMatcher));
-
- if (((AnnotatedMatcher) getFieldMatcher()).getMatch() != null)
- {
- this.annotation = (T) ((AnnotatedMatcher) getFieldMatcher()).getMatch();
- }
- else if (((AnnotatedMatcher) getMethodMatcher()).getMatch() != null)
- {
- this.annotation = (T) ((AnnotatedMatcher) getMethodMatcher()).getMatch();
- }
- }
-
- /**
- * Returns the annotation instance
- *
- * @return The annotation instance
- */
- public T getAnnotation()
- {
- return annotation;
- }
-}
\ No newline at end of file
Deleted:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/TypedBeanProperty.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/TypedBeanProperty.java 2010-06-01
13:58:26 UTC (rev 6370)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/TypedBeanProperty.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -1,43 +0,0 @@
-package org.jboss.weld.extensions.util;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-/**
- * A convenience class for working with a typed property (either a field or
- * method) of a JavaBean class.
- *
- * @author Shane Bryzak
- */
-public class TypedBeanProperty extends AbstractBeanProperty
-{
- private static class TypedMatcher implements FieldMatcher, MethodMatcher
- {
- private Class<?> propertyClass;
-
- public TypedMatcher(Class<?> propertyClass)
- {
- if (propertyClass == null)
- {
- throw new IllegalArgumentException("propertyClass can not be
null.");
- }
-
- this.propertyClass = propertyClass;
- }
-
- public boolean matches(Field f)
- {
- return propertyClass.equals(f.getType());
- }
-
- public boolean matches(Method m)
- {
- return propertyClass.equals(m.getReturnType());
- }
- }
-
- public TypedBeanProperty(Class<?> cls, Class<?> propertyClass)
- {
- super(cls, new TypedMatcher(propertyClass), new TypedMatcher(propertyClass));
- }
-}
Copied:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/AbstractBeanProperty.java
(from rev 6370,
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AbstractBeanProperty.java)
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/AbstractBeanProperty.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/AbstractBeanProperty.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -0,0 +1,112 @@
+package org.jboss.weld.extensions.util.properties;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * Base class for bean property wrappers. Non-deterministic in the case their
+ * are multiple annotated properties.
+ *
+ * Threadsafe.
+ *
+ * @author Shane Bryzak
+ */
+public class AbstractBeanProperty<V>
+{
+
+ static class Matched<T>
+ {
+
+ private T matched;
+
+ void setMatched(T matched)
+ {
+ this.matched = matched;
+ }
+
+ T getMatched()
+ {
+ return matched;
+ }
+
+ }
+
+ /**
+ * Subclasses should provide an implementation of FieldMatcher to determine
+ * whether a Field contains the bean property
+ */
+ static interface FieldMatcher
+ {
+ boolean matches(Field field);
+ }
+
+ /**
+ * Subclasses should provide an implementation of MethodMatcher to determine
+ * whether a method provides the bean property
+ */
+ static interface MethodMatcher
+ {
+ boolean matches(Method method);
+ }
+
+ /**
+ * Property field
+ */
+ private final Property<V> property;
+
+ /**
+ *
+ * @param targetClass
+ */
+ public AbstractBeanProperty(Class<?> targetClass, FieldMatcher fieldMatcher,
MethodMatcher methodMatcher)
+ {
+
+ // First check declared fields
+ for (Field field : targetClass.getDeclaredFields())
+ {
+ if (fieldMatcher.matches(field))
+ {
+ this.property = Properties.createProperty(field);
+ return;
+ }
+ }
+
+ // Then check public fields, in case it's inherited
+ for (Field field : targetClass.getFields())
+ {
+ if (fieldMatcher.matches(field))
+ {
+ this.property = Properties.createProperty(field);
+ return;
+ }
+ }
+
+ // Then check public methods (we ignore private methods)
+ for (Method method : targetClass.getMethods())
+ {
+ if (methodMatcher.matches(method))
+ {
+ this.property = Properties.createProperty(method);
+ return;
+ }
+ }
+ this.property = null;
+ }
+
+ /**
+ * Returns true if the property has been successfully located, otherwise
+ * returns false.
+ *
+ * @return
+ */
+ public boolean exists()
+ {
+ return property != null;
+ }
+
+ public Property<V> getProperty()
+ {
+ return property;
+ }
+
+}
Copied:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/AnnotatedBeanProperty.java
(from rev 6370,
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/AnnotatedBeanProperty.java)
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/AnnotatedBeanProperty.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/AnnotatedBeanProperty.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -0,0 +1,63 @@
+package org.jboss.weld.extensions.util.properties;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+
+/**
+ * A convenience class for working with an annotated property (either a field or
+ * method) of a JavaBean class.
+ *
+ * @author Shane Bryzak
+ * @author Pete Muir
+ */
+public class AnnotatedBeanProperty<V> extends AbstractBeanProperty<V>
+{
+
+ /**
+ * An {@link AnnotatedElement} based matcher
+ *
+ * @author pmuir
+ *
+ */
+ public interface AnnotationMatcher
+ {
+ boolean matches(AnnotatedElement element);
+ }
+
+ private static class AnnotationMatcherAdapter implements FieldMatcher, MethodMatcher
+ {
+ private final AnnotationMatcher matcher;
+
+ public AnnotationMatcherAdapter(AnnotationMatcher matcher)
+ {
+ if (matcher == null)
+ {
+ throw new IllegalArgumentException("matcher must not be null");
+ }
+ this.matcher = matcher;
+ }
+
+ public boolean matches(Field f)
+ {
+ return matcher.matches(f);
+ }
+
+ public boolean matches(Method m)
+ {
+ return matcher.matches(m);
+ }
+ }
+
+ public AnnotatedBeanProperty(Class<?> targetClass, AnnotationMatcher
annotationMatcher)
+ {
+ this(targetClass, new AnnotationMatcherAdapter(annotationMatcher));
+ }
+
+ private AnnotatedBeanProperty(Class<?> targetClass, AnnotationMatcherAdapter
matcher)
+ {
+ super(targetClass, matcher, matcher);
+ }
+
+}
\ No newline at end of file
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/FieldProperty.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/FieldProperty.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/FieldProperty.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -0,0 +1,89 @@
+/**
+ *
+ */
+package org.jboss.weld.extensions.util.properties;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+
+class FieldProperty<V> implements Property<V>
+{
+
+
+ private static String buildGetFieldValueErrorMessage(Field field, Object obj)
+ {
+ return String.format("Exception reading [%s] field from object [%s].",
field.getName(), obj);
+ }
+
+ private static String buildSetFieldValueErrorMessage(Field field, Object obj, Object
value)
+ {
+ return String.format("Exception setting [%s] field on object [%s] to value
[%s]", field.getName(), obj, value);
+ }
+
+ private final Field field;
+
+ FieldProperty(Field field)
+ {
+ this.field = field;
+ }
+
+ public String getName()
+ {
+ return field.getName();
+ }
+
+ public Type getBaseType()
+ {
+ return field.getGenericType();
+ }
+
+ public Field getAnnotatedElement()
+ {
+ return field;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Class<V> getJavaClass()
+ {
+ return (Class<V>) field.getType();
+ }
+
+ public V getValue(Object instance)
+ {
+ field.setAccessible(true);
+ try
+ {
+ return getJavaClass().cast(field.get(instance));
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new RuntimeException(buildGetFieldValueErrorMessage(field, instance), e);
+ }
+ catch (NullPointerException ex)
+ {
+ NullPointerException ex2 = new
NullPointerException(buildGetFieldValueErrorMessage(field, instance));
+ ex2.initCause(ex.getCause());
+ throw ex2;
+ }
+ }
+
+ public void setValue(Object instance, V value)
+ {
+ field.setAccessible(true);
+ try
+ {
+ field.set(instance, value);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new RuntimeException(buildSetFieldValueErrorMessage(field, instance,
value), e);
+ }
+ catch (NullPointerException ex)
+ {
+ NullPointerException ex2 = new
NullPointerException(buildSetFieldValueErrorMessage(field, instance, value));
+ ex2.initCause(ex.getCause());
+ throw ex2;
+ }
+ }
+
+}
\ No newline at end of file
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/FieldProperty.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/MethodProperty.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/MethodProperty.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/MethodProperty.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -0,0 +1,151 @@
+/**
+ *
+ */
+package org.jboss.weld.extensions.util.properties;
+
+import java.beans.Introspector;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+class MethodProperty<V> implements Property<V>
+{
+
+ private static String buildInvokeMethodErrorMessage(Method method, Object obj,
Object... args)
+ {
+ StringBuilder message = new StringBuilder(String.format("Exception invoking
method [%s] on object [%s], using arguments [", method.getName(), obj));
+ if (args != null)
+ for (int i = 0; i < args.length; i++)
+ message.append((i > 0 ? "," : "") + args[i]);
+ message.append("]");
+ return message.toString();
+ }
+
+ private static Object invokeMethod(Method method, Object obj, Object... args)
+ {
+ try
+ {
+ return method.invoke(obj, args);
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RuntimeException(buildInvokeMethodErrorMessage(method, obj, args),
ex);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new IllegalArgumentException(buildInvokeMethodErrorMessage(method, obj,
args), ex.getCause());
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RuntimeException(buildInvokeMethodErrorMessage(method, obj, args),
ex);
+ }
+ catch (NullPointerException ex)
+ {
+ NullPointerException ex2 = new
NullPointerException(buildInvokeMethodErrorMessage(method, obj, args));
+ ex2.initCause(ex.getCause());
+ throw ex2;
+ }
+ catch (ExceptionInInitializerError e)
+ {
+ throw new RuntimeException(buildInvokeMethodErrorMessage(method, obj, args),
e);
+ }
+ }
+
+ private 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);
+ }
+
+ private static Method getGetterMethod(Class<?> clazz, String name)
+ {
+ for (Method method : clazz.getDeclaredMethods())
+ {
+ 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);
+ }
+
+ private final Method getterMethod;
+ private final String propertyName;
+ private final Method setterMethod;
+
+ MethodProperty(Method method)
+ {
+ if (method.getName().startsWith("get"))
+ {
+ this.propertyName = Introspector.decapitalize(method.getName().substring(3));
+ }
+ else if (method.getName().startsWith("is"))
+ {
+ this.propertyName = Introspector.decapitalize(method.getName().substring(2));
+ }
+ else
+ {
+ throw new IllegalArgumentException("Invalid accessor method, must start
with 'get' or 'is'. " + "Method: " + method);
+ }
+ this.getterMethod = getGetterMethod(method.getDeclaringClass(), propertyName);
+ this.setterMethod = getSetterMethod(method.getDeclaringClass(), propertyName);
+
+ }
+
+ public String getName()
+ {
+ return propertyName;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Class<V> getJavaClass()
+ {
+ return (Class<V>) getterMethod.getReturnType();
+ }
+
+ public Type getBaseType()
+ {
+ return getterMethod.getGenericReturnType();
+ }
+
+ public Method getAnnotatedElement()
+ {
+ return getterMethod;
+ }
+
+ public V getValue(Object instance)
+ {
+ return getJavaClass().cast(invokeMethod(getterMethod, instance));
+ }
+
+ public void setValue(Object instance, V value)
+ {
+ invokeMethod(setterMethod, instance, value);
+ }
+
+}
\ No newline at end of file
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/MethodProperty.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Properties.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Properties.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Properties.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -0,0 +1,42 @@
+package org.jboss.weld.extensions.util.properties;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * Utility class for working with JavaBean style properties
+ *
+ * @author pmuir
+ *
+ */
+public class Properties
+{
+
+ private Properties() {}
+
+ /**
+ * Create a JavaBean style property from the field
+ *
+ * @param <V>
+ * @param field
+ * @return
+ */
+ public static <V> Property<V> createProperty(Field field)
+ {
+ return new FieldProperty<V>(field);
+ }
+
+ /**
+ * Create a JavaBean style property from the specified method
+ *
+ * @param <V>
+ * @param method
+ * @return
+ * @throws IllegalArgumentException if the method does not match JavaBean conventions
+ */
+ public static <V> Property<V> createProperty(Method method)
+ {
+ return new MethodProperty<V>(method);
+ }
+
+}
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Properties.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Property.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Property.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Property.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -0,0 +1,62 @@
+package org.jboss.weld.extensions.util.properties;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Type;
+
+/**
+ * A representation of a JavaBean style property
+ *
+ * @see Properties
+ *
+ * @author pmuir
+ *
+ * @param <V>
+ */
+public interface Property<V>
+{
+
+ /**
+ * 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();
+
+ /**
+ * Returns the property type
+ *
+ * @return The property type
+ */
+ public Type getBaseType();
+
+ /**
+ * Returns the property type
+ *
+ * @return The property type
+ */
+ public Class<V> getJavaClass();
+
+ public AnnotatedElement getAnnotatedElement();
+
+ /**
+ * Returns the property value for the specified bean. The property to be
+ * returned is either a field or getter method.
+ *
+ * @param bean The bean to read the property from
+ * @return The property value
+ */
+ public V getValue(Object instance);
+
+ /**
+ * 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.
+ *
+ * @param bean The bean containing the property to set
+ * @param value The new property value
+ */
+ public void setValue(Object instance, V value);
+
+}
\ No newline at end of file
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/Property.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/TypeAnnotatedBeanProperty.java
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/TypeAnnotatedBeanProperty.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/TypeAnnotatedBeanProperty.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -0,0 +1,72 @@
+package org.jboss.weld.extensions.util.properties;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+
+public class TypeAnnotatedBeanProperty<T extends Annotation, V> extends
AnnotatedBeanProperty<V>
+{
+
+
+ /**
+ * An AnnotationMatcher which simply requires the the annotation to be of the
+ * specified type
+ *
+ */
+ private static class TypeAnnotationMatcher<T extends Annotation> implements
AnnotationMatcher
+ {
+
+ private final Class<T> annotationType;
+
+ private final Matched<T> matched;
+
+ public TypeAnnotationMatcher(Class<T> annotationType, Matched<T>
matched)
+ {
+ if (annotationType == null)
+ {
+ throw new IllegalArgumentException("annotationType must not be
null");
+ }
+ this.annotationType = annotationType;
+ this.matched = matched;
+ }
+
+ public boolean matches(AnnotatedElement element)
+ {
+ if (element.isAnnotationPresent(annotationType))
+ {
+ this.matched.setMatched(element.getAnnotation(annotationType));
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ private final T annotation;
+
+ /**
+ * 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 TypeAnnotatedBeanProperty(Class<?> cls, Class<T> annotationType)
+ {
+ this(cls, annotationType, new Matched<T>());
+ }
+
+ private TypeAnnotatedBeanProperty(Class<?> targetClass, Class<T>
annotationType, Matched<T> matched)
+ {
+ super(targetClass, new TypeAnnotationMatcher<T>(annotationType, matched));
+ this.annotation = matched.getMatched();
+ }
+
+ public T getAnnotation()
+ {
+ return annotation;
+ }
+
+}
Property changes on:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/TypeAnnotatedBeanProperty.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Copied:
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/TypedBeanProperty.java
(from rev 6370,
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/TypedBeanProperty.java)
===================================================================
---
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/TypedBeanProperty.java
(rev 0)
+++
extensions/trunk/src/main/java/org/jboss/weld/extensions/util/properties/TypedBeanProperty.java 2010-06-01
16:34:09 UTC (rev 6371)
@@ -0,0 +1,44 @@
+package org.jboss.weld.extensions.util.properties;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+
+/**
+ * A convenience class for working with a typed property (either a field or
+ * method) of a JavaBean class.
+ *
+ * @author Shane Bryzak
+ */
+public class TypedBeanProperty<V> extends AbstractBeanProperty<V>
+{
+ private static class TypedMatcher<V> implements FieldMatcher, MethodMatcher
+ {
+ private Class<V> propertyClass;
+
+ public TypedMatcher(Class<V> propertyClass)
+ {
+ if (propertyClass == null)
+ {
+ throw new IllegalArgumentException("propertyClass can not be
null.");
+ }
+
+ this.propertyClass = propertyClass;
+ }
+
+ public boolean matches(Field f)
+ {
+ return propertyClass.equals(f.getType());
+ }
+
+ public boolean matches(Method m)
+ {
+ return propertyClass.equals(m.getReturnType());
+ }
+ }
+
+ public TypedBeanProperty(Class<?> targetClass, Class<V> propertyClass)
+ {
+ super(targetClass, new TypedMatcher<V>(propertyClass), new
TypedMatcher<V>(propertyClass));
+ }
+}