You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by db...@apache.org on 2006/11/27 02:24:22 UTC

svn commit: r479486 - in /geronimo/xbean/trunk/xbean-reflect/src: main/java/org/apache/xbean/recipe/ObjectRecipe.java test/java/org/apache/xbean/recipe/Box.java test/java/org/apache/xbean/recipe/ExplicitInjectionStyleTest.java

Author: dblevins
Date: Sun Nov 26 17:24:22 2006
New Revision: 479486

URL: http://svn.apache.org/viewvc?view=rev&rev=479486
Log:
(XBEAN-64) Methods to allow explicit designation of field properties vs setter properties vs constuctor properties

Added:
    geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/Box.java
    geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ExplicitInjectionStyleTest.java
Modified:
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java?view=diff&rev=479486&r1=479485&r2=479486
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java Sun Nov 26 17:24:22 2006
@@ -120,13 +120,26 @@
     }
 
     public void setProperty(String name, Object value) {
-        if (name == null) throw new NullPointerException("name is null");
+        setProperty(new Property(name), value);
+    }
+
+    public void setFieldProperty(String name, Object value){
+        setProperty(new FieldProperty(name), value);
+        options.add(Option.FIELD_INJECTION);
+    }
+
+    public void setMethodProperty(String name, Object value){
+        setProperty(new SetterProperty(name), value);
+    }
+
+    private void setProperty(Property key, Object value) {
         if (!RecipeHelper.isSimpleType(value)) {
             value = new ValueRecipe(value);
         }
-        properties.put(name, value);
+        properties.put(key, value);
     }
 
+
     public void setAllProperties(Map map) {
         if (map == null) throw new NullPointerException("map is null");
         for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
@@ -184,47 +197,45 @@
         // set remaining properties
         for (Iterator iterator = propertyValues.entrySet().iterator(); iterator.hasNext();) {
             Map.Entry entry = (Map.Entry) iterator.next();
-            String propertyName = (String) entry.getKey();
+            Property propertyName = (Property) entry.getKey();
             Object propertyValue = entry.getValue();
 
-            MissingAccessorException missingSetter = null;
-            Method setter = null;
+            Member member;
             try {
-                setter = findSetter(typeClass, propertyName, propertyValue, allowPrivate);
-                propertyValue = convert(setter.getParameterTypes()[0], propertyValue);
-                setter.invoke(instance, new Object[]{propertyValue});
-                continue;
+                if (propertyName instanceof SetterProperty){
+                    member = new MethodMember(findSetter(typeClass, propertyName.name, propertyValue, allowPrivate));
+                } else if (propertyName instanceof FieldProperty){
+                    member = new FieldMember(findField(typeClass, propertyName.name, propertyValue, allowPrivate));
+                } else {
+                    try {
+                        member = new MethodMember(findSetter(typeClass, propertyName.name, propertyValue, allowPrivate));
+                    } catch (MissingAccessorException noSetter) {
+                        if (!options.contains(Option.FIELD_INJECTION)) {
+                            throw noSetter;
+                        }
+
+                        try {
+                            member = new FieldMember(findField(typeClass, propertyName.name, propertyValue, allowPrivate));
+                        } catch (MissingAccessorException noField) {
+                            throw (noField.getMatchLevel() > noSetter.getMatchLevel())? noField: noSetter;
+                        }
+                    }
+                }
             } catch (MissingAccessorException e) {
-                missingSetter = e;
-            } catch (Exception e) {
-                throw new ConstructionException("Error setting property: " + setter);
-            }
-
-            MissingAccessorException missingField = null;
-            if (options.contains(Option.FIELD_INJECTION)){
-                Field field = null;
-                try {
-                    field = findField(typeClass, propertyName, propertyValue, allowPrivate);
-                    propertyValue = convert(field.getType(), propertyValue);
-                    field.set(instance, propertyValue);
+                if (ignoreMissingProperties){
+                    unsetProperties.put(propertyName.name, propertyValue);
                     continue;
-                } catch (MissingAccessorException e) {
-                    missingField = e;
-                } catch (Exception e) {
-                    throw new ConstructionException("Error setting property: " + field);
-                }
-            }
-
-            if (ignoreMissingProperties){
-                unsetProperties.put(propertyName, propertyValue);
-            } else {
-                if (missingField != null && missingField.getMatchLevel() > missingSetter.getMatchLevel()) {
-                    throw missingField;
                 } else {
-                    throw missingSetter;
+                    throw e;
                 }
             }
 
+            try {
+                propertyValue = convert(member.getType(), propertyValue);
+                member.setValue(instance, propertyValue);
+            } catch (Exception e) {
+                throw new ConstructionException("Error setting property: " + member);
+            }
         }
         return instance;
     }
@@ -756,5 +767,105 @@
                 return null;
             }
         });
+    }
+
+    public static interface Member {
+        Class getType();
+        void setValue(Object instance, Object value) throws Exception;
+    }
+
+    public static class MethodMember implements Member {
+        private final Method setter;
+
+        public MethodMember(Method method) {
+            this.setter = method;
+        }
+
+        public Class getType() {
+            return setter.getParameterTypes()[0];
+        }
+
+        public void setValue(Object instance, Object value) throws Exception {
+            setter.invoke(instance, new Object[]{value});
+        }
+
+        public String toString() {
+            return setter.toString();
+        }
+    }
+
+    public static class FieldMember implements Member {
+        private final Field field;
+
+        public FieldMember(Field field) {
+            this.field = field;
+        }
+
+        public Class getType() {
+            return field.getType();
+        }
+
+        public void setValue(Object instance, Object value) throws Exception {
+            field.set(instance, value);
+        }
+
+        public String toString() {
+            return field.toString();
+        }
+    }
+
+    private static class Property {
+        private final String name;
+
+        public Property(String name) {
+            if (name == null) throw new NullPointerException("name is null");
+            this.name = name;
+        }
+
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null) return false;
+            if (o instanceof String){
+                return this.name.equals(o);
+            }
+            if (o instanceof Property) {
+                Property property = (Property) o;
+                return this.name.equals(property.name);
+            }
+            return false;
+        }
+
+        public int hashCode() {
+            return name.hashCode();
+        }
+
+        public String toString() {
+            return name;
+        }
+    }
+
+    private static class SetterProperty extends Property {
+        public SetterProperty(String name) {
+            super(name);
+        }
+        public int hashCode() {
+            return super.hashCode()+2;
+        }
+        public String toString() {
+            return "[setter] "+toString();
+        }
+
+    }
+    private static class FieldProperty extends Property {
+        public FieldProperty(String name) {
+            super(name);
+        }
+
+        public int hashCode() {
+            return super.hashCode()+1;
+        }
+        public String toString() {
+            return "[field] "+toString();
+        }
     }
 }

Added: geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/Box.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/Box.java?view=auto&rev=479486
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/Box.java (added)
+++ geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/Box.java Sun Nov 26 17:24:22 2006
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.xbean.recipe;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class Box {
+
+    private int width;
+    private int height;
+    private int depth;
+
+    public Box() {
+    }
+
+    public Box(int width, int height, int depth) {
+        this.depth = depth;
+        this.height = height;
+        this.width = width;
+    }
+
+    public int getDepth() {
+        return depth;
+    }
+
+    public void setDepth(int depth) {
+        this.depth = depth * 2;
+    }
+
+    public int getHeight() {
+        return height;
+    }
+
+    public void setHeight(int height) {
+        this.height = height;
+    }
+
+    public int getWidth() {
+        return width;
+    }
+
+    public void setWidth(int width) {
+        this.width = width;
+    }
+
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final Box box = (Box) o;
+
+        return depth == box.depth && height == box.height && width == box.width;
+    }
+
+    public String toString() {
+        return "Box(width=" +width+ ", height=" + height + ", depth=" + depth+ ")";
+    }
+}

Added: geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ExplicitInjectionStyleTest.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ExplicitInjectionStyleTest.java?view=auto&rev=479486
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ExplicitInjectionStyleTest.java (added)
+++ geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ExplicitInjectionStyleTest.java Sun Nov 26 17:24:22 2006
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.xbean.recipe;
+
+import junit.framework.TestCase;
+import org.apache.xbean.propertyeditor.PropertyEditors;
+
+public class ExplicitInjectionStyleTest extends TestCase {
+
+    protected void setUp() throws Exception {
+        PropertyEditors.class.getName();
+    }
+
+    public void testAll() throws Exception {
+        Box expected = new Box(10, 20, 30);
+
+
+        ObjectRecipe objectRecipe = new ObjectRecipe(Box.class);
+        objectRecipe.allow(Option.PRIVATE_PROPERTIES);
+
+        objectRecipe.setProperty("width", "10");
+        objectRecipe.setMethodProperty("height", "20");
+        objectRecipe.setFieldProperty("depth", "30");
+
+        Box actual = (Box) objectRecipe.create(Box.class.getClassLoader());
+        assertEquals("box", expected, actual);
+
+        objectRecipe.setMethodProperty("depth", "15");
+
+        actual = (Box) objectRecipe.create(Box.class.getClassLoader());
+        assertEquals("box", expected, actual);
+    }
+
+}