]> source.dussan.org Git - vaadin-framework.git/commitdiff
#8095 Added field type to field factory to be able to validate that a
authorArtur Signell <artur@vaadin.com>
Fri, 16 Dec 2011 07:27:56 +0000 (09:27 +0200)
committerArtur Signell <artur@vaadin.com>
Fri, 16 Dec 2011 07:27:56 +0000 (09:27 +0200)
field of correct type is created and to be able to create different
fields (e.g. selects) based on what the user wants.

src/com/vaadin/data/fieldbinder/DefaultFieldBinderFieldFactory.java
src/com/vaadin/data/fieldbinder/FieldBinderFieldFactory.java
src/com/vaadin/data/fieldbinder/FormBuilder.java

index c2dac851649a471d4e5495af9983ee0625c9c3a1..18a979cf655d82522fa4a4d82537e3b9fc73c099 100644 (file)
@@ -6,41 +6,118 @@ package com.vaadin.data.fieldbinder;
 import java.util.EnumSet;\r
 \r
 import com.vaadin.data.Item;\r
+import com.vaadin.ui.AbstractSelect;\r
+import com.vaadin.ui.AbstractTextField;\r
 import com.vaadin.ui.CheckBox;\r
 import com.vaadin.ui.ComboBox;\r
 import com.vaadin.ui.Field;\r
+import com.vaadin.ui.ListSelect;\r
+import com.vaadin.ui.NativeSelect;\r
+import com.vaadin.ui.OptionGroup;\r
+import com.vaadin.ui.PasswordField;\r
+import com.vaadin.ui.Table;\r
+import com.vaadin.ui.TextArea;\r
 import com.vaadin.ui.TextField;\r
 \r
 public class DefaultFieldBinderFieldFactory implements FieldBinderFieldFactory {\r
 \r
     public static final Object CAPTION_PROPERTY_ID = "Caption";\r
 \r
-    @SuppressWarnings("unchecked")\r
-    public Field createField(Class<?> type) {\r
+    public Field createField(Class<?> type, Class<? extends Field> fieldType) {\r
         if (Enum.class.isAssignableFrom(type)) {\r
-            return createEnumField((Class<? extends Enum<?>>) type);\r
-        }\r
-        if (Boolean.class.isAssignableFrom(type)\r
+            return createEnumField(type, fieldType);\r
+        } else if (Boolean.class.isAssignableFrom(type)\r
                 || boolean.class.isAssignableFrom(type)) {\r
-            return createBooleanField();\r
+            return createBooleanField(fieldType);\r
         }\r
-        return createDefaultField(type);\r
+        return createDefaultField(type, fieldType);\r
     }\r
 \r
-    private Field createBooleanField() {\r
-        CheckBox cb = new CheckBox(null);\r
-        cb.setImmediate(true);\r
-        return cb;\r
-    }\r
+    private Field createEnumField(Class<?> type,\r
+            Class<? extends Field> fieldType) {\r
+        if (AbstractSelect.class.isAssignableFrom(fieldType)) {\r
+            AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType);\r
+            populateWithEnumData(s, (Class<? extends Enum>) type);\r
+            return s;\r
+        }\r
 \r
-    private Field createDefaultField(Class<?> type) {\r
-        return new TextField();\r
+        return null;\r
     }\r
 \r
-    public Field createEnumField(Class<? extends Enum> enumClass) {\r
-        ComboBox select = new ComboBox(null);\r
+    protected AbstractSelect createCompatibleSelect(\r
+            Class<? extends AbstractSelect> fieldType) {\r
+        AbstractSelect select;\r
+        if (fieldType.isAssignableFrom(ListSelect.class)) {\r
+            select = new ListSelect();\r
+            select.setMultiSelect(false);\r
+        } else if (fieldType.isAssignableFrom(NativeSelect.class)) {\r
+            select = new NativeSelect();\r
+        } else if (fieldType.isAssignableFrom(OptionGroup.class)) {\r
+            select = new OptionGroup();\r
+            select.setMultiSelect(false);\r
+        } else if (fieldType.isAssignableFrom(Table.class)) {\r
+            Table t = new Table();\r
+            t.setSelectable(true);\r
+            select = t;\r
+        } else {\r
+            select = new ComboBox(null);\r
+        }\r
         select.setImmediate(true);\r
         select.setNullSelectionAllowed(false);\r
+\r
+        return select;\r
+    }\r
+\r
+    protected Field createBooleanField(Class<? extends Field> fieldType) {\r
+        if (fieldType.isAssignableFrom(CheckBox.class)) {\r
+            CheckBox cb = new CheckBox(null);\r
+            cb.setImmediate(true);\r
+            return cb;\r
+        } else if (AbstractTextField.class.isAssignableFrom(fieldType)) {\r
+            return createAbstractTextField((Class<? extends AbstractTextField>) fieldType);\r
+        }\r
+\r
+        return null;\r
+    }\r
+\r
+    protected AbstractTextField createAbstractTextField(\r
+            Class<? extends AbstractTextField> fieldType) {\r
+        if (fieldType.isAssignableFrom(PasswordField.class)) {\r
+            PasswordField pf = new PasswordField();\r
+            pf.setImmediate(true);\r
+            return pf;\r
+        } else if (fieldType.isAssignableFrom(TextField.class)) {\r
+            TextField tf = new TextField();\r
+            tf.setImmediate(true);\r
+            return tf;\r
+        } else if (fieldType.isAssignableFrom(TextArea.class)) {\r
+            TextArea ta = new TextArea();\r
+            ta.setImmediate(true);\r
+            return ta;\r
+        }\r
+\r
+        return null;\r
+    }\r
+\r
+    protected Field createDefaultField(Class<?> type,\r
+            Class<? extends Field> fieldType) {\r
+        if (AbstractTextField.class.isAssignableFrom(fieldType)) {\r
+            return createAbstractTextField((Class<? extends AbstractTextField>) fieldType);\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * @param select\r
+     * @param enumClass\r
+     */\r
+    protected void populateWithEnumData(AbstractSelect select,\r
+            Class<? extends Enum> enumClass) {\r
+        // TODO EnumContainer?\r
+        select.removeAllItems();\r
+        for (Object p : select.getContainerPropertyIds()) {\r
+            select.removeContainerProperty(p);\r
+        }\r
         select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, "");\r
         select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID);\r
         @SuppressWarnings("unchecked")\r
@@ -49,7 +126,5 @@ public class DefaultFieldBinderFieldFactory implements FieldBinderFieldFactory {
             Item newItem = select.addItem(r);\r
             newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString());\r
         }\r
-        return select;\r
     }\r
-\r
 }\r
index 0d445364d35d19a0d5e368b97e3f6ac0afa9a571..3d4b0b49a3ac2038eb5aad2c98126f50dd62433e 100644 (file)
@@ -21,7 +21,11 @@ public interface FieldBinderFieldFactory extends Serializable {
      * \r
      * @param dataType\r
      *            The type that we want to edit using the field\r
-     * @return A field capable of editing the given type of data\r
+     * @param fieldType\r
+     *            The type of field we want to create. If set to {@link Field}\r
+     *            then any type of field is accepted\r
+     * @return A field that can be assigned to the given fieldType and that is\r
+     *         capable of editing the given type of data\r
      */\r
-    Field<?> createField(Class<?> dataType);\r
+    Field<?> createField(Class<?> dataType, Class<? extends Field> fieldType);\r
 }\r
index a623cb1e245f1da31066571dd653c1d60c35bb15..2dc567570e31ac661e2781cc3c44797cb09d861e 100644 (file)
@@ -5,21 +5,29 @@ package com.vaadin.data.fieldbinder;
 \r
 import java.beans.IntrospectionException;\r
 import java.beans.PropertyDescriptor;\r
+import java.io.Serializable;\r
 import java.lang.reflect.InvocationTargetException;\r
 import java.lang.reflect.Method;\r
+import java.util.logging.Logger;\r
+\r
+import org.apache.tools.ant.BuildException;\r
 \r
 import com.vaadin.data.fieldbinder.FieldBinder.BindException;\r
 import com.vaadin.ui.DefaultFieldFactory;\r
 import com.vaadin.ui.Field;\r
 \r
 /**\r
- * FIXME Javadoc\r
+ * Class for constructing form fields based on a data type.\r
+ * <p>\r
  * \r
+ * FIXME Javadoc\r
  */\r
-public class FormBuilder {\r
+public class FormBuilder implements Serializable {\r
 \r
     private FieldBinderFieldFactory fieldFactory = new com.vaadin.data.fieldbinder.DefaultFieldBinderFieldFactory();\r
     private FieldBinder fieldBinder;\r
+    private static final Logger logger = Logger.getLogger(FormBuilder.class\r
+            .getName());\r
 \r
     /**\r
      * Constructs a FormBuilder that can be used to build forms automatically.\r
@@ -77,11 +85,11 @@ public class FormBuilder {
      * @param propertyId\r
      *            The property id to bind to. Must be present in the field\r
      *            finder.\r
-     * @return The created and bound field\r
+     * @return The created and bound field. Can be any type of {@link Field}.\r
      */\r
     public Field<?> buildAndBind(String caption, Object propertyId) {\r
         Class<?> type = getFieldBinder().getPropertyType(propertyId);\r
-        return buildAndBind(caption, propertyId, type);\r
+        return buildAndBind(caption, propertyId, type, Field.class);\r
 \r
     }\r
 \r
@@ -96,29 +104,44 @@ public class FormBuilder {
      *            binder.\r
      * @param type\r
      *            The data model type we want to edit using the field\r
+     * @param fieldType\r
+     *            The type of field we want to create\r
      * @return The created and bound field\r
      */\r
     protected Field<?> buildAndBind(String caption, Object propertyId,\r
-            Class<?> type) {\r
-        Field<?> field = build(caption, type);\r
+            Class<?> type, Class<? extends Field> fieldType) {\r
+        Field<?> field = build(caption, type, fieldType);\r
         fieldBinder.bind(field, propertyId);\r
         return field;\r
     }\r
 \r
     /**\r
-     * Creates a field based on the given type. The type should be the data\r
-     * model type and not a Vaadin Field type.\r
+     * Creates a field based on the given data type.\r
+     * <p>\r
+     * The data type is the type that we want to edit using the field. The field\r
+     * type is the type of field we want to create, can be {@link Field} if any\r
+     * Field is good.\r
+     * </p>\r
      * \r
      * @param caption\r
      *            The caption for the new field\r
-     * @param type\r
+     * @param dataType\r
      *            The data model type that we want to edit using the field\r
+     * @param fieldType\r
+     *            The type of field that we want to create\r
      * @return A Field capable of editing the given type\r
      */\r
-    protected Field<?> build(String caption, Class<?> type) {\r
-        System.err.println("Building a field with caption " + caption\r
-                + " of type " + type.getName());\r
-        Field<?> field = getFieldFactory().createField(type);\r
+    protected Field<?> build(String caption, Class<?> dataType,\r
+            Class<? extends Field> fieldType) {\r
+        logger.finest("Building a field with caption " + caption + " of type "\r
+                + dataType.getName());\r
+        Field<?> field = getFieldFactory().createField(dataType, fieldType);\r
+        if (field == null) {\r
+            throw new BuildException("Unable to build a field of type "\r
+                    + fieldType.getName() + " for editing "\r
+                    + dataType.getName());\r
+        }\r
+\r
         field.setCaption(caption);\r
         return field;\r
     }\r
@@ -171,6 +194,8 @@ public class FormBuilder {
                 // Process next field\r
                 continue;\r
             }\r
+            Class<? extends Field> fieldType = (Class<? extends Field>) f\r
+                    .getType();\r
 \r
             Object propertyId = null;\r
             if (propertyIdAnnotation != null) {\r
@@ -210,7 +235,7 @@ public class FormBuilder {
                             .createCaptionByPropertyId(propertyId);\r
                 }\r
                 // Create the component (Field)\r
-                builtField = build(caption, propertyType);\r
+                builtField = build(caption, propertyType, fieldType);\r
                 // Store it in the field\r
                 setJavaFieldValue(object, f, builtField);\r
             }\r