[weld-commits] Weld SVN: r6371 - in extensions/trunk/src/main/java/org/jboss/weld/extensions/util: properties and 1 other directory.

weld-commits at lists.jboss.org weld-commits at lists.jboss.org
Tue Jun 1 12:34:10 EDT 2010


Author: pete.muir at 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));
+   }
+}



More information about the weld-commits mailing list