]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix for ticket #10121, a unit test for the ticket's issue and a unit 90/490/2
authorJonni Nakari <jonni@vaadin.com>
Thu, 13 Dec 2012 12:41:26 +0000 (14:41 +0200)
committerJonni Nakari <jonni@vaadin.com>
Thu, 13 Dec 2012 12:41:26 +0000 (14:41 +0200)
test for the new method in ReflectTools

Change-Id: If8d57b4b38e8856ff2a9ef130dc71cf5b315858a

server/src/com/vaadin/data/fieldgroup/FieldGroup.java
server/src/com/vaadin/util/ReflectTools.java
server/tests/src/com/vaadin/tests/server/component/fieldgroup/FieldNamedDescription.java [new file with mode: 0644]
server/tests/src/com/vaadin/util/ReflectToolsGetFieldValueByType.java [new file with mode: 0644]
server/tests/src/com/vaadin/util/ReflectToolsGetPrimitiveFieldValue.java [new file with mode: 0644]

index 5a69cad62e6b5f68eb3b906ba9ce8cba15298185..51cd3126cbd7b99973b41b1199530c069f9d63a5 100644 (file)
@@ -830,7 +830,7 @@ public class FieldGroup implements Serializable {
             try {
                 // Get the field from the object
                 field = (Field<?>) ReflectTools.getJavaFieldValue(
-                        objectWithMemberFields, memberField);
+                        objectWithMemberFields, memberField, Field.class);
             } catch (Exception e) {
                 // If we cannot determine the value, just skip the field and try
                 // the next one
index 285d876e1ce72686a9fe1ba66629c645d8e8755a..2b0b4ce29a65c49245b65407b4dea180aa492caf 100644 (file)
@@ -93,6 +93,56 @@ public class ReflectTools {
         return field.get(object);
     }
 
+    /**
+     * Returns the value of the java field that is assignable to the property
+     * type.
+     * <p>
+     * Uses getter if a getter for the correct return type is present, otherwise
+     * tries to access even private fields directly. If the java field is not
+     * assignable to the property type throws an IllegalArgumentException.
+     * 
+     * @param object
+     *            The object containing the field
+     * @param field
+     *            The field we want to get the value for
+     * @param propertyType
+     *            The type the field must be assignable to
+     * @return The value of the field in the object
+     * @throws InvocationTargetException
+     *             If the value could not be retrieved
+     * @throws IllegalAccessException
+     *             If the value could not be retrieved
+     * @throws IllegalArgumentException
+     *             If the value could not be retrieved
+     */
+    public static Object getJavaFieldValue(Object object,
+            java.lang.reflect.Field field, Class<?> propertyType)
+            throws IllegalArgumentException, IllegalAccessException,
+            InvocationTargetException {
+        PropertyDescriptor pd;
+        try {
+            pd = new PropertyDescriptor(field.getName(), object.getClass());
+            if (propertyType.isAssignableFrom(pd.getPropertyType())) {
+                Method getter = pd.getReadMethod();
+                if (getter != null) {
+                    return getter.invoke(object, (Object[]) null);
+                }
+            }
+        } catch (IntrospectionException e1) {
+            // Ignore this and try to get directly using the field
+        }
+        // If the field's type cannot be casted in to the requested type
+        if (!propertyType.isAssignableFrom(field.getType())) {
+            throw new IllegalArgumentException();
+        }
+        // Try to get the value or throw an exception
+        if (!field.isAccessible()) {
+            // Try to gain access even if field is private
+            field.setAccessible(true);
+        }
+        return field.get(object);
+    }
+
     /**
      * Sets the value of a java field.
      * <p>
diff --git a/server/tests/src/com/vaadin/tests/server/component/fieldgroup/FieldNamedDescription.java b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/FieldNamedDescription.java
new file mode 100644 (file)
index 0000000..033f145
--- /dev/null
@@ -0,0 +1,53 @@
+package com.vaadin.tests.server.component.fieldgroup;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.fieldgroup.PropertyId;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.TextField;
+
+public class FieldNamedDescription {
+
+    @Test
+    public void bindReadOnlyPropertyToFieldGroup() {
+        // Create an item
+        PropertysetItem item = new PropertysetItem();
+        item.addItemProperty("name", new ObjectProperty<String>("Zaphod"));
+        item.addItemProperty("description", new ObjectProperty<String>(
+                "This is a description"));
+
+        // Define a form as a class that extends some layout
+        class MyForm extends FormLayout {
+            // Member that will bind to the "name" property
+            TextField name = new TextField("Name");
+
+            // This member will not bind to the desctiptionProperty as the name
+            // description conflicts with something in the binding process
+            @PropertyId("description")
+            TextField description = new TextField("Description");
+
+            public MyForm() {
+
+                // Add the fields
+                addComponent(name);
+                addComponent(description);
+            }
+        }
+
+        // Create one
+        MyForm form = new MyForm();
+
+        // Now create a binder that can also creates the fields
+        // using the default field factory
+        FieldGroup binder = new FieldGroup(item);
+        binder.bindMemberFields(form);
+
+        assertTrue(form.description.getValue().equals("This is a description"));
+    }
+
+}
diff --git a/server/tests/src/com/vaadin/util/ReflectToolsGetFieldValueByType.java b/server/tests/src/com/vaadin/util/ReflectToolsGetFieldValueByType.java
new file mode 100644 (file)
index 0000000..78be9b0
--- /dev/null
@@ -0,0 +1,65 @@
+package com.vaadin.util;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.junit.Test;
+
+public class ReflectToolsGetFieldValueByType {
+    @Test
+    public void getFieldValue() {
+        class MyClass {
+            public Integer getField() {
+                return 1;
+            }
+
+            public void setField(Integer i) {
+            }
+
+        }
+        class MySubClass extends MyClass {
+            public String field = "Hello";
+        }
+
+        MySubClass myInstance = new MySubClass();
+
+        java.lang.reflect.Field memberField;
+        Object fieldValue = new Boolean(false);
+        try {
+            memberField = myInstance.getClass().getField("field");
+            // Should get a String value. Without the third parameter (calling
+            // ReflectTools.getJavaFieldValue(Object object, Field field)) would
+            // get an Integer value
+            fieldValue = ReflectTools.getJavaFieldValue(myInstance,
+                    memberField, String.class);
+        } catch (Exception e) {
+        }
+        assertTrue(fieldValue instanceof String);
+
+    }
+
+    @Test
+    public void getFieldValueViaGetter() {
+        class MyClass {
+            public Integer field = 1;
+        }
+        class MySubClass extends MyClass {
+            public String field = "Hello";
+        }
+
+        MySubClass myInstance = new MySubClass();
+
+        java.lang.reflect.Field memberField;
+        try {
+            memberField = myInstance.getClass().getField("field");
+            // Should throw an IllegalArgument exception as the mySubClass class
+            // doesn't have an Integer field.
+            ReflectTools.getJavaFieldValue(myInstance,
+                    memberField, Integer.class);
+            fail("Previous method call should have thrown an exception");
+        } catch (Exception e) {
+        }
+    }
+}
\ No newline at end of file
diff --git a/server/tests/src/com/vaadin/util/ReflectToolsGetPrimitiveFieldValue.java b/server/tests/src/com/vaadin/util/ReflectToolsGetPrimitiveFieldValue.java
new file mode 100644 (file)
index 0000000..df192c5
--- /dev/null
@@ -0,0 +1,26 @@
+package com.vaadin.util;
+
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+
+public class ReflectToolsGetPrimitiveFieldValue {
+    @Test
+    public void getFieldValueViaGetter() {
+        class MyClass {
+            public int field = 1;
+        }
+
+        MyClass myInstance = new MyClass();
+
+        java.lang.reflect.Field memberField;
+        Object fieldValue = new Boolean(false);
+        try {
+            memberField = myInstance.getClass().getField("field");
+            fieldValue = ReflectTools.getJavaFieldValue(myInstance,
+                    memberField);
+        } catch (Exception e) {
+        }
+        assertFalse(fieldValue instanceof Boolean);
+    }
+}
\ No newline at end of file