import com.vaadin.data.Property;\r
import com.vaadin.data.TransactionalProperty;\r
import com.vaadin.data.Validator.InvalidValueException;\r
+import com.vaadin.data.fieldbinder.FormBuilder.FormBuilderException;\r
import com.vaadin.data.util.TransactionalPropertyWrapper;\r
+import com.vaadin.tools.ReflectTools;\r
import com.vaadin.ui.Field;\r
\r
/**\r
return false;\r
}\r
\r
+ /**\r
+ * Binds fields for the given class.\r
+ * <p>\r
+ * This method processes all fields whose type extends {@link Field} and\r
+ * that can be mapped to a property id. Property id mapping is done based on\r
+ * the field name or on a {@link PropertyId} annotation on the field. All\r
+ * non-null fields for which a property id can be determined are bound to\r
+ * the property id.\r
+ * \r
+ * @param object\r
+ * The object to process\r
+ * @throws FormBuilderException\r
+ * If there is a problem building or binding a field\r
+ */\r
+ public void bindFields(Object object) throws BindException {\r
+ Class<?> objectClass = object.getClass();\r
+\r
+ for (java.lang.reflect.Field f : objectClass.getDeclaredFields()) {\r
+\r
+ if (!Field.class.isAssignableFrom(f.getType())) {\r
+ // Process next field\r
+ continue;\r
+ }\r
+\r
+ PropertyId propertyIdAnnotation = f.getAnnotation(PropertyId.class);\r
+\r
+ Class<? extends Field> fieldType = (Class<? extends Field>) f\r
+ .getType();\r
+\r
+ Object propertyId = null;\r
+ if (propertyIdAnnotation != null) {\r
+ // @PropertyId(propertyId) always overrides property id\r
+ propertyId = propertyIdAnnotation.value();\r
+ } else {\r
+ propertyId = f.getName();\r
+ }\r
+\r
+ // Ensure that the property id exists\r
+ Class<?> propertyType;\r
+\r
+ try {\r
+ propertyType = getPropertyType(propertyId);\r
+ } catch (BindException e) {\r
+ // Property id was not found, skip this field\r
+ continue;\r
+ }\r
+\r
+ try {\r
+ // Get the field from the object\r
+ Field<?> field = (Field<?>) ReflectTools.getJavaFieldValue(\r
+ object, f);\r
+ // Bind it to the property id\r
+ bind(field, propertyId);\r
+ } catch (Exception e) {\r
+ // If we cannot determine the value, just skip the field and try\r
+ // the next one\r
+ continue;\r
+ }\r
+\r
+ }\r
+ }\r
+\r
public static class CommitException extends Exception {\r
\r
public CommitException() {\r
*/\r
package com.vaadin.data.fieldbinder;\r
\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.tools.ReflectTools;\r
import com.vaadin.ui.DefaultFieldFactory;\r
import com.vaadin.ui.Field;\r
\r
* If there is a problem building or binding a field\r
*/\r
public void buildAndBindFields(Object object) throws FormBuilderException {\r
- buildAndBindFields(object, false);\r
- }\r
-\r
- /**\r
- * Builds and binds fields for the given class.\r
- * <p>\r
- * This method processes all fields whose type extends {@link Field} and\r
- * that can be mapped to a property id. Property id mapping is done based on\r
- * the field name or on a {@link PropertyId} annotation on the field. All\r
- * fields for which a property id can be determined are built if they are\r
- * null and then bound to the property id. Also existing fields are bound to\r
- * the corresponding property id.\r
- * \r
- * @param object\r
- * The object to process\r
- * @param onlyBind\r
- * true if only binding should be done, false if also building\r
- * should be done when necessary\r
- * @throws FormBuilderException\r
- * If there is a problem building or binding a field\r
- */\r
- public void buildAndBindFields(Object object, boolean onlyBind)\r
- throws FormBuilderException {\r
Class<?> objectClass = object.getClass();\r
\r
for (java.lang.reflect.Field f : objectClass.getDeclaredFields()) {\r
\r
Field<?> builtField;\r
try {\r
- builtField = (Field<?>) getJavaFieldValue(object, f);\r
+ builtField = (Field<?>) ReflectTools.getJavaFieldValue(object,\r
+ f);\r
} catch (Exception e) {\r
// If we cannot determine the value, just skip the field and try\r
// the next one\r
continue;\r
}\r
\r
- if (builtField == null && !onlyBind) {\r
+ if (builtField == null) {\r
// Field is null -> build the field\r
Caption captionAnnotation = f.getAnnotation(Caption.class);\r
String caption;\r
caption = DefaultFieldFactory\r
.createCaptionByPropertyId(propertyId);\r
}\r
+\r
// Create the component (Field)\r
builtField = build(caption, propertyType, fieldType);\r
+\r
// Store it in the field\r
- setJavaFieldValue(object, f, builtField);\r
+ ReflectTools.setJavaFieldValue(object, f, builtField);\r
}\r
\r
// Bind it to the property id\r
}\r
}\r
\r
- /**\r
- * Returns the value of the java field.\r
- * <p>\r
- * Uses getter if present, otherwise tries to access even private fields.\r
- * \r
- * @param object\r
- * The object containing the field\r
- * @param field\r
- * The field we want to get the value for\r
- * @return The value of the field in the object\r
- * @throws FormBuilderException\r
- * If the field value cannot be determined\r
- */\r
- protected Object getJavaFieldValue(Object object,\r
- java.lang.reflect.Field field) throws FormBuilderException {\r
- PropertyDescriptor pd;\r
- try {\r
- pd = new PropertyDescriptor(field.getName(), object.getClass());\r
- Method getter = pd.getReadMethod();\r
- if (getter != null) {\r
- return getter.invoke(object, (Object[]) null);\r
- }\r
- } catch (Exception e) {\r
- // Ignore all problems with getter and try to get the value directly\r
- // from the field\r
- }\r
-\r
- try {\r
- if (!field.isAccessible()) {\r
- // Try to gain access even if field is private\r
- field.setAccessible(true);\r
- }\r
- return field.get(object);\r
- } catch (IllegalArgumentException e) {\r
- throw new FormBuilderException("Could not get value for field '"\r
- + field.getName() + "'", e.getCause());\r
- } catch (IllegalAccessException e) {\r
- throw new FormBuilderException(\r
- "Access denied while assigning built component to field '"\r
- + field.getName() + "' in "\r
- + object.getClass().getName(), e);\r
- }\r
- }\r
-\r
- /**\r
- * Sets the value of a java field.\r
- * <p>\r
- * Uses setter if present, otherwise tries to access even private fields\r
- * directly.\r
- * \r
- * @param object\r
- * The object containing the field\r
- * @param field\r
- * The field we want to set the value for\r
- * @param value\r
- * The value to set\r
- * @throws FormBuilderException\r
- * If the value could not be assigned to the field\r
- */\r
- protected void setJavaFieldValue(Object object,\r
- java.lang.reflect.Field field, Object value)\r
- throws FormBuilderException {\r
- PropertyDescriptor pd;\r
- try {\r
- pd = new PropertyDescriptor(field.getName(), object.getClass());\r
- Method setter = pd.getWriteMethod();\r
- if (setter != null) {\r
- try {\r
- setter.invoke(object, value);\r
- } catch (IllegalArgumentException e) {\r
- throw new FormBuilderException(\r
- "Could not assign built component to field '"\r
- + field.getName() + "'", e);\r
- } catch (IllegalAccessException e) {\r
- throw new FormBuilderException(\r
- "Access denied while assigning built component to field using "\r
- + setter.getName() + " in "\r
- + object.getClass().getName(), e);\r
- } catch (InvocationTargetException e) {\r
- throw new FormBuilderException(\r
- "Could not assign built component to field '"\r
- + field.getName() + "'", e.getCause());\r
- }\r
- }\r
- } catch (IntrospectionException e1) {\r
- // Ignore this and try to set directly using the field\r
- }\r
-\r
- try {\r
- if (!field.isAccessible()) {\r
- // Try to gain access even if field is private\r
- field.setAccessible(true);\r
- }\r
- field.set(object, value);\r
- } catch (IllegalArgumentException e) {\r
- throw new FormBuilderException(\r
- "Could not assign built component to field '"\r
- + field.getName() + "'", e.getCause());\r
- } catch (IllegalAccessException e) {\r
- throw new FormBuilderException(\r
- "Access denied while assigning built component to field '"\r
- + field.getName() + "' in "\r
- + object.getClass().getName(), e);\r
- }\r
- }\r
-\r
- // /**\r
- // * Constructs fields for all properties in the data source and adds them\r
- // to\r
- // * the given component container. The order of the fields is determined by\r
- // * the order in which the item returns its property ids.\r
- // *\r
- // * This is pretty much what the old Form class used to do.\r
- // *\r
- // * @param cc\r
- // * The ComponentContainer where fields should be added.\r
- // */\r
- // public void buildAndBindEverything(ComponentContainer cc) {\r
- // Item ds = getFieldBinder().getItemDataSource();\r
- // for (Object propertyId : ds.getItemPropertyIds()) {\r
- // Field<?> f = buildAndBind(propertyId);\r
- // cc.addComponent(f);\r
- // }\r
- //\r
- // }\r
-\r
public static class FormBuilderException extends RuntimeException {\r
\r
public FormBuilderException() {\r
*/
package com.vaadin.tools;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import com.vaadin.data.fieldbinder.FormBuilder.FormBuilderException;
+
/**
* An util class with helpers for reflection operations. Used internally by
* Vaadin and should not be used by application developers. Subject to change at
throw new ExceptionInInitializerError(e);
}
}
+
+ /**
+ * Returns the value of the java field.
+ * <p>
+ * Uses getter if present, otherwise tries to access even private fields
+ * directly.
+ *
+ * @param object
+ * The object containing the field
+ * @param field
+ * The field we want to get the value for
+ * @return The value of the field in the object
+ * @throws FormBuilderException
+ * If the field value cannot be determined
+ */
+ public static Object getJavaFieldValue(Object object,
+ java.lang.reflect.Field field) throws FormBuilderException {
+ PropertyDescriptor pd;
+ try {
+ pd = new PropertyDescriptor(field.getName(), object.getClass());
+ Method getter = pd.getReadMethod();
+ if (getter != null) {
+ return getter.invoke(object, (Object[]) null);
+ }
+ } catch (Exception e) {
+ // Ignore all problems with getter and try to get the value directly
+ // from the field
+ }
+
+ try {
+ if (!field.isAccessible()) {
+ // Try to gain access even if field is private
+ field.setAccessible(true);
+ }
+ return field.get(object);
+ } catch (IllegalArgumentException e) {
+ throw new FormBuilderException("Could not get value for field '"
+ + field.getName() + "'", e.getCause());
+ } catch (IllegalAccessException e) {
+ throw new FormBuilderException(
+ "Access denied while assigning built component to field '"
+ + field.getName() + "' in "
+ + object.getClass().getName(), e);
+ }
+ }
+
+ /**
+ * Sets the value of a java field.
+ * <p>
+ * Uses setter if present, otherwise tries to access even private fields
+ * directly.
+ *
+ * @param object
+ * The object containing the field
+ * @param field
+ * The field we want to set the value for
+ * @param value
+ * The value to set
+ * @throws FormBuilderException
+ * If the value could not be assigned to the field
+ */
+ public static void setJavaFieldValue(Object object,
+ java.lang.reflect.Field field, Object value)
+ throws FormBuilderException {
+ PropertyDescriptor pd;
+ try {
+ pd = new PropertyDescriptor(field.getName(), object.getClass());
+ Method setter = pd.getWriteMethod();
+ if (setter != null) {
+ try {
+ setter.invoke(object, value);
+ } catch (IllegalArgumentException e) {
+ throw new FormBuilderException(
+ "Could not assign value to field '"
+ + field.getName() + "'", e);
+ } catch (IllegalAccessException e) {
+ throw new FormBuilderException(
+ "Access denied while assigning value to field using "
+ + setter.getName() + " in "
+ + object.getClass().getName(), e);
+ } catch (InvocationTargetException e) {
+ throw new FormBuilderException(
+ "Could not assign value to field '"
+ + field.getName() + "'", e.getCause());
+ }
+ }
+ } catch (IntrospectionException e1) {
+ // Ignore this and try to set directly using the field
+ }
+
+ try {
+ if (!field.isAccessible()) {
+ // Try to gain access even if field is private
+ field.setAccessible(true);
+ }
+ field.set(object, value);
+ } catch (IllegalArgumentException e) {
+ throw new FormBuilderException("Could not assign value to field '"
+ + field.getName() + "'", e.getCause());
+ } catch (IllegalAccessException e) {
+ throw new FormBuilderException(
+ "Access denied while assigning value to field '"
+ + field.getName() + "' in "
+ + object.getClass().getName(), e);
+ }
+ }
}