geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject svn commit: r776331 - in /geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint: context/BlueprintObjectRecipe.java utils/ReflectionUtils.java
Date Tue, 19 May 2009 14:34:14 GMT
Author: gnodet
Date: Tue May 19 14:34:13 2009
New Revision: 776331

URL: http://svn.apache.org/viewvc?rev=776331&view=rev
Log:
Refactor property descriptors discovery to fix some use cases

Modified:
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java?rev=776331&r1=776330&r2=776331&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java
Tue May 19 14:34:13 2009
@@ -18,10 +18,6 @@
  */
 package org.apache.geronimo.blueprint.context;
 
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -46,9 +42,9 @@
 import org.apache.geronimo.blueprint.di.ConstructionException;
 import org.apache.geronimo.blueprint.di.Option;
 import org.apache.geronimo.blueprint.di.Recipe;
-import static org.apache.geronimo.blueprint.utils.TypeUtils.toClass;
 import org.apache.geronimo.blueprint.di.ReferenceRecipe;
 import org.apache.geronimo.blueprint.utils.ReflectionUtils;
+import static org.apache.geronimo.blueprint.utils.TypeUtils.toClass;
 
 /**
  *
@@ -623,7 +619,7 @@
     private void setProperty(Object instance, Class clazz, String propertyName, Object propertyValue)
{
         String[] names = propertyName.split("\\.");
         for (int i = 0; i < names.length - 1; i++) {
-            Method getter = getPropertyDescriptor(clazz, names[i]).getReadMethod();
+            Method getter = getPropertyDescriptor(clazz, names[i]).getGetter();
             if (getter != null) {
                 try {
                     instance = getter.invoke(instance);
@@ -642,7 +638,7 @@
                 throw new ConstructionException("No getter for " + names[i] + " property
on bean " + getName() + " when setting property " + propertyName + " on class " + clazz.getName());
             }
         }
-        Method setter = getPropertyDescriptor(clazz, names[names.length - 1]).getWriteMethod();
+        Method setter = getPropertyDescriptor(clazz, names[names.length - 1]).getSetter();
         if (setter != null) {
             // convert the value to type of setter/field
             Type type = setter.getGenericParameterTypes()[0];
@@ -678,20 +674,13 @@
         }
     }
 
-    PropertyDescriptor getPropertyDescriptor(Class clazz, String name) {
-        // TODO: it seems to fail in some cases, for example if there are two setters and
no getters
-        //    it should throw an exception
-        try {
-            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
-            for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
-                if (pd.getName().equals(name)) {
-                    return pd;
-                }
+    private ReflectionUtils.PropertyDescriptor getPropertyDescriptor(Class clazz, String
name) {
+        for (ReflectionUtils.PropertyDescriptor pd : ReflectionUtils.getPropertyDescriptors(clazz))
{
+            if (pd.getName().equals(name)) {
+                return pd;
             }
-            throw new ConstructionException("Unable to find property descriptor " + name
+ " on class " + clazz.getName());
-        } catch (IntrospectionException e) {
-            throw new ConstructionException("Unable to find property descriptor " + name
+ " on class " + clazz.getName(), e);
         }
+        throw new ConstructionException("Unable to find property descriptor " + name + "
on class " + clazz.getName());
     }
 
     private static Object UNMATCHED = new Object();

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java?rev=776331&r1=776330&r2=776331&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ReflectionUtils.java
Tue May 19 14:34:13 2009
@@ -19,9 +19,14 @@
 package org.apache.geronimo.blueprint.utils;
 
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.WeakHashMap;
 
 /**
  * TODO: javadoc
@@ -31,6 +36,8 @@
  */
 public class ReflectionUtils {
            
+    private static Map<Class, PropertyDescriptor[]> beanInfos = Collections.synchronizedMap(new
WeakHashMap<Class, PropertyDescriptor[]>());
+
     public static Set<String> getImplementedInterfaces(Set<String> classes, Class
clazz) {
         if (clazz != null && clazz != Object.class) {
             for (Class itf : clazz.getInterfaces()) {
@@ -81,4 +88,116 @@
         return methods;
     }
 
+    public static PropertyDescriptor[] getPropertyDescriptors(Class clazz) {
+        PropertyDescriptor[] properties = beanInfos.get(clazz);
+        if (properties == null) {
+            List<PropertyDescriptor> props = new ArrayList<PropertyDescriptor>();
+            for (Method method : clazz.getMethods()) {
+                if (Modifier.isStatic(method.getModifiers())) {
+                    continue;
+                }
+                String name = method.getName();
+                Class argTypes[] = method.getParameterTypes();
+                Class resultType = method.getReturnType();
+                if (name.length() > 3 && name.startsWith("set") && resultType
== Void.TYPE && argTypes.length == 1) {
+                    props.add(new PropertyDescriptor(decapitalize(name.substring(3)), argTypes[0],
null, method));
+
+                } else if (name.length() > 3 && name.startsWith("get") &&
argTypes.length == 0) {
+                    props.add(new PropertyDescriptor(decapitalize(name.substring(3)), resultType,
method, null));
+                } else if (name.length() > 2 && name.startsWith("is") &&
argTypes.length == 0 && resultType == boolean.class) {
+                    props.add(new PropertyDescriptor(decapitalize(name.substring(2)), resultType,
method, null));
+                }
+            }
+            PropertyDescriptor[] pds = props.toArray(new PropertyDescriptor[props.size()]);
+            for (int i = 0; i < pds.length - 1; i++) {
+                boolean remove = false;
+                for (int j = i + 1; j < pds.length; j++) {
+                    if (pds[i] != null && pds[j] != null) {
+                        if (pds[i].name.equals(pds[j].name)) {
+                            if (remove || !pds[i].type.equals(pds[j].type)) {
+                                remove = true;
+                                pds[j] = null;
+                                continue;
+                            } else {
+                                if (pds[j].getter != null) {
+                                    if (pds[i].getter == null) {
+                                        pds[i].getter = pds[j].getter;
+                                    } else if (pds[i].getter != pds[j].getter) {
+                                        remove = true;
+                                        pds[j] = null;
+                                        continue;
+                                    }
+                                }
+                                if (pds[j].setter != null) {
+                                    if (pds[i].setter == null) {
+                                        pds[i].setter = pds[j].setter;
+                                    } else if (pds[i].setter != pds[j].setter) {
+                                        remove = true;
+                                        pds[j] = null;
+                                        continue;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                if (remove) {
+                    pds[i] = null;
+                }
+            }
+            props.clear();
+            for (int i = 0; i < pds.length - 1; i++) {
+                if (pds[i] != null) {
+                    props.add(pds[i]);
+                }
+            }
+            properties = props.toArray(new PropertyDescriptor[props.size()]);
+            beanInfos.put(clazz, properties);
+        }
+        return properties;
+    }
+
+    private static String decapitalize(String name) {
+        if (name == null || name.length() == 0) {
+            return name;
+        }
+        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
+                Character.isUpperCase(name.charAt(0))) {
+            return name;
+        }
+        char chars[] = name.toCharArray();
+        chars[0] = Character.toLowerCase(chars[0]);
+        return new String(chars);
+    }
+
+    public static class PropertyDescriptor {
+        private String name;
+        private Class type;
+        private Method getter;
+        private Method setter;
+
+        public PropertyDescriptor(String name, Class type, Method getter, Method setter)
{
+            this.name = name;
+            this.type = type;
+            this.getter = getter;
+            this.setter = setter;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public Type getType() {
+            return type;
+        }
+
+        public Method getGetter() {
+            return getter;
+        }
+
+        public Method getSetter() {
+            return setter;
+        }
+    }
+
 }



Mime
View raw message