diff options
Diffstat (limited to 'src/com/vaadin/data')
28 files changed, 3559 insertions, 3559 deletions
diff --git a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java index 8ca6c95069..2584a4770b 100644 --- a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java +++ b/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java @@ -1,157 +1,157 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.reflect.Method;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.util.BeanItem;
-import com.vaadin.data.validator.BeanValidator;
-import com.vaadin.ui.Field;
-
-public class BeanFieldGroup<T> extends FieldGroup {
-
- private Class<T> beanType;
-
- private static Boolean beanValidationImplementationAvailable = null;
-
- public BeanFieldGroup(Class<T> beanType) {
- this.beanType = beanType;
- }
-
- @Override
- protected Class<?> getPropertyType(Object propertyId) {
- if (getItemDataSource() != null) {
- return super.getPropertyType(propertyId);
- } else {
- // Data source not set so we need to figure out the type manually
- /*
- * toString should never really be needed as propertyId should be of
- * form "fieldName" or "fieldName.subField[.subField2]" but the
- * method declaration comes from parent.
- */
- java.lang.reflect.Field f;
- try {
- f = getField(beanType, propertyId.toString());
- return f.getType();
- } catch (SecurityException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'.", e);
- } catch (NoSuchFieldException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'. The propertyId was not found in "
- + beanType.getName(), e);
- }
- }
- }
-
- private static java.lang.reflect.Field getField(Class<?> cls,
- String propertyId) throws SecurityException, NoSuchFieldException {
- if (propertyId.contains(".")) {
- String[] parts = propertyId.split("\\.", 2);
- // Get the type of the field in the "cls" class
- java.lang.reflect.Field field1 = getField(cls, parts[0]);
- // Find the rest from the sub type
- return getField(field1.getType(), parts[1]);
- } else {
- try {
- // Try to find the field directly in the given class
- java.lang.reflect.Field field1 = cls
- .getDeclaredField(propertyId);
- return field1;
- } catch (NoSuchFieldError e) {
- // Try super classes until we reach Object
- Class<?> superClass = cls.getSuperclass();
- if (superClass != Object.class) {
- return getField(superClass, propertyId);
- } else {
- throw e;
- }
- }
- }
- }
-
- /**
- * Helper method for setting the data source directly using a bean. This
- * method wraps the bean in a {@link BeanItem} and calls
- * {@link #setItemDataSource(Item)}.
- *
- * @param bean
- * The bean to use as data source.
- */
- public void setItemDataSource(T bean) {
- setItemDataSource(new BeanItem(bean));
- }
-
- @Override
- public void setItemDataSource(Item item) {
- if (!(item instanceof BeanItem)) {
- throw new RuntimeException(getClass().getSimpleName()
- + " only supports BeanItems as item data source");
- }
- super.setItemDataSource(item);
- }
-
- @Override
- public BeanItem<T> getItemDataSource() {
- return (BeanItem<T>) super.getItemDataSource();
- }
-
- @Override
- public void bind(Field field, Object propertyId) {
- if (getItemDataSource() != null) {
- // The data source is set so the property must be found in the item.
- // If it is not we try to add it.
- try {
- getItemProperty(propertyId);
- } catch (BindException e) {
- // Not found, try to add a nested property;
- // BeanItem property ids are always strings so this is safe
- getItemDataSource().addNestedProperty((String) propertyId);
- }
- }
-
- super.bind(field, propertyId);
- }
-
- @Override
- protected void configureField(Field<?> field) {
- super.configureField(field);
- // Add Bean validators if there are annotations
- if (isBeanValidationImplementationAvailable()) {
- BeanValidator validator = new BeanValidator(
- beanType, getPropertyId(field).toString());
- field.addValidator(validator);
- if (field.getLocale() != null) {
- validator.setLocale(field.getLocale());
- }
- }
- }
-
- /**
- * Checks whether a bean validation implementation (e.g. Hibernate Validator
- * or Apache Bean Validation) is available.
- *
- * TODO move this method to some more generic location
- *
- * @return true if a JSR-303 bean validation implementation is available
- */
- protected static boolean isBeanValidationImplementationAvailable() {
- if (beanValidationImplementationAvailable != null) {
- return beanValidationImplementationAvailable;
- }
- try {
- Class<?> validationClass = Class
- .forName("javax.validation.Validation");
- Method buildFactoryMethod = validationClass
- .getMethod("buildDefaultValidatorFactory");
- Object factory = buildFactoryMethod.invoke(null);
- beanValidationImplementationAvailable = (factory != null);
- } catch (Exception e) {
- // no bean validation implementation available
- beanValidationImplementationAvailable = false;
- }
- return beanValidationImplementationAvailable;
- }
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.fieldgroup; + +import java.lang.reflect.Method; + +import com.vaadin.data.Item; +import com.vaadin.data.util.BeanItem; +import com.vaadin.data.validator.BeanValidator; +import com.vaadin.ui.Field; + +public class BeanFieldGroup<T> extends FieldGroup { + + private Class<T> beanType; + + private static Boolean beanValidationImplementationAvailable = null; + + public BeanFieldGroup(Class<T> beanType) { + this.beanType = beanType; + } + + @Override + protected Class<?> getPropertyType(Object propertyId) { + if (getItemDataSource() != null) { + return super.getPropertyType(propertyId); + } else { + // Data source not set so we need to figure out the type manually + /* + * toString should never really be needed as propertyId should be of + * form "fieldName" or "fieldName.subField[.subField2]" but the + * method declaration comes from parent. + */ + java.lang.reflect.Field f; + try { + f = getField(beanType, propertyId.toString()); + return f.getType(); + } catch (SecurityException e) { + throw new BindException("Cannot determine type of propertyId '" + + propertyId + "'.", e); + } catch (NoSuchFieldException e) { + throw new BindException("Cannot determine type of propertyId '" + + propertyId + "'. The propertyId was not found in " + + beanType.getName(), e); + } + } + } + + private static java.lang.reflect.Field getField(Class<?> cls, + String propertyId) throws SecurityException, NoSuchFieldException { + if (propertyId.contains(".")) { + String[] parts = propertyId.split("\\.", 2); + // Get the type of the field in the "cls" class + java.lang.reflect.Field field1 = getField(cls, parts[0]); + // Find the rest from the sub type + return getField(field1.getType(), parts[1]); + } else { + try { + // Try to find the field directly in the given class + java.lang.reflect.Field field1 = cls + .getDeclaredField(propertyId); + return field1; + } catch (NoSuchFieldError e) { + // Try super classes until we reach Object + Class<?> superClass = cls.getSuperclass(); + if (superClass != Object.class) { + return getField(superClass, propertyId); + } else { + throw e; + } + } + } + } + + /** + * Helper method for setting the data source directly using a bean. This + * method wraps the bean in a {@link BeanItem} and calls + * {@link #setItemDataSource(Item)}. + * + * @param bean + * The bean to use as data source. + */ + public void setItemDataSource(T bean) { + setItemDataSource(new BeanItem(bean)); + } + + @Override + public void setItemDataSource(Item item) { + if (!(item instanceof BeanItem)) { + throw new RuntimeException(getClass().getSimpleName() + + " only supports BeanItems as item data source"); + } + super.setItemDataSource(item); + } + + @Override + public BeanItem<T> getItemDataSource() { + return (BeanItem<T>) super.getItemDataSource(); + } + + @Override + public void bind(Field field, Object propertyId) { + if (getItemDataSource() != null) { + // The data source is set so the property must be found in the item. + // If it is not we try to add it. + try { + getItemProperty(propertyId); + } catch (BindException e) { + // Not found, try to add a nested property; + // BeanItem property ids are always strings so this is safe + getItemDataSource().addNestedProperty((String) propertyId); + } + } + + super.bind(field, propertyId); + } + + @Override + protected void configureField(Field<?> field) { + super.configureField(field); + // Add Bean validators if there are annotations + if (isBeanValidationImplementationAvailable()) { + BeanValidator validator = new BeanValidator( + beanType, getPropertyId(field).toString()); + field.addValidator(validator); + if (field.getLocale() != null) { + validator.setLocale(field.getLocale()); + } + } + } + + /** + * Checks whether a bean validation implementation (e.g. Hibernate Validator + * or Apache Bean Validation) is available. + * + * TODO move this method to some more generic location + * + * @return true if a JSR-303 bean validation implementation is available + */ + protected static boolean isBeanValidationImplementationAvailable() { + if (beanValidationImplementationAvailable != null) { + return beanValidationImplementationAvailable; + } + try { + Class<?> validationClass = Class + .forName("javax.validation.Validation"); + Method buildFactoryMethod = validationClass + .getMethod("buildDefaultValidatorFactory"); + Object factory = buildFactoryMethod.invoke(null); + beanValidationImplementationAvailable = (factory != null); + } catch (Exception e) { + // no bean validation implementation available + beanValidationImplementationAvailable = false; + } + return beanValidationImplementationAvailable; + } }
\ No newline at end of file diff --git a/src/com/vaadin/data/fieldgroup/Caption.java b/src/com/vaadin/data/fieldgroup/Caption.java index e9ae01a2d2..b990b720cd 100644 --- a/src/com/vaadin/data/fieldgroup/Caption.java +++ b/src/com/vaadin/data/fieldgroup/Caption.java @@ -1,15 +1,15 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Caption {
- String value();
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.fieldgroup; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Caption { + String value(); +} diff --git a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java index 2fc7bc6b7e..569f643998 100644 --- a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java +++ b/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java @@ -1,156 +1,156 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.util.EnumSet;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.fieldgroup.FieldGroup.BindException;
-import com.vaadin.ui.AbstractSelect;
-import com.vaadin.ui.AbstractTextField;
-import com.vaadin.ui.CheckBox;
-import com.vaadin.ui.ComboBox;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.ListSelect;
-import com.vaadin.ui.NativeSelect;
-import com.vaadin.ui.OptionGroup;
-import com.vaadin.ui.RichTextArea;
-import com.vaadin.ui.Table;
-import com.vaadin.ui.TextField;
-
-public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
-
- public static final Object CAPTION_PROPERTY_ID = "Caption";
-
- public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {
- if (Enum.class.isAssignableFrom(type)) {
- return createEnumField(type, fieldType);
- } else if (Boolean.class.isAssignableFrom(type)
- || boolean.class.isAssignableFrom(type)) {
- return createBooleanField(fieldType);
- }
- if (AbstractTextField.class.isAssignableFrom(fieldType)) {
- return fieldType.cast(createAbstractTextField(fieldType
- .asSubclass(AbstractTextField.class)));
- } else if (fieldType == RichTextArea.class) {
- return fieldType.cast(createRichTextArea());
- }
- return createDefaultField(type, fieldType);
- }
-
- protected RichTextArea createRichTextArea() {
- RichTextArea rta = new RichTextArea();
- rta.setImmediate(true);
-
- return rta;
- }
-
- private <T extends Field> T createEnumField(Class<?> type,
- Class<T> fieldType) {
- if (AbstractSelect.class.isAssignableFrom(fieldType)) {
- AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType);
- populateWithEnumData(s, (Class<? extends Enum>) type);
- return (T) s;
- }
-
- return null;
- }
-
- protected AbstractSelect createCompatibleSelect(
- Class<? extends AbstractSelect> fieldType) {
- AbstractSelect select;
- if (fieldType.isAssignableFrom(ListSelect.class)) {
- select = new ListSelect();
- select.setMultiSelect(false);
- } else if (fieldType.isAssignableFrom(NativeSelect.class)) {
- select = new NativeSelect();
- } else if (fieldType.isAssignableFrom(OptionGroup.class)) {
- select = new OptionGroup();
- select.setMultiSelect(false);
- } else if (fieldType.isAssignableFrom(Table.class)) {
- Table t = new Table();
- t.setSelectable(true);
- select = t;
- } else {
- select = new ComboBox(null);
- }
- select.setImmediate(true);
- select.setNullSelectionAllowed(false);
-
- return select;
- }
-
- protected <T extends Field> T createBooleanField(Class<T> fieldType) {
- if (fieldType.isAssignableFrom(CheckBox.class)) {
- CheckBox cb = new CheckBox(null);
- cb.setImmediate(true);
- return (T) cb;
- } else if (AbstractTextField.class.isAssignableFrom(fieldType)) {
- return (T) createAbstractTextField((Class<? extends AbstractTextField>) fieldType);
- }
-
- return null;
- }
-
- protected <T extends AbstractTextField> T createAbstractTextField(
- Class<T> fieldType) {
- if (fieldType == AbstractTextField.class) {
- fieldType = (Class<T>) TextField.class;
- }
- try {
- T field = fieldType.newInstance();
- field.setImmediate(true);
- return field;
- } catch (Exception e) {
- throw new BindException("Could not create a field of type "
- + fieldType, e);
- }
- }
-
- /**
- * Fallback when no specific field has been created. Typically returns a
- * TextField.
- *
- * @param <T>
- * The type of field to create
- * @param type
- * The type of data that should be edited
- * @param fieldType
- * The type of field to create
- * @return A field capable of editing the data or null if no field could be
- * created
- */
- protected <T extends Field> T createDefaultField(Class<?> type,
- Class<T> fieldType) {
- if (fieldType.isAssignableFrom(TextField.class)) {
- return fieldType.cast(createAbstractTextField(TextField.class));
- }
- return null;
- }
-
- /**
- * Populates the given select with all the enums in the given {@link Enum}
- * class. Uses {@link Enum}.toString() for caption.
- *
- * @param select
- * The select to populate
- * @param enumClass
- * The Enum class to use
- */
- protected void populateWithEnumData(AbstractSelect select,
- Class<? extends Enum> enumClass) {
- select.removeAllItems();
- for (Object p : select.getContainerPropertyIds()) {
- select.removeContainerProperty(p);
- }
- select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, "");
- select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID);
- @SuppressWarnings("unchecked")
- EnumSet<?> enumSet = EnumSet.allOf(enumClass);
- for (Object r : enumSet) {
- Item newItem = select.addItem(r);
- newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString());
- }
- }
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.fieldgroup; + +import java.util.EnumSet; + +import com.vaadin.data.Item; +import com.vaadin.data.fieldgroup.FieldGroup.BindException; +import com.vaadin.ui.AbstractSelect; +import com.vaadin.ui.AbstractTextField; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Field; +import com.vaadin.ui.ListSelect; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.OptionGroup; +import com.vaadin.ui.RichTextArea; +import com.vaadin.ui.Table; +import com.vaadin.ui.TextField; + +public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory { + + public static final Object CAPTION_PROPERTY_ID = "Caption"; + + public <T extends Field> T createField(Class<?> type, Class<T> fieldType) { + if (Enum.class.isAssignableFrom(type)) { + return createEnumField(type, fieldType); + } else if (Boolean.class.isAssignableFrom(type) + || boolean.class.isAssignableFrom(type)) { + return createBooleanField(fieldType); + } + if (AbstractTextField.class.isAssignableFrom(fieldType)) { + return fieldType.cast(createAbstractTextField(fieldType + .asSubclass(AbstractTextField.class))); + } else if (fieldType == RichTextArea.class) { + return fieldType.cast(createRichTextArea()); + } + return createDefaultField(type, fieldType); + } + + protected RichTextArea createRichTextArea() { + RichTextArea rta = new RichTextArea(); + rta.setImmediate(true); + + return rta; + } + + private <T extends Field> T createEnumField(Class<?> type, + Class<T> fieldType) { + if (AbstractSelect.class.isAssignableFrom(fieldType)) { + AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType); + populateWithEnumData(s, (Class<? extends Enum>) type); + return (T) s; + } + + return null; + } + + protected AbstractSelect createCompatibleSelect( + Class<? extends AbstractSelect> fieldType) { + AbstractSelect select; + if (fieldType.isAssignableFrom(ListSelect.class)) { + select = new ListSelect(); + select.setMultiSelect(false); + } else if (fieldType.isAssignableFrom(NativeSelect.class)) { + select = new NativeSelect(); + } else if (fieldType.isAssignableFrom(OptionGroup.class)) { + select = new OptionGroup(); + select.setMultiSelect(false); + } else if (fieldType.isAssignableFrom(Table.class)) { + Table t = new Table(); + t.setSelectable(true); + select = t; + } else { + select = new ComboBox(null); + } + select.setImmediate(true); + select.setNullSelectionAllowed(false); + + return select; + } + + protected <T extends Field> T createBooleanField(Class<T> fieldType) { + if (fieldType.isAssignableFrom(CheckBox.class)) { + CheckBox cb = new CheckBox(null); + cb.setImmediate(true); + return (T) cb; + } else if (AbstractTextField.class.isAssignableFrom(fieldType)) { + return (T) createAbstractTextField((Class<? extends AbstractTextField>) fieldType); + } + + return null; + } + + protected <T extends AbstractTextField> T createAbstractTextField( + Class<T> fieldType) { + if (fieldType == AbstractTextField.class) { + fieldType = (Class<T>) TextField.class; + } + try { + T field = fieldType.newInstance(); + field.setImmediate(true); + return field; + } catch (Exception e) { + throw new BindException("Could not create a field of type " + + fieldType, e); + } + } + + /** + * Fallback when no specific field has been created. Typically returns a + * TextField. + * + * @param <T> + * The type of field to create + * @param type + * The type of data that should be edited + * @param fieldType + * The type of field to create + * @return A field capable of editing the data or null if no field could be + * created + */ + protected <T extends Field> T createDefaultField(Class<?> type, + Class<T> fieldType) { + if (fieldType.isAssignableFrom(TextField.class)) { + return fieldType.cast(createAbstractTextField(TextField.class)); + } + return null; + } + + /** + * Populates the given select with all the enums in the given {@link Enum} + * class. Uses {@link Enum}.toString() for caption. + * + * @param select + * The select to populate + * @param enumClass + * The Enum class to use + */ + protected void populateWithEnumData(AbstractSelect select, + Class<? extends Enum> enumClass) { + select.removeAllItems(); + for (Object p : select.getContainerPropertyIds()) { + select.removeContainerProperty(p); + } + select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, ""); + select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID); + @SuppressWarnings("unchecked") + EnumSet<?> enumSet = EnumSet.allOf(enumClass); + for (Object r : enumSet) { + Item newItem = select.addItem(r); + newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString()); + } + } +} diff --git a/src/com/vaadin/data/fieldgroup/FieldGroup.java b/src/com/vaadin/data/fieldgroup/FieldGroup.java index 381f4fef3f..3df19f5bc9 100644 --- a/src/com/vaadin/data/fieldgroup/FieldGroup.java +++ b/src/com/vaadin/data/fieldgroup/FieldGroup.java @@ -1,978 +1,978 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.data.util.TransactionalPropertyWrapper;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.DefaultFieldFactory;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.Form;
-
-/**
- * FieldGroup provides an easy way of binding fields to data and handling
- * commits of these fields.
- * <p>
- * The functionality of FieldGroup is similar to {@link Form} but
- * {@link FieldGroup} does not handle layouts in any way. The typical use case
- * is to create a layout outside the FieldGroup and then use FieldGroup to bind
- * the fields to a data source.
- * </p>
- * <p>
- * {@link FieldGroup} is not a UI component so it cannot be added to a layout.
- * Using the buildAndBind methods {@link FieldGroup} can create fields for you
- * using a FieldGroupFieldFactory but you still have to add them to the correct
- * position in your layout.
- * </p>
- *
- * @author Vaadin Ltd
- * @version @version@
- * @since 7.0
- */
-public class FieldGroup implements Serializable {
-
- private static final Logger logger = Logger.getLogger(FieldGroup.class
- .getName());
-
- private Item itemDataSource;
- private boolean buffered = true;
-
- private boolean enabled = true;
- private boolean readOnly = false;
-
- private HashMap<Object, Field<?>> propertyIdToField = new HashMap<Object, Field<?>>();
- private LinkedHashMap<Field<?>, Object> fieldToPropertyId = new LinkedHashMap<Field<?>, Object>();
- private List<CommitHandler> commitHandlers = new ArrayList<CommitHandler>();
-
- /**
- * The field factory used by builder methods.
- */
- private FieldGroupFieldFactory fieldFactory = new DefaultFieldGroupFieldFactory();
-
- /**
- * Constructs a field binder. Use {@link #setItemDataSource(Item)} to set a
- * data source for the field binder.
- *
- */
- public FieldGroup() {
-
- }
-
- /**
- * Constructs a field binder that uses the given data source.
- *
- * @param itemDataSource
- * The data source to bind the fields to
- */
- public FieldGroup(Item itemDataSource) {
- setItemDataSource(itemDataSource);
- }
-
- /**
- * Updates the item that is used by this FieldBinder. Rebinds all fields to
- * the properties in the new item.
- *
- * @param itemDataSource
- * The new item to use
- */
- public void setItemDataSource(Item itemDataSource) {
- this.itemDataSource = itemDataSource;
-
- for (Field<?> f : fieldToPropertyId.keySet()) {
- bind(f, fieldToPropertyId.get(f));
- }
- }
-
- /**
- * Gets the item used by this FieldBinder. Note that you must call
- * {@link #commit()} for the item to be updated unless buffered mode has
- * been switched off.
- *
- * @see #setBuffered(boolean)
- * @see #commit()
- *
- * @return The item used by this FieldBinder
- */
- public Item getItemDataSource() {
- return itemDataSource;
- }
-
- /**
- * Checks the buffered mode for the bound fields.
- * <p>
- *
- * @see #setBuffered(boolean) for more details on buffered mode
- *
- * @see Field#isBuffered()
- * @return true if buffered mode is on, false otherwise
- *
- */
- public boolean isBuffered() {
- return buffered;
- }
-
- /**
- * Sets the buffered mode for the bound fields.
- * <p>
- * When buffered mode is on the item will not be updated until
- * {@link #commit()} is called. If buffered mode is off the item will be
- * updated once the fields are updated.
- * </p>
- * <p>
- * The default is to use buffered mode.
- * </p>
- *
- * @see Field#setBuffered(boolean)
- * @param buffered
- * true to turn on buffered mode, false otherwise
- */
- public void setBuffered(boolean buffered) {
- if (buffered == this.buffered) {
- return;
- }
-
- this.buffered = buffered;
- for (Field<?> field : getFields()) {
- field.setBuffered(buffered);
- }
- }
-
- /**
- * Returns the enabled status for the fields.
- * <p>
- * Note that this will not accurately represent the enabled status of all
- * fields if you change the enabled status of the fields through some other
- * method than {@link #setEnabled(boolean)}.
- *
- * @return true if the fields are enabled, false otherwise
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * Updates the enabled state of all bound fields.
- *
- * @param fieldsEnabled
- * true to enable all bound fields, false to disable them
- */
- public void setEnabled(boolean fieldsEnabled) {
- enabled = fieldsEnabled;
- for (Field<?> field : getFields()) {
- field.setEnabled(fieldsEnabled);
- }
- }
-
- /**
- * Returns the read only status for the fields.
- * <p>
- * Note that this will not accurately represent the read only status of all
- * fields if you change the read only status of the fields through some
- * other method than {@link #setReadOnly(boolean)}.
- *
- * @return true if the fields are set to read only, false otherwise
- */
- public boolean isReadOnly() {
- return readOnly;
- }
-
- /**
- * Updates the read only state of all bound fields.
- *
- * @param fieldsReadOnly
- * true to set all bound fields to read only, false to set them
- * to read write
- */
- public void setReadOnly(boolean fieldsReadOnly) {
- readOnly = fieldsReadOnly;
- }
-
- /**
- * Returns a collection of all fields that have been bound.
- * <p>
- * The fields are not returned in any specific order.
- * </p>
- *
- * @return A collection with all bound Fields
- */
- public Collection<Field<?>> getFields() {
- return fieldToPropertyId.keySet();
- }
-
- /**
- * Binds the field with the given propertyId from the current item. If an
- * item has not been set then the binding is postponed until the item is set
- * using {@link #setItemDataSource(Item)}.
- * <p>
- * This method also adds validators when applicable.
- * </p>
- *
- * @param field
- * The field to bind
- * @param propertyId
- * The propertyId to bind to the field
- * @throws BindException
- * If the property id is already bound to another field by this
- * field binder
- */
- public void bind(Field<?> field, Object propertyId) throws BindException {
- if (propertyIdToField.containsKey(propertyId)
- && propertyIdToField.get(propertyId) != field) {
- throw new BindException("Property id " + propertyId
- + " is already bound to another field");
- }
- fieldToPropertyId.put(field, propertyId);
- propertyIdToField.put(propertyId, field);
- if (itemDataSource == null) {
- // Will be bound when data source is set
- return;
- }
-
- field.setPropertyDataSource(wrapInTransactionalProperty(getItemProperty(propertyId)));
- configureField(field);
- }
-
- private <T> Property.Transactional<T> wrapInTransactionalProperty(
- Property<T> itemProperty) {
- return new TransactionalPropertyWrapper<T>(itemProperty);
- }
-
- /**
- * Gets the property with the given property id from the item.
- *
- * @param propertyId
- * The id if the property to find
- * @return The property with the given id from the item
- * @throws BindException
- * If the property was not found in the item or no item has been
- * set
- */
- protected Property<?> getItemProperty(Object propertyId)
- throws BindException {
- Item item = getItemDataSource();
- if (item == null) {
- throw new BindException("Could not lookup property with id "
- + propertyId + " as no item has been set");
- }
- Property<?> p = item.getItemProperty(propertyId);
- if (p == null) {
- throw new BindException("A property with id " + propertyId
- + " was not found in the item");
- }
- return p;
- }
-
- /**
- * Detaches the field from its property id and removes it from this
- * FieldBinder.
- * <p>
- * Note that the field is not detached from its property data source if it
- * is no longer connected to the same property id it was bound to using this
- * FieldBinder.
- *
- * @param field
- * The field to detach
- * @throws BindException
- * If the field is not bound by this field binder or not bound
- * to the correct property id
- */
- public void unbind(Field<?> field) throws BindException {
- Object propertyId = fieldToPropertyId.get(field);
- if (propertyId == null) {
- throw new BindException(
- "The given field is not part of this FieldBinder");
- }
-
- Property fieldDataSource = field.getPropertyDataSource();
- if (fieldDataSource instanceof TransactionalPropertyWrapper) {
- fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource)
- .getWrappedProperty();
- }
- if (fieldDataSource == getItemProperty(propertyId)) {
- field.setPropertyDataSource(null);
- }
- fieldToPropertyId.remove(field);
- propertyIdToField.remove(propertyId);
- }
-
- /**
- * Configures a field with the settings set for this FieldBinder.
- * <p>
- * By default this updates the buffered, read only and enabled state of the
- * field. Also adds validators when applicable.
- *
- * @param field
- * The field to update
- */
- protected void configureField(Field<?> field) {
- field.setBuffered(isBuffered());
-
- field.setEnabled(isEnabled());
- field.setReadOnly(isReadOnly());
- }
-
- /**
- * Gets the type of the property with the given property id.
- *
- * @param propertyId
- * The propertyId. Must be find
- * @return The type of the property
- */
- protected Class<?> getPropertyType(Object propertyId) throws BindException {
- if (getItemDataSource() == null) {
- throw new BindException(
- "Property type for '"
- + propertyId
- + "' could not be determined. No item data source has been set.");
- }
- Property<?> p = getItemDataSource().getItemProperty(propertyId);
- if (p == null) {
- throw new BindException(
- "Property type for '"
- + propertyId
- + "' could not be determined. No property with that id was found.");
- }
-
- return p.getType();
- }
-
- /**
- * Returns a collection of all property ids that have been bound to fields.
- * <p>
- * Note that this will return property ids even before the item has been
- * set. In that case it returns the property ids that will be bound once the
- * item is set.
- * </p>
- * <p>
- * No guarantee is given for the order of the property ids
- * </p>
- *
- * @return A collection of bound property ids
- */
- public Collection<Object> getBoundPropertyIds() {
- return Collections.unmodifiableCollection(propertyIdToField.keySet());
- }
-
- /**
- * Returns a collection of all property ids that exist in the item set using
- * {@link #setItemDataSource(Item)} but have not been bound to fields.
- * <p>
- * Will always return an empty collection before an item has been set using
- * {@link #setItemDataSource(Item)}.
- * </p>
- * <p>
- * No guarantee is given for the order of the property ids
- * </p>
- *
- * @return A collection of property ids that have not been bound to fields
- */
- public Collection<Object> getUnboundPropertyIds() {
- if (getItemDataSource() == null) {
- return new ArrayList<Object>();
- }
- List<Object> unboundPropertyIds = new ArrayList<Object>();
- unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds());
- unboundPropertyIds.removeAll(propertyIdToField.keySet());
- return unboundPropertyIds;
- }
-
- /**
- * Commits all changes done to the bound fields.
- * <p>
- * Calls all {@link CommitHandler}s before and after committing the field
- * changes to the item data source. The whole commit is aborted and state is
- * restored to what it was before commit was called if any
- * {@link CommitHandler} throws a CommitException or there is a problem
- * committing the fields
- *
- * @throws CommitException
- * If the commit was aborted
- */
- public void commit() throws CommitException {
- if (!isBuffered()) {
- // Not using buffered mode, nothing to do
- return;
- }
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .startTransaction();
- }
- try {
- firePreCommitEvent();
- // Commit the field values to the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- f.commit();
- }
- firePostCommitEvent();
-
- // Commit the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .commit();
- }
-
- } catch (Exception e) {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .rollback();
- } catch (Exception rollbackException) {
- // FIXME: What to do ?
- }
- }
-
- throw new CommitException("Commit failed", e);
- }
-
- }
-
- /**
- * Sends a preCommit event to all registered commit handlers
- *
- * @throws CommitException
- * If the commit should be aborted
- */
- private void firePreCommitEvent() throws CommitException {
- CommitHandler[] handlers = commitHandlers
- .toArray(new CommitHandler[commitHandlers.size()]);
-
- for (CommitHandler handler : handlers) {
- handler.preCommit(new CommitEvent(this));
- }
- }
-
- /**
- * Sends a postCommit event to all registered commit handlers
- *
- * @throws CommitException
- * If the commit should be aborted
- */
- private void firePostCommitEvent() throws CommitException {
- CommitHandler[] handlers = commitHandlers
- .toArray(new CommitHandler[commitHandlers.size()]);
-
- for (CommitHandler handler : handlers) {
- handler.postCommit(new CommitEvent(this));
- }
- }
-
- /**
- * Discards all changes done to the bound fields.
- * <p>
- * Only has effect if buffered mode is used.
- *
- */
- public void discard() {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- f.discard();
- } catch (Exception e) {
- // TODO: handle exception
- // What can we do if discard fails other than try to discard all
- // other fields?
- }
- }
- }
-
- /**
- * Returns the field that is bound to the given property id
- *
- * @param propertyId
- * The property id to use to lookup the field
- * @return The field that is bound to the property id or null if no field is
- * bound to that property id
- */
- public Field<?> getField(Object propertyId) {
- return propertyIdToField.get(propertyId);
- }
-
- /**
- * Returns the property id that is bound to the given field
- *
- * @param field
- * The field to use to lookup the property id
- * @return The property id that is bound to the field or null if the field
- * is not bound to any property id by this FieldBinder
- */
- public Object getPropertyId(Field<?> field) {
- return fieldToPropertyId.get(field);
- }
-
- /**
- * Adds a commit handler.
- * <p>
- * The commit handler is called before the field values are committed to the
- * item ( {@link CommitHandler#preCommit(CommitEvent)}) and after the item
- * has been updated ({@link CommitHandler#postCommit(CommitEvent)}). If a
- * {@link CommitHandler} throws a CommitException the whole commit is
- * aborted and the fields retain their old values.
- *
- * @param commitHandler
- * The commit handler to add
- */
- public void addCommitHandler(CommitHandler commitHandler) {
- commitHandlers.add(commitHandler);
- }
-
- /**
- * Removes the given commit handler.
- *
- * @see #addCommitHandler(CommitHandler)
- *
- * @param commitHandler
- * The commit handler to remove
- */
- public void removeCommitHandler(CommitHandler commitHandler) {
- commitHandlers.remove(commitHandler);
- }
-
- /**
- * Returns a list of all commit handlers for this {@link FieldGroup}.
- * <p>
- * Use {@link #addCommitHandler(CommitHandler)} and
- * {@link #removeCommitHandler(CommitHandler)} to register or unregister a
- * commit handler.
- *
- * @return A collection of commit handlers
- */
- protected Collection<CommitHandler> getCommitHandlers() {
- return Collections.unmodifiableCollection(commitHandlers);
- }
-
- /**
- * CommitHandlers are used by {@link FieldGroup#commit()} as part of the
- * commit transactions. CommitHandlers can perform custom operations as part
- * of the commit and cause the commit to be aborted by throwing a
- * {@link CommitException}.
- */
- public interface CommitHandler extends Serializable {
- /**
- * Called before changes are committed to the field and the item is
- * updated.
- * <p>
- * Throw a {@link CommitException} to abort the commit.
- *
- * @param commitEvent
- * An event containing information regarding the commit
- * @throws CommitException
- * if the commit should be aborted
- */
- public void preCommit(CommitEvent commitEvent) throws CommitException;
-
- /**
- * Called after changes are committed to the fields and the item is
- * updated..
- * <p>
- * Throw a {@link CommitException} to abort the commit.
- *
- * @param commitEvent
- * An event containing information regarding the commit
- * @throws CommitException
- * if the commit should be aborted
- */
- public void postCommit(CommitEvent commitEvent) throws CommitException;
- }
-
- /**
- * FIXME javadoc
- *
- */
- public static class CommitEvent implements Serializable {
- private FieldGroup fieldBinder;
-
- private CommitEvent(FieldGroup fieldBinder) {
- this.fieldBinder = fieldBinder;
- }
-
- /**
- * Returns the field binder that this commit relates to
- *
- * @return The FieldBinder that is being committed.
- */
- public FieldGroup getFieldBinder() {
- return fieldBinder;
- }
-
- }
-
- /**
- * Checks the validity of the bound fields.
- * <p>
- * Call the {@link Field#validate()} for the fields to get the individual
- * error messages.
- *
- * @return true if all bound fields are valid, false otherwise.
- */
- public boolean isValid() {
- try {
- for (Field<?> field : getFields()) {
- field.validate();
- }
- return true;
- } catch (InvalidValueException e) {
- return false;
- }
- }
-
- /**
- * Checks if any bound field has been modified.
- *
- * @return true if at least on field has been modified, false otherwise
- */
- public boolean isModified() {
- for (Field<?> field : getFields()) {
- if (field.isModified()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Gets the field factory for the {@link FieldGroup}. The field factory is
- * only used when {@link FieldGroup} creates a new field.
- *
- * @return The field factory in use
- *
- */
- public FieldGroupFieldFactory getFieldFactory() {
- return fieldFactory;
- }
-
- /**
- * Sets the field factory for the {@link FieldGroup}. The field factory is
- * only used when {@link FieldGroup} creates a new field.
- *
- * @param fieldFactory
- * The field factory to use
- */
- public void setFieldFactory(FieldGroupFieldFactory fieldFactory) {
- this.fieldFactory = fieldFactory;
- }
-
- /**
- * Binds member fields found in the given object.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. All non-null fields for which a property id can
- * be determined are bound to the property id.
- * </p>
- * <p>
- * For example:
- *
- * <pre>
- * public class MyForm extends VerticalLayout {
- * private TextField firstName = new TextField("First name");
- * @PropertyId("last")
- * private TextField lastName = new TextField("Last name");
- * private TextField age = new TextField("Age"); ... }
- *
- * MyForm myForm = new MyForm();
- * ...
- * fieldGroup.bindMemberFields(myForm);
- * </pre>
- *
- * </p>
- * This binds the firstName TextField to a "firstName" property in the item,
- * lastName TextField to a "last" property and the age TextField to a "age"
- * property.
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to bind
- * @throws BindException
- * If there is a problem binding a field
- */
- public void bindMemberFields(Object objectWithMemberFields)
- throws BindException {
- buildAndBindMemberFields(objectWithMemberFields, false);
- }
-
- /**
- * Binds member fields found in the given object and builds member fields
- * that have not been initialized.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory. All non-null fields for which a property id can
- * be determined are bound to the property id.
- * </p>
- * <p>
- * For example:
- *
- * <pre>
- * public class MyForm extends VerticalLayout {
- * private TextField firstName = new TextField("First name");
- * @PropertyId("last")
- * private TextField lastName = new TextField("Last name");
- * private TextField age;
- *
- * MyForm myForm = new MyForm();
- * ...
- * fieldGroup.buildAndBindMemberFields(myForm);
- * </pre>
- *
- * </p>
- * <p>
- * This binds the firstName TextField to a "firstName" property in the item,
- * lastName TextField to a "last" property and builds an age TextField using
- * the field factory and then binds it to the "age" property.
- * </p>
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to build and
- * bind
- * @throws BindException
- * If there is a problem binding or building a field
- */
- public void buildAndBindMemberFields(Object objectWithMemberFields)
- throws BindException {
- buildAndBindMemberFields(objectWithMemberFields, true);
- }
-
- /**
- * Binds member fields found in the given object and optionally builds
- * member fields that have not been initialized.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory is buildFields is true. All non-null fields for
- * which a property id can be determined are bound to the property id.
- * </p>
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to build and
- * bind
- * @throws BindException
- * If there is a problem binding or building a field
- */
- protected void buildAndBindMemberFields(Object objectWithMemberFields,
- boolean buildFields) throws BindException {
- Class<?> objectClass = objectWithMemberFields.getClass();
-
- for (java.lang.reflect.Field memberField : objectClass
- .getDeclaredFields()) {
-
- if (!Field.class.isAssignableFrom(memberField.getType())) {
- // Process next field
- continue;
- }
-
- PropertyId propertyIdAnnotation = memberField
- .getAnnotation(PropertyId.class);
-
- Class<? extends Field> fieldType = (Class<? extends Field>) memberField
- .getType();
-
- Object propertyId = null;
- if (propertyIdAnnotation != null) {
- // @PropertyId(propertyId) always overrides property id
- propertyId = propertyIdAnnotation.value();
- } else {
- propertyId = memberField.getName();
- }
-
- // Ensure that the property id exists
- Class<?> propertyType;
-
- try {
- propertyType = getPropertyType(propertyId);
- } catch (BindException e) {
- // Property id was not found, skip this field
- continue;
- }
-
- Field<?> field;
- try {
- // Get the field from the object
- field = (Field<?>) ReflectTools.getJavaFieldValue(
- objectWithMemberFields, memberField);
- } catch (Exception e) {
- // If we cannot determine the value, just skip the field and try
- // the next one
- continue;
- }
-
- if (field == null && buildFields) {
- Caption captionAnnotation = memberField
- .getAnnotation(Caption.class);
- String caption;
- if (captionAnnotation != null) {
- caption = captionAnnotation.value();
- } else {
- caption = DefaultFieldFactory
- .createCaptionByPropertyId(propertyId);
- }
-
- // Create the component (Field)
- field = build(caption, propertyType, fieldType);
-
- // Store it in the field
- try {
- ReflectTools.setJavaFieldValue(objectWithMemberFields,
- memberField, field);
- } catch (IllegalArgumentException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- } catch (IllegalAccessException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- } catch (InvocationTargetException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- }
- }
-
- if (field != null) {
- // Bind it to the property id
- bind(field, propertyId);
- }
- }
- }
-
- public static class CommitException extends Exception {
-
- public CommitException() {
- super();
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(String message, Throwable cause) {
- super(message, cause);
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(String message) {
- super(message);
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(Throwable cause) {
- super(cause);
- // TODO Auto-generated constructor stub
- }
-
- }
-
- public static class BindException extends RuntimeException {
-
- public BindException(String message) {
- super(message);
- }
-
- public BindException(String message, Throwable t) {
- super(message, t);
- }
-
- }
-
- /**
- * Builds a field and binds it to the given property id using the field
- * binder.
- *
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If there is a problem while building or binding
- * @return The created and bound field
- */
- public Field<?> buildAndBind(Object propertyId) throws BindException {
- String caption = DefaultFieldFactory
- .createCaptionByPropertyId(propertyId);
- return buildAndBind(caption, propertyId);
- }
-
- /**
- * Builds a field using the given caption and binds it to the given property
- * id using the field binder.
- *
- * @param caption
- * The caption for the field
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If there is a problem while building or binding
- * @return The created and bound field. Can be any type of {@link Field}.
- */
- public Field<?> buildAndBind(String caption, Object propertyId)
- throws BindException {
- Class<?> type = getPropertyType(propertyId);
- return buildAndBind(caption, propertyId, Field.class);
-
- }
-
- /**
- * Builds a field using the given caption and binds it to the given property
- * id using the field binder. Ensures the new field is of the given type.
- *
- * @param caption
- * The caption for the field
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If the field could not be created
- * @return The created and bound field. Can be any type of {@link Field}.
- */
-
- public <T extends Field> T buildAndBind(String caption, Object propertyId,
- Class<T> fieldType) throws BindException {
- Class<?> type = getPropertyType(propertyId);
-
- T field = build(caption, type, fieldType);
- bind(field, propertyId);
-
- return field;
- }
-
- /**
- * Creates a field based on the given data type.
- * <p>
- * The data type is the type that we want to edit using the field. The field
- * type is the type of field we want to create, can be {@link Field} if any
- * Field is good.
- * </p>
- *
- * @param caption
- * The caption for the new field
- * @param dataType
- * The data model type that we want to edit using the field
- * @param fieldType
- * The type of field that we want to create
- * @return A Field capable of editing the given type
- * @throws BindException
- * If the field could not be created
- */
- protected <T extends Field> T build(String caption, Class<?> dataType,
- Class<T> fieldType) throws BindException {
- T field = getFieldFactory().createField(dataType, fieldType);
- if (field == null) {
- throw new BindException("Unable to build a field of type "
- + fieldType.getName() + " for editing "
- + dataType.getName());
- }
-
- field.setCaption(caption);
- return field;
- }
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.fieldgroup; + +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.logging.Logger; + +import com.vaadin.data.Item; +import com.vaadin.data.Property; +import com.vaadin.data.Validator.InvalidValueException; +import com.vaadin.data.util.TransactionalPropertyWrapper; +import com.vaadin.tools.ReflectTools; +import com.vaadin.ui.DefaultFieldFactory; +import com.vaadin.ui.Field; +import com.vaadin.ui.Form; + +/** + * FieldGroup provides an easy way of binding fields to data and handling + * commits of these fields. + * <p> + * The functionality of FieldGroup is similar to {@link Form} but + * {@link FieldGroup} does not handle layouts in any way. The typical use case + * is to create a layout outside the FieldGroup and then use FieldGroup to bind + * the fields to a data source. + * </p> + * <p> + * {@link FieldGroup} is not a UI component so it cannot be added to a layout. + * Using the buildAndBind methods {@link FieldGroup} can create fields for you + * using a FieldGroupFieldFactory but you still have to add them to the correct + * position in your layout. + * </p> + * + * @author Vaadin Ltd + * @version @version@ + * @since 7.0 + */ +public class FieldGroup implements Serializable { + + private static final Logger logger = Logger.getLogger(FieldGroup.class + .getName()); + + private Item itemDataSource; + private boolean buffered = true; + + private boolean enabled = true; + private boolean readOnly = false; + + private HashMap<Object, Field<?>> propertyIdToField = new HashMap<Object, Field<?>>(); + private LinkedHashMap<Field<?>, Object> fieldToPropertyId = new LinkedHashMap<Field<?>, Object>(); + private List<CommitHandler> commitHandlers = new ArrayList<CommitHandler>(); + + /** + * The field factory used by builder methods. + */ + private FieldGroupFieldFactory fieldFactory = new DefaultFieldGroupFieldFactory(); + + /** + * Constructs a field binder. Use {@link #setItemDataSource(Item)} to set a + * data source for the field binder. + * + */ + public FieldGroup() { + + } + + /** + * Constructs a field binder that uses the given data source. + * + * @param itemDataSource + * The data source to bind the fields to + */ + public FieldGroup(Item itemDataSource) { + setItemDataSource(itemDataSource); + } + + /** + * Updates the item that is used by this FieldBinder. Rebinds all fields to + * the properties in the new item. + * + * @param itemDataSource + * The new item to use + */ + public void setItemDataSource(Item itemDataSource) { + this.itemDataSource = itemDataSource; + + for (Field<?> f : fieldToPropertyId.keySet()) { + bind(f, fieldToPropertyId.get(f)); + } + } + + /** + * Gets the item used by this FieldBinder. Note that you must call + * {@link #commit()} for the item to be updated unless buffered mode has + * been switched off. + * + * @see #setBuffered(boolean) + * @see #commit() + * + * @return The item used by this FieldBinder + */ + public Item getItemDataSource() { + return itemDataSource; + } + + /** + * Checks the buffered mode for the bound fields. + * <p> + * + * @see #setBuffered(boolean) for more details on buffered mode + * + * @see Field#isBuffered() + * @return true if buffered mode is on, false otherwise + * + */ + public boolean isBuffered() { + return buffered; + } + + /** + * Sets the buffered mode for the bound fields. + * <p> + * When buffered mode is on the item will not be updated until + * {@link #commit()} is called. If buffered mode is off the item will be + * updated once the fields are updated. + * </p> + * <p> + * The default is to use buffered mode. + * </p> + * + * @see Field#setBuffered(boolean) + * @param buffered + * true to turn on buffered mode, false otherwise + */ + public void setBuffered(boolean buffered) { + if (buffered == this.buffered) { + return; + } + + this.buffered = buffered; + for (Field<?> field : getFields()) { + field.setBuffered(buffered); + } + } + + /** + * Returns the enabled status for the fields. + * <p> + * Note that this will not accurately represent the enabled status of all + * fields if you change the enabled status of the fields through some other + * method than {@link #setEnabled(boolean)}. + * + * @return true if the fields are enabled, false otherwise + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Updates the enabled state of all bound fields. + * + * @param fieldsEnabled + * true to enable all bound fields, false to disable them + */ + public void setEnabled(boolean fieldsEnabled) { + enabled = fieldsEnabled; + for (Field<?> field : getFields()) { + field.setEnabled(fieldsEnabled); + } + } + + /** + * Returns the read only status for the fields. + * <p> + * Note that this will not accurately represent the read only status of all + * fields if you change the read only status of the fields through some + * other method than {@link #setReadOnly(boolean)}. + * + * @return true if the fields are set to read only, false otherwise + */ + public boolean isReadOnly() { + return readOnly; + } + + /** + * Updates the read only state of all bound fields. + * + * @param fieldsReadOnly + * true to set all bound fields to read only, false to set them + * to read write + */ + public void setReadOnly(boolean fieldsReadOnly) { + readOnly = fieldsReadOnly; + } + + /** + * Returns a collection of all fields that have been bound. + * <p> + * The fields are not returned in any specific order. + * </p> + * + * @return A collection with all bound Fields + */ + public Collection<Field<?>> getFields() { + return fieldToPropertyId.keySet(); + } + + /** + * Binds the field with the given propertyId from the current item. If an + * item has not been set then the binding is postponed until the item is set + * using {@link #setItemDataSource(Item)}. + * <p> + * This method also adds validators when applicable. + * </p> + * + * @param field + * The field to bind + * @param propertyId + * The propertyId to bind to the field + * @throws BindException + * If the property id is already bound to another field by this + * field binder + */ + public void bind(Field<?> field, Object propertyId) throws BindException { + if (propertyIdToField.containsKey(propertyId) + && propertyIdToField.get(propertyId) != field) { + throw new BindException("Property id " + propertyId + + " is already bound to another field"); + } + fieldToPropertyId.put(field, propertyId); + propertyIdToField.put(propertyId, field); + if (itemDataSource == null) { + // Will be bound when data source is set + return; + } + + field.setPropertyDataSource(wrapInTransactionalProperty(getItemProperty(propertyId))); + configureField(field); + } + + private <T> Property.Transactional<T> wrapInTransactionalProperty( + Property<T> itemProperty) { + return new TransactionalPropertyWrapper<T>(itemProperty); + } + + /** + * Gets the property with the given property id from the item. + * + * @param propertyId + * The id if the property to find + * @return The property with the given id from the item + * @throws BindException + * If the property was not found in the item or no item has been + * set + */ + protected Property<?> getItemProperty(Object propertyId) + throws BindException { + Item item = getItemDataSource(); + if (item == null) { + throw new BindException("Could not lookup property with id " + + propertyId + " as no item has been set"); + } + Property<?> p = item.getItemProperty(propertyId); + if (p == null) { + throw new BindException("A property with id " + propertyId + + " was not found in the item"); + } + return p; + } + + /** + * Detaches the field from its property id and removes it from this + * FieldBinder. + * <p> + * Note that the field is not detached from its property data source if it + * is no longer connected to the same property id it was bound to using this + * FieldBinder. + * + * @param field + * The field to detach + * @throws BindException + * If the field is not bound by this field binder or not bound + * to the correct property id + */ + public void unbind(Field<?> field) throws BindException { + Object propertyId = fieldToPropertyId.get(field); + if (propertyId == null) { + throw new BindException( + "The given field is not part of this FieldBinder"); + } + + Property fieldDataSource = field.getPropertyDataSource(); + if (fieldDataSource instanceof TransactionalPropertyWrapper) { + fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource) + .getWrappedProperty(); + } + if (fieldDataSource == getItemProperty(propertyId)) { + field.setPropertyDataSource(null); + } + fieldToPropertyId.remove(field); + propertyIdToField.remove(propertyId); + } + + /** + * Configures a field with the settings set for this FieldBinder. + * <p> + * By default this updates the buffered, read only and enabled state of the + * field. Also adds validators when applicable. + * + * @param field + * The field to update + */ + protected void configureField(Field<?> field) { + field.setBuffered(isBuffered()); + + field.setEnabled(isEnabled()); + field.setReadOnly(isReadOnly()); + } + + /** + * Gets the type of the property with the given property id. + * + * @param propertyId + * The propertyId. Must be find + * @return The type of the property + */ + protected Class<?> getPropertyType(Object propertyId) throws BindException { + if (getItemDataSource() == null) { + throw new BindException( + "Property type for '" + + propertyId + + "' could not be determined. No item data source has been set."); + } + Property<?> p = getItemDataSource().getItemProperty(propertyId); + if (p == null) { + throw new BindException( + "Property type for '" + + propertyId + + "' could not be determined. No property with that id was found."); + } + + return p.getType(); + } + + /** + * Returns a collection of all property ids that have been bound to fields. + * <p> + * Note that this will return property ids even before the item has been + * set. In that case it returns the property ids that will be bound once the + * item is set. + * </p> + * <p> + * No guarantee is given for the order of the property ids + * </p> + * + * @return A collection of bound property ids + */ + public Collection<Object> getBoundPropertyIds() { + return Collections.unmodifiableCollection(propertyIdToField.keySet()); + } + + /** + * Returns a collection of all property ids that exist in the item set using + * {@link #setItemDataSource(Item)} but have not been bound to fields. + * <p> + * Will always return an empty collection before an item has been set using + * {@link #setItemDataSource(Item)}. + * </p> + * <p> + * No guarantee is given for the order of the property ids + * </p> + * + * @return A collection of property ids that have not been bound to fields + */ + public Collection<Object> getUnboundPropertyIds() { + if (getItemDataSource() == null) { + return new ArrayList<Object>(); + } + List<Object> unboundPropertyIds = new ArrayList<Object>(); + unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds()); + unboundPropertyIds.removeAll(propertyIdToField.keySet()); + return unboundPropertyIds; + } + + /** + * Commits all changes done to the bound fields. + * <p> + * Calls all {@link CommitHandler}s before and after committing the field + * changes to the item data source. The whole commit is aborted and state is + * restored to what it was before commit was called if any + * {@link CommitHandler} throws a CommitException or there is a problem + * committing the fields + * + * @throws CommitException + * If the commit was aborted + */ + public void commit() throws CommitException { + if (!isBuffered()) { + // Not using buffered mode, nothing to do + return; + } + for (Field<?> f : fieldToPropertyId.keySet()) { + ((Property.Transactional<?>) f.getPropertyDataSource()) + .startTransaction(); + } + try { + firePreCommitEvent(); + // Commit the field values to the properties + for (Field<?> f : fieldToPropertyId.keySet()) { + f.commit(); + } + firePostCommitEvent(); + + // Commit the properties + for (Field<?> f : fieldToPropertyId.keySet()) { + ((Property.Transactional<?>) f.getPropertyDataSource()) + .commit(); + } + + } catch (Exception e) { + for (Field<?> f : fieldToPropertyId.keySet()) { + try { + ((Property.Transactional<?>) f.getPropertyDataSource()) + .rollback(); + } catch (Exception rollbackException) { + // FIXME: What to do ? + } + } + + throw new CommitException("Commit failed", e); + } + + } + + /** + * Sends a preCommit event to all registered commit handlers + * + * @throws CommitException + * If the commit should be aborted + */ + private void firePreCommitEvent() throws CommitException { + CommitHandler[] handlers = commitHandlers + .toArray(new CommitHandler[commitHandlers.size()]); + + for (CommitHandler handler : handlers) { + handler.preCommit(new CommitEvent(this)); + } + } + + /** + * Sends a postCommit event to all registered commit handlers + * + * @throws CommitException + * If the commit should be aborted + */ + private void firePostCommitEvent() throws CommitException { + CommitHandler[] handlers = commitHandlers + .toArray(new CommitHandler[commitHandlers.size()]); + + for (CommitHandler handler : handlers) { + handler.postCommit(new CommitEvent(this)); + } + } + + /** + * Discards all changes done to the bound fields. + * <p> + * Only has effect if buffered mode is used. + * + */ + public void discard() { + for (Field<?> f : fieldToPropertyId.keySet()) { + try { + f.discard(); + } catch (Exception e) { + // TODO: handle exception + // What can we do if discard fails other than try to discard all + // other fields? + } + } + } + + /** + * Returns the field that is bound to the given property id + * + * @param propertyId + * The property id to use to lookup the field + * @return The field that is bound to the property id or null if no field is + * bound to that property id + */ + public Field<?> getField(Object propertyId) { + return propertyIdToField.get(propertyId); + } + + /** + * Returns the property id that is bound to the given field + * + * @param field + * The field to use to lookup the property id + * @return The property id that is bound to the field or null if the field + * is not bound to any property id by this FieldBinder + */ + public Object getPropertyId(Field<?> field) { + return fieldToPropertyId.get(field); + } + + /** + * Adds a commit handler. + * <p> + * The commit handler is called before the field values are committed to the + * item ( {@link CommitHandler#preCommit(CommitEvent)}) and after the item + * has been updated ({@link CommitHandler#postCommit(CommitEvent)}). If a + * {@link CommitHandler} throws a CommitException the whole commit is + * aborted and the fields retain their old values. + * + * @param commitHandler + * The commit handler to add + */ + public void addCommitHandler(CommitHandler commitHandler) { + commitHandlers.add(commitHandler); + } + + /** + * Removes the given commit handler. + * + * @see #addCommitHandler(CommitHandler) + * + * @param commitHandler + * The commit handler to remove + */ + public void removeCommitHandler(CommitHandler commitHandler) { + commitHandlers.remove(commitHandler); + } + + /** + * Returns a list of all commit handlers for this {@link FieldGroup}. + * <p> + * Use {@link #addCommitHandler(CommitHandler)} and + * {@link #removeCommitHandler(CommitHandler)} to register or unregister a + * commit handler. + * + * @return A collection of commit handlers + */ + protected Collection<CommitHandler> getCommitHandlers() { + return Collections.unmodifiableCollection(commitHandlers); + } + + /** + * CommitHandlers are used by {@link FieldGroup#commit()} as part of the + * commit transactions. CommitHandlers can perform custom operations as part + * of the commit and cause the commit to be aborted by throwing a + * {@link CommitException}. + */ + public interface CommitHandler extends Serializable { + /** + * Called before changes are committed to the field and the item is + * updated. + * <p> + * Throw a {@link CommitException} to abort the commit. + * + * @param commitEvent + * An event containing information regarding the commit + * @throws CommitException + * if the commit should be aborted + */ + public void preCommit(CommitEvent commitEvent) throws CommitException; + + /** + * Called after changes are committed to the fields and the item is + * updated.. + * <p> + * Throw a {@link CommitException} to abort the commit. + * + * @param commitEvent + * An event containing information regarding the commit + * @throws CommitException + * if the commit should be aborted + */ + public void postCommit(CommitEvent commitEvent) throws CommitException; + } + + /** + * FIXME javadoc + * + */ + public static class CommitEvent implements Serializable { + private FieldGroup fieldBinder; + + private CommitEvent(FieldGroup fieldBinder) { + this.fieldBinder = fieldBinder; + } + + /** + * Returns the field binder that this commit relates to + * + * @return The FieldBinder that is being committed. + */ + public FieldGroup getFieldBinder() { + return fieldBinder; + } + + } + + /** + * Checks the validity of the bound fields. + * <p> + * Call the {@link Field#validate()} for the fields to get the individual + * error messages. + * + * @return true if all bound fields are valid, false otherwise. + */ + public boolean isValid() { + try { + for (Field<?> field : getFields()) { + field.validate(); + } + return true; + } catch (InvalidValueException e) { + return false; + } + } + + /** + * Checks if any bound field has been modified. + * + * @return true if at least on field has been modified, false otherwise + */ + public boolean isModified() { + for (Field<?> field : getFields()) { + if (field.isModified()) { + return true; + } + } + return false; + } + + /** + * Gets the field factory for the {@link FieldGroup}. The field factory is + * only used when {@link FieldGroup} creates a new field. + * + * @return The field factory in use + * + */ + public FieldGroupFieldFactory getFieldFactory() { + return fieldFactory; + } + + /** + * Sets the field factory for the {@link FieldGroup}. The field factory is + * only used when {@link FieldGroup} creates a new field. + * + * @param fieldFactory + * The field factory to use + */ + public void setFieldFactory(FieldGroupFieldFactory fieldFactory) { + this.fieldFactory = fieldFactory; + } + + /** + * Binds member fields found in the given object. + * <p> + * This method processes all (Java) member fields whose type extends + * {@link Field} and that can be mapped to a property id. Property id + * mapping is done based on the field name or on a @{@link PropertyId} + * annotation on the field. All non-null fields for which a property id can + * be determined are bound to the property id. + * </p> + * <p> + * For example: + * + * <pre> + * public class MyForm extends VerticalLayout { + * private TextField firstName = new TextField("First name"); + * @PropertyId("last") + * private TextField lastName = new TextField("Last name"); + * private TextField age = new TextField("Age"); ... } + * + * MyForm myForm = new MyForm(); + * ... + * fieldGroup.bindMemberFields(myForm); + * </pre> + * + * </p> + * This binds the firstName TextField to a "firstName" property in the item, + * lastName TextField to a "last" property and the age TextField to a "age" + * property. + * + * @param objectWithMemberFields + * The object that contains (Java) member fields to bind + * @throws BindException + * If there is a problem binding a field + */ + public void bindMemberFields(Object objectWithMemberFields) + throws BindException { + buildAndBindMemberFields(objectWithMemberFields, false); + } + + /** + * Binds member fields found in the given object and builds member fields + * that have not been initialized. + * <p> + * This method processes all (Java) member fields whose type extends + * {@link Field} and that can be mapped to a property id. Property id + * mapping is done based on the field name or on a @{@link PropertyId} + * annotation on the field. Fields that are not initialized (null) are built + * using the field factory. All non-null fields for which a property id can + * be determined are bound to the property id. + * </p> + * <p> + * For example: + * + * <pre> + * public class MyForm extends VerticalLayout { + * private TextField firstName = new TextField("First name"); + * @PropertyId("last") + * private TextField lastName = new TextField("Last name"); + * private TextField age; + * + * MyForm myForm = new MyForm(); + * ... + * fieldGroup.buildAndBindMemberFields(myForm); + * </pre> + * + * </p> + * <p> + * This binds the firstName TextField to a "firstName" property in the item, + * lastName TextField to a "last" property and builds an age TextField using + * the field factory and then binds it to the "age" property. + * </p> + * + * @param objectWithMemberFields + * The object that contains (Java) member fields to build and + * bind + * @throws BindException + * If there is a problem binding or building a field + */ + public void buildAndBindMemberFields(Object objectWithMemberFields) + throws BindException { + buildAndBindMemberFields(objectWithMemberFields, true); + } + + /** + * Binds member fields found in the given object and optionally builds + * member fields that have not been initialized. + * <p> + * This method processes all (Java) member fields whose type extends + * {@link Field} and that can be mapped to a property id. Property id + * mapping is done based on the field name or on a @{@link PropertyId} + * annotation on the field. Fields that are not initialized (null) are built + * using the field factory is buildFields is true. All non-null fields for + * which a property id can be determined are bound to the property id. + * </p> + * + * @param objectWithMemberFields + * The object that contains (Java) member fields to build and + * bind + * @throws BindException + * If there is a problem binding or building a field + */ + protected void buildAndBindMemberFields(Object objectWithMemberFields, + boolean buildFields) throws BindException { + Class<?> objectClass = objectWithMemberFields.getClass(); + + for (java.lang.reflect.Field memberField : objectClass + .getDeclaredFields()) { + + if (!Field.class.isAssignableFrom(memberField.getType())) { + // Process next field + continue; + } + + PropertyId propertyIdAnnotation = memberField + .getAnnotation(PropertyId.class); + + Class<? extends Field> fieldType = (Class<? extends Field>) memberField + .getType(); + + Object propertyId = null; + if (propertyIdAnnotation != null) { + // @PropertyId(propertyId) always overrides property id + propertyId = propertyIdAnnotation.value(); + } else { + propertyId = memberField.getName(); + } + + // Ensure that the property id exists + Class<?> propertyType; + + try { + propertyType = getPropertyType(propertyId); + } catch (BindException e) { + // Property id was not found, skip this field + continue; + } + + Field<?> field; + try { + // Get the field from the object + field = (Field<?>) ReflectTools.getJavaFieldValue( + objectWithMemberFields, memberField); + } catch (Exception e) { + // If we cannot determine the value, just skip the field and try + // the next one + continue; + } + + if (field == null && buildFields) { + Caption captionAnnotation = memberField + .getAnnotation(Caption.class); + String caption; + if (captionAnnotation != null) { + caption = captionAnnotation.value(); + } else { + caption = DefaultFieldFactory + .createCaptionByPropertyId(propertyId); + } + + // Create the component (Field) + field = build(caption, propertyType, fieldType); + + // Store it in the field + try { + ReflectTools.setJavaFieldValue(objectWithMemberFields, + memberField, field); + } catch (IllegalArgumentException e) { + throw new BindException("Could not assign value to field '" + + memberField.getName() + "'", e); + } catch (IllegalAccessException e) { + throw new BindException("Could not assign value to field '" + + memberField.getName() + "'", e); + } catch (InvocationTargetException e) { + throw new BindException("Could not assign value to field '" + + memberField.getName() + "'", e); + } + } + + if (field != null) { + // Bind it to the property id + bind(field, propertyId); + } + } + } + + public static class CommitException extends Exception { + + public CommitException() { + super(); + // TODO Auto-generated constructor stub + } + + public CommitException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + public CommitException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + public CommitException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + } + + public static class BindException extends RuntimeException { + + public BindException(String message) { + super(message); + } + + public BindException(String message, Throwable t) { + super(message, t); + } + + } + + /** + * Builds a field and binds it to the given property id using the field + * binder. + * + * @param propertyId + * The property id to bind to. Must be present in the field + * finder. + * @throws BindException + * If there is a problem while building or binding + * @return The created and bound field + */ + public Field<?> buildAndBind(Object propertyId) throws BindException { + String caption = DefaultFieldFactory + .createCaptionByPropertyId(propertyId); + return buildAndBind(caption, propertyId); + } + + /** + * Builds a field using the given caption and binds it to the given property + * id using the field binder. + * + * @param caption + * The caption for the field + * @param propertyId + * The property id to bind to. Must be present in the field + * finder. + * @throws BindException + * If there is a problem while building or binding + * @return The created and bound field. Can be any type of {@link Field}. + */ + public Field<?> buildAndBind(String caption, Object propertyId) + throws BindException { + Class<?> type = getPropertyType(propertyId); + return buildAndBind(caption, propertyId, Field.class); + + } + + /** + * Builds a field using the given caption and binds it to the given property + * id using the field binder. Ensures the new field is of the given type. + * + * @param caption + * The caption for the field + * @param propertyId + * The property id to bind to. Must be present in the field + * finder. + * @throws BindException + * If the field could not be created + * @return The created and bound field. Can be any type of {@link Field}. + */ + + public <T extends Field> T buildAndBind(String caption, Object propertyId, + Class<T> fieldType) throws BindException { + Class<?> type = getPropertyType(propertyId); + + T field = build(caption, type, fieldType); + bind(field, propertyId); + + return field; + } + + /** + * Creates a field based on the given data type. + * <p> + * The data type is the type that we want to edit using the field. The field + * type is the type of field we want to create, can be {@link Field} if any + * Field is good. + * </p> + * + * @param caption + * The caption for the new field + * @param dataType + * The data model type that we want to edit using the field + * @param fieldType + * The type of field that we want to create + * @return A Field capable of editing the given type + * @throws BindException + * If the field could not be created + */ + protected <T extends Field> T build(String caption, Class<?> dataType, + Class<T> fieldType) throws BindException { + T field = getFieldFactory().createField(dataType, fieldType); + if (field == null) { + throw new BindException("Unable to build a field of type " + + fieldType.getName() + " for editing " + + dataType.getName()); + } + + field.setCaption(caption); + return field; + } }
\ No newline at end of file diff --git a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java index 6945a492bd..80c012cbdc 100644 --- a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java +++ b/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java @@ -1,31 +1,31 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.io.Serializable;
-
-import com.vaadin.ui.Field;
-
-/**
- * Factory interface for creating new Field-instances based on the data type
- * that should be edited.
- *
- * @author Vaadin Ltd.
- * @version @version@
- * @since 7.0
- */
-public interface FieldGroupFieldFactory extends Serializable {
- /**
- * Creates a field based on the data type that we want to edit
- *
- * @param dataType
- * The type that we want to edit using the field
- * @param fieldType
- * The type of field we want to create. If set to {@link Field}
- * then any type of field is accepted
- * @return A field that can be assigned to the given fieldType and that is
- * capable of editing the given type of data
- */
- <T extends Field> T createField(Class<?> dataType, Class<T> fieldType);
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.fieldgroup; + +import java.io.Serializable; + +import com.vaadin.ui.Field; + +/** + * Factory interface for creating new Field-instances based on the data type + * that should be edited. + * + * @author Vaadin Ltd. + * @version @version@ + * @since 7.0 + */ +public interface FieldGroupFieldFactory extends Serializable { + /** + * Creates a field based on the data type that we want to edit + * + * @param dataType + * The type that we want to edit using the field + * @param fieldType + * The type of field we want to create. If set to {@link Field} + * then any type of field is accepted + * @return A field that can be assigned to the given fieldType and that is + * capable of editing the given type of data + */ + <T extends Field> T createField(Class<?> dataType, Class<T> fieldType); +} diff --git a/src/com/vaadin/data/fieldgroup/PropertyId.java b/src/com/vaadin/data/fieldgroup/PropertyId.java index 588fdc3020..268047401d 100644 --- a/src/com/vaadin/data/fieldgroup/PropertyId.java +++ b/src/com/vaadin/data/fieldgroup/PropertyId.java @@ -1,15 +1,15 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface PropertyId {
- String value();
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.fieldgroup; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface PropertyId { + String value(); +} diff --git a/src/com/vaadin/data/util/TextFileProperty.java b/src/com/vaadin/data/util/TextFileProperty.java index 77325e141d..5ebba98062 100644 --- a/src/com/vaadin/data/util/TextFileProperty.java +++ b/src/com/vaadin/data/util/TextFileProperty.java @@ -1,141 +1,141 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.nio.charset.Charset;
-
-/**
- * Property implementation for wrapping a text file.
- *
- * Supports reading and writing of a File from/to String.
- *
- * {@link ValueChangeListener}s are supported, but only fire when
- * setValue(Object) is explicitly called. {@link ReadOnlyStatusChangeListener}s
- * are supported but only fire when setReadOnly(boolean) is explicitly called.
- *
- */
-@SuppressWarnings("serial")
-public class TextFileProperty extends AbstractProperty<String> {
-
- private File file;
- private Charset charset = null;
-
- /**
- * Wrap given file with property interface.
- *
- * Setting the file to null works, but getValue() will return null.
- *
- * @param file
- * File to be wrapped.
- */
- public TextFileProperty(File file) {
- this.file = file;
- }
-
- /**
- * Wrap the given file with the property interface and specify character
- * set.
- *
- * Setting the file to null works, but getValue() will return null.
- *
- * @param file
- * File to be wrapped.
- * @param charset
- * Charset to be used for reading and writing the file.
- */
- public TextFileProperty(File file, Charset charset) {
- this.file = file;
- this.charset = charset;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getType()
- */
- public Class<String> getType() {
- return String.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getValue()
- */
- public String getValue() {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- InputStreamReader isr = charset == null ? new InputStreamReader(fis)
- : new InputStreamReader(fis, charset);
- BufferedReader r = new BufferedReader(isr);
- StringBuilder b = new StringBuilder();
- char buf[] = new char[8 * 1024];
- int len;
- while ((len = r.read(buf)) != -1) {
- b.append(buf, 0, len);
- }
- r.close();
- isr.close();
- fis.close();
- return b.toString();
- } catch (FileNotFoundException e) {
- return null;
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#isReadOnly()
- */
- @Override
- public boolean isReadOnly() {
- return file == null || super.isReadOnly() || !file.canWrite();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#setValue(java.lang.Object)
- */
- public void setValue(Object newValue) throws ReadOnlyException {
- if (isReadOnly()) {
- throw new ReadOnlyException();
- }
- if (file == null) {
- return;
- }
-
- try {
- FileOutputStream fos = new FileOutputStream(file);
- OutputStreamWriter osw = charset == null ? new OutputStreamWriter(
- fos) : new OutputStreamWriter(fos, charset);
- BufferedWriter w = new BufferedWriter(osw);
- w.append(newValue.toString());
- w.flush();
- w.close();
- osw.close();
- fos.close();
- fireValueChange();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.nio.charset.Charset; + +/** + * Property implementation for wrapping a text file. + * + * Supports reading and writing of a File from/to String. + * + * {@link ValueChangeListener}s are supported, but only fire when + * setValue(Object) is explicitly called. {@link ReadOnlyStatusChangeListener}s + * are supported but only fire when setReadOnly(boolean) is explicitly called. + * + */ +@SuppressWarnings("serial") +public class TextFileProperty extends AbstractProperty<String> { + + private File file; + private Charset charset = null; + + /** + * Wrap given file with property interface. + * + * Setting the file to null works, but getValue() will return null. + * + * @param file + * File to be wrapped. + */ + public TextFileProperty(File file) { + this.file = file; + } + + /** + * Wrap the given file with the property interface and specify character + * set. + * + * Setting the file to null works, but getValue() will return null. + * + * @param file + * File to be wrapped. + * @param charset + * Charset to be used for reading and writing the file. + */ + public TextFileProperty(File file, Charset charset) { + this.file = file; + this.charset = charset; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.Property#getType() + */ + public Class<String> getType() { + return String.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.Property#getValue() + */ + public String getValue() { + if (file == null) { + return null; + } + try { + FileInputStream fis = new FileInputStream(file); + InputStreamReader isr = charset == null ? new InputStreamReader(fis) + : new InputStreamReader(fis, charset); + BufferedReader r = new BufferedReader(isr); + StringBuilder b = new StringBuilder(); + char buf[] = new char[8 * 1024]; + int len; + while ((len = r.read(buf)) != -1) { + b.append(buf, 0, len); + } + r.close(); + isr.close(); + fis.close(); + return b.toString(); + } catch (FileNotFoundException e) { + return null; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.Property#isReadOnly() + */ + @Override + public boolean isReadOnly() { + return file == null || super.isReadOnly() || !file.canWrite(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.Property#setValue(java.lang.Object) + */ + public void setValue(Object newValue) throws ReadOnlyException { + if (isReadOnly()) { + throw new ReadOnlyException(); + } + if (file == null) { + return; + } + + try { + FileOutputStream fos = new FileOutputStream(file); + OutputStreamWriter osw = charset == null ? new OutputStreamWriter( + fos) : new OutputStreamWriter(fos, charset); + BufferedWriter w = new BufferedWriter(osw); + w.append(newValue.toString()); + w.flush(); + w.close(); + osw.close(); + fos.close(); + fireValueChange(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java b/src/com/vaadin/data/util/TransactionalPropertyWrapper.java index de44dbe544..06ec0935c3 100644 --- a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java +++ b/src/com/vaadin/data/util/TransactionalPropertyWrapper.java @@ -1,107 +1,107 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import com.vaadin.data.Property;
-import com.vaadin.data.Property.ValueChangeEvent;
-import com.vaadin.data.Property.ValueChangeNotifier;
-
-/**
- * Wrapper class that helps implement two-phase commit for a non-transactional
- * property.
- *
- * When accessing the property through the wrapper, getting and setting the
- * property value take place immediately. However, the wrapper keeps track of
- * the old value of the property so that it can be set for the property in case
- * of a roll-back. This can result in the underlying property value changing
- * multiple times (first based on modifications made by the application, then
- * back upon roll-back).
- *
- * Value change events on the {@link TransactionalPropertyWrapper} are only
- * fired at the end of a successful transaction, whereas listeners attached to
- * the underlying property may receive multiple value change events.
- *
- * @see com.vaadin.data.Property.Transactional
- *
- * @author Vaadin Ltd
- * @version @version@
- * @since 7.0
- *
- * @param <T>
- */
-public class TransactionalPropertyWrapper<T> extends AbstractProperty<T>
- implements ValueChangeNotifier, Property.Transactional<T> {
-
- private Property<T> wrappedProperty;
- private boolean inTransaction = false;
- private boolean valueChangePending;
- private T valueBeforeTransaction;
-
- public TransactionalPropertyWrapper(Property<T> wrappedProperty) {
- this.wrappedProperty = wrappedProperty;
- if (wrappedProperty instanceof ValueChangeNotifier) {
- ((ValueChangeNotifier) wrappedProperty)
- .addListener(new ValueChangeListener() {
-
- public void valueChange(ValueChangeEvent event) {
- fireValueChange();
- }
- });
- }
- }
-
- public Class getType() {
- return wrappedProperty.getType();
- }
-
- public T getValue() {
- return wrappedProperty.getValue();
- }
-
- public void setValue(Object newValue) throws ReadOnlyException {
- // Causes a value change to be sent to this listener which in turn fires
- // a new value change event for this property
- wrappedProperty.setValue(newValue);
- }
-
- public void startTransaction() {
- inTransaction = true;
- valueBeforeTransaction = getValue();
- }
-
- public void commit() {
- endTransaction();
- }
-
- public void rollback() {
- try {
- wrappedProperty.setValue(valueBeforeTransaction);
- } finally {
- valueChangePending = false;
- endTransaction();
- }
- }
-
- protected void endTransaction() {
- inTransaction = false;
- valueBeforeTransaction = null;
- if (valueChangePending) {
- fireValueChange();
- }
- }
-
- @Override
- protected void fireValueChange() {
- if (inTransaction) {
- valueChangePending = true;
- } else {
- super.fireValueChange();
- }
- }
-
- public Property<T> getWrappedProperty() {
- return wrappedProperty;
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.util; + +import com.vaadin.data.Property; +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeNotifier; + +/** + * Wrapper class that helps implement two-phase commit for a non-transactional + * property. + * + * When accessing the property through the wrapper, getting and setting the + * property value take place immediately. However, the wrapper keeps track of + * the old value of the property so that it can be set for the property in case + * of a roll-back. This can result in the underlying property value changing + * multiple times (first based on modifications made by the application, then + * back upon roll-back). + * + * Value change events on the {@link TransactionalPropertyWrapper} are only + * fired at the end of a successful transaction, whereas listeners attached to + * the underlying property may receive multiple value change events. + * + * @see com.vaadin.data.Property.Transactional + * + * @author Vaadin Ltd + * @version @version@ + * @since 7.0 + * + * @param <T> + */ +public class TransactionalPropertyWrapper<T> extends AbstractProperty<T> + implements ValueChangeNotifier, Property.Transactional<T> { + + private Property<T> wrappedProperty; + private boolean inTransaction = false; + private boolean valueChangePending; + private T valueBeforeTransaction; + + public TransactionalPropertyWrapper(Property<T> wrappedProperty) { + this.wrappedProperty = wrappedProperty; + if (wrappedProperty instanceof ValueChangeNotifier) { + ((ValueChangeNotifier) wrappedProperty) + .addListener(new ValueChangeListener() { + + public void valueChange(ValueChangeEvent event) { + fireValueChange(); + } + }); + } + } + + public Class getType() { + return wrappedProperty.getType(); + } + + public T getValue() { + return wrappedProperty.getValue(); + } + + public void setValue(Object newValue) throws ReadOnlyException { + // Causes a value change to be sent to this listener which in turn fires + // a new value change event for this property + wrappedProperty.setValue(newValue); + } + + public void startTransaction() { + inTransaction = true; + valueBeforeTransaction = getValue(); + } + + public void commit() { + endTransaction(); + } + + public void rollback() { + try { + wrappedProperty.setValue(valueBeforeTransaction); + } finally { + valueChangePending = false; + endTransaction(); + } + } + + protected void endTransaction() { + inTransaction = false; + valueBeforeTransaction = null; + if (valueChangePending) { + fireValueChange(); + } + } + + @Override + protected void fireValueChange() { + if (inTransaction) { + valueChangePending = true; + } else { + super.fireValueChange(); + } + } + + public Property<T> getWrappedProperty() { + return wrappedProperty; + } + +} diff --git a/src/com/vaadin/data/util/converter/Converter.java b/src/com/vaadin/data/util/converter/Converter.java index 065d06b071..b8c15e8cdc 100644 --- a/src/com/vaadin/data/util/converter/Converter.java +++ b/src/com/vaadin/data/util/converter/Converter.java @@ -1,159 +1,159 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.io.Serializable;
-import java.util.Locale;
-
-/**
- * Interface that implements conversion between a model and a presentation type.
- * <p>
- * Typically {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should be symmetric so that chaining
- * these together returns the original result for all input but this is not a
- * requirement.
- * </p>
- * <p>
- * Converters must not have any side effects (never update UI from inside a
- * converter).
- * </p>
- * <p>
- * All Converters must be stateless and thread safe.
- * </p>
- * <p>
- * If conversion of a value fails, a {@link ConversionException} is thrown.
- * </p>
- *
- * @param <MODEL>
- * The model type. Must be compatible with what
- * {@link #getModelType()} returns.
- * @param <PRESENTATION>
- * The presentation type. Must be compatible with what
- * {@link #getPresentationType()} returns.
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public interface Converter<PRESENTATION, MODEL> extends Serializable {
-
- /**
- * Converts the given value from target type to source type.
- * <p>
- * A converter can optionally use locale to do the conversion.
- * </p>
- * A converter should in most cases be symmetric so chaining
- * {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should return the original value.
- *
- * @param value
- * The value to convert, compatible with the target type. Can be
- * null
- * @param locale
- * The locale to use for conversion. Can be null.
- * @return The converted value compatible with the source type
- * @throws ConversionException
- * If the value could not be converted
- */
- public MODEL convertToModel(PRESENTATION value, Locale locale)
- throws ConversionException;
-
- /**
- * Converts the given value from source type to target type.
- * <p>
- * A converter can optionally use locale to do the conversion.
- * </p>
- * A converter should in most cases be symmetric so chaining
- * {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should return the original value.
- *
- * @param value
- * The value to convert, compatible with the target type. Can be
- * null
- * @param locale
- * The locale to use for conversion. Can be null.
- * @return The converted value compatible with the source type
- * @throws ConversionException
- * If the value could not be converted
- */
- public PRESENTATION convertToPresentation(MODEL value, Locale locale)
- throws ConversionException;
-
- /**
- * The source type of the converter.
- *
- * Values of this type can be passed to
- * {@link #convertToPresentation(Object, Locale)}.
- *
- * @return The source type
- */
- public Class<MODEL> getModelType();
-
- /**
- * The target type of the converter.
- *
- * Values of this type can be passed to
- * {@link #convertToModel(Object, Locale)}.
- *
- * @return The target type
- */
- public Class<PRESENTATION> getPresentationType();
-
- /**
- * An exception that signals that the value passed to
- * {@link Converter#convertToPresentation(Object, Locale)} or
- * {@link Converter#convertToModel(Object, Locale)} could not be converted.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public static class ConversionException extends RuntimeException {
-
- /**
- * Constructs a new <code>ConversionException</code> without a detail
- * message.
- */
- public ConversionException() {
- }
-
- /**
- * Constructs a new <code>ConversionException</code> with the specified
- * detail message.
- *
- * @param msg
- * the detail message
- */
- public ConversionException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs a new {@code ConversionException} with the specified
- * cause.
- *
- * @param cause
- * The cause of the the exception
- */
- public ConversionException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Constructs a new <code>ConversionException</code> with the specified
- * detail message and cause.
- *
- * @param message
- * the detail message
- * @param cause
- * The cause of the the exception
- */
- public ConversionException(String message, Throwable cause) {
- super(message, cause);
- }
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.io.Serializable; +import java.util.Locale; + +/** + * Interface that implements conversion between a model and a presentation type. + * <p> + * Typically {@link #convertToPresentation(Object, Locale)} and + * {@link #convertToModel(Object, Locale)} should be symmetric so that chaining + * these together returns the original result for all input but this is not a + * requirement. + * </p> + * <p> + * Converters must not have any side effects (never update UI from inside a + * converter). + * </p> + * <p> + * All Converters must be stateless and thread safe. + * </p> + * <p> + * If conversion of a value fails, a {@link ConversionException} is thrown. + * </p> + * + * @param <MODEL> + * The model type. Must be compatible with what + * {@link #getModelType()} returns. + * @param <PRESENTATION> + * The presentation type. Must be compatible with what + * {@link #getPresentationType()} returns. + * @author Vaadin Ltd. + * @version + * @VERSION@ + * @since 7.0 + */ +public interface Converter<PRESENTATION, MODEL> extends Serializable { + + /** + * Converts the given value from target type to source type. + * <p> + * A converter can optionally use locale to do the conversion. + * </p> + * A converter should in most cases be symmetric so chaining + * {@link #convertToPresentation(Object, Locale)} and + * {@link #convertToModel(Object, Locale)} should return the original value. + * + * @param value + * The value to convert, compatible with the target type. Can be + * null + * @param locale + * The locale to use for conversion. Can be null. + * @return The converted value compatible with the source type + * @throws ConversionException + * If the value could not be converted + */ + public MODEL convertToModel(PRESENTATION value, Locale locale) + throws ConversionException; + + /** + * Converts the given value from source type to target type. + * <p> + * A converter can optionally use locale to do the conversion. + * </p> + * A converter should in most cases be symmetric so chaining + * {@link #convertToPresentation(Object, Locale)} and + * {@link #convertToModel(Object, Locale)} should return the original value. + * + * @param value + * The value to convert, compatible with the target type. Can be + * null + * @param locale + * The locale to use for conversion. Can be null. + * @return The converted value compatible with the source type + * @throws ConversionException + * If the value could not be converted + */ + public PRESENTATION convertToPresentation(MODEL value, Locale locale) + throws ConversionException; + + /** + * The source type of the converter. + * + * Values of this type can be passed to + * {@link #convertToPresentation(Object, Locale)}. + * + * @return The source type + */ + public Class<MODEL> getModelType(); + + /** + * The target type of the converter. + * + * Values of this type can be passed to + * {@link #convertToModel(Object, Locale)}. + * + * @return The target type + */ + public Class<PRESENTATION> getPresentationType(); + + /** + * An exception that signals that the value passed to + * {@link Converter#convertToPresentation(Object, Locale)} or + * {@link Converter#convertToModel(Object, Locale)} could not be converted. + * + * @author Vaadin Ltd + * @version + * @VERSION@ + * @since 7.0 + */ + public static class ConversionException extends RuntimeException { + + /** + * Constructs a new <code>ConversionException</code> without a detail + * message. + */ + public ConversionException() { + } + + /** + * Constructs a new <code>ConversionException</code> with the specified + * detail message. + * + * @param msg + * the detail message + */ + public ConversionException(String msg) { + super(msg); + } + + /** + * Constructs a new {@code ConversionException} with the specified + * cause. + * + * @param cause + * The cause of the the exception + */ + public ConversionException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new <code>ConversionException</code> with the specified + * detail message and cause. + * + * @param message + * the detail message + * @param cause + * The cause of the the exception + */ + public ConversionException(String message, Throwable cause) { + super(message, cause); + } + } + +} diff --git a/src/com/vaadin/data/util/converter/ConverterFactory.java b/src/com/vaadin/data/util/converter/ConverterFactory.java index 451f84185d..ed4ab41ac0 100644 --- a/src/com/vaadin/data/util/converter/ConverterFactory.java +++ b/src/com/vaadin/data/util/converter/ConverterFactory.java @@ -1,23 +1,23 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.io.Serializable;
-
-/**
- * Factory interface for providing Converters based on a presentation type and a
- * model type.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- *
- */
-public interface ConverterFactory extends Serializable {
- public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType);
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.io.Serializable; + +/** + * Factory interface for providing Converters based on a presentation type and a + * model type. + * + * @author Vaadin Ltd. + * @version + * @VERSION@ + * @since 7.0 + * + */ +public interface ConverterFactory extends Serializable { + public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter( + Class<PRESENTATION> presentationType, Class<MODEL> modelType); + +} diff --git a/src/com/vaadin/data/util/converter/DateToLongConverter.java b/src/com/vaadin/data/util/converter/DateToLongConverter.java index d66adece06..537800f617 100644 --- a/src/com/vaadin/data/util/converter/DateToLongConverter.java +++ b/src/com/vaadin/data/util/converter/DateToLongConverter.java @@ -1,68 +1,68 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Long} to {@link Date} and back.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DateToLongConverter implements Converter<Date, Long> {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Long convertToModel(Date value, Locale locale) {
- if (value == null) {
- return null;
- }
-
- return value.getTime();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public Date convertToPresentation(Long value, Locale locale) {
- if (value == null) {
- return null;
- }
-
- return new Date(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Long> getModelType() {
- return Long.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<Date> getPresentationType() {
- return Date.class;
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.util.Date; +import java.util.Locale; + +/** + * A converter that converts from {@link Long} to {@link Date} and back. + * + * @author Vaadin Ltd + * @version + * @VERSION@ + * @since 7.0 + */ +public class DateToLongConverter implements Converter<Date, Long> { + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.util.Locale) + */ + public Long convertToModel(Date value, Locale locale) { + if (value == null) { + return null; + } + + return value.getTime(); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.util.Locale) + */ + public Date convertToPresentation(Long value, Locale locale) { + if (value == null) { + return null; + } + + return new Date(value); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + public Class<Long> getModelType() { + return Long.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getPresentationType() + */ + public Class<Date> getPresentationType() { + return Date.class; + } + +} diff --git a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/src/com/vaadin/data/util/converter/DefaultConverterFactory.java index 9233624819..3ad7b6a85b 100644 --- a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java +++ b/src/com/vaadin/data/util/converter/DefaultConverterFactory.java @@ -1,100 +1,100 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Date;
-import java.util.logging.Logger;
-
-import com.vaadin.Application;
-
-/**
- * Default implementation of {@link ConverterFactory}. Provides converters for
- * standard types like {@link String}, {@link Double} and {@link Date}. </p>
- * <p>
- * Custom converters can be provided by extending this class and using
- * {@link Application#setConverterFactory(ConverterFactory)}.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DefaultConverterFactory implements ConverterFactory {
-
- private final static Logger log = Logger
- .getLogger(DefaultConverterFactory.class.getName());
-
- public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
- Converter<PRESENTATION, MODEL> converter = findConverter(
- presentationType, modelType);
- if (converter != null) {
- log.finest(getClass().getName() + " created a "
- + converter.getClass());
- return converter;
- }
-
- // Try to find a reverse converter
- Converter<MODEL, PRESENTATION> reverseConverter = findConverter(
- modelType, presentationType);
- if (reverseConverter != null) {
- log.finest(getClass().getName() + " created a reverse "
- + reverseConverter.getClass());
- return new ReverseConverter<PRESENTATION, MODEL>(reverseConverter);
- }
-
- log.finest(getClass().getName() + " could not find a converter for "
- + presentationType.getName() + " to " + modelType.getName()
- + " conversion");
- return null;
-
- }
-
- protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> findConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
- if (presentationType == String.class) {
- // TextField converters and more
- Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createStringConverter(modelType);
- if (converter != null) {
- return converter;
- }
- } else if (presentationType == Date.class) {
- // DateField converters and more
- Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createDateConverter(modelType);
- if (converter != null) {
- return converter;
- }
- }
-
- return null;
-
- }
-
- protected Converter<Date, ?> createDateConverter(Class<?> sourceType) {
- if (Long.class.isAssignableFrom(sourceType)) {
- return new DateToLongConverter();
- } else {
- return null;
- }
- }
-
- protected Converter<String, ?> createStringConverter(Class<?> sourceType) {
- if (Double.class.isAssignableFrom(sourceType)) {
- return new StringToDoubleConverter();
- } else if (Integer.class.isAssignableFrom(sourceType)) {
- return new StringToIntegerConverter();
- } else if (Boolean.class.isAssignableFrom(sourceType)) {
- return new StringToBooleanConverter();
- } else if (Number.class.isAssignableFrom(sourceType)) {
- return new StringToNumberConverter();
- } else if (Date.class.isAssignableFrom(sourceType)) {
- return new StringToDateConverter();
- } else {
- return null;
- }
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.util.Date; +import java.util.logging.Logger; + +import com.vaadin.Application; + +/** + * Default implementation of {@link ConverterFactory}. Provides converters for + * standard types like {@link String}, {@link Double} and {@link Date}. </p> + * <p> + * Custom converters can be provided by extending this class and using + * {@link Application#setConverterFactory(ConverterFactory)}. + * </p> + * + * @author Vaadin Ltd + * @version + * @VERSION@ + * @since 7.0 + */ +public class DefaultConverterFactory implements ConverterFactory { + + private final static Logger log = Logger + .getLogger(DefaultConverterFactory.class.getName()); + + public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter( + Class<PRESENTATION> presentationType, Class<MODEL> modelType) { + Converter<PRESENTATION, MODEL> converter = findConverter( + presentationType, modelType); + if (converter != null) { + log.finest(getClass().getName() + " created a " + + converter.getClass()); + return converter; + } + + // Try to find a reverse converter + Converter<MODEL, PRESENTATION> reverseConverter = findConverter( + modelType, presentationType); + if (reverseConverter != null) { + log.finest(getClass().getName() + " created a reverse " + + reverseConverter.getClass()); + return new ReverseConverter<PRESENTATION, MODEL>(reverseConverter); + } + + log.finest(getClass().getName() + " could not find a converter for " + + presentationType.getName() + " to " + modelType.getName() + + " conversion"); + return null; + + } + + protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> findConverter( + Class<PRESENTATION> presentationType, Class<MODEL> modelType) { + if (presentationType == String.class) { + // TextField converters and more + Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createStringConverter(modelType); + if (converter != null) { + return converter; + } + } else if (presentationType == Date.class) { + // DateField converters and more + Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createDateConverter(modelType); + if (converter != null) { + return converter; + } + } + + return null; + + } + + protected Converter<Date, ?> createDateConverter(Class<?> sourceType) { + if (Long.class.isAssignableFrom(sourceType)) { + return new DateToLongConverter(); + } else { + return null; + } + } + + protected Converter<String, ?> createStringConverter(Class<?> sourceType) { + if (Double.class.isAssignableFrom(sourceType)) { + return new StringToDoubleConverter(); + } else if (Integer.class.isAssignableFrom(sourceType)) { + return new StringToIntegerConverter(); + } else if (Boolean.class.isAssignableFrom(sourceType)) { + return new StringToBooleanConverter(); + } else if (Number.class.isAssignableFrom(sourceType)) { + return new StringToNumberConverter(); + } else if (Date.class.isAssignableFrom(sourceType)) { + return new StringToDateConverter(); + } else { + return null; + } + } + +} diff --git a/src/com/vaadin/data/util/converter/ReverseConverter.java b/src/com/vaadin/data/util/converter/ReverseConverter.java index b191d1ca0b..1c561f29e8 100644 --- a/src/com/vaadin/data/util/converter/ReverseConverter.java +++ b/src/com/vaadin/data/util/converter/ReverseConverter.java @@ -1,80 +1,80 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Locale;
-
-/**
- * A converter that wraps another {@link Converter} and reverses source and
- * target types.
- *
- * @param <MODEL>
- * The source type
- * @param <PRESENTATION>
- * The target type
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class ReverseConverter<PRESENTATION, MODEL> implements
- Converter<PRESENTATION, MODEL> {
-
- private Converter<MODEL, PRESENTATION> realConverter;
-
- /**
- * Creates a converter from source to target based on a converter that
- * converts from target to source.
- *
- * @param converter
- * The converter to use in a reverse fashion
- */
- public ReverseConverter(Converter<MODEL, PRESENTATION> converter) {
- this.realConverter = converter;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#convertToModel(java
- * .lang.Object, java.util.Locale)
- */
- public MODEL convertToModel(PRESENTATION value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- return realConverter.convertToPresentation(value, locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public PRESENTATION convertToPresentation(MODEL value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- return realConverter.convertToModel(value, locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getSourceType()
- */
- public Class<MODEL> getModelType() {
- return realConverter.getPresentationType();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getTargetType()
- */
- public Class<PRESENTATION> getPresentationType() {
- return realConverter.getModelType();
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.util.Locale; + +/** + * A converter that wraps another {@link Converter} and reverses source and + * target types. + * + * @param <MODEL> + * The source type + * @param <PRESENTATION> + * The target type + * + * @author Vaadin Ltd + * @version + * @VERSION@ + * @since 7.0 + */ +public class ReverseConverter<PRESENTATION, MODEL> implements + Converter<PRESENTATION, MODEL> { + + private Converter<MODEL, PRESENTATION> realConverter; + + /** + * Creates a converter from source to target based on a converter that + * converts from target to source. + * + * @param converter + * The converter to use in a reverse fashion + */ + public ReverseConverter(Converter<MODEL, PRESENTATION> converter) { + this.realConverter = converter; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#convertToModel(java + * .lang.Object, java.util.Locale) + */ + public MODEL convertToModel(PRESENTATION value, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return realConverter.convertToPresentation(value, locale); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.util.Locale) + */ + public PRESENTATION convertToPresentation(MODEL value, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return realConverter.convertToModel(value, locale); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getSourceType() + */ + public Class<MODEL> getModelType() { + return realConverter.getPresentationType(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getTargetType() + */ + public Class<PRESENTATION> getPresentationType() { + return realConverter.getModelType(); + } + +} diff --git a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java b/src/com/vaadin/data/util/converter/StringToBooleanConverter.java index 3b2034a361..96a3a3d071 100644 --- a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java +++ b/src/com/vaadin/data/util/converter/StringToBooleanConverter.java @@ -1,104 +1,104 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Boolean} and back.
- * The String representation is given by Boolean.toString().
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToBooleanConverter implements Converter<String, Boolean> {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Boolean convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- if (getTrueString().equals(value)) {
- return true;
- } else if (getFalseString().equals(value)) {
- return false;
- } else {
- throw new ConversionException("Cannot convert " + value + " to "
- + getModelType().getName());
- }
- }
-
- /**
- * Gets the string representation for true. Default is "true".
- *
- * @return the string representation for true
- */
- protected String getTrueString() {
- return Boolean.TRUE.toString();
- }
-
- /**
- * Gets the string representation for false. Default is "false".
- *
- * @return the string representation for false
- */
- protected String getFalseString() {
- return Boolean.FALSE.toString();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Boolean value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
- if (value) {
- return getTrueString();
- } else {
- return getFalseString();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Boolean> getModelType() {
- return Boolean.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Boolean} and back. + * The String representation is given by Boolean.toString(). + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * + * @author Vaadin Ltd + * @version + * @VERSION@ + * @since 7.0 + */ +public class StringToBooleanConverter implements Converter<String, Boolean> { + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.util.Locale) + */ + public Boolean convertToModel(String value, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + // Remove leading and trailing white space + value = value.trim(); + + if (getTrueString().equals(value)) { + return true; + } else if (getFalseString().equals(value)) { + return false; + } else { + throw new ConversionException("Cannot convert " + value + " to " + + getModelType().getName()); + } + } + + /** + * Gets the string representation for true. Default is "true". + * + * @return the string representation for true + */ + protected String getTrueString() { + return Boolean.TRUE.toString(); + } + + /** + * Gets the string representation for false. Default is "false". + * + * @return the string representation for false + */ + protected String getFalseString() { + return Boolean.FALSE.toString(); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.util.Locale) + */ + public String convertToPresentation(Boolean value, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + if (value) { + return getTrueString(); + } else { + return getFalseString(); + } + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + public Class<Boolean> getModelType() { + return Boolean.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getPresentationType() + */ + public Class<String> getPresentationType() { + return String.class; + } + +} diff --git a/src/com/vaadin/data/util/converter/StringToDateConverter.java b/src/com/vaadin/data/util/converter/StringToDateConverter.java index 2aa9395532..6f3c2e47f6 100644 --- a/src/com/vaadin/data/util/converter/StringToDateConverter.java +++ b/src/com/vaadin/data/util/converter/StringToDateConverter.java @@ -1,108 +1,108 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.DateFormat;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Date} to {@link String} and back. Uses
- * the given locale and {@link DateFormat} for formatting and parsing.
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToDateConverter implements Converter<String, Date> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Date, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A DateFormat instance
- */
- protected DateFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
- DateFormat.MEDIUM, locale);
- f.setLenient(false);
- return f;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Date convertToModel(String value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Date parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- return parsedValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Date value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Date> getModelType() {
- return Date.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.text.DateFormat; +import java.text.ParsePosition; +import java.util.Date; +import java.util.Locale; + +/** + * A converter that converts from {@link Date} to {@link String} and back. Uses + * the given locale and {@link DateFormat} for formatting and parsing. + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @version + * @VERSION@ + * @since 7.0 + */ +public class StringToDateConverter implements Converter<String, Date> { + + /** + * Returns the format used by {@link #convertToPresentation(Date, Locale)} + * and {@link #convertToModel(String, Locale)}. + * + * @param locale + * The locale to use + * @return A DateFormat instance + */ + protected DateFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + + DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, + DateFormat.MEDIUM, locale); + f.setLenient(false); + return f; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.util.Locale) + */ + public Date convertToModel(String value, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + if (value == null) { + return null; + } + + // Remove leading and trailing white space + value = value.trim(); + + ParsePosition parsePosition = new ParsePosition(0); + Date parsedValue = getFormat(locale).parse(value, parsePosition); + if (parsePosition.getIndex() != value.length()) { + throw new ConversionException("Could not convert '" + value + + "' to " + getModelType().getName()); + } + + return parsedValue; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.util.Locale) + */ + public String convertToPresentation(Date value, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + if (value == null) { + return null; + } + + return getFormat(locale).format(value); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + public Class<Date> getModelType() { + return Date.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getPresentationType() + */ + public Class<String> getPresentationType() { + return String.class; + } + +} diff --git a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java b/src/com/vaadin/data/util/converter/StringToDoubleConverter.java index 29c6329451..60a38f4127 100644 --- a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java +++ b/src/com/vaadin/data/util/converter/StringToDoubleConverter.java @@ -1,103 +1,103 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Double} and back.
- * Uses the given locale and a {@link NumberFormat} instance for formatting and
- * parsing.
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToDoubleConverter implements Converter<String, Double> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Double, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Double convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
- return parsedValue.doubleValue();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Double value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Double> getModelType() {
- return Double.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.text.NumberFormat; +import java.text.ParsePosition; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Double} and back. + * Uses the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @version + * @VERSION@ + * @since 7.0 + */ +public class StringToDoubleConverter implements Converter<String, Double> { + + /** + * Returns the format used by {@link #convertToPresentation(Double, Locale)} + * and {@link #convertToModel(String, Locale)}. + * + * @param locale + * The locale to use + * @return A NumberFormat instance + */ + protected NumberFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + + return NumberFormat.getNumberInstance(locale); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.util.Locale) + */ + public Double convertToModel(String value, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + // Remove leading and trailing white space + value = value.trim(); + + ParsePosition parsePosition = new ParsePosition(0); + Number parsedValue = getFormat(locale).parse(value, parsePosition); + if (parsePosition.getIndex() != value.length()) { + throw new ConversionException("Could not convert '" + value + + "' to " + getModelType().getName()); + } + return parsedValue.doubleValue(); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.util.Locale) + */ + public String convertToPresentation(Double value, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + return getFormat(locale).format(value); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + public Class<Double> getModelType() { + return Double.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getPresentationType() + */ + public Class<String> getPresentationType() { + return String.class; + } +} diff --git a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java b/src/com/vaadin/data/util/converter/StringToIntegerConverter.java index 7fa4458c51..e55feec3b6 100644 --- a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java +++ b/src/com/vaadin/data/util/converter/StringToIntegerConverter.java @@ -1,84 +1,84 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Integer} and back.
- * Uses the given locale and a {@link NumberFormat} instance for formatting and
- * parsing.
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToIntegerConverter implements Converter<String, Integer> {
-
- /**
- * Returns the format used by
- * {@link #convertToPresentation(Integer, Locale)} and
- * {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
- return NumberFormat.getIntegerInstance(locale);
- }
-
- public Integer convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue.intValue();
- }
-
- public String convertToPresentation(Integer value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- public Class<Integer> getModelType() {
- return Integer.class;
- }
-
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.text.NumberFormat; +import java.text.ParsePosition; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link Integer} and back. + * Uses the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @version + * @VERSION@ + * @since 7.0 + */ +public class StringToIntegerConverter implements Converter<String, Integer> { + + /** + * Returns the format used by + * {@link #convertToPresentation(Integer, Locale)} and + * {@link #convertToModel(String, Locale)}. + * + * @param locale + * The locale to use + * @return A NumberFormat instance + */ + protected NumberFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + return NumberFormat.getIntegerInstance(locale); + } + + public Integer convertToModel(String value, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + // Remove leading and trailing white space + value = value.trim(); + + // Parse and detect errors. If the full string was not used, it is + // an error. + ParsePosition parsePosition = new ParsePosition(0); + Number parsedValue = getFormat(locale).parse(value, parsePosition); + if (parsePosition.getIndex() != value.length()) { + throw new ConversionException("Could not convert '" + value + + "' to " + getModelType().getName()); + } + + if (parsedValue == null) { + // Convert "" to null + return null; + } + return parsedValue.intValue(); + } + + public String convertToPresentation(Integer value, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + return getFormat(locale).format(value); + } + + public Class<Integer> getModelType() { + return Integer.class; + } + + public Class<String> getPresentationType() { + return String.class; + } + +} diff --git a/src/com/vaadin/data/util/converter/StringToNumberConverter.java b/src/com/vaadin/data/util/converter/StringToNumberConverter.java index 64944a434c..d1816007e7 100644 --- a/src/com/vaadin/data/util/converter/StringToNumberConverter.java +++ b/src/com/vaadin/data/util/converter/StringToNumberConverter.java @@ -1,107 +1,107 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Number} to {@link String} and back.
- * Uses the given locale and {@link NumberFormat} for formatting and parsing.
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToNumberConverter implements Converter<String, Number> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Number, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- public Number convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- public String convertToPresentation(Number value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- public Class<Number> getModelType() {
- return Number.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.util.converter; + +import java.text.NumberFormat; +import java.text.ParsePosition; +import java.util.Locale; + +/** + * A converter that converts from {@link Number} to {@link String} and back. + * Uses the given locale and {@link NumberFormat} for formatting and parsing. + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @version + * @VERSION@ + * @since 7.0 + */ +public class StringToNumberConverter implements Converter<String, Number> { + + /** + * Returns the format used by {@link #convertToPresentation(Number, Locale)} + * and {@link #convertToModel(String, Locale)}. + * + * @param locale + * The locale to use + * @return A NumberFormat instance + */ + protected NumberFormat getFormat(Locale locale) { + if (locale == null) { + locale = Locale.getDefault(); + } + + return NumberFormat.getNumberInstance(locale); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, + * java.util.Locale) + */ + public Number convertToModel(String value, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + // Remove leading and trailing white space + value = value.trim(); + + // Parse and detect errors. If the full string was not used, it is + // an error. + ParsePosition parsePosition = new ParsePosition(0); + Number parsedValue = getFormat(locale).parse(value, parsePosition); + if (parsePosition.getIndex() != value.length()) { + throw new ConversionException("Could not convert '" + value + + "' to " + getModelType().getName()); + } + + if (parsedValue == null) { + // Convert "" to null + return null; + } + return parsedValue; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang + * .Object, java.util.Locale) + */ + public String convertToPresentation(Number value, Locale locale) + throws ConversionException { + if (value == null) { + return null; + } + + return getFormat(locale).format(value); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getModelType() + */ + public Class<Number> getModelType() { + return Number.class; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.util.converter.Converter#getPresentationType() + */ + public Class<String> getPresentationType() { + return String.class; + } + +} diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java b/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java index ac6efaa49b..788966048d 100644 --- a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java +++ b/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java @@ -1,92 +1,92 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
-import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
-import com.vaadin.data.util.sqlcontainer.query.TableQuery;
-
-/**
- * CacheFlushNotifier is a simple static notification mechanism to inform other
- * SQLContainers that the contents of their caches may have become stale.
- */
-class CacheFlushNotifier implements Serializable {
- /*
- * SQLContainer instance reference list and dead reference queue. Used for
- * the cache flush notification feature.
- */
- private static List<WeakReference<SQLContainer>> allInstances = new ArrayList<WeakReference<SQLContainer>>();
- private static ReferenceQueue<SQLContainer> deadInstances = new ReferenceQueue<SQLContainer>();
-
- /**
- * Adds the given SQLContainer to the cache flush notification receiver list
- *
- * @param c
- * Container to add
- */
- public static void addInstance(SQLContainer c) {
- removeDeadReferences();
- if (c != null) {
- allInstances.add(new WeakReference<SQLContainer>(c, deadInstances));
- }
- }
-
- /**
- * Removes dead references from instance list
- */
- private static void removeDeadReferences() {
- java.lang.ref.Reference<? extends SQLContainer> dead = deadInstances
- .poll();
- while (dead != null) {
- allInstances.remove(dead);
- dead = deadInstances.poll();
- }
- }
-
- /**
- * Iterates through the instances and notifies containers which are
- * connected to the same table or are using the same query string.
- *
- * @param c
- * SQLContainer that issued the cache flush notification
- */
- public static void notifyOfCacheFlush(SQLContainer c) {
- removeDeadReferences();
- for (WeakReference<SQLContainer> wr : allInstances) {
- if (wr.get() != null) {
- SQLContainer wrc = wr.get();
- if (wrc == null) {
- continue;
- }
- /*
- * If the reference points to the container sending the
- * notification, do nothing.
- */
- if (wrc.equals(c)) {
- continue;
- }
- /* Compare QueryDelegate types and tableName/queryString */
- QueryDelegate wrQd = wrc.getQueryDelegate();
- QueryDelegate qd = c.getQueryDelegate();
- if (wrQd instanceof TableQuery
- && qd instanceof TableQuery
- && ((TableQuery) wrQd).getTableName().equals(
- ((TableQuery) qd).getTableName())) {
- wrc.refresh();
- } else if (wrQd instanceof FreeformQuery
- && qd instanceof FreeformQuery
- && ((FreeformQuery) wrQd).getQueryString().equals(
- ((FreeformQuery) qd).getQueryString())) {
- wrc.refresh();
- }
- }
- }
- }
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.util.sqlcontainer; + +import java.io.Serializable; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.data.util.sqlcontainer.query.FreeformQuery; +import com.vaadin.data.util.sqlcontainer.query.QueryDelegate; +import com.vaadin.data.util.sqlcontainer.query.TableQuery; + +/** + * CacheFlushNotifier is a simple static notification mechanism to inform other + * SQLContainers that the contents of their caches may have become stale. + */ +class CacheFlushNotifier implements Serializable { + /* + * SQLContainer instance reference list and dead reference queue. Used for + * the cache flush notification feature. + */ + private static List<WeakReference<SQLContainer>> allInstances = new ArrayList<WeakReference<SQLContainer>>(); + private static ReferenceQueue<SQLContainer> deadInstances = new ReferenceQueue<SQLContainer>(); + + /** + * Adds the given SQLContainer to the cache flush notification receiver list + * + * @param c + * Container to add + */ + public static void addInstance(SQLContainer c) { + removeDeadReferences(); + if (c != null) { + allInstances.add(new WeakReference<SQLContainer>(c, deadInstances)); + } + } + + /** + * Removes dead references from instance list + */ + private static void removeDeadReferences() { + java.lang.ref.Reference<? extends SQLContainer> dead = deadInstances + .poll(); + while (dead != null) { + allInstances.remove(dead); + dead = deadInstances.poll(); + } + } + + /** + * Iterates through the instances and notifies containers which are + * connected to the same table or are using the same query string. + * + * @param c + * SQLContainer that issued the cache flush notification + */ + public static void notifyOfCacheFlush(SQLContainer c) { + removeDeadReferences(); + for (WeakReference<SQLContainer> wr : allInstances) { + if (wr.get() != null) { + SQLContainer wrc = wr.get(); + if (wrc == null) { + continue; + } + /* + * If the reference points to the container sending the + * notification, do nothing. + */ + if (wrc.equals(c)) { + continue; + } + /* Compare QueryDelegate types and tableName/queryString */ + QueryDelegate wrQd = wrc.getQueryDelegate(); + QueryDelegate qd = c.getQueryDelegate(); + if (wrQd instanceof TableQuery + && qd instanceof TableQuery + && ((TableQuery) wrQd).getTableName().equals( + ((TableQuery) qd).getTableName())) { + wrc.refresh(); + } else if (wrQd instanceof FreeformQuery + && qd instanceof FreeformQuery + && ((FreeformQuery) wrQd).getQueryString().equals( + ((FreeformQuery) qd).getQueryString())) { + wrc.refresh(); + } + } + } + } +} diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java b/src/com/vaadin/data/util/sqlcontainer/CacheMap.java index 44921dd12d..839fceb3c2 100644 --- a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java +++ b/src/com/vaadin/data/util/sqlcontainer/CacheMap.java @@ -1,31 +1,31 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * CacheMap extends LinkedHashMap, adding the possibility to adjust maximum
- * number of items. In SQLContainer this is used for RowItem -cache. Cache size
- * will be two times the page length parameter of the container.
- */
-class CacheMap<K, V> extends LinkedHashMap<K, V> {
- private static final long serialVersionUID = 679999766473555231L;
- private int cacheLimit = SQLContainer.CACHE_RATIO
- * SQLContainer.DEFAULT_PAGE_LENGTH;
-
- @Override
- protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
- return size() > cacheLimit;
- }
-
- void setCacheLimit(int limit) {
- cacheLimit = limit > 0 ? limit : SQLContainer.DEFAULT_PAGE_LENGTH;
- }
-
- int getCacheLimit() {
- return cacheLimit;
- }
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.util.sqlcontainer; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * CacheMap extends LinkedHashMap, adding the possibility to adjust maximum + * number of items. In SQLContainer this is used for RowItem -cache. Cache size + * will be two times the page length parameter of the container. + */ +class CacheMap<K, V> extends LinkedHashMap<K, V> { + private static final long serialVersionUID = 679999766473555231L; + private int cacheLimit = SQLContainer.CACHE_RATIO + * SQLContainer.DEFAULT_PAGE_LENGTH; + + @Override + protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { + return size() > cacheLimit; + } + + void setCacheLimit(int limit) { + cacheLimit = limit > 0 ? limit : SQLContainer.DEFAULT_PAGE_LENGTH; + } + + int getCacheLimit() { + return cacheLimit; + } }
\ No newline at end of file diff --git a/src/com/vaadin/data/util/sqlcontainer/Reference.java b/src/com/vaadin/data/util/sqlcontainer/Reference.java index 6e863fa040..dea1aa87c0 100644 --- a/src/com/vaadin/data/util/sqlcontainer/Reference.java +++ b/src/com/vaadin/data/util/sqlcontainer/Reference.java @@ -1,56 +1,56 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-
-/**
- * The reference class represents a simple [usually foreign key] reference to
- * another SQLContainer. Actual foreign key reference in the database is not
- * required, but it is recommended to make sure that certain constraints are
- * followed.
- */
-@SuppressWarnings("serial")
-class Reference implements Serializable {
-
- /**
- * The SQLContainer that this reference points to.
- */
- private SQLContainer referencedContainer;
-
- /**
- * The column ID/name in the referencing SQLContainer that contains the key
- * used for the reference.
- */
- private String referencingColumn;
-
- /**
- * The column ID/name in the referenced SQLContainer that contains the key
- * used for the reference.
- */
- private String referencedColumn;
-
- /**
- * Constructs a new reference to be used within the SQLContainer to
- * reference another SQLContainer.
- */
- Reference(SQLContainer referencedContainer, String referencingColumn,
- String referencedColumn) {
- this.referencedContainer = referencedContainer;
- this.referencingColumn = referencingColumn;
- this.referencedColumn = referencedColumn;
- }
-
- SQLContainer getReferencedContainer() {
- return referencedContainer;
- }
-
- String getReferencingColumn() {
- return referencingColumn;
- }
-
- String getReferencedColumn() {
- return referencedColumn;
- }
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.util.sqlcontainer; + +import java.io.Serializable; + +/** + * The reference class represents a simple [usually foreign key] reference to + * another SQLContainer. Actual foreign key reference in the database is not + * required, but it is recommended to make sure that certain constraints are + * followed. + */ +@SuppressWarnings("serial") +class Reference implements Serializable { + + /** + * The SQLContainer that this reference points to. + */ + private SQLContainer referencedContainer; + + /** + * The column ID/name in the referencing SQLContainer that contains the key + * used for the reference. + */ + private String referencingColumn; + + /** + * The column ID/name in the referenced SQLContainer that contains the key + * used for the reference. + */ + private String referencedColumn; + + /** + * Constructs a new reference to be used within the SQLContainer to + * reference another SQLContainer. + */ + Reference(SQLContainer referencedContainer, String referencingColumn, + String referencedColumn) { + this.referencedContainer = referencedContainer; + this.referencingColumn = referencingColumn; + this.referencedColumn = referencedColumn; + } + + SQLContainer getReferencedContainer() { + return referencedContainer; + } + + String getReferencingColumn() { + return referencingColumn; + } + + String getReferencedColumn() { + return referencedColumn; + } +} diff --git a/src/com/vaadin/data/util/sqlcontainer/RowId.java b/src/com/vaadin/data/util/sqlcontainer/RowId.java index ed01b72e06..925325134a 100644 --- a/src/com/vaadin/data/util/sqlcontainer/RowId.java +++ b/src/com/vaadin/data/util/sqlcontainer/RowId.java @@ -1,81 +1,81 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-
-/**
- * RowId represents identifiers of a single database result set row.
- *
- * The data structure of a RowId is an Object array which contains the values of
- * the primary key columns of the identified row. This allows easy equals()
- * -comparison of RowItems.
- */
-public class RowId implements Serializable {
- private static final long serialVersionUID = -3161778404698901258L;
- protected Object[] id;
-
- /**
- * Prevent instantiation without required parameters.
- */
- protected RowId() {
- }
-
- public RowId(Object[] id) {
- if (id == null) {
- throw new IllegalArgumentException("id parameter must not be null!");
- }
- this.id = id;
- }
-
- public Object[] getId() {
- return id;
- }
-
- @Override
- public int hashCode() {
- int result = 31;
- if (id != null) {
- for (Object o : id) {
- if (o != null) {
- result += o.hashCode();
- }
- }
- }
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof RowId)) {
- return false;
- }
- Object[] compId = ((RowId) obj).getId();
- if (id == null && compId == null) {
- return true;
- }
- if (id.length != compId.length) {
- return false;
- }
- for (int i = 0; i < id.length; i++) {
- if ((id[i] == null && compId[i] != null)
- || (id[i] != null && !id[i].equals(compId[i]))) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String toString() {
- StringBuffer s = new StringBuffer();
- for (int i = 0; i < id.length; i++) {
- s.append(id[i]);
- if (i < id.length - 1) {
- s.append("/");
- }
- }
- return s.toString();
- }
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.util.sqlcontainer; + +import java.io.Serializable; + +/** + * RowId represents identifiers of a single database result set row. + * + * The data structure of a RowId is an Object array which contains the values of + * the primary key columns of the identified row. This allows easy equals() + * -comparison of RowItems. + */ +public class RowId implements Serializable { + private static final long serialVersionUID = -3161778404698901258L; + protected Object[] id; + + /** + * Prevent instantiation without required parameters. + */ + protected RowId() { + } + + public RowId(Object[] id) { + if (id == null) { + throw new IllegalArgumentException("id parameter must not be null!"); + } + this.id = id; + } + + public Object[] getId() { + return id; + } + + @Override + public int hashCode() { + int result = 31; + if (id != null) { + for (Object o : id) { + if (o != null) { + result += o.hashCode(); + } + } + } + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof RowId)) { + return false; + } + Object[] compId = ((RowId) obj).getId(); + if (id == null && compId == null) { + return true; + } + if (id.length != compId.length) { + return false; + } + for (int i = 0; i < id.length; i++) { + if ((id[i] == null && compId[i] != null) + || (id[i] != null && !id[i].equals(compId[i]))) { + return false; + } + } + return true; + } + + @Override + public String toString() { + StringBuffer s = new StringBuffer(); + for (int i = 0; i < id.length; i++) { + s.append(id[i]); + if (i < id.length - 1) { + s.append("/"); + } + } + return s.toString(); + } +} diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java index c1a7c61eab..2a1068e786 100644 --- a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java +++ b/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java @@ -1,165 +1,165 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.connection;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Simple implementation of the JDBCConnectionPool interface. Handles loading
- * the JDBC driver, setting up the connections and ensuring they are still
- * usable upon release.
- */
-@SuppressWarnings("serial")
-public class SimpleJDBCConnectionPool implements JDBCConnectionPool {
-
- private int initialConnections = 5;
- private int maxConnections = 20;
-
- private String driverName;
- private String connectionUri;
- private String userName;
- private String password;
-
- private transient Set<Connection> availableConnections;
- private transient Set<Connection> reservedConnections;
-
- private boolean initialized;
-
- public SimpleJDBCConnectionPool(String driverName, String connectionUri,
- String userName, String password) throws SQLException {
- if (driverName == null) {
- throw new IllegalArgumentException(
- "JDBC driver class name must be given.");
- }
- if (connectionUri == null) {
- throw new IllegalArgumentException(
- "Database connection URI must be given.");
- }
- if (userName == null) {
- throw new IllegalArgumentException(
- "Database username must be given.");
- }
- if (password == null) {
- throw new IllegalArgumentException(
- "Database password must be given.");
- }
- this.driverName = driverName;
- this.connectionUri = connectionUri;
- this.userName = userName;
- this.password = password;
-
- /* Initialize JDBC driver */
- try {
- Class.forName(driverName).newInstance();
- } catch (Exception ex) {
- throw new RuntimeException("Specified JDBC Driver: " + driverName
- + " - initialization failed.", ex);
- }
- }
-
- public SimpleJDBCConnectionPool(String driverName, String connectionUri,
- String userName, String password, int initialConnections,
- int maxConnections) throws SQLException {
- this(driverName, connectionUri, userName, password);
- this.initialConnections = initialConnections;
- this.maxConnections = maxConnections;
- }
-
- private void initializeConnections() throws SQLException {
- availableConnections = new HashSet<Connection>(initialConnections);
- reservedConnections = new HashSet<Connection>(initialConnections);
- for (int i = 0; i < initialConnections; i++) {
- availableConnections.add(createConnection());
- }
- initialized = true;
- }
-
- public synchronized Connection reserveConnection() throws SQLException {
- if (!initialized) {
- initializeConnections();
- }
- if (availableConnections.isEmpty()) {
- if (reservedConnections.size() < maxConnections) {
- availableConnections.add(createConnection());
- } else {
- throw new SQLException("Connection limit has been reached.");
- }
- }
-
- Connection c = availableConnections.iterator().next();
- availableConnections.remove(c);
- reservedConnections.add(c);
-
- return c;
- }
-
- public synchronized void releaseConnection(Connection conn) {
- if (conn == null || !initialized) {
- return;
- }
- /* Try to roll back if necessary */
- try {
- if (!conn.getAutoCommit()) {
- conn.rollback();
- }
- } catch (SQLException e) {
- /* Roll back failed, close and discard connection */
- try {
- conn.close();
- } catch (SQLException e1) {
- /* Nothing needs to be done */
- }
- reservedConnections.remove(conn);
- return;
- }
- reservedConnections.remove(conn);
- availableConnections.add(conn);
- }
-
- private Connection createConnection() throws SQLException {
- Connection c = DriverManager.getConnection(connectionUri, userName,
- password);
- c.setAutoCommit(false);
- if (driverName.toLowerCase().contains("mysql")) {
- try {
- Statement s = c.createStatement();
- s.execute("SET SESSION sql_mode = 'ANSI'");
- s.close();
- } catch (Exception e) {
- // Failed to set ansi mode; continue
- }
- }
- return c;
- }
-
- public void destroy() {
- for (Connection c : availableConnections) {
- try {
- c.close();
- } catch (SQLException e) {
- // No need to do anything
- }
- }
- for (Connection c : reservedConnections) {
- try {
- c.close();
- } catch (SQLException e) {
- // No need to do anything
- }
- }
-
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- initialized = false;
- out.defaultWriteObject();
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.util.sqlcontainer.connection; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashSet; +import java.util.Set; + +/** + * Simple implementation of the JDBCConnectionPool interface. Handles loading + * the JDBC driver, setting up the connections and ensuring they are still + * usable upon release. + */ +@SuppressWarnings("serial") +public class SimpleJDBCConnectionPool implements JDBCConnectionPool { + + private int initialConnections = 5; + private int maxConnections = 20; + + private String driverName; + private String connectionUri; + private String userName; + private String password; + + private transient Set<Connection> availableConnections; + private transient Set<Connection> reservedConnections; + + private boolean initialized; + + public SimpleJDBCConnectionPool(String driverName, String connectionUri, + String userName, String password) throws SQLException { + if (driverName == null) { + throw new IllegalArgumentException( + "JDBC driver class name must be given."); + } + if (connectionUri == null) { + throw new IllegalArgumentException( + "Database connection URI must be given."); + } + if (userName == null) { + throw new IllegalArgumentException( + "Database username must be given."); + } + if (password == null) { + throw new IllegalArgumentException( + "Database password must be given."); + } + this.driverName = driverName; + this.connectionUri = connectionUri; + this.userName = userName; + this.password = password; + + /* Initialize JDBC driver */ + try { + Class.forName(driverName).newInstance(); + } catch (Exception ex) { + throw new RuntimeException("Specified JDBC Driver: " + driverName + + " - initialization failed.", ex); + } + } + + public SimpleJDBCConnectionPool(String driverName, String connectionUri, + String userName, String password, int initialConnections, + int maxConnections) throws SQLException { + this(driverName, connectionUri, userName, password); + this.initialConnections = initialConnections; + this.maxConnections = maxConnections; + } + + private void initializeConnections() throws SQLException { + availableConnections = new HashSet<Connection>(initialConnections); + reservedConnections = new HashSet<Connection>(initialConnections); + for (int i = 0; i < initialConnections; i++) { + availableConnections.add(createConnection()); + } + initialized = true; + } + + public synchronized Connection reserveConnection() throws SQLException { + if (!initialized) { + initializeConnections(); + } + if (availableConnections.isEmpty()) { + if (reservedConnections.size() < maxConnections) { + availableConnections.add(createConnection()); + } else { + throw new SQLException("Connection limit has been reached."); + } + } + + Connection c = availableConnections.iterator().next(); + availableConnections.remove(c); + reservedConnections.add(c); + + return c; + } + + public synchronized void releaseConnection(Connection conn) { + if (conn == null || !initialized) { + return; + } + /* Try to roll back if necessary */ + try { + if (!conn.getAutoCommit()) { + conn.rollback(); + } + } catch (SQLException e) { + /* Roll back failed, close and discard connection */ + try { + conn.close(); + } catch (SQLException e1) { + /* Nothing needs to be done */ + } + reservedConnections.remove(conn); + return; + } + reservedConnections.remove(conn); + availableConnections.add(conn); + } + + private Connection createConnection() throws SQLException { + Connection c = DriverManager.getConnection(connectionUri, userName, + password); + c.setAutoCommit(false); + if (driverName.toLowerCase().contains("mysql")) { + try { + Statement s = c.createStatement(); + s.execute("SET SESSION sql_mode = 'ANSI'"); + s.close(); + } catch (Exception e) { + // Failed to set ansi mode; continue + } + } + return c; + } + + public void destroy() { + for (Connection c : availableConnections) { + try { + c.close(); + } catch (SQLException e) { + // No need to do anything + } + } + for (Connection c : reservedConnections) { + try { + c.close(); + } catch (SQLException e) { + // No need to do anything + } + } + + } + + private void writeObject(java.io.ObjectOutputStream out) throws IOException { + initialized = false; + out.defaultWriteObject(); + } + +} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java b/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java index 2ea151c578..95521c5019 100644 --- a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java +++ b/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java @@ -1,57 +1,57 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query;
-
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-/**
- * FreeformStatementDelegate is an extension to FreeformQueryDelegate that
- * provides definitions for methods that produce StatementHelper objects instead
- * of basic query strings. This allows the FreeformQuery query delegate to use
- * PreparedStatements instead of regular Statement when accessing the database.
- *
- * Due to the injection protection and other benefits of prepared statements, it
- * is advisable to implement this interface instead of the FreeformQueryDelegate
- * whenever possible.
- */
-public interface FreeformStatementDelegate extends FreeformQueryDelegate {
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement. This
- * method is responsible for gluing together the select query from the
- * filters and the order by conditions if these are supported.
- *
- * @param offset
- * the first record (row) to fetch.
- * @param pagelength
- * the number of records (rows) to fetch. 0 means all records
- * starting from offset.
- */
- public StatementHelper getQueryStatement(int offset, int limit)
- throws UnsupportedOperationException;
-
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement that
- * will fetch the row count from the DB. Row count should be fetched using
- * filters that are currently set to the QueryDelegate.
- */
- public StatementHelper getCountStatement()
- throws UnsupportedOperationException;
-
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement used
- * by the FreeformQuery.containsRowWithKeys() method. This is useful for
- * cases when the default logic in said method is not enough to support more
- * complex free form queries.
- *
- * @param keys
- * the values of the primary keys
- * @throws UnsupportedOperationException
- * to use the default logic in FreeformQuery
- */
- public StatementHelper getContainsRowQueryStatement(Object... keys)
- throws UnsupportedOperationException;
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.util.sqlcontainer.query; + +import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; + +/** + * FreeformStatementDelegate is an extension to FreeformQueryDelegate that + * provides definitions for methods that produce StatementHelper objects instead + * of basic query strings. This allows the FreeformQuery query delegate to use + * PreparedStatements instead of regular Statement when accessing the database. + * + * Due to the injection protection and other benefits of prepared statements, it + * is advisable to implement this interface instead of the FreeformQueryDelegate + * whenever possible. + */ +public interface FreeformStatementDelegate extends FreeformQueryDelegate { + /** + * Should return a new instance of StatementHelper that contains the query + * string and parameter values required to create a PreparedStatement. This + * method is responsible for gluing together the select query from the + * filters and the order by conditions if these are supported. + * + * @param offset + * the first record (row) to fetch. + * @param pagelength + * the number of records (rows) to fetch. 0 means all records + * starting from offset. + */ + public StatementHelper getQueryStatement(int offset, int limit) + throws UnsupportedOperationException; + + /** + * Should return a new instance of StatementHelper that contains the query + * string and parameter values required to create a PreparedStatement that + * will fetch the row count from the DB. Row count should be fetched using + * filters that are currently set to the QueryDelegate. + */ + public StatementHelper getCountStatement() + throws UnsupportedOperationException; + + /** + * Should return a new instance of StatementHelper that contains the query + * string and parameter values required to create a PreparedStatement used + * by the FreeformQuery.containsRowWithKeys() method. This is useful for + * cases when the default logic in said method is not enough to support more + * complex free form queries. + * + * @param keys + * the values of the primary keys + * @throws UnsupportedOperationException + * to use the default logic in FreeformQuery + */ + public StatementHelper getContainsRowQueryStatement(Object... keys) + throws UnsupportedOperationException; +} diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java index 888f1ec501..3fd92e920d 100644 --- a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java +++ b/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java @@ -1,135 +1,135 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * StatementHelper is a simple helper class that assists TableQuery and the
- * query generators in filling a PreparedStatement. The actual statement is
- * generated by the query generator methods, but the resulting statement and all
- * the parameter values are stored in an instance of StatementHelper.
- *
- * This class will also fill the values with correct setters into the
- * PreparedStatement on request.
- */
-public class StatementHelper implements Serializable {
-
- private String queryString;
-
- private List<Object> parameters = new ArrayList<Object>();
- private Map<Integer, Class<?>> dataTypes = new HashMap<Integer, Class<?>>();
-
- public StatementHelper() {
- }
-
- public void setQueryString(String queryString) {
- this.queryString = queryString;
- }
-
- public String getQueryString() {
- return queryString;
- }
-
- public void addParameterValue(Object parameter) {
- if (parameter != null) {
- parameters.add(parameter);
- dataTypes.put(parameters.size() - 1, parameter.getClass());
- }
- }
-
- public void addParameterValue(Object parameter, Class<?> type) {
- parameters.add(parameter);
- dataTypes.put(parameters.size() - 1, type);
- }
-
- public void setParameterValuesToStatement(PreparedStatement pstmt)
- throws SQLException {
- for (int i = 0; i < parameters.size(); i++) {
- if (parameters.get(i) == null) {
- handleNullValue(i, pstmt);
- } else {
- pstmt.setObject(i + 1, parameters.get(i));
- }
- }
-
- /*
- * The following list contains the data types supported by
- * PreparedStatement but not supported by SQLContainer:
- *
- * [The list is provided as PreparedStatement method signatures]
- *
- * setNCharacterStream(int parameterIndex, Reader value)
- *
- * setNClob(int parameterIndex, NClob value)
- *
- * setNString(int parameterIndex, String value)
- *
- * setRef(int parameterIndex, Ref x)
- *
- * setRowId(int parameterIndex, RowId x)
- *
- * setSQLXML(int parameterIndex, SQLXML xmlObject)
- *
- * setBytes(int parameterIndex, byte[] x)
- *
- * setCharacterStream(int parameterIndex, Reader reader)
- *
- * setClob(int parameterIndex, Clob x)
- *
- * setURL(int parameterIndex, URL x)
- *
- * setArray(int parameterIndex, Array x)
- *
- * setAsciiStream(int parameterIndex, InputStream x)
- *
- * setBinaryStream(int parameterIndex, InputStream x)
- *
- * setBlob(int parameterIndex, Blob x)
- */
- }
-
- private void handleNullValue(int i, PreparedStatement pstmt)
- throws SQLException {
- if (BigDecimal.class.equals(dataTypes.get(i))) {
- pstmt.setBigDecimal(i + 1, null);
- } else if (Boolean.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.BOOLEAN);
- } else if (Byte.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.SMALLINT);
- } else if (Date.class.equals(dataTypes.get(i))) {
- pstmt.setDate(i + 1, null);
- } else if (Double.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.DOUBLE);
- } else if (Float.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.FLOAT);
- } else if (Integer.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.INTEGER);
- } else if (Long.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.BIGINT);
- } else if (Short.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.SMALLINT);
- } else if (String.class.equals(dataTypes.get(i))) {
- pstmt.setString(i + 1, null);
- } else if (Time.class.equals(dataTypes.get(i))) {
- pstmt.setTime(i + 1, null);
- } else if (Timestamp.class.equals(dataTypes.get(i))) {
- pstmt.setTimestamp(i + 1, null);
- } else {
- throw new SQLException("Data type not supported by SQLContainer: "
- + parameters.get(i).getClass().toString());
- }
- }
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.util.sqlcontainer.query.generator; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Time; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * StatementHelper is a simple helper class that assists TableQuery and the + * query generators in filling a PreparedStatement. The actual statement is + * generated by the query generator methods, but the resulting statement and all + * the parameter values are stored in an instance of StatementHelper. + * + * This class will also fill the values with correct setters into the + * PreparedStatement on request. + */ +public class StatementHelper implements Serializable { + + private String queryString; + + private List<Object> parameters = new ArrayList<Object>(); + private Map<Integer, Class<?>> dataTypes = new HashMap<Integer, Class<?>>(); + + public StatementHelper() { + } + + public void setQueryString(String queryString) { + this.queryString = queryString; + } + + public String getQueryString() { + return queryString; + } + + public void addParameterValue(Object parameter) { + if (parameter != null) { + parameters.add(parameter); + dataTypes.put(parameters.size() - 1, parameter.getClass()); + } + } + + public void addParameterValue(Object parameter, Class<?> type) { + parameters.add(parameter); + dataTypes.put(parameters.size() - 1, type); + } + + public void setParameterValuesToStatement(PreparedStatement pstmt) + throws SQLException { + for (int i = 0; i < parameters.size(); i++) { + if (parameters.get(i) == null) { + handleNullValue(i, pstmt); + } else { + pstmt.setObject(i + 1, parameters.get(i)); + } + } + + /* + * The following list contains the data types supported by + * PreparedStatement but not supported by SQLContainer: + * + * [The list is provided as PreparedStatement method signatures] + * + * setNCharacterStream(int parameterIndex, Reader value) + * + * setNClob(int parameterIndex, NClob value) + * + * setNString(int parameterIndex, String value) + * + * setRef(int parameterIndex, Ref x) + * + * setRowId(int parameterIndex, RowId x) + * + * setSQLXML(int parameterIndex, SQLXML xmlObject) + * + * setBytes(int parameterIndex, byte[] x) + * + * setCharacterStream(int parameterIndex, Reader reader) + * + * setClob(int parameterIndex, Clob x) + * + * setURL(int parameterIndex, URL x) + * + * setArray(int parameterIndex, Array x) + * + * setAsciiStream(int parameterIndex, InputStream x) + * + * setBinaryStream(int parameterIndex, InputStream x) + * + * setBlob(int parameterIndex, Blob x) + */ + } + + private void handleNullValue(int i, PreparedStatement pstmt) + throws SQLException { + if (BigDecimal.class.equals(dataTypes.get(i))) { + pstmt.setBigDecimal(i + 1, null); + } else if (Boolean.class.equals(dataTypes.get(i))) { + pstmt.setNull(i + 1, Types.BOOLEAN); + } else if (Byte.class.equals(dataTypes.get(i))) { + pstmt.setNull(i + 1, Types.SMALLINT); + } else if (Date.class.equals(dataTypes.get(i))) { + pstmt.setDate(i + 1, null); + } else if (Double.class.equals(dataTypes.get(i))) { + pstmt.setNull(i + 1, Types.DOUBLE); + } else if (Float.class.equals(dataTypes.get(i))) { + pstmt.setNull(i + 1, Types.FLOAT); + } else if (Integer.class.equals(dataTypes.get(i))) { + pstmt.setNull(i + 1, Types.INTEGER); + } else if (Long.class.equals(dataTypes.get(i))) { + pstmt.setNull(i + 1, Types.BIGINT); + } else if (Short.class.equals(dataTypes.get(i))) { + pstmt.setNull(i + 1, Types.SMALLINT); + } else if (String.class.equals(dataTypes.get(i))) { + pstmt.setString(i + 1, null); + } else if (Time.class.equals(dataTypes.get(i))) { + pstmt.setTime(i + 1, null); + } else if (Timestamp.class.equals(dataTypes.get(i))) { + pstmt.setTimestamp(i + 1, null); + } else { + throw new SQLException("Data type not supported by SQLContainer: " + + parameters.get(i).getClass().toString()); + } + } +} diff --git a/src/com/vaadin/data/validator/BeanValidator.java b/src/com/vaadin/data/validator/BeanValidator.java index 939fd2e9c4..817df85248 100644 --- a/src/com/vaadin/data/validator/BeanValidator.java +++ b/src/com/vaadin/data/validator/BeanValidator.java @@ -1,173 +1,173 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.validator;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-
-import javax.validation.ConstraintViolation;
-import javax.validation.MessageInterpolator.Context;
-import javax.validation.Validation;
-import javax.validation.ValidatorFactory;
-import javax.validation.metadata.ConstraintDescriptor;
-
-import com.vaadin.data.Validator;
-
-/**
- * Vaadin {@link Validator} using the JSR-303 (javax.validation)
- * annotation-based bean validation.
- *
- * The annotations of the fields of the beans are used to determine the
- * validation to perform.
- *
- * Note that a JSR-303 implementation (e.g. Hibernate Validator or Apache Bean
- * Validation - formerly agimatec validation) must be present on the project
- * classpath when using bean validation.
- *
- * @since 7.0
- *
- * @author Petri Hakala
- * @author Henri Sara
- */
-public class BeanValidator implements Validator {
-
- private static final long serialVersionUID = 1L;
- private static ValidatorFactory factory;
-
- private transient javax.validation.Validator javaxBeanValidator;
- private String propertyName;
- private Class<?> beanClass;
- private Locale locale;
-
- /**
- * Simple implementation of a message interpolator context that returns
- * fixed values.
- */
- protected static class SimpleContext implements Context, Serializable {
-
- private final Object value;
- private final ConstraintDescriptor<?> descriptor;
-
- /**
- * Create a simple immutable message interpolator context.
- *
- * @param value
- * value being validated
- * @param descriptor
- * ConstraintDescriptor corresponding to the constraint being
- * validated
- */
- public SimpleContext(Object value, ConstraintDescriptor<?> descriptor) {
- this.value = value;
- this.descriptor = descriptor;
- }
-
- public ConstraintDescriptor<?> getConstraintDescriptor() {
- return descriptor;
- }
-
- public Object getValidatedValue() {
- return value;
- }
-
- }
-
- /**
- * Creates a Vaadin {@link Validator} utilizing JSR-303 bean validation.
- *
- * @param beanClass
- * bean class based on which the validation should be performed
- * @param propertyName
- * property to validate
- */
- public BeanValidator(Class<?> beanClass, String propertyName) {
- this.beanClass = beanClass;
- this.propertyName = propertyName;
- locale = Locale.getDefault();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Validator#validate(java.lang.Object)
- */
- public void validate(final Object value) throws InvalidValueException {
- Set<?> violations = getJavaxBeanValidator().validateValue(beanClass,
- propertyName, value);
- if (violations.size() > 0) {
- List<String> exceptions = new ArrayList<String>();
- for (Object v : violations) {
- final ConstraintViolation<?> violation = (ConstraintViolation<?>) v;
- String msg = getJavaxBeanValidatorFactory()
- .getMessageInterpolator().interpolate(
- violation.getMessageTemplate(),
- new SimpleContext(value, violation
- .getConstraintDescriptor()), locale);
- exceptions.add(msg);
- }
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < exceptions.size(); i++) {
- if (i != 0) {
- b.append("<br/>");
- }
- b.append(exceptions.get(i));
- }
- throw new InvalidValueException(b.toString());
- }
- }
-
- /**
- * Sets the locale used for validation error messages.
- *
- * Revalidation is not automatically triggered by setting the locale.
- *
- * @param locale
- */
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
-
- /**
- * Gets the locale used for validation error messages.
- *
- * @return locale used for validation
- */
- public Locale getLocale() {
- return locale;
- }
-
- /**
- * Returns the underlying JSR-303 bean validator factory used. A factory is
- * created using {@link Validation} if necessary.
- *
- * @return {@link ValidatorFactory} to use
- */
- protected static ValidatorFactory getJavaxBeanValidatorFactory() {
- if (factory == null) {
- factory = Validation.buildDefaultValidatorFactory();
- }
-
- return factory;
- }
-
- /**
- * Returns a shared Validator instance to use. An instance is created using
- * the validator factory if necessary and thereafter reused by the
- * {@link BeanValidator} instance.
- *
- * @return the JSR-303 {@link javax.validation.Validator} to use
- */
- protected javax.validation.Validator getJavaxBeanValidator() {
- if (javaxBeanValidator == null) {
- javaxBeanValidator = getJavaxBeanValidatorFactory().getValidator();
- }
-
- return javaxBeanValidator;
- }
-
+/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.data.validator; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.MessageInterpolator.Context; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import javax.validation.metadata.ConstraintDescriptor; + +import com.vaadin.data.Validator; + +/** + * Vaadin {@link Validator} using the JSR-303 (javax.validation) + * annotation-based bean validation. + * + * The annotations of the fields of the beans are used to determine the + * validation to perform. + * + * Note that a JSR-303 implementation (e.g. Hibernate Validator or Apache Bean + * Validation - formerly agimatec validation) must be present on the project + * classpath when using bean validation. + * + * @since 7.0 + * + * @author Petri Hakala + * @author Henri Sara + */ +public class BeanValidator implements Validator { + + private static final long serialVersionUID = 1L; + private static ValidatorFactory factory; + + private transient javax.validation.Validator javaxBeanValidator; + private String propertyName; + private Class<?> beanClass; + private Locale locale; + + /** + * Simple implementation of a message interpolator context that returns + * fixed values. + */ + protected static class SimpleContext implements Context, Serializable { + + private final Object value; + private final ConstraintDescriptor<?> descriptor; + + /** + * Create a simple immutable message interpolator context. + * + * @param value + * value being validated + * @param descriptor + * ConstraintDescriptor corresponding to the constraint being + * validated + */ + public SimpleContext(Object value, ConstraintDescriptor<?> descriptor) { + this.value = value; + this.descriptor = descriptor; + } + + public ConstraintDescriptor<?> getConstraintDescriptor() { + return descriptor; + } + + public Object getValidatedValue() { + return value; + } + + } + + /** + * Creates a Vaadin {@link Validator} utilizing JSR-303 bean validation. + * + * @param beanClass + * bean class based on which the validation should be performed + * @param propertyName + * property to validate + */ + public BeanValidator(Class<?> beanClass, String propertyName) { + this.beanClass = beanClass; + this.propertyName = propertyName; + locale = Locale.getDefault(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.Validator#validate(java.lang.Object) + */ + public void validate(final Object value) throws InvalidValueException { + Set<?> violations = getJavaxBeanValidator().validateValue(beanClass, + propertyName, value); + if (violations.size() > 0) { + List<String> exceptions = new ArrayList<String>(); + for (Object v : violations) { + final ConstraintViolation<?> violation = (ConstraintViolation<?>) v; + String msg = getJavaxBeanValidatorFactory() + .getMessageInterpolator().interpolate( + violation.getMessageTemplate(), + new SimpleContext(value, violation + .getConstraintDescriptor()), locale); + exceptions.add(msg); + } + StringBuilder b = new StringBuilder(); + for (int i = 0; i < exceptions.size(); i++) { + if (i != 0) { + b.append("<br/>"); + } + b.append(exceptions.get(i)); + } + throw new InvalidValueException(b.toString()); + } + } + + /** + * Sets the locale used for validation error messages. + * + * Revalidation is not automatically triggered by setting the locale. + * + * @param locale + */ + public void setLocale(Locale locale) { + this.locale = locale; + } + + /** + * Gets the locale used for validation error messages. + * + * @return locale used for validation + */ + public Locale getLocale() { + return locale; + } + + /** + * Returns the underlying JSR-303 bean validator factory used. A factory is + * created using {@link Validation} if necessary. + * + * @return {@link ValidatorFactory} to use + */ + protected static ValidatorFactory getJavaxBeanValidatorFactory() { + if (factory == null) { + factory = Validation.buildDefaultValidatorFactory(); + } + + return factory; + } + + /** + * Returns a shared Validator instance to use. An instance is created using + * the validator factory if necessary and thereafter reused by the + * {@link BeanValidator} instance. + * + * @return the JSR-303 {@link javax.validation.Validator} to use + */ + protected javax.validation.Validator getJavaxBeanValidator() { + if (javaxBeanValidator == null) { + javaxBeanValidator = getJavaxBeanValidatorFactory().getValidator(); + } + + return javaxBeanValidator; + } + }
\ No newline at end of file diff --git a/src/com/vaadin/data/validator/DateRangeValidator.java b/src/com/vaadin/data/validator/DateRangeValidator.java index 42f5a224ed..24f3d3ce10 100644 --- a/src/com/vaadin/data/validator/DateRangeValidator.java +++ b/src/com/vaadin/data/validator/DateRangeValidator.java @@ -1,51 +1,51 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-import java.util.Date;
-
-import com.vaadin.ui.DateField.Resolution;
-
-/**
- * Validator for validating that a Date is inside a given range.
- *
- * <p>
- * Note that the comparison is done directly on the Date object so take care
- * that the hours/minutes/seconds/milliseconds of the min/max values are
- * properly set.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DateRangeValidator extends RangeValidator<Date> {
-
- /**
- * Creates a validator for checking that an Date is within a given range.
- * <p>
- * By default the range is inclusive i.e. both minValue and maxValue are
- * valid values. Use {@link #setMinValueIncluded(boolean)} or
- * {@link #setMaxValueIncluded(boolean)} to change it.
- * </p>
- * <p>
- * Note that the comparison is done directly on the Date object so take care
- * that the hours/minutes/seconds/milliseconds of the min/max values are
- * properly set.
- * </p>
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- * @param minValue
- * The minimum value to accept or null for no limit
- * @param maxValue
- * The maximum value to accept or null for no limit
- */
- public DateRangeValidator(String errorMessage, Date minValue,
- Date maxValue, Resolution resolution) {
- super(errorMessage, Date.class, minValue, maxValue);
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.validator; + +import java.util.Date; + +import com.vaadin.ui.DateField.Resolution; + +/** + * Validator for validating that a Date is inside a given range. + * + * <p> + * Note that the comparison is done directly on the Date object so take care + * that the hours/minutes/seconds/milliseconds of the min/max values are + * properly set. + * </p> + * + * @author Vaadin Ltd. + * @version + * @VERSION@ + * @since 7.0 + */ +public class DateRangeValidator extends RangeValidator<Date> { + + /** + * Creates a validator for checking that an Date is within a given range. + * <p> + * By default the range is inclusive i.e. both minValue and maxValue are + * valid values. Use {@link #setMinValueIncluded(boolean)} or + * {@link #setMaxValueIncluded(boolean)} to change it. + * </p> + * <p> + * Note that the comparison is done directly on the Date object so take care + * that the hours/minutes/seconds/milliseconds of the min/max values are + * properly set. + * </p> + * + * @param errorMessage + * the message to display in case the value does not validate. + * @param minValue + * The minimum value to accept or null for no limit + * @param maxValue + * The maximum value to accept or null for no limit + */ + public DateRangeValidator(String errorMessage, Date minValue, + Date maxValue, Resolution resolution) { + super(errorMessage, Date.class, minValue, maxValue); + } + +} diff --git a/src/com/vaadin/data/validator/RangeValidator.java b/src/com/vaadin/data/validator/RangeValidator.java index 457f046360..433271274f 100644 --- a/src/com/vaadin/data/validator/RangeValidator.java +++ b/src/com/vaadin/data/validator/RangeValidator.java @@ -1,186 +1,186 @@ -/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * An base implementation for validating any objects that implement
- * {@link Comparable}.
- *
- * Verifies that the value is of the given type and within the (optionally)
- * given limits. Typically you want to use a sub class of this like
- * {@link IntegerRangeValidator}, {@link DoubleRangeValidator} or
- * {@link DateRangeValidator} in applications.
- * <p>
- * Note that {@link RangeValidator} always accept null values. Make a field
- * required to ensure that no empty values are accepted or override
- * {@link #isValidValue(Comparable)}.
- * </p>
- *
- * @param <T>
- * The type of Number to validate. Must implement Comparable so that
- * minimum and maximum checks work.
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class RangeValidator<T extends Comparable> extends AbstractValidator<T> {
-
- private T minValue = null;
- private boolean minValueIncluded = true;
- private T maxValue = null;
- private boolean maxValueIncluded = true;
- private Class<T> type;
-
- /**
- * Creates a new range validator of the given type.
- *
- * @param errorMessage
- * The error message to use if validation fails
- * @param type
- * The type of object the validator can validate.
- * @param minValue
- * The minimum value that should be accepted or null for no limit
- * @param maxValue
- * The maximum value that should be accepted or null for no limit
- */
- public RangeValidator(String errorMessage, Class<T> type, T minValue,
- T maxValue) {
- super(errorMessage);
- this.type = type;
- this.minValue = minValue;
- this.maxValue = maxValue;
- }
-
- /**
- * Checks if the minimum value is part of the accepted range
- *
- * @return true if the minimum value is part of the range, false otherwise
- */
- public boolean isMinValueIncluded() {
- return minValueIncluded;
- }
-
- /**
- * Sets if the minimum value is part of the accepted range
- *
- * @param minValueIncluded
- * true if the minimum value should be part of the range, false
- * otherwise
- */
- public void setMinValueIncluded(boolean minValueIncluded) {
- this.minValueIncluded = minValueIncluded;
- }
-
- /**
- * Checks if the maximum value is part of the accepted range
- *
- * @return true if the maximum value is part of the range, false otherwise
- */
- public boolean isMaxValueIncluded() {
- return maxValueIncluded;
- }
-
- /**
- * Sets if the maximum value is part of the accepted range
- *
- * @param maxValueIncluded
- * true if the maximum value should be part of the range, false
- * otherwise
- */
- public void setMaxValueIncluded(boolean maxValueIncluded) {
- this.maxValueIncluded = maxValueIncluded;
- }
-
- /**
- * Gets the minimum value of the range
- *
- * @return the minimum value
- */
- public T getMinValue() {
- return minValue;
- }
-
- /**
- * Sets the minimum value of the range. Use
- * {@link #setMinValueIncluded(boolean)} to control whether this value is
- * part of the range or not.
- *
- * @param minValue
- * the minimum value
- */
- public void setMinValue(T minValue) {
- this.minValue = minValue;
- }
-
- /**
- * Gets the maximum value of the range
- *
- * @return the maximum value
- */
- public T getMaxValue() {
- return maxValue;
- }
-
- /**
- * Sets the maximum value of the range. Use
- * {@link #setMaxValueIncluded(boolean)} to control whether this value is
- * part of the range or not.
- *
- * @param maxValue
- * the maximum value
- */
- public void setMaxValue(T maxValue) {
- this.maxValue = maxValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object
- * )
- */
- @Override
- protected boolean isValidValue(T value) {
- if (value == null) {
- return true;
- }
-
- if (getMinValue() != null) {
- // Ensure that the min limit is ok
- int result = value.compareTo(getMinValue());
- if (result < 0) {
- // value less than min value
- return false;
- } else if (result == 0 && !isMinValueIncluded()) {
- // values equal and min value not included
- return false;
- }
- }
- if (getMaxValue() != null) {
- // Ensure that the Max limit is ok
- int result = value.compareTo(getMaxValue());
- if (result > 0) {
- // value greater than max value
- return false;
- } else if (result == 0 && !isMaxValueIncluded()) {
- // values equal and max value not included
- return false;
- }
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.validator.AbstractValidator#getType()
- */
- @Override
- public Class<T> getType() {
- return type;
- }
-
-}
+/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.data.validator; + +/** + * An base implementation for validating any objects that implement + * {@link Comparable}. + * + * Verifies that the value is of the given type and within the (optionally) + * given limits. Typically you want to use a sub class of this like + * {@link IntegerRangeValidator}, {@link DoubleRangeValidator} or + * {@link DateRangeValidator} in applications. + * <p> + * Note that {@link RangeValidator} always accept null values. Make a field + * required to ensure that no empty values are accepted or override + * {@link #isValidValue(Comparable)}. + * </p> + * + * @param <T> + * The type of Number to validate. Must implement Comparable so that + * minimum and maximum checks work. + * @author Vaadin Ltd. + * @version + * @VERSION@ + * @since 7.0 + */ +public class RangeValidator<T extends Comparable> extends AbstractValidator<T> { + + private T minValue = null; + private boolean minValueIncluded = true; + private T maxValue = null; + private boolean maxValueIncluded = true; + private Class<T> type; + + /** + * Creates a new range validator of the given type. + * + * @param errorMessage + * The error message to use if validation fails + * @param type + * The type of object the validator can validate. + * @param minValue + * The minimum value that should be accepted or null for no limit + * @param maxValue + * The maximum value that should be accepted or null for no limit + */ + public RangeValidator(String errorMessage, Class<T> type, T minValue, + T maxValue) { + super(errorMessage); + this.type = type; + this.minValue = minValue; + this.maxValue = maxValue; + } + + /** + * Checks if the minimum value is part of the accepted range + * + * @return true if the minimum value is part of the range, false otherwise + */ + public boolean isMinValueIncluded() { + return minValueIncluded; + } + + /** + * Sets if the minimum value is part of the accepted range + * + * @param minValueIncluded + * true if the minimum value should be part of the range, false + * otherwise + */ + public void setMinValueIncluded(boolean minValueIncluded) { + this.minValueIncluded = minValueIncluded; + } + + /** + * Checks if the maximum value is part of the accepted range + * + * @return true if the maximum value is part of the range, false otherwise + */ + public boolean isMaxValueIncluded() { + return maxValueIncluded; + } + + /** + * Sets if the maximum value is part of the accepted range + * + * @param maxValueIncluded + * true if the maximum value should be part of the range, false + * otherwise + */ + public void setMaxValueIncluded(boolean maxValueIncluded) { + this.maxValueIncluded = maxValueIncluded; + } + + /** + * Gets the minimum value of the range + * + * @return the minimum value + */ + public T getMinValue() { + return minValue; + } + + /** + * Sets the minimum value of the range. Use + * {@link #setMinValueIncluded(boolean)} to control whether this value is + * part of the range or not. + * + * @param minValue + * the minimum value + */ + public void setMinValue(T minValue) { + this.minValue = minValue; + } + + /** + * Gets the maximum value of the range + * + * @return the maximum value + */ + public T getMaxValue() { + return maxValue; + } + + /** + * Sets the maximum value of the range. Use + * {@link #setMaxValueIncluded(boolean)} to control whether this value is + * part of the range or not. + * + * @param maxValue + * the maximum value + */ + public void setMaxValue(T maxValue) { + this.maxValue = maxValue; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object + * ) + */ + @Override + protected boolean isValidValue(T value) { + if (value == null) { + return true; + } + + if (getMinValue() != null) { + // Ensure that the min limit is ok + int result = value.compareTo(getMinValue()); + if (result < 0) { + // value less than min value + return false; + } else if (result == 0 && !isMinValueIncluded()) { + // values equal and min value not included + return false; + } + } + if (getMaxValue() != null) { + // Ensure that the Max limit is ok + int result = value.compareTo(getMaxValue()); + if (result > 0) { + // value greater than max value + return false; + } else if (result == 0 && !isMaxValueIncluded()) { + // values equal and max value not included + return false; + } + } + return true; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.data.validator.AbstractValidator#getType() + */ + @Override + public Class<T> getType() { + return type; + } + +} |