From f6f111b88fcf65c9d75f36daaa046dd26efc68e5 Mon Sep 17 00:00:00 2001
From: Johannes Dahlström
Date: Thu, 4 Aug 2016 20:58:28 +0300
Subject: Rename Field, AbstractField to legacy names
Change-Id: I46ce708e0f10e4c9fa3d11a2aef5be0248c2999f
---
.../com/vaadin/data/fieldgroup/BeanFieldGroup.java | 18 +-
.../fieldgroup/DefaultFieldGroupFieldFactory.java | 22 +-
.../com/vaadin/data/fieldgroup/FieldGroup.java | 114 +-
.../data/fieldgroup/FieldGroupFieldFactory.java | 8 +-
.../com/vaadin/data/fieldgroup/PropertyId.java | 4 +-
.../main/java/com/vaadin/event/FieldEvents.java | 20 +-
.../com/vaadin/legacy/ui/LegacyAbstractField.java | 1863 ++++++++++++++++++++
.../java/com/vaadin/legacy/ui/LegacyField.java | 140 ++
.../main/java/com/vaadin/server/VaadinSession.java | 4 +-
.../main/java/com/vaadin/ui/AbstractComponent.java | 5 +-
.../src/main/java/com/vaadin/ui/AbstractField.java | 1852 -------------------
.../main/java/com/vaadin/ui/AbstractSelect.java | 13 +-
.../main/java/com/vaadin/ui/AbstractTextField.java | 5 +-
server/src/main/java/com/vaadin/ui/CheckBox.java | 7 +-
server/src/main/java/com/vaadin/ui/Component.java | 11 +-
.../src/main/java/com/vaadin/ui/CustomField.java | 6 +-
server/src/main/java/com/vaadin/ui/DateField.java | 28 +-
.../java/com/vaadin/ui/DefaultFieldFactory.java | 13 +-
server/src/main/java/com/vaadin/ui/Field.java | 138 --
server/src/main/java/com/vaadin/ui/Form.java | 141 +-
.../main/java/com/vaadin/ui/FormFieldFactory.java | 6 +-
server/src/main/java/com/vaadin/ui/Grid.java | 192 +-
.../src/main/java/com/vaadin/ui/ProgressBar.java | 7 +-
.../src/main/java/com/vaadin/ui/RichTextArea.java | 3 +-
server/src/main/java/com/vaadin/ui/Slider.java | 7 +-
server/src/main/java/com/vaadin/ui/Table.java | 23 +-
.../main/java/com/vaadin/ui/TableFieldFactory.java | 7 +-
server/src/main/java/com/vaadin/ui/TextField.java | 4 +-
28 files changed, 2366 insertions(+), 2295 deletions(-)
create mode 100644 server/src/main/java/com/vaadin/legacy/ui/LegacyAbstractField.java
create mode 100644 server/src/main/java/com/vaadin/legacy/ui/LegacyField.java
delete mode 100644 server/src/main/java/com/vaadin/ui/AbstractField.java
delete mode 100644 server/src/main/java/com/vaadin/ui/Field.java
(limited to 'server/src/main/java/com/vaadin')
diff --git a/server/src/main/java/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/server/src/main/java/com/vaadin/data/fieldgroup/BeanFieldGroup.java
index 0a92c00cad..62eb51b811 100644
--- a/server/src/main/java/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/BeanFieldGroup.java
@@ -24,18 +24,18 @@ import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanUtil;
import com.vaadin.data.validator.BeanValidator;
-import com.vaadin.ui.Field;
+import com.vaadin.legacy.ui.LegacyField;
public class BeanFieldGroup extends FieldGroup {
private final Class beanType;
private static Boolean beanValidationImplementationAvailable = null;
- private final Map, BeanValidator> defaultValidators;
+ private final Map, BeanValidator> defaultValidators;
public BeanFieldGroup(Class beanType) {
this.beanType = beanType;
- this.defaultValidators = new HashMap, BeanValidator>();
+ this.defaultValidators = new HashMap, BeanValidator>();
}
@Override
@@ -149,20 +149,20 @@ public class BeanFieldGroup extends FieldGroup {
}
@Override
- public void bind(Field field, Object propertyId) {
+ public void bind(LegacyField field, Object propertyId) {
ensureNestedPropertyAdded(propertyId);
super.bind(field, propertyId);
}
@Override
- public T buildAndBind(String caption, Object propertyId,
+ public T buildAndBind(String caption, Object propertyId,
Class fieldType) throws BindException {
ensureNestedPropertyAdded(propertyId);
return super.buildAndBind(caption, propertyId, fieldType);
}
@Override
- public void unbind(Field> field) throws BindException {
+ public void unbind(LegacyField> field) throws BindException {
super.unbind(field);
BeanValidator removed = defaultValidators.remove(field);
@@ -172,7 +172,7 @@ public class BeanFieldGroup extends FieldGroup {
}
@Override
- protected void configureField(Field> field) {
+ protected void configureField(LegacyField> field) {
super.configureField(field);
// Add Bean validators if there are annotations
if (isBeanValidationImplementationAvailable()
@@ -226,7 +226,7 @@ public class BeanFieldGroup extends FieldGroup {
* @param bean
* the bean to be bound
* @param objectWithMemberFields
- * the class that contains {@link Field}s for bean properties
+ * the class that contains {@link LegacyField}s for bean properties
* @return the bean field group used to make binding
*/
public static BeanFieldGroup bindFieldsUnbuffered(T bean,
@@ -247,7 +247,7 @@ public class BeanFieldGroup extends FieldGroup {
* @param bean
* the bean to be bound
* @param objectWithMemberFields
- * the class that contains {@link Field}s for bean properties
+ * the class that contains {@link LegacyField}s for bean properties
* @return the bean field group used to make binding
*/
public static BeanFieldGroup bindFieldsBuffered(T bean,
diff --git a/server/src/main/java/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java b/server/src/main/java/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
index b6bf97e68e..27f4628bae 100644
--- a/server/src/main/java/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
@@ -20,13 +20,13 @@ import java.util.EnumSet;
import com.vaadin.data.Item;
import com.vaadin.data.fieldgroup.FieldGroup.BindException;
-import com.vaadin.ui.AbstractField;
+import com.vaadin.legacy.ui.LegacyField;
+import com.vaadin.legacy.ui.LegacyAbstractField;
import com.vaadin.ui.AbstractSelect;
import com.vaadin.ui.AbstractTextField;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.DateField;
-import com.vaadin.ui.Field;
import com.vaadin.ui.InlineDateField;
import com.vaadin.ui.ListSelect;
import com.vaadin.ui.NativeSelect;
@@ -64,7 +64,7 @@ public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
}
@Override
- public T createField(Class> type, Class fieldType) {
+ public T createField(Class> type, Class fieldType) {
if (Enum.class.isAssignableFrom(type)) {
return createEnumField(type, fieldType);
} else if (Date.class.isAssignableFrom(type)) {
@@ -89,7 +89,7 @@ public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
return rta;
}
- private T createEnumField(Class> type,
+ private T createEnumField(Class> type,
Class fieldType) {
// Determine first if we should (or can) create a select for the enum
Class selectClass = null;
@@ -110,9 +110,9 @@ public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
return null;
}
- private T createDateField(Class> type,
+ private T createDateField(Class> type,
Class fieldType) {
- AbstractField field;
+ LegacyAbstractField field;
if (InlineDateField.class.isAssignableFrom(fieldType)) {
field = new InlineDateField();
@@ -157,10 +157,10 @@ public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
* @since 7.4
* @param fieldType
* the type of the field
- * @return true if any AbstractField can be assigned to the field
+ * @return true if any LegacyAbstractField can be assigned to the field
*/
protected boolean anyField(Class> fieldType) {
- return fieldType == Field.class || fieldType == AbstractField.class;
+ return fieldType == LegacyField.class || fieldType == LegacyAbstractField.class;
}
/**
@@ -169,11 +169,11 @@ public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
* the type of the field
* @return true if any AbstractSelect can be assigned to the field
*/
- protected boolean anySelect(Class extends Field> fieldType) {
+ protected boolean anySelect(Class extends LegacyField> fieldType) {
return anyField(fieldType) || fieldType == AbstractSelect.class;
}
- protected T createBooleanField(Class fieldType) {
+ protected T createBooleanField(Class fieldType) {
if (fieldType.isAssignableFrom(CheckBox.class)) {
CheckBox cb = new CheckBox(null);
cb.setImmediate(true);
@@ -213,7 +213,7 @@ public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
* @return A field capable of editing the data or null if no field could be
* created
*/
- protected T createDefaultField(Class> type,
+ protected T createDefaultField(Class> type,
Class fieldType) {
if (fieldType.isAssignableFrom(TextField.class)) {
return fieldType.cast(createAbstractTextField(TextField.class));
diff --git a/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java
index aaaae9e4f7..9c926637ef 100644
--- a/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroup.java
@@ -29,9 +29,9 @@ 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.ui.AbstractField;
+import com.vaadin.legacy.ui.LegacyField;
+import com.vaadin.legacy.ui.LegacyAbstractField;
import com.vaadin.ui.DefaultFieldFactory;
-import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.util.ReflectTools;
@@ -62,8 +62,8 @@ public class FieldGroup implements Serializable {
private boolean enabled = true;
private boolean readOnly = false;
- private HashMap
*
- * @see Field#setBuffered(boolean)
+ * @see LegacyField#setBuffered(boolean)
* @param buffered
* true to turn on buffered mode, false otherwise
*/
@@ -155,7 +155,7 @@ public class FieldGroup implements Serializable {
}
this.buffered = buffered;
- for (Field> field : getFields()) {
+ for (LegacyField> field : getFields()) {
field.setBuffered(buffered);
}
}
@@ -181,7 +181,7 @@ public class FieldGroup implements Serializable {
*/
public void setEnabled(boolean fieldsEnabled) {
enabled = fieldsEnabled;
- for (Field> field : getFields()) {
+ for (LegacyField> field : getFields()) {
field.setEnabled(fieldsEnabled);
}
}
@@ -211,7 +211,7 @@ public class FieldGroup implements Serializable {
*/
public void setReadOnly(boolean fieldsReadOnly) {
readOnly = fieldsReadOnly;
- for (Field> field : getFields()) {
+ for (LegacyField> field : getFields()) {
if (field.getPropertyDataSource() == null
|| !field.getPropertyDataSource().isReadOnly()) {
field.setReadOnly(fieldsReadOnly);
@@ -229,7 +229,7 @@ public class FieldGroup implements Serializable {
*
* @return A collection with all bound Fields
*/
- public Collection> getFields() {
+ public Collection> getFields() {
return fieldToPropertyId.keySet();
}
@@ -249,7 +249,7 @@ public class FieldGroup implements Serializable {
* If the field is null or the property id is already bound to
* another field by this field binder
*/
- public void bind(Field> field, Object propertyId) throws BindException {
+ public void bind(LegacyField> field, Object propertyId) throws BindException {
throwIfFieldIsNull(field, propertyId);
throwIfPropertyIdAlreadyBound(field, propertyId);
@@ -287,7 +287,7 @@ public class FieldGroup implements Serializable {
return new TransactionalPropertyWrapper(itemProperty);
}
- private void throwIfFieldIsNull(Field> field, Object propertyId) {
+ private void throwIfFieldIsNull(LegacyField> field, Object propertyId) {
if (field == null) {
throw new BindException(
String.format(
@@ -296,7 +296,7 @@ public class FieldGroup implements Serializable {
}
}
- private void throwIfPropertyIdAlreadyBound(Field> field, Object propertyId) {
+ private void throwIfPropertyIdAlreadyBound(LegacyField> field, Object propertyId) {
if (propertyIdToField.containsKey(propertyId)
&& propertyIdToField.get(propertyId) != field) {
throw new BindException("Property id " + propertyId
@@ -342,7 +342,7 @@ public class FieldGroup implements Serializable {
* 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 {
+ public void unbind(LegacyField> field) throws BindException {
Object propertyId = fieldToPropertyId.get(field);
if (propertyId == null) {
throw new BindException(
@@ -378,7 +378,7 @@ public class FieldGroup implements Serializable {
* @param field
* The field to update
*/
- protected void configureField(Field> field) {
+ protected void configureField(LegacyField> field) {
field.setBuffered(isBuffered());
field.setEnabled(isEnabled());
@@ -478,7 +478,7 @@ public class FieldGroup implements Serializable {
try {
firePreCommitEvent();
- Map, InvalidValueException> invalidValueExceptions = commitFields();
+ Map, InvalidValueException> invalidValueExceptions = commitFields();
if (invalidValueExceptions.isEmpty()) {
firePostCommitEvent();
@@ -501,10 +501,10 @@ public class FieldGroup implements Serializable {
* @return a propertyId to validation exception map which is empty if all
* commits succeeded
*/
- private Map, InvalidValueException> commitFields() {
- Map, InvalidValueException> invalidValueExceptions = new HashMap, InvalidValueException>();
+ private Map, InvalidValueException> commitFields() {
+ Map, InvalidValueException> invalidValueExceptions = new HashMap, InvalidValueException>();
- for (Field> f : fieldToPropertyId.keySet()) {
+ for (LegacyField> f : fieldToPropertyId.keySet()) {
try {
f.commit();
} catch (InvalidValueException e) {
@@ -523,7 +523,7 @@ public class FieldGroup implements Serializable {
*/
public static class FieldGroupInvalidValueException extends
InvalidValueException {
- private Map, InvalidValueException> invalidValueExceptions;
+ private Map, InvalidValueException> invalidValueExceptions;
/**
* Constructs a new exception with the specified validation exceptions.
@@ -532,7 +532,7 @@ public class FieldGroup implements Serializable {
* a property id to exception map
*/
public FieldGroupInvalidValueException(
- Map, InvalidValueException> invalidValueExceptions) {
+ Map, InvalidValueException> invalidValueExceptions) {
super(null, invalidValueExceptions.values().toArray(
new InvalidValueException[invalidValueExceptions.size()]));
this.invalidValueExceptions = invalidValueExceptions;
@@ -544,13 +544,13 @@ public class FieldGroup implements Serializable {
*
* @return a map with all the invalid value exceptions
*/
- public Map, InvalidValueException> getInvalidFields() {
+ public Map, InvalidValueException> getInvalidFields() {
return invalidValueExceptions;
}
}
private void startTransactions() throws CommitException {
- for (Field> f : fieldToPropertyId.keySet()) {
+ for (LegacyField> f : fieldToPropertyId.keySet()) {
Property.Transactional> property = (Property.Transactional>) f
.getPropertyDataSource();
if (property == null) {
@@ -563,13 +563,13 @@ public class FieldGroup implements Serializable {
}
private void commitTransactions() {
- for (Field> f : fieldToPropertyId.keySet()) {
+ for (LegacyField> f : fieldToPropertyId.keySet()) {
((Property.Transactional>) f.getPropertyDataSource()).commit();
}
}
private void rollbackTransactions() {
- for (Field> f : fieldToPropertyId.keySet()) {
+ for (LegacyField> f : fieldToPropertyId.keySet()) {
try {
((Property.Transactional>) f.getPropertyDataSource())
.rollback();
@@ -616,7 +616,7 @@ public class FieldGroup implements Serializable {
*
*/
public void discard() {
- for (Field> f : fieldToPropertyId.keySet()) {
+ for (LegacyField> f : fieldToPropertyId.keySet()) {
try {
f.discard();
} catch (Exception e) {
@@ -635,7 +635,7 @@ public class FieldGroup implements Serializable {
* @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) {
+ public LegacyField> getField(Object propertyId) {
return propertyIdToField.get(propertyId);
}
@@ -647,7 +647,7 @@ public class FieldGroup implements Serializable {
* @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) {
+ public Object getPropertyId(LegacyField> field) {
return fieldToPropertyId.get(field);
}
@@ -751,14 +751,14 @@ public class FieldGroup implements Serializable {
/**
* Checks the validity of the bound fields.
*
- * Call the {@link Field#validate()} for the fields to get the individual
+ * Call the {@link LegacyField#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()) {
+ for (LegacyField> field : getFields()) {
field.validate();
}
return true;
@@ -773,7 +773,7 @@ public class FieldGroup implements Serializable {
* @return true if at least one field has been modified, false otherwise
*/
public boolean isModified() {
- for (Field> field : getFields()) {
+ for (LegacyField> field : getFields()) {
if (field.isModified()) {
return true;
}
@@ -807,7 +807,7 @@ public class FieldGroup implements Serializable {
* Binds member fields found in the given object.
*
* This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
+ * {@link LegacyField} 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.
@@ -847,7 +847,7 @@ public class FieldGroup implements Serializable {
* that have not been initialized.
*
* This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property ids are
+ * {@link LegacyField} and that can be mapped to a property id. Property ids are
* searched in the following order: @{@link PropertyId} annotations, exact
* field name matches and the case-insensitive matching that ignores
* underscores. Fields that are not initialized (null) are built using the
@@ -892,7 +892,7 @@ public class FieldGroup implements Serializable {
* member fields that have not been initialized.
*
* This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property ids are
+ * {@link LegacyField} and that can be mapped to a property id. Property ids are
* searched in the following order: @{@link PropertyId} annotations, exact
* field name matches and the case-insensitive matching that ignores
* underscores. Fields that are not initialized (null) are built using the
@@ -912,7 +912,7 @@ public class FieldGroup implements Serializable {
for (java.lang.reflect.Field memberField : getFieldsInDeclareOrder(objectClass)) {
- if (!Field.class.isAssignableFrom(memberField.getType())) {
+ if (!LegacyField.class.isAssignableFrom(memberField.getType())) {
// Process next field
continue;
}
@@ -920,7 +920,7 @@ public class FieldGroup implements Serializable {
PropertyId propertyIdAnnotation = memberField
.getAnnotation(PropertyId.class);
- Class extends Field> fieldType = (Class extends Field>) memberField
+ Class extends LegacyField> fieldType = (Class extends LegacyField>) memberField
.getType();
Object propertyId = null;
@@ -950,11 +950,11 @@ public class FieldGroup implements Serializable {
continue;
}
- Field> field;
+ LegacyField> field;
try {
// Get the field from the object
- field = (Field>) ReflectTools.getJavaFieldValue(
- objectWithMemberFields, memberField, Field.class);
+ field = (LegacyField>) ReflectTools.getJavaFieldValue(
+ objectWithMemberFields, memberField, LegacyField.class);
} catch (Exception e) {
// If we cannot determine the value, just skip the field and try
// the next one
@@ -972,7 +972,7 @@ public class FieldGroup implements Serializable {
.createCaptionByPropertyId(propertyId);
}
- // Create the component (Field)
+ // Create the component (LegacyField)
field = build(caption, propertyType, fieldType);
// Store it in the field
@@ -1089,12 +1089,12 @@ public class FieldGroup implements Serializable {
* @return a map with all the invalid value exceptions. Can be empty but
* not null
*/
- public Map, InvalidValueException> getInvalidFields() {
+ public Map, InvalidValueException> getInvalidFields() {
if (getCause() instanceof FieldGroupInvalidValueException) {
return ((FieldGroupInvalidValueException) getCause())
.getInvalidFields();
}
- return new HashMap, InvalidValueException>();
+ return new HashMap, InvalidValueException>();
}
/**
@@ -1144,7 +1144,7 @@ public class FieldGroup implements Serializable {
* If there is a problem while building or binding
* @return The created and bound field
*/
- public Field> buildAndBind(Object propertyId) throws BindException {
+ public LegacyField> buildAndBind(Object propertyId) throws BindException {
String caption = DefaultFieldFactory
.createCaptionByPropertyId(propertyId);
return buildAndBind(caption, propertyId);
@@ -1161,11 +1161,11 @@ public class FieldGroup implements Serializable {
* 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}.
+ * @return The created and bound field. Can be any type of {@link LegacyField}.
*/
- public Field> buildAndBind(String caption, Object propertyId)
+ public LegacyField> buildAndBind(String caption, Object propertyId)
throws BindException {
- return buildAndBind(caption, propertyId, Field.class);
+ return buildAndBind(caption, propertyId, LegacyField.class);
}
/**
@@ -1179,10 +1179,10 @@ public class FieldGroup implements Serializable {
* finder.
* @throws BindException
* If the field could not be created
- * @return The created and bound field. Can be any type of {@link Field}.
+ * @return The created and bound field. Can be any type of {@link LegacyField}.
*/
- public T buildAndBind(String caption, Object propertyId,
+ public T buildAndBind(String caption, Object propertyId,
Class fieldType) throws BindException {
Class> type = getPropertyType(propertyId);
@@ -1196,8 +1196,8 @@ public class FieldGroup implements Serializable {
* Creates a field based on the given data type.
*
* 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.
+ * type is the type of field we want to create, can be {@link LegacyField} if any
+ * LegacyField is good.
*
*
* @param caption
@@ -1206,11 +1206,11 @@ public class FieldGroup implements Serializable {
* 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
+ * @return A LegacyField capable of editing the given type
* @throws BindException
* If the field could not be created
*/
- protected T build(String caption, Class> dataType,
+ protected T build(String caption, Class> dataType,
Class fieldType) throws BindException {
T field = getFieldFactory().createField(dataType, fieldType);
if (field == null) {
@@ -1224,7 +1224,7 @@ public class FieldGroup implements Serializable {
}
/**
- * Returns an array containing Field objects reflecting all the fields of
+ * Returns an array containing LegacyField objects reflecting all the fields of
* the class or interface represented by this Class object. The elements in
* the array returned are sorted in declare order from sub class to super
* class.
@@ -1252,9 +1252,9 @@ public class FieldGroup implements Serializable {
* @since 7.4
*/
public void clear() {
- for (Field> f : getFields()) {
- if (f instanceof AbstractField) {
- ((AbstractField) f).clear();
+ for (LegacyField> f : getFields()) {
+ if (f instanceof LegacyAbstractField) {
+ ((LegacyAbstractField) f).clear();
}
}
diff --git a/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java b/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
index 4aad08ba8d..fb2a579093 100644
--- a/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
@@ -17,10 +17,10 @@ package com.vaadin.data.fieldgroup;
import java.io.Serializable;
-import com.vaadin.ui.Field;
+import com.vaadin.legacy.ui.LegacyField;
/**
- * Factory interface for creating new Field-instances based on the data type
+ * Factory interface for creating new LegacyField-instances based on the data type
* that should be edited.
*
* @author Vaadin Ltd.
@@ -33,10 +33,10 @@ public interface FieldGroupFieldFactory extends Serializable {
* @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}
+ * The type of field we want to create. If set to {@link LegacyField}
* 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 createField(Class> dataType, Class fieldType);
+ T createField(Class> dataType, Class fieldType);
}
diff --git a/server/src/main/java/com/vaadin/data/fieldgroup/PropertyId.java b/server/src/main/java/com/vaadin/data/fieldgroup/PropertyId.java
index e7fe50305e..c8be515c6d 100644
--- a/server/src/main/java/com/vaadin/data/fieldgroup/PropertyId.java
+++ b/server/src/main/java/com/vaadin/data/fieldgroup/PropertyId.java
@@ -21,13 +21,13 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Defines the custom property name to be bound to a {@link Field} using
+ * Defines the custom property name to be bound to a {@link LegacyField} using
* {@link FieldGroup} or {@link BeanFieldGroup}.
*
* The automatic data binding in FieldGroup and BeanFieldGroup relies on a
* naming convention by default: properties of an item are bound to similarly
* named field components in given a editor object. If you want to map a
- * property with a different name (ID) to a {@link com.vaadin.client.ui.Field},
+ * property with a different name (ID) to a {@link com.vaadin.client.ui.LegacyField},
* you can use this annotation for the member fields, with the name (ID) of the
* desired property as the parameter.
*
diff --git a/server/src/main/java/com/vaadin/event/FieldEvents.java b/server/src/main/java/com/vaadin/event/FieldEvents.java
index 364ac76ffd..c6109a79d2 100644
--- a/server/src/main/java/com/vaadin/event/FieldEvents.java
+++ b/server/src/main/java/com/vaadin/event/FieldEvents.java
@@ -19,17 +19,17 @@ package com.vaadin.event;
import java.io.Serializable;
import java.lang.reflect.Method;
+import com.vaadin.legacy.ui.LegacyField;
+import com.vaadin.legacy.ui.LegacyField.ValueChangeEvent;
import com.vaadin.shared.EventId;
import com.vaadin.shared.communication.FieldRpc.FocusAndBlurServerRpc;
import com.vaadin.ui.Component;
import com.vaadin.ui.Component.Event;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.Field.ValueChangeEvent;
import com.vaadin.ui.TextField;
import com.vaadin.util.ReflectTools;
/**
- * Interface that serves as a wrapper for {@link Field} related events.
+ * Interface that serves as a wrapper for {@link LegacyField} related events.
*/
public interface FieldEvents {
@@ -53,7 +53,7 @@ public interface FieldEvents {
public interface FocusNotifier extends Serializable {
/**
* Adds a FocusListener to the Component which gets fired
- * when a Field receives keyboard focus.
+ * when a LegacyField receives keyboard focus.
*
* @param listener
* @see FocusListener
@@ -105,7 +105,7 @@ public interface FieldEvents {
public interface BlurNotifier extends Serializable {
/**
* Adds a BlurListener to the Component which gets fired
- * when a Field loses keyboard focus.
+ * when a LegacyField loses keyboard focus.
*
* @param listener
* @see BlurListener
@@ -139,7 +139,7 @@ public interface FieldEvents {
/**
* FocusEvent class for holding additional event information.
- * Fired when a Field receives keyboard focus.
+ * Fired when a LegacyField receives keyboard focus.
*
* @since 6.2
*/
@@ -158,7 +158,7 @@ public interface FieldEvents {
/**
* FocusListener interface for listening for
- * FocusEvent fired by a Field.
+ * FocusEvent fired by a LegacyField.
*
* @see FocusEvent
* @since 6.2
@@ -179,7 +179,7 @@ public interface FieldEvents {
/**
* BlurEvent class for holding additional event information.
- * Fired when a Field loses keyboard focus.
+ * Fired when a LegacyField loses keyboard focus.
*
* @since 6.2
*/
@@ -198,7 +198,7 @@ public interface FieldEvents {
/**
* BlurListener interface for listening for
- * BlurEvent fired by a Field.
+ * BlurEvent fired by a LegacyField.
*
* @see BlurEvent
* @since 6.2
@@ -281,7 +281,7 @@ public interface FieldEvents {
}
/**
- * An interface implemented by a {@link Field} supporting
+ * An interface implemented by a {@link LegacyField} supporting
* {@link TextChangeEvent}s. An example a {@link TextField} supports
* {@link TextChangeListener}s.
*/
diff --git a/server/src/main/java/com/vaadin/legacy/ui/LegacyAbstractField.java b/server/src/main/java/com/vaadin/legacy/ui/LegacyAbstractField.java
new file mode 100644
index 0000000000..d1b013a64a
--- /dev/null
+++ b/server/src/main/java/com/vaadin/legacy/ui/LegacyAbstractField.java
@@ -0,0 +1,1863 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.legacy.ui;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.logging.Logger;
+
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+
+import com.vaadin.data.Buffered;
+import com.vaadin.data.Property;
+import com.vaadin.data.Validatable;
+import com.vaadin.data.Validator;
+import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.data.util.LegacyPropertyHelper;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.data.util.converter.ConverterUtil;
+import com.vaadin.event.Action;
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.event.ShortcutListener;
+import com.vaadin.server.AbstractErrorMessage;
+import com.vaadin.server.CompositeErrorMessage;
+import com.vaadin.server.ErrorMessage;
+import com.vaadin.shared.AbstractFieldState;
+import com.vaadin.shared.util.SharedUtil;
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.declarative.DesignAttributeHandler;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ *
+ * Abstract field component for implementing buffered property editors. The
+ * field may hold an internal value, or it may be connected to any data source
+ * that implements the {@link com.vaadin.data.Property}interface.
+ * LegacyAbstractField implements that interface itself, too, so
+ * accessing the Property value represented by it is straightforward.
+ *
+ *
+ *
+ * LegacyAbstractField also provides the {@link com.vaadin.data.Buffered} interface
+ * for buffering the data source value. By default the LegacyField is in write
+ * through-mode and {@link #setWriteThrough(boolean)}should be called to enable
+ * buffering.
+ *
+ *
+ *
+ * The class also supports {@link com.vaadin.data.Validator validators} to make
+ * sure the value contained in the field is valid.
+ *
+ *
+ * @author Vaadin Ltd.
+ * @since 3.0
+ */
+@SuppressWarnings("serial")
+public abstract class LegacyAbstractField extends AbstractComponent implements
+ LegacyField, Property.ReadOnlyStatusChangeListener,
+ Property.ReadOnlyStatusChangeNotifier, Action.ShortcutNotifier {
+
+ /* Private members */
+
+ /**
+ * Value of the abstract field.
+ */
+ private T value;
+
+ /**
+ * A converter used to convert from the data model type to the field type
+ * and vice versa.
+ */
+ private Converter converter = null;
+ /**
+ * Connected data-source.
+ */
+ private Property> dataSource = null;
+
+ /**
+ * The list of validators.
+ */
+ private LinkedList validators = null;
+
+ /**
+ * True if field is in buffered mode, false otherwise
+ */
+ private boolean buffered;
+
+ /**
+ * Flag to indicate that the field is currently committing its value to the
+ * datasource.
+ */
+ private boolean committingValueToDataSource = false;
+
+ /**
+ * Current source exception.
+ */
+ private Buffered.SourceException currentBufferedSourceException = null;
+
+ /**
+ * Are the invalid values allowed in fields ?
+ */
+ private boolean invalidAllowed = true;
+
+ /**
+ * Are the invalid values committed ?
+ */
+ private boolean invalidCommitted = false;
+
+ /**
+ * The error message for the exception that is thrown when the field is
+ * required but empty.
+ */
+ private String requiredError = "";
+
+ /**
+ * The error message that is shown when the field value cannot be converted.
+ */
+ private String conversionError = "Could not convert value to {0}";
+
+ /**
+ * Is automatic validation enabled.
+ */
+ private boolean validationVisible = true;
+
+ private boolean valueWasModifiedByDataSourceDuringCommit;
+
+ /**
+ * Whether this field is currently registered as listening to events from
+ * its data source.
+ *
+ * @see #setPropertyDataSource(Property)
+ * @see #addPropertyListeners()
+ * @see #removePropertyListeners()
+ */
+ private boolean isListeningToPropertyEvents = false;
+
+ /**
+ * The locale used when setting the value.
+ */
+ private Locale valueLocale = null;
+
+ /* Component basics */
+
+ /*
+ * Paints the field. Don't add a JavaDoc comment here, we use the default
+ * documentation from the implemented interface.
+ */
+
+ /**
+ * Returns true if the error indicator be hidden when painting the component
+ * even when there are errors.
+ *
+ * This is a mostly internal method, but can be overridden in subclasses
+ * e.g. if the error indicator should also be shown for empty fields in some
+ * cases.
+ *
+ * @return true to hide the error indicator, false to use the normal logic
+ * to show it when there are errors
+ */
+ protected boolean shouldHideErrors() {
+ // getErrorMessage() can still return something else than null based on
+ // validation etc.
+ return isRequired() && isEmpty() && getComponentError() == null;
+ }
+
+ /**
+ * Returns the type of the LegacyField. The methods getValue and
+ * setValue must be compatible with this type: one must be able
+ * to safely cast the value returned from getValue to the given
+ * type and pass any variable assignable to this type as an argument to
+ * setValue.
+ *
+ * @return the type of the LegacyField
+ */
+ @Override
+ public abstract Class extends T> getType();
+
+ /**
+ * The abstract field is read only also if the data source is in read only
+ * mode.
+ */
+ @Override
+ public boolean isReadOnly() {
+ return super.isReadOnly()
+ || (dataSource != null && dataSource.isReadOnly());
+ }
+
+ /**
+ * Changes the readonly state and throw read-only status change events.
+ *
+ * @see com.vaadin.ui.Component#setReadOnly(boolean)
+ */
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ super.setReadOnly(readOnly);
+ fireReadOnlyStatusChange();
+ }
+
+ /**
+ * Tests if the invalid data is committed to datasource.
+ *
+ * @see com.vaadin.data.BufferedValidatable#isInvalidCommitted()
+ */
+ @Override
+ public boolean isInvalidCommitted() {
+ return invalidCommitted;
+ }
+
+ /**
+ * Sets if the invalid data should be committed to datasource.
+ *
+ * @see com.vaadin.data.BufferedValidatable#setInvalidCommitted(boolean)
+ */
+ @Override
+ public void setInvalidCommitted(boolean isCommitted) {
+ invalidCommitted = isCommitted;
+ }
+
+ /*
+ * Saves the current value to the data source Don't add a JavaDoc comment
+ * here, we use the default documentation from the implemented interface.
+ */
+ @Override
+ public void commit() throws Buffered.SourceException,
+ InvalidValueException {
+ if (dataSource != null && !dataSource.isReadOnly()) {
+ if ((isInvalidCommitted() || isValid())) {
+ try {
+
+ // Commits the value to datasource.
+ valueWasModifiedByDataSourceDuringCommit = false;
+ committingValueToDataSource = true;
+ getPropertyDataSource().setValue(getConvertedValue());
+ } catch (final Throwable e) {
+
+ // Sets the buffering state.
+ SourceException sourceException = new Buffered.SourceException(
+ this, e);
+ setCurrentBufferedSourceException(sourceException);
+
+ // Throws the source exception.
+ throw sourceException;
+ } finally {
+ committingValueToDataSource = false;
+ }
+ } else {
+ /*
+ * An invalid value and we don't allow them, throw the exception
+ */
+ validate();
+ }
+ }
+
+ // The abstract field is not modified anymore
+ if (isModified()) {
+ setModified(false);
+ }
+
+ // If successful, remove set the buffering state to be ok
+ if (getCurrentBufferedSourceException() != null) {
+ setCurrentBufferedSourceException(null);
+ }
+
+ if (valueWasModifiedByDataSourceDuringCommit) {
+ valueWasModifiedByDataSourceDuringCommit = false;
+ fireValueChange(false);
+ }
+
+ }
+
+ /*
+ * Updates the value from the data source. Don't add a JavaDoc comment here,
+ * we use the default documentation from the implemented interface.
+ */
+ @Override
+ public void discard() throws Buffered.SourceException {
+ updateValueFromDataSource();
+ }
+
+ /**
+ * Gets the value from the data source. This is only here because of clarity
+ * in the code that handles both the data model value and the field value.
+ *
+ * @return The value of the property data source
+ */
+ private Object getDataSourceValue() {
+ return dataSource.getValue();
+ }
+
+ /**
+ * Returns the field value. This is always identical to {@link #getValue()}
+ * and only here because of clarity in the code that handles both the data
+ * model value and the field value.
+ *
+ * @return The value of the field
+ */
+ private T getFieldValue() {
+ // Give the value from abstract buffers if the field if possible
+ if (dataSource == null || isBuffered() || isModified()) {
+ return getInternalValue();
+ }
+
+ // There is no buffered value so use whatever the data model provides
+ return convertFromModel(getDataSourceValue());
+ }
+
+ /*
+ * Has the field been modified since the last commit()? Don't add a JavaDoc
+ * comment here, we use the default documentation from the implemented
+ * interface.
+ */
+ @Override
+ public boolean isModified() {
+ return getState(false).modified;
+ }
+
+ private void setModified(boolean modified) {
+ getState().modified = modified;
+ }
+
+ /**
+ * Sets the buffered mode of this LegacyField.
+ *
+ * When the field is in buffered mode, changes will not be committed to the
+ * property data source until {@link #commit()} is called.
+ *
+ *
+ * Setting buffered mode from true to false will commit any pending changes.
+ *
+ *
+ *
+ *
+ *
+ * @since 7.0.0
+ * @param buffered
+ * true if buffered mode should be turned on, false otherwise
+ */
+ @Override
+ public void setBuffered(boolean buffered) {
+ if (this.buffered == buffered) {
+ return;
+ }
+ this.buffered = buffered;
+ if (!buffered) {
+ commit();
+ }
+ }
+
+ /**
+ * Checks the buffered mode of this LegacyField.
+ *
+ * @return true if buffered mode is on, false otherwise
+ */
+ @Override
+ public boolean isBuffered() {
+ return buffered;
+ }
+
+ /**
+ * Returns a string representation of this object. The returned string
+ * representation depends on if the legacy Property toString mode is enabled
+ * or disabled.
+ *
+ * If legacy Property toString mode is enabled, returns the value of this
+ * LegacyField converted to a String.
+ *
+ *
+ * If legacy Property toString mode is disabled, the string representation
+ * has no special meaning
+ *
+ *
+ * @see LegacyPropertyHelper#isLegacyToStringEnabled()
+ *
+ * @return A string representation of the value value stored in the Property
+ * or a string representation of the Property object.
+ * @deprecated As of 7.0. Use {@link #getValue()} to get the value of the
+ * field, {@link #getConvertedValue()} to get the field value
+ * converted to the data model type or
+ * {@link #getPropertyDataSource()} .getValue() to get the value
+ * of the data source.
+ */
+ @Deprecated
+ @Override
+ public String toString() {
+ if (!LegacyPropertyHelper.isLegacyToStringEnabled()) {
+ return super.toString();
+ } else {
+ return LegacyPropertyHelper.legacyPropertyToString(this);
+ }
+ }
+
+ /* Property interface implementation */
+
+ /**
+ * Gets the current value of the field.
+ *
+ *
+ * This is the visible, modified and possible invalid value the user have
+ * entered to the field.
+ *
+ *
+ *
+ * Note that the object returned is compatible with getType(). For example,
+ * if the type is String, this returns Strings even when the underlying
+ * datasource is of some other type. In order to access the converted value,
+ * use {@link #getConvertedValue()} and to access the value of the property
+ * data source, use {@link Property#getValue()} for the property data
+ * source.
+ *
+ *
+ *
+ * Since Vaadin 7.0, no implicit conversions between other data types and
+ * String are performed, but a converter is used if set.
+ *
+ *
+ * @return the current value of the field.
+ */
+ @Override
+ public T getValue() {
+ return getFieldValue();
+ }
+
+ /**
+ * Sets the value of the field.
+ *
+ * @param newFieldValue
+ * the New value of the field.
+ * @throws Property.ReadOnlyException
+ */
+ @Override
+ public void setValue(T newFieldValue) throws Property.ReadOnlyException,
+ Converter.ConversionException {
+ setValue(newFieldValue, false);
+ }
+
+ /**
+ * Sets the value of the field.
+ *
+ * @param newFieldValue
+ * the New value of the field.
+ * @param repaintIsNotNeeded
+ * True iff caller is sure that repaint is not needed.
+ * @throws Property.ReadOnlyException
+ * @throws Converter.ConversionException
+ * @throws InvalidValueException
+ */
+ protected void setValue(T newFieldValue, boolean repaintIsNotNeeded) {
+ setValue(newFieldValue, repaintIsNotNeeded, false);
+ }
+
+ /**
+ * Sets the value of the field.
+ *
+ * @since 7.5.7
+ * @param newFieldValue
+ * the New value of the field.
+ * @param repaintIsNotNeeded
+ * True iff caller is sure that repaint is not needed.
+ * @param ignoreReadOnly
+ * True iff if the read-only check should be ignored
+ * @throws Property.ReadOnlyException
+ * @throws Converter.ConversionException
+ * @throws InvalidValueException
+ */
+ protected void setValue(T newFieldValue, boolean repaintIsNotNeeded,
+ boolean ignoreReadOnly) throws Property.ReadOnlyException,
+ Converter.ConversionException, InvalidValueException {
+
+ if (!SharedUtil.equals(newFieldValue, getInternalValue())) {
+
+ // Read only fields can not be changed
+ if (!ignoreReadOnly && isReadOnly()) {
+ throw new Property.ReadOnlyException();
+ }
+ try {
+ T doubleConvertedFieldValue = convertFromModel(convertToModel(
+ newFieldValue));
+ if (!SharedUtil
+ .equals(newFieldValue, doubleConvertedFieldValue)) {
+ newFieldValue = doubleConvertedFieldValue;
+ repaintIsNotNeeded = false;
+ }
+ } catch (Throwable t) {
+ // Ignore exceptions in the conversion at this stage. Any
+ // conversion error will be handled later by validate().
+ }
+
+ // Repaint is needed even when the client thinks that it knows the
+ // new state if validity of the component may change
+ if (repaintIsNotNeeded
+ && (isRequired() || hasValidators()
+ || getConverter() != null)) {
+ repaintIsNotNeeded = false;
+ }
+
+ if (!isInvalidAllowed()) {
+ /*
+ * If invalid values are not allowed the value must be validated
+ * before it is set. If validation fails, the
+ * InvalidValueException is thrown and the internal value is not
+ * updated.
+ */
+ validate(newFieldValue);
+ }
+
+ // Changes the value
+ setInternalValue(newFieldValue);
+ setModified(dataSource != null);
+
+ valueWasModifiedByDataSourceDuringCommit = false;
+ // In not buffering, try to commit
+ if (!isBuffered() && dataSource != null
+ && (isInvalidCommitted() || isValid())) {
+ try {
+
+ // Commits the value to datasource
+ committingValueToDataSource = true;
+ getPropertyDataSource().setValue(
+ convertToModel(newFieldValue));
+
+ // The buffer is now unmodified
+ setModified(false);
+
+ } catch (final Throwable e) {
+
+ // Sets the buffering state
+ currentBufferedSourceException = new Buffered.SourceException(
+ this, e);
+ markAsDirty();
+
+ // Throws the source exception
+ throw currentBufferedSourceException;
+ } finally {
+ committingValueToDataSource = false;
+ }
+ }
+
+ // If successful, remove set the buffering state to be ok
+ if (getCurrentBufferedSourceException() != null) {
+ setCurrentBufferedSourceException(null);
+ }
+
+ if (valueWasModifiedByDataSourceDuringCommit) {
+ /*
+ * Value was modified by datasource. Force repaint even if
+ * repaint was not requested.
+ */
+ valueWasModifiedByDataSourceDuringCommit = repaintIsNotNeeded = false;
+ }
+
+ // Fires the value change
+ fireValueChange(repaintIsNotNeeded);
+
+ }
+ }
+
+ @Deprecated
+ static boolean equals(Object value1, Object value2) {
+ return SharedUtil.equals(value1, value2);
+ }
+
+ /* External data source */
+
+ /**
+ * Gets the current data source of the field, if any.
+ *
+ * @return the current data source as a Property, or null if
+ * none defined.
+ */
+ @Override
+ public Property getPropertyDataSource() {
+ return dataSource;
+ }
+
+ /**
+ *
+ * Sets the specified Property as the data source for the field. All
+ * uncommitted changes are replaced with a value from the new data source.
+ *
+ *
+ *
+ * If the datasource has any validators, the same validators are added to
+ * the field. Because the default behavior of the field is to allow invalid
+ * values, but not to allow committing them, this only adds visual error
+ * messages to fields and do not allow committing them as long as the value
+ * is invalid. After the value is valid, the error message is not shown and
+ * the commit can be done normally.
+ *
+ *
+ *
+ * If the data source implements
+ * {@link com.vaadin.data.Property.ValueChangeNotifier} and/or
+ * {@link com.vaadin.data.Property.ReadOnlyStatusChangeNotifier}, the field
+ * registers itself as a listener and updates itself according to the events
+ * it receives. To avoid memory leaks caused by references to a field no
+ * longer in use, the listener registrations are removed on
+ * {@link LegacyAbstractField#detach() detach} and re-added on
+ * {@link LegacyAbstractField#attach() attach}.
+ *
+ *
+ *
+ * Note: before 6.5 we actually called discard() method in the beginning of
+ * the method. This was removed to simplify implementation, avoid excess
+ * calls to backing property and to avoid odd value change events that were
+ * previously fired (developer expects 0-1 value change events if this
+ * method is called). Some complex field implementations might now need to
+ * override this method to do housekeeping similar to discard().
+ *
+ *
+ * @param newDataSource
+ * the new data source Property.
+ */
+ @Override
+ public void setPropertyDataSource(Property newDataSource) {
+
+ // Saves the old value
+ final Object oldValue = getInternalValue();
+
+ // Stop listening to the old data source
+ removePropertyListeners();
+
+ // Sets the new data source
+ dataSource = newDataSource;
+ getState().propertyReadOnly = dataSource == null ? false : dataSource
+ .isReadOnly();
+
+ // Check if the current converter is compatible.
+ if (newDataSource != null
+ && !ConverterUtil.canConverterPossiblyHandle(getConverter(),
+ getType(), newDataSource.getType())) {
+ // There is no converter set or there is no way the current
+ // converter can be compatible.
+ setConverter(newDataSource.getType());
+ }
+ // Gets the value from source. This requires that a valid converter has
+ // been set.
+ try {
+ if (dataSource != null) {
+ T fieldValue = convertFromModel(getDataSourceValue());
+ setInternalValue(fieldValue);
+ }
+ setModified(false);
+ if (getCurrentBufferedSourceException() != null) {
+ setCurrentBufferedSourceException(null);
+ }
+ } catch (final Throwable e) {
+ setCurrentBufferedSourceException(new Buffered.SourceException(
+ this, e));
+ setModified(true);
+ throw getCurrentBufferedSourceException();
+ }
+
+ // Listen to new data source if possible
+ addPropertyListeners();
+
+ // Copy the validators from the data source
+ if (dataSource instanceof Validatable) {
+ final Collection validators = ((Validatable) dataSource)
+ .getValidators();
+ if (validators != null) {
+ for (final Iterator i = validators.iterator(); i
+ .hasNext();) {
+ addValidator(i.next());
+ }
+ }
+ }
+
+ // Fires value change if the value has changed
+ T value = getInternalValue();
+ if ((value != oldValue)
+ && ((value != null && !value.equals(oldValue))
+ || value == null)) {
+ fireValueChange(false);
+ }
+ }
+
+ /**
+ * Retrieves a converter for the field from the converter factory defined
+ * for the application. Clears the converter if no application reference is
+ * available or if the factory returns null.
+ *
+ * @param datamodelType
+ * The type of the data model that we want to be able to convert
+ * from
+ */
+ public void setConverter(Class> datamodelType) {
+ Converter c = (Converter) ConverterUtil.getConverter(
+ getType(), datamodelType, getSession());
+ setConverter(c);
+ }
+
+ /**
+ * Convert the given value from the data source type to the UI type.
+ *
+ * @param newValue
+ * The data source value to convert.
+ * @return The converted value that is compatible with the UI type or the
+ * original value if its type is compatible and no converter is set.
+ * @throws Converter.ConversionException
+ * if there is no converter and the type is not compatible with
+ * the data source type.
+ */
+ private T convertFromModel(Object newValue) {
+ return convertFromModel(newValue, getLocale());
+ }
+
+ /**
+ * Convert the given value from the data source type to the UI type.
+ *
+ * @param newValue
+ * The data source value to convert.
+ * @return The converted value that is compatible with the UI type or the
+ * original value if its type is compatible and no converter is set.
+ * @throws Converter.ConversionException
+ * if there is no converter and the type is not compatible with
+ * the data source type.
+ */
+ private T convertFromModel(Object newValue, Locale locale) {
+ return ConverterUtil.convertFromModel(newValue, getType(),
+ getConverter(), locale);
+ }
+
+ /**
+ * Convert the given value from the UI type to the data source type.
+ *
+ * @param fieldValue
+ * The value to convert. Typically returned by
+ * {@link #getFieldValue()}
+ * @return The converted value that is compatible with the data source type.
+ * @throws Converter.ConversionException
+ * if there is no converter and the type is not compatible with
+ * the data source type.
+ */
+ private Object convertToModel(T fieldValue)
+ throws Converter.ConversionException {
+ return convertToModel(fieldValue, getLocale());
+ }
+
+ /**
+ * Convert the given value from the UI type to the data source type.
+ *
+ * @param fieldValue
+ * The value to convert. Typically returned by
+ * {@link #getFieldValue()}
+ * @param locale
+ * The locale to use for the conversion
+ * @return The converted value that is compatible with the data source type.
+ * @throws Converter.ConversionException
+ * if there is no converter and the type is not compatible with
+ * the data source type.
+ */
+ private Object convertToModel(T fieldValue, Locale locale)
+ throws Converter.ConversionException {
+ Class> modelType = getModelType();
+ try {
+ return ConverterUtil.convertToModel(fieldValue,
+ (Class) modelType, getConverter(), locale);
+ } catch (ConversionException e) {
+ throw new ConversionException(getConversionError(modelType, e), e);
+ }
+ }
+
+ /**
+ * Retrieves the type of the currently used data model. If the field has no
+ * data source then the model type of the converter is used.
+ *
+ * @since 7.1
+ * @return The type of the currently used data model or null if no data
+ * source or converter is set.
+ */
+ protected Class> getModelType() {
+ Property> pd = getPropertyDataSource();
+ if (pd != null) {
+ return pd.getType();
+ } else if (getConverter() != null) {
+ return getConverter().getModelType();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the conversion error with {0} replaced by the data source type
+ * and {1} replaced by the exception (localized) message.
+ *
+ * @since 7.1
+ * @param dataSourceType
+ * the type of the data source
+ * @param e
+ * a conversion exception which can provide additional
+ * information
+ * @return The value conversion error string with parameters replaced.
+ */
+ protected String getConversionError(Class> dataSourceType,
+ ConversionException e) {
+ String conversionError = getConversionError();
+
+ if (conversionError != null) {
+ if (dataSourceType != null) {
+ conversionError = conversionError.replace("{0}",
+ dataSourceType.getSimpleName());
+ }
+ if (e != null) {
+ conversionError = conversionError.replace("{1}",
+ e.getLocalizedMessage());
+ }
+ }
+ return conversionError;
+ }
+
+ /**
+ * Returns the current value (as returned by {@link #getValue()}) converted
+ * to the data source type.
+ *
+ * This returns the same as {@link LegacyAbstractField#getValue()} if no converter
+ * has been set. The value is not necessarily the same as the data source
+ * value e.g. if the field is in buffered mode and has been modified.
+ *
+ *
+ * @return The converted value that is compatible with the data source type
+ */
+ public Object getConvertedValue() {
+ return convertToModel(getFieldValue());
+ }
+
+ /**
+ * Sets the value of the field using a value of the data source type. The
+ * value given is converted to the field type and then assigned to the
+ * field. This will update the property data source in the same way as when
+ * {@link #setValue(Object)} is called.
+ *
+ * @param value
+ * The value to set. Must be the same type as the data source.
+ */
+ public void setConvertedValue(Object value) {
+ setValue(convertFromModel(value));
+ }
+
+ /* Validation */
+
+ /**
+ * Adds a new validator for the field's value. All validators added to a
+ * field are checked each time the its value changes.
+ *
+ * @param validator
+ * the new validator to be added.
+ */
+ @Override
+ public void addValidator(Validator validator) {
+ if (validators == null) {
+ validators = new LinkedList();
+ }
+ validators.add(validator);
+ markAsDirty();
+ }
+
+ /**
+ * Gets the validators of the field.
+ *
+ * @return An unmodifiable collection that holds all validators for the
+ * field.
+ */
+ @Override
+ public Collection getValidators() {
+ if (validators == null) {
+ return Collections.emptyList();
+ } else {
+ return Collections.unmodifiableCollection(validators);
+ }
+ }
+
+ private boolean hasValidators() {
+ return validators != null && !validators.isEmpty();
+ }
+
+ /**
+ * Removes the validator from the field.
+ *
+ * @param validator
+ * the validator to remove.
+ */
+ @Override
+ public void removeValidator(Validator validator) {
+ if (validators != null) {
+ validators.remove(validator);
+ }
+ markAsDirty();
+ }
+
+ /**
+ * Removes all validators from the field.
+ */
+ @Override
+ public void removeAllValidators() {
+ if (validators != null) {
+ validators.clear();
+ }
+ markAsDirty();
+ }
+
+ /**
+ * Tests the current value against registered validators if the field is not
+ * empty. If the field is empty it is considered valid if it is not required
+ * and invalid otherwise. Validators are never checked for empty fields.
+ *
+ * In most cases, {@link #validate()} should be used instead of
+ * {@link #isValid()} to also get the error message.
+ *
+ * @return true if all registered validators claim that the
+ * current value is valid or if the field is empty and not required,
+ * false otherwise.
+ */
+ @Override
+ public boolean isValid() {
+
+ try {
+ validate();
+ return true;
+ } catch (InvalidValueException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Checks the validity of the LegacyField.
+ *
+ * A field is invalid if it is set as required (using
+ * {@link #setRequired(boolean)} and is empty, if one or several of the
+ * validators added to the field indicate it is invalid or if the value
+ * cannot be converted provided a converter has been set.
+ *
+ * The "required" validation is a built-in validation feature. If the field
+ * is required and empty this method throws an EmptyValueException with the
+ * error message set using {@link #setRequiredError(String)}.
+ *
+ * @see com.vaadin.data.Validatable#validate()
+ */
+ @Override
+ public void validate() throws Validator.InvalidValueException {
+
+ if (isRequired() && isEmpty()) {
+ throw new Validator.EmptyValueException(requiredError);
+ }
+ validate(getFieldValue());
+ }
+
+ /**
+ * Validates that the given value pass the validators for the field.
+ *
+ * This method does not check the requiredness of the field.
+ *
+ * @param fieldValue
+ * The value to check
+ * @throws Validator.InvalidValueException
+ * if one or several validators fail
+ */
+ protected void validate(T fieldValue)
+ throws Validator.InvalidValueException {
+
+ Object valueToValidate = fieldValue;
+
+ // If there is a converter we start by converting the value as we want
+ // to validate the converted value
+ if (getConverter() != null) {
+ try {
+ valueToValidate = getConverter().convertToModel(fieldValue,
+ getModelType(), getLocale());
+ } catch (ConversionException e) {
+ throw new InvalidValueException(getConversionError(
+ getConverter().getModelType(), e));
+ }
+ }
+
+ List validationExceptions = new ArrayList();
+ if (validators != null) {
+ // Gets all the validation errors
+ for (Validator v : validators) {
+ try {
+ v.validate(valueToValidate);
+ } catch (final Validator.InvalidValueException e) {
+ validationExceptions.add(e);
+ }
+ }
+ }
+
+ // If there were no errors
+ if (validationExceptions.isEmpty()) {
+ return;
+ }
+
+ // If only one error occurred, throw it forwards
+ if (validationExceptions.size() == 1) {
+ throw validationExceptions.get(0);
+ }
+
+ InvalidValueException[] exceptionArray = validationExceptions
+ .toArray(new InvalidValueException[validationExceptions
+ .size()]);
+
+ // Create a composite validator and include all exceptions
+ throw new Validator.InvalidValueException(null, exceptionArray);
+ }
+
+ /**
+ * Fields allow invalid values by default. In most cases this is wanted,
+ * because the field otherwise visually forget the user input immediately.
+ *
+ * @return true iff the invalid values are allowed.
+ * @see com.vaadin.data.Validatable#isInvalidAllowed()
+ */
+ @Override
+ public boolean isInvalidAllowed() {
+ return invalidAllowed;
+ }
+
+ /**
+ * Fields allow invalid values by default. In most cases this is wanted,
+ * because the field otherwise visually forget the user input immediately.
+ *
+ * In common setting where the user wants to assure the correctness of the
+ * datasource, but allow temporarily invalid contents in the field, the user
+ * should add the validators to datasource, that should not allow invalid
+ * values. The validators are automatically copied to the field when the
+ * datasource is set.
+ *
+ *
+ * @see com.vaadin.data.Validatable#setInvalidAllowed(boolean)
+ */
+ @Override
+ public void setInvalidAllowed(boolean invalidAllowed)
+ throws UnsupportedOperationException {
+ this.invalidAllowed = invalidAllowed;
+ }
+
+ /**
+ * Error messages shown by the fields are composites of the error message
+ * thrown by the superclasses (that is the component error message),
+ * validation errors and buffered source errors.
+ *
+ * @see com.vaadin.ui.AbstractComponent#getErrorMessage()
+ */
+ @Override
+ public ErrorMessage getErrorMessage() {
+
+ /*
+ * Check validation errors only if automatic validation is enabled.
+ * Empty, required fields will generate a validation error containing
+ * the requiredError string. For these fields the exclamation mark will
+ * be hidden but the error must still be sent to the client.
+ */
+ Validator.InvalidValueException validationError = null;
+ if (isValidationVisible()) {
+ try {
+ validate();
+ } catch (Validator.InvalidValueException e) {
+ if (!e.isInvisible()) {
+ validationError = e;
+ }
+ }
+ }
+
+ // Check if there are any systems errors
+ final ErrorMessage superError = super.getErrorMessage();
+
+ // Return if there are no errors at all
+ if (superError == null && validationError == null
+ && getCurrentBufferedSourceException() == null) {
+ return null;
+ }
+
+ // Throw combination of the error types
+ return new CompositeErrorMessage(
+ new ErrorMessage[] {
+ superError,
+ AbstractErrorMessage
+ .getErrorMessageForException(validationError),
+ AbstractErrorMessage
+ .getErrorMessageForException(
+ getCurrentBufferedSourceException()) });
+
+ }
+
+ /* Value change events */
+
+ private static final Method VALUE_CHANGE_METHOD;
+
+ static {
+ try {
+ VALUE_CHANGE_METHOD = Property.ValueChangeListener.class
+ .getDeclaredMethod("valueChange",
+ new Class[] { Property.ValueChangeEvent.class });
+ } catch (final java.lang.NoSuchMethodException e) {
+ // This should never happen
+ throw new java.lang.RuntimeException(
+ "Internal error finding methods in LegacyAbstractField");
+ }
+ }
+
+ /*
+ * Adds a value change listener for the field. Don't add a JavaDoc comment
+ * here, we use the default documentation from the implemented interface.
+ */
+ @Override
+ public void addValueChangeListener(Property.ValueChangeListener listener) {
+ addListener(LegacyAbstractField.ValueChangeEvent.class, listener,
+ VALUE_CHANGE_METHOD);
+ // ensure "automatic immediate handling" works
+ markAsDirty();
+ }
+
+ /**
+ * @deprecated As of 7.0, replaced by
+ * {@link #addValueChangeListener(com.vaadin.data.Property.ValueChangeListener)}
+ **/
+ @Override
+ @Deprecated
+ public void addListener(Property.ValueChangeListener listener) {
+ addValueChangeListener(listener);
+ }
+
+ /*
+ * Removes a value change listener from the field. Don't add a JavaDoc
+ * comment here, we use the default documentation from the implemented
+ * interface.
+ */
+ @Override
+ public void removeValueChangeListener(
+ Property.ValueChangeListener listener) {
+ removeListener(LegacyAbstractField.ValueChangeEvent.class, listener,
+ VALUE_CHANGE_METHOD);
+ // ensure "automatic immediate handling" works
+ markAsDirty();
+ }
+
+ /**
+ * @deprecated As of 7.0, replaced by
+ * {@link #removeValueChangeListener(com.vaadin.data.Property.ValueChangeListener)}
+ **/
+ @Override
+ @Deprecated
+ public void removeListener(Property.ValueChangeListener listener) {
+ removeValueChangeListener(listener);
+ }
+
+ /**
+ * Emits the value change event. The value contained in the field is
+ * validated before the event is created.
+ */
+ protected void fireValueChange(boolean repaintIsNotNeeded) {
+ fireEvent(new LegacyAbstractField.ValueChangeEvent(this));
+ if (!repaintIsNotNeeded) {
+ markAsDirty();
+ }
+ }
+
+ /* Read-only status change events */
+
+ private static final Method READ_ONLY_STATUS_CHANGE_METHOD;
+
+ static {
+ try {
+ READ_ONLY_STATUS_CHANGE_METHOD = Property.ReadOnlyStatusChangeListener.class
+ .getDeclaredMethod(
+ "readOnlyStatusChange",
+ new Class[] {
+ Property.ReadOnlyStatusChangeEvent.class });
+ } catch (final java.lang.NoSuchMethodException e) {
+ // This should never happen
+ throw new java.lang.RuntimeException(
+ "Internal error finding methods in LegacyAbstractField");
+ }
+ }
+
+ /**
+ * React to read only status changes of the property by requesting a
+ * repaint.
+ *
+ * @see Property.ReadOnlyStatusChangeListener
+ */
+ @Override
+ public void readOnlyStatusChange(Property.ReadOnlyStatusChangeEvent event) {
+ boolean readOnly = event.getProperty().isReadOnly();
+
+ boolean shouldFireChange = isReadOnly() != readOnly
+ || getState().propertyReadOnly != readOnly;
+
+ getState().propertyReadOnly = readOnly;
+
+ if (shouldFireChange) {
+ fireReadOnlyStatusChange();
+ }
+ }
+
+ /**
+ * An Event object specifying the Property whose read-only
+ * status has changed.
+ *
+ * @author Vaadin Ltd.
+ * @since 3.0
+ */
+ public static class ReadOnlyStatusChangeEvent extends Component.Event
+ implements Property.ReadOnlyStatusChangeEvent, Serializable {
+
+ /**
+ * New instance of text change event.
+ *
+ * @param source
+ * the Source of the event.
+ */
+ public ReadOnlyStatusChangeEvent(LegacyAbstractField source) {
+ super(source);
+ }
+
+ /**
+ * Property where the event occurred.
+ *
+ * @return the Source of the event.
+ */
+ @Override
+ public Property getProperty() {
+ return (Property) getSource();
+ }
+ }
+
+ /*
+ * Adds a read-only status change listener for the field. Don't add a
+ * JavaDoc comment here, we use the default documentation from the
+ * implemented interface.
+ */
+ @Override
+ public void addReadOnlyStatusChangeListener(
+ Property.ReadOnlyStatusChangeListener listener) {
+ addListener(Property.ReadOnlyStatusChangeEvent.class, listener,
+ READ_ONLY_STATUS_CHANGE_METHOD);
+ }
+
+ /**
+ * @deprecated As of 7.0, replaced by
+ * {@link #addReadOnlyStatusChangeListener(com.vaadin.data.Property.ReadOnlyStatusChangeListener)}
+ **/
+ @Override
+ @Deprecated
+ public void addListener(Property.ReadOnlyStatusChangeListener listener) {
+ addReadOnlyStatusChangeListener(listener);
+ }
+
+ /*
+ * Removes a read-only status change listener from the field. Don't add a
+ * JavaDoc comment here, we use the default documentation from the
+ * implemented interface.
+ */
+ @Override
+ public void removeReadOnlyStatusChangeListener(
+ Property.ReadOnlyStatusChangeListener listener) {
+ removeListener(Property.ReadOnlyStatusChangeEvent.class, listener,
+ READ_ONLY_STATUS_CHANGE_METHOD);
+ }
+
+ /**
+ * @deprecated As of 7.0, replaced by
+ * {@link #removeReadOnlyStatusChangeListener(com.vaadin.data.Property.ReadOnlyStatusChangeListener)}
+ **/
+ @Override
+ @Deprecated
+ public void removeListener(Property.ReadOnlyStatusChangeListener listener) {
+ removeReadOnlyStatusChangeListener(listener);
+ }
+
+ /**
+ * Emits the read-only status change event. The value contained in the field
+ * is validated before the event is created.
+ */
+ protected void fireReadOnlyStatusChange() {
+ fireEvent(new LegacyAbstractField.ReadOnlyStatusChangeEvent(this));
+ }
+
+ /**
+ * This method listens to data source value changes and passes the changes
+ * forwards.
+ *
+ * Changes are not forwarded to the listeners of the field during internal
+ * operations of the field to avoid duplicate notifications.
+ *
+ * @param event
+ * the value change event telling the data source contents have
+ * changed.
+ */
+ @Override
+ public void valueChange(Property.ValueChangeEvent event) {
+ if (!isBuffered()) {
+ if (committingValueToDataSource) {
+ boolean propertyNotifiesOfTheBufferedValue = SharedUtil.equals(
+ event.getProperty().getValue(), getInternalValue());
+ if (!propertyNotifiesOfTheBufferedValue) {
+ /*
+ * Property (or chained property like PropertyFormatter) now
+ * reports different value than the one the field has just
+ * committed to it. In this case we respect the property
+ * value.
+ *
+ * Still, we don't fire value change yet, but instead
+ * postpone it until "commit" is done. See setValue(Object,
+ * boolean) and commit().
+ */
+ readValueFromProperty(event);
+ valueWasModifiedByDataSourceDuringCommit = true;
+ }
+ } else if (!isModified()) {
+ readValueFromProperty(event);
+ fireValueChange(false);
+ }
+ }
+ }
+
+ private void readValueFromProperty(Property.ValueChangeEvent event) {
+ setInternalValue(convertFromModel(event.getProperty().getValue()));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void focus() {
+ super.focus();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.Component.Focusable#getTabIndex()
+ */
+ @Override
+ public int getTabIndex() {
+ return getState(false).tabIndex;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.Component.Focusable#setTabIndex(int)
+ */
+ @Override
+ public void setTabIndex(int tabIndex) {
+ getState().tabIndex = tabIndex;
+ }
+
+ /**
+ * Returns the internal field value, which might not match the data source
+ * value e.g. if the field has been modified and is not in write-through
+ * mode.
+ *
+ * This method can be overridden by subclasses together with
+ * {@link #setInternalValue(Object)} to compute internal field value at
+ * runtime. When doing so, typically also {@link #isModified()} needs to be
+ * overridden and care should be taken in the management of the empty state
+ * and buffering support.
+ *
+ * @return internal field value
+ */
+ protected T getInternalValue() {
+ return value;
+ }
+
+ /**
+ * Sets the internal field value. This is purely used by LegacyAbstractField to
+ * change the internal LegacyField value. It does not trigger valuechange events.
+ * It can be overridden by the inheriting classes to update all dependent
+ * variables.
+ *
+ * Subclasses can also override {@link #getInternalValue()} if necessary.
+ *
+ * @param newValue
+ * the new value to be set.
+ */
+ protected void setInternalValue(T newValue) {
+ value = newValue;
+ valueLocale = getLocale();
+ if (validators != null && !validators.isEmpty()) {
+ markAsDirty();
+ }
+ }
+
+ /**
+ * Notifies the component that it is connected to an application.
+ *
+ * @see com.vaadin.ui.Component#attach()
+ */
+ @Override
+ public void attach() {
+ super.attach();
+
+ localeMightHaveChanged();
+ if (!isListeningToPropertyEvents) {
+ addPropertyListeners();
+ if (!isModified() && !isBuffered()) {
+ // Update value from data source
+ updateValueFromDataSource();
+ }
+ }
+ }
+
+ @Override
+ public void setLocale(Locale locale) {
+ super.setLocale(locale);
+ localeMightHaveChanged();
+ }
+
+ private void localeMightHaveChanged() {
+ if (!SharedUtil.equals(valueLocale, getLocale())) {
+ // The locale HAS actually changed
+
+ if (dataSource != null && !isModified()) {
+ // When we have a data source and the internal value is directly
+ // read from that we want to update the value
+ T newInternalValue = convertFromModel(getPropertyDataSource()
+ .getValue());
+ if (!SharedUtil.equals(newInternalValue, getInternalValue())) {
+ setInternalValue(newInternalValue);
+ fireValueChange(false);
+ }
+ } else if (dataSource == null && converter != null) {
+ /*
+ * No data source but a converter has been set. The same issues
+ * as above but we cannot use propertyDataSource. Convert the
+ * current value back to a model value using the old locale and
+ * then convert back using the new locale. If this does not
+ * match the field value we need to set the converted value
+ * again.
+ */
+ Object convertedValue = convertToModel(getInternalValue(),
+ valueLocale);
+ T newinternalValue = convertFromModel(convertedValue);
+ if (!SharedUtil.equals(getInternalValue(), newinternalValue)) {
+ setInternalValue(newinternalValue);
+ fireValueChange(false);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void detach() {
+ super.detach();
+ // Stop listening to data source events on detach to avoid a potential
+ // memory leak. See #6155.
+ removePropertyListeners();
+ }
+
+ /**
+ * Is this field required. Required fields must filled by the user.
+ *
+ * If the field is required, it is visually indicated in the user interface.
+ * Furthermore, setting field to be required implicitly adds "non-empty"
+ * validator and thus isValid() == false or any isEmpty() fields. In those
+ * cases validation errors are not painted as it is obvious that the user
+ * must fill in the required fields.
+ *
+ * On the other hand, for the non-required fields isValid() == true if the
+ * field isEmpty() regardless of any attached validators.
+ *
+ *
+ * @return true if the field is required, otherwise
+ * false.
+ */
+ @Override
+ public boolean isRequired() {
+ return getState(false).required;
+ }
+
+ /**
+ * Sets the field required. Required fields must filled by the user.
+ *
+ * If the field is required, it is visually indicated in the user interface.
+ * Furthermore, setting field to be required implicitly adds "non-empty"
+ * validator and thus isValid() == false or any isEmpty() fields. In those
+ * cases validation errors are not painted as it is obvious that the user
+ * must fill in the required fields.
+ *
+ * On the other hand, for the non-required fields isValid() == true if the
+ * field isEmpty() regardless of any attached validators.
+ *
+ * @param required
+ * Is the field required.
+ */
+ @Override
+ public void setRequired(boolean required) {
+ getState().required = required;
+ }
+
+ /**
+ * Set the error that is show if this field is required, but empty. When
+ * setting requiredMessage to be "" or null, no error pop-up or exclamation
+ * mark is shown for a empty required field. This faults to "". Even in
+ * those cases isValid() returns false for empty required fields.
+ *
+ * @param requiredMessage
+ * Message to be shown when this field is required, but empty.
+ */
+ @Override
+ public void setRequiredError(String requiredMessage) {
+ requiredError = requiredMessage;
+ markAsDirty();
+ }
+
+ @Override
+ public String getRequiredError() {
+ return requiredError;
+ }
+
+ /**
+ * Gets the error that is shown if the field value cannot be converted to
+ * the data source type.
+ *
+ * @return The error that is shown if conversion of the field value fails
+ */
+ public String getConversionError() {
+ return conversionError;
+ }
+
+ /**
+ * Sets the error that is shown if the field value cannot be converted to
+ * the data source type. If {0} is present in the message, it will be
+ * replaced by the simple name of the data source type. If {1} is present in
+ * the message, it will be replaced by the ConversionException message.
+ *
+ * @param valueConversionError
+ * Message to be shown when conversion of the value fails
+ */
+ public void setConversionError(String valueConversionError) {
+ this.conversionError = valueConversionError;
+ markAsDirty();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return (getFieldValue() == null);
+ }
+
+ @Override
+ public void clear() {
+ setValue(null);
+ }
+
+ /**
+ * Is automatic, visible validation enabled?
+ *
+ * If automatic validation is enabled, any validators connected to this
+ * component are evaluated while painting the component and potential error
+ * messages are sent to client. If the automatic validation is turned off,
+ * isValid() and validate() methods still work, but one must show the
+ * validation in their own code.
+ *
+ * @return True, if automatic validation is enabled.
+ */
+ public boolean isValidationVisible() {
+ return validationVisible;
+ }
+
+ /**
+ * Enable or disable automatic, visible validation.
+ *
+ * If automatic validation is enabled, any validators connected to this
+ * component are evaluated while painting the component and potential error
+ * messages are sent to client. If the automatic validation is turned off,
+ * isValid() and validate() methods still work, but one must show the
+ * validation in their own code.
+ *
+ * @param validateAutomatically
+ * True, if automatic validation is enabled.
+ */
+ public void setValidationVisible(boolean validateAutomatically) {
+ if (validationVisible != validateAutomatically) {
+ markAsDirty();
+ validationVisible = validateAutomatically;
+ }
+ }
+
+ /**
+ * Sets the current buffered source exception.
+ *
+ * @param currentBufferedSourceException
+ */
+ public void setCurrentBufferedSourceException(
+ Buffered.SourceException currentBufferedSourceException) {
+ this.currentBufferedSourceException = currentBufferedSourceException;
+ markAsDirty();
+ }
+
+ /**
+ * Gets the current buffered source exception.
+ *
+ * @return The current source exception
+ */
+ protected Buffered.SourceException getCurrentBufferedSourceException() {
+ return currentBufferedSourceException;
+ }
+
+ /**
+ * A ready-made {@link ShortcutListener} that focuses the given
+ * {@link Focusable} (usually a {@link LegacyField}) when the keyboard shortcut is
+ * invoked.
+ *
+ */
+ public static class FocusShortcut extends ShortcutListener {
+ protected Focusable focusable;
+
+ /**
+ * Creates a keyboard shortcut for focusing the given {@link Focusable}
+ * using the shorthand notation defined in {@link ShortcutAction}.
+ *
+ * @param focusable
+ * to focused when the shortcut is invoked
+ * @param shorthandCaption
+ * caption with keycode and modifiers indicated
+ */
+ public FocusShortcut(Focusable focusable, String shorthandCaption) {
+ super(shorthandCaption);
+ this.focusable = focusable;
+ }
+
+ /**
+ * Creates a keyboard shortcut for focusing the given {@link Focusable}.
+ *
+ * @param focusable
+ * to focused when the shortcut is invoked
+ * @param keyCode
+ * keycode that invokes the shortcut
+ * @param modifiers
+ * modifiers required to invoke the shortcut
+ */
+ public FocusShortcut(Focusable focusable, int keyCode,
+ int... modifiers) {
+ super(null, keyCode, modifiers);
+ this.focusable = focusable;
+ }
+
+ /**
+ * Creates a keyboard shortcut for focusing the given {@link Focusable}.
+ *
+ * @param focusable
+ * to focused when the shortcut is invoked
+ * @param keyCode
+ * keycode that invokes the shortcut
+ */
+ public FocusShortcut(Focusable focusable, int keyCode) {
+ this(focusable, keyCode, null);
+ }
+
+ @Override
+ public void handleAction(Object sender, Object target) {
+ focusable.focus();
+ }
+ }
+
+ private void updateValueFromDataSource() {
+ if (dataSource != null) {
+
+ // Gets the correct value from datasource
+ T newFieldValue;
+ try {
+
+ // Discards buffer by overwriting from datasource
+ newFieldValue = convertFromModel(getDataSourceValue());
+
+ // If successful, remove set the buffering state to be ok
+ if (getCurrentBufferedSourceException() != null) {
+ setCurrentBufferedSourceException(null);
+ }
+ } catch (final Throwable e) {
+ // FIXME: What should really be done here if conversion fails?
+
+ // Sets the buffering state
+ currentBufferedSourceException = new Buffered.SourceException(
+ this, e);
+ markAsDirty();
+
+ // Throws the source exception
+ throw currentBufferedSourceException;
+ }
+
+ final boolean wasModified = isModified();
+ setModified(false);
+
+ // If the new value differs from the previous one
+ if (!SharedUtil.equals(newFieldValue, getInternalValue())) {
+ setInternalValue(newFieldValue);
+ fireValueChange(false);
+ } else if (wasModified) {
+ // If the value did not change, but the modification status did
+ markAsDirty();
+ }
+ }
+ }
+
+ /**
+ * Gets the converter used to convert the property data source value to the
+ * field value.
+ *
+ * @return The converter or null if none is set.
+ */
+ public Converter getConverter() {
+ return converter;
+ }
+
+ /**
+ * Sets the converter used to convert the field value to property data
+ * source type. The converter must have a presentation type that matches the
+ * field type.
+ *
+ * @param converter
+ * The new converter to use.
+ */
+ public void setConverter(Converter converter) {
+ this.converter = (Converter) converter;
+ markAsDirty();
+ }
+
+ @Override
+ protected AbstractFieldState getState() {
+ return (AbstractFieldState) super.getState();
+ }
+
+ @Override
+ protected AbstractFieldState getState(boolean markAsDirty) {
+ return (AbstractFieldState) super.getState(markAsDirty);
+ }
+
+ @Override
+ public void beforeClientResponse(boolean initial) {
+ super.beforeClientResponse(initial);
+
+ // Hide the error indicator if needed
+ getState().hideErrors = shouldHideErrors();
+ }
+
+ /**
+ * Registers this as an event listener for events sent by the data source
+ * (if any). Does nothing if
+ * isListeningToPropertyEvents == true.
+ */
+ private void addPropertyListeners() {
+ if (!isListeningToPropertyEvents) {
+ if (dataSource instanceof Property.ValueChangeNotifier) {
+ ((Property.ValueChangeNotifier) dataSource).addListener(this);
+ }
+ if (dataSource instanceof Property.ReadOnlyStatusChangeNotifier) {
+ ((Property.ReadOnlyStatusChangeNotifier) dataSource)
+ .addListener(this);
+ }
+ isListeningToPropertyEvents = true;
+ }
+ }
+
+ /**
+ * Stops listening to events sent by the data source (if any). Does nothing
+ * if isListeningToPropertyEvents == false.
+ */
+ private void removePropertyListeners() {
+ if (isListeningToPropertyEvents) {
+ if (dataSource instanceof Property.ValueChangeNotifier) {
+ ((Property.ValueChangeNotifier) dataSource)
+ .removeListener(this);
+ }
+ if (dataSource instanceof Property.ReadOnlyStatusChangeNotifier) {
+ ((Property.ReadOnlyStatusChangeNotifier) dataSource)
+ .removeListener(this);
+ }
+ isListeningToPropertyEvents = false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Fields are automatically set to immediate if validators have been added.
+ */
+ @Override
+ public boolean isImmediate() {
+ if (getExplicitImmediateValue() != null) {
+ return getExplicitImmediateValue();
+ }
+ // Make field immediate when there is some kind of validation present
+ // (validator or required). This will avoid the UI being in a wrong
+ // state, e.g. user entered valid data but old validation error is still
+ // shown
+ return super.isImmediate() || !getValidators().isEmpty()
+ || isRequired();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractComponent#readDesign(org.jsoup.nodes .Element,
+ * com.vaadin.ui.declarative.DesignContext)
+ */
+ @Override
+ public void readDesign(Element design, DesignContext designContext) {
+ super.readDesign(design, designContext);
+ Attributes attr = design.attributes();
+ if (design.hasAttr("readonly")) {
+ setReadOnly(DesignAttributeHandler.readAttribute("readonly", attr,
+ Boolean.class));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractComponent#getCustomAttributes()
+ */
+ @Override
+ protected Collection getCustomAttributes() {
+ Collection attributes = super.getCustomAttributes();
+ attributes.add("readonly");
+ // must be handled by subclasses
+ attributes.add("value");
+ attributes.add("converted-value");
+ return attributes;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractComponent#writeDesign(org.jsoup.nodes.Element
+ * , com.vaadin.ui.declarative.DesignContext)
+ */
+ @Override
+ public void writeDesign(Element design, DesignContext designContext) {
+ super.writeDesign(design, designContext);
+ LegacyAbstractField def = (LegacyAbstractField) designContext
+ .getDefaultInstance(this);
+ Attributes attr = design.attributes();
+ // handle readonly
+ DesignAttributeHandler.writeAttribute("readonly", attr,
+ super.isReadOnly(), def.isReadOnly(), Boolean.class);
+ }
+
+ private static final Logger getLogger() {
+ return Logger.getLogger(LegacyAbstractField.class.getName());
+ }
+}
diff --git a/server/src/main/java/com/vaadin/legacy/ui/LegacyField.java b/server/src/main/java/com/vaadin/legacy/ui/LegacyField.java
new file mode 100644
index 0000000000..a3ac84871d
--- /dev/null
+++ b/server/src/main/java/com/vaadin/legacy/ui/LegacyField.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.vaadin.legacy.ui;
+
+import com.vaadin.data.BufferedValidatable;
+import com.vaadin.data.Property;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Component.Event;
+import com.vaadin.ui.Component.Focusable;
+
+/**
+ * LegacyField interface is implemented by all classes (field components) that have a
+ * value that the user can change through the user interface.
+ *
+ * LegacyField components are built upon the framework defined in the LegacyField interface
+ * and the {@link com.vaadin.LegacyAbstractField} base class.
+ *
+ * The LegacyField interface inherits the {@link com.vaadin.ui.Component}
+ * superinterface and also the {@link com.vaadin.ui.Property} interface to have
+ * a value for the field.
+ *
+ *
+ * @author Vaadin Ltd.
+ *
+ * @param T
+ * the type of values in the field, which might not be the same type
+ * as that of the data source if converters are used
+ *
+ * @author IT Mill Ltd.
+ */
+public interface LegacyField extends Component, BufferedValidatable, Property,
+ Property.ValueChangeNotifier, Property.ValueChangeListener,
+ Property.Editor, Focusable {
+
+ /**
+ * Is this field required.
+ *
+ * Required fields must filled by the user.
+ *
+ * @return true if the field is required,otherwise
+ * false.
+ * @since 3.1
+ */
+ public boolean isRequired();
+
+ /**
+ * Sets the field required. Required fields must filled by the user.
+ *
+ * @param required
+ * Is the field required.
+ * @since 3.1
+ */
+ public void setRequired(boolean required);
+
+ /**
+ * Sets the error message to be displayed if a required field is empty.
+ *
+ * @param requiredMessage
+ * Error message.
+ * @since 5.2.6
+ */
+ public void setRequiredError(String requiredMessage);
+
+ /**
+ * Gets the error message that is to be displayed if a required field is
+ * empty.
+ *
+ * @return Error message.
+ * @since 5.2.6
+ */
+ public String getRequiredError();
+
+ /**
+ * An Event object specifying the LegacyField whose value has been
+ * changed.
+ *
+ * @author Vaadin Ltd.
+ * @since 3.0
+ */
+ @SuppressWarnings("serial")
+ public static class ValueChangeEvent extends Component.Event implements
+ Property.ValueChangeEvent {
+
+ /**
+ * Constructs a new event object with the specified source field object.
+ *
+ * @param source
+ * the field that caused the event.
+ */
+ public ValueChangeEvent(LegacyField source) {
+ super(source);
+ }
+
+ /**
+ * Gets the Property which triggered the event.
+ *
+ * @return the Source Property of the event.
+ */
+ @Override
+ public Property getProperty() {
+ return (Property) getSource();
+ }
+ }
+
+ /**
+ * Is the field empty?
+ *
+ * In general, "empty" state is same as null. As an exception, TextField
+ * also treats empty string as "empty".
+ *
+ * @since 7.4
+ * @return true if the field is empty, false otherwise
+ */
+ public boolean isEmpty();
+
+ /**
+ * Clears the value of the field.
+ *
+ * The field value is typically reset to the initial value of the field.
+ * Calling {@link #isEmpty()} on a cleared field must always returns true.
+ *
+ * @since 7.4
+ */
+ public void clear();
+
+}
diff --git a/server/src/main/java/com/vaadin/server/VaadinSession.java b/server/src/main/java/com/vaadin/server/VaadinSession.java
index 304dd4bec6..d99bd75de8 100644
--- a/server/src/main/java/com/vaadin/server/VaadinSession.java
+++ b/server/src/main/java/com/vaadin/server/VaadinSession.java
@@ -51,8 +51,8 @@ import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.ConverterFactory;
import com.vaadin.data.util.converter.DefaultConverterFactory;
import com.vaadin.event.EventRouter;
+import com.vaadin.legacy.ui.LegacyAbstractField;
import com.vaadin.shared.communication.PushMode;
-import com.vaadin.ui.AbstractField;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.util.CurrentInstance;
@@ -615,7 +615,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
*
*
* The {@link Converter} for an individual field can be overridden using
- * {@link AbstractField#setConverter(Converter)} and for individual property
+ * {@link LegacyAbstractField#setConverter(Converter)} and for individual property
* ids in a {@link Table} using
* {@link Table#setConverter(Object, Converter)}.
*
diff --git a/server/src/main/java/com/vaadin/ui/AbstractComponent.java b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
index 8fa1f523ff..24f1ef098b 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractComponent.java
@@ -39,6 +39,8 @@ import com.vaadin.event.ConnectorActionManager;
import com.vaadin.event.ContextClickEvent;
import com.vaadin.event.ContextClickEvent.ContextClickListener;
import com.vaadin.event.ContextClickEvent.ContextClickNotifier;
+import com.vaadin.legacy.ui.LegacyField;
+import com.vaadin.legacy.ui.LegacyField.ValueChangeEvent;
import com.vaadin.event.ShortcutListener;
import com.vaadin.server.AbstractClientConnector;
import com.vaadin.server.AbstractErrorMessage.ContentMode;
@@ -59,7 +61,6 @@ import com.vaadin.shared.EventId;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.ui.ComponentStateUtil;
import com.vaadin.shared.util.SharedUtil;
-import com.vaadin.ui.Field.ValueChangeEvent;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
import com.vaadin.util.ReflectTools;
@@ -1345,7 +1346,7 @@ public abstract class AbstractComponent extends AbstractClientConnector
/**
* Gets the {@link ActionManager} used to manage the
- * {@link ShortcutListener}s added to this {@link Field}.
+ * {@link ShortcutListener}s added to this {@link LegacyField}.
*
* @return the ActionManager in use
*/
diff --git a/server/src/main/java/com/vaadin/ui/AbstractField.java b/server/src/main/java/com/vaadin/ui/AbstractField.java
deleted file mode 100644
index 6d25076526..0000000000
--- a/server/src/main/java/com/vaadin/ui/AbstractField.java
+++ /dev/null
@@ -1,1852 +0,0 @@
-/*
- * Copyright 2000-2014 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.logging.Logger;
-
-import org.jsoup.nodes.Attributes;
-import org.jsoup.nodes.Element;
-
-import com.vaadin.data.Buffered;
-import com.vaadin.data.Property;
-import com.vaadin.data.Validatable;
-import com.vaadin.data.Validator;
-import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.data.util.LegacyPropertyHelper;
-import com.vaadin.data.util.converter.Converter;
-import com.vaadin.data.util.converter.Converter.ConversionException;
-import com.vaadin.data.util.converter.ConverterUtil;
-import com.vaadin.event.Action;
-import com.vaadin.event.ShortcutAction;
-import com.vaadin.event.ShortcutListener;
-import com.vaadin.server.AbstractErrorMessage;
-import com.vaadin.server.CompositeErrorMessage;
-import com.vaadin.server.ErrorMessage;
-import com.vaadin.shared.AbstractFieldState;
-import com.vaadin.shared.util.SharedUtil;
-import com.vaadin.ui.declarative.DesignAttributeHandler;
-import com.vaadin.ui.declarative.DesignContext;
-
-/**
- *
- * Abstract field component for implementing buffered property editors. The
- * field may hold an internal value, or it may be connected to any data source
- * that implements the {@link com.vaadin.data.Property}interface.
- * AbstractField implements that interface itself, too, so
- * accessing the Property value represented by it is straightforward.
- *
- *
- *
- * AbstractField also provides the {@link com.vaadin.data.Buffered} interface
- * for buffering the data source value. By default the Field is in write
- * through-mode and {@link #setWriteThrough(boolean)}should be called to enable
- * buffering.
- *
- *
- *
- * The class also supports {@link com.vaadin.data.Validator validators} to make
- * sure the value contained in the field is valid.
- *
- *
- * @author Vaadin Ltd.
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public abstract class AbstractField extends AbstractComponent implements
- Field, Property.ReadOnlyStatusChangeListener,
- Property.ReadOnlyStatusChangeNotifier, Action.ShortcutNotifier {
-
- /* Private members */
-
- /**
- * Value of the abstract field.
- */
- private T value;
-
- /**
- * A converter used to convert from the data model type to the field type
- * and vice versa.
- */
- private Converter converter = null;
- /**
- * Connected data-source.
- */
- private Property> dataSource = null;
-
- /**
- * The list of validators.
- */
- private LinkedList validators = null;
-
- /**
- * True if field is in buffered mode, false otherwise
- */
- private boolean buffered;
-
- /**
- * Flag to indicate that the field is currently committing its value to the
- * datasource.
- */
- private boolean committingValueToDataSource = false;
-
- /**
- * Current source exception.
- */
- private Buffered.SourceException currentBufferedSourceException = null;
-
- /**
- * Are the invalid values allowed in fields ?
- */
- private boolean invalidAllowed = true;
-
- /**
- * Are the invalid values committed ?
- */
- private boolean invalidCommitted = false;
-
- /**
- * The error message for the exception that is thrown when the field is
- * required but empty.
- */
- private String requiredError = "";
-
- /**
- * The error message that is shown when the field value cannot be converted.
- */
- private String conversionError = "Could not convert value to {0}";
-
- /**
- * Is automatic validation enabled.
- */
- private boolean validationVisible = true;
-
- private boolean valueWasModifiedByDataSourceDuringCommit;
-
- /**
- * Whether this field is currently registered as listening to events from
- * its data source.
- *
- * @see #setPropertyDataSource(Property)
- * @see #addPropertyListeners()
- * @see #removePropertyListeners()
- */
- private boolean isListeningToPropertyEvents = false;
-
- /**
- * The locale used when setting the value.
- */
- private Locale valueLocale = null;
-
- /* Component basics */
-
- /*
- * Paints the field. Don't add a JavaDoc comment here, we use the default
- * documentation from the implemented interface.
- */
-
- /**
- * Returns true if the error indicator be hidden when painting the component
- * even when there are errors.
- *
- * This is a mostly internal method, but can be overridden in subclasses
- * e.g. if the error indicator should also be shown for empty fields in some
- * cases.
- *
- * @return true to hide the error indicator, false to use the normal logic
- * to show it when there are errors
- */
- protected boolean shouldHideErrors() {
- // getErrorMessage() can still return something else than null based on
- // validation etc.
- return isRequired() && isEmpty() && getComponentError() == null;
- }
-
- /**
- * Returns the type of the Field. The methods getValue and
- * setValue must be compatible with this type: one must be able
- * to safely cast the value returned from getValue to the given
- * type and pass any variable assignable to this type as an argument to
- * setValue.
- *
- * @return the type of the Field
- */
- @Override
- public abstract Class extends T> getType();
-
- /**
- * The abstract field is read only also if the data source is in read only
- * mode.
- */
- @Override
- public boolean isReadOnly() {
- return super.isReadOnly()
- || (dataSource != null && dataSource.isReadOnly());
- }
-
- /**
- * Changes the readonly state and throw read-only status change events.
- *
- * @see com.vaadin.ui.Component#setReadOnly(boolean)
- */
- @Override
- public void setReadOnly(boolean readOnly) {
- super.setReadOnly(readOnly);
- fireReadOnlyStatusChange();
- }
-
- /**
- * Tests if the invalid data is committed to datasource.
- *
- * @see com.vaadin.data.BufferedValidatable#isInvalidCommitted()
- */
- @Override
- public boolean isInvalidCommitted() {
- return invalidCommitted;
- }
-
- /**
- * Sets if the invalid data should be committed to datasource.
- *
- * @see com.vaadin.data.BufferedValidatable#setInvalidCommitted(boolean)
- */
- @Override
- public void setInvalidCommitted(boolean isCommitted) {
- invalidCommitted = isCommitted;
- }
-
- /*
- * Saves the current value to the data source Don't add a JavaDoc comment
- * here, we use the default documentation from the implemented interface.
- */
- @Override
- public void commit() throws Buffered.SourceException, InvalidValueException {
- if (dataSource != null && !dataSource.isReadOnly()) {
- if ((isInvalidCommitted() || isValid())) {
- try {
-
- // Commits the value to datasource.
- valueWasModifiedByDataSourceDuringCommit = false;
- committingValueToDataSource = true;
- getPropertyDataSource().setValue(getConvertedValue());
- } catch (final Throwable e) {
-
- // Sets the buffering state.
- SourceException sourceException = new Buffered.SourceException(
- this, e);
- setCurrentBufferedSourceException(sourceException);
-
- // Throws the source exception.
- throw sourceException;
- } finally {
- committingValueToDataSource = false;
- }
- } else {
- /*
- * An invalid value and we don't allow them, throw the exception
- */
- validate();
- }
- }
-
- // The abstract field is not modified anymore
- if (isModified()) {
- setModified(false);
- }
-
- // If successful, remove set the buffering state to be ok
- if (getCurrentBufferedSourceException() != null) {
- setCurrentBufferedSourceException(null);
- }
-
- if (valueWasModifiedByDataSourceDuringCommit) {
- valueWasModifiedByDataSourceDuringCommit = false;
- fireValueChange(false);
- }
-
- }
-
- /*
- * Updates the value from the data source. Don't add a JavaDoc comment here,
- * we use the default documentation from the implemented interface.
- */
- @Override
- public void discard() throws Buffered.SourceException {
- updateValueFromDataSource();
- }
-
- /**
- * Gets the value from the data source. This is only here because of clarity
- * in the code that handles both the data model value and the field value.
- *
- * @return The value of the property data source
- */
- private Object getDataSourceValue() {
- return dataSource.getValue();
- }
-
- /**
- * Returns the field value. This is always identical to {@link #getValue()}
- * and only here because of clarity in the code that handles both the data
- * model value and the field value.
- *
- * @return The value of the field
- */
- private T getFieldValue() {
- // Give the value from abstract buffers if the field if possible
- if (dataSource == null || isBuffered() || isModified()) {
- return getInternalValue();
- }
-
- // There is no buffered value so use whatever the data model provides
- return convertFromModel(getDataSourceValue());
- }
-
- /*
- * Has the field been modified since the last commit()? Don't add a JavaDoc
- * comment here, we use the default documentation from the implemented
- * interface.
- */
- @Override
- public boolean isModified() {
- return getState(false).modified;
- }
-
- private void setModified(boolean modified) {
- getState().modified = modified;
- }
-
- /**
- * Sets the buffered mode of this Field.
- *
- * When the field is in buffered mode, changes will not be committed to the
- * property data source until {@link #commit()} is called.
- *
- *
- * Setting buffered mode from true to false will commit any pending changes.
- *
- *
- *
- *
- *
- * @since 7.0.0
- * @param buffered
- * true if buffered mode should be turned on, false otherwise
- */
- @Override
- public void setBuffered(boolean buffered) {
- if (this.buffered == buffered) {
- return;
- }
- this.buffered = buffered;
- if (!buffered) {
- commit();
- }
- }
-
- /**
- * Checks the buffered mode of this Field.
- *
- * @return true if buffered mode is on, false otherwise
- */
- @Override
- public boolean isBuffered() {
- return buffered;
- }
-
- /**
- * Returns a string representation of this object. The returned string
- * representation depends on if the legacy Property toString mode is enabled
- * or disabled.
- *
- * If legacy Property toString mode is enabled, returns the value of this
- * Field converted to a String.
- *
- *
- * If legacy Property toString mode is disabled, the string representation
- * has no special meaning
- *
- *
- * @see LegacyPropertyHelper#isLegacyToStringEnabled()
- *
- * @return A string representation of the value value stored in the Property
- * or a string representation of the Property object.
- * @deprecated As of 7.0. Use {@link #getValue()} to get the value of the
- * field, {@link #getConvertedValue()} to get the field value
- * converted to the data model type or
- * {@link #getPropertyDataSource()} .getValue() to get the value
- * of the data source.
- */
- @Deprecated
- @Override
- public String toString() {
- if (!LegacyPropertyHelper.isLegacyToStringEnabled()) {
- return super.toString();
- } else {
- return LegacyPropertyHelper.legacyPropertyToString(this);
- }
- }
-
- /* Property interface implementation */
-
- /**
- * Gets the current value of the field.
- *
- *
- * This is the visible, modified and possible invalid value the user have
- * entered to the field.
- *
- *
- *
- * Note that the object returned is compatible with getType(). For example,
- * if the type is String, this returns Strings even when the underlying
- * datasource is of some other type. In order to access the converted value,
- * use {@link #getConvertedValue()} and to access the value of the property
- * data source, use {@link Property#getValue()} for the property data
- * source.
- *
- *
- *
- * Since Vaadin 7.0, no implicit conversions between other data types and
- * String are performed, but a converter is used if set.
- *
- *
- * @return the current value of the field.
- */
- @Override
- public T getValue() {
- return getFieldValue();
- }
-
- /**
- * Sets the value of the field.
- *
- * @param newFieldValue
- * the New value of the field.
- * @throws Property.ReadOnlyException
- */
- @Override
- public void setValue(T newFieldValue) throws Property.ReadOnlyException,
- Converter.ConversionException {
- setValue(newFieldValue, false);
- }
-
- /**
- * Sets the value of the field.
- *
- * @param newFieldValue
- * the New value of the field.
- * @param repaintIsNotNeeded
- * True iff caller is sure that repaint is not needed.
- * @throws Property.ReadOnlyException
- * @throws Converter.ConversionException
- * @throws InvalidValueException
- */
- protected void setValue(T newFieldValue, boolean repaintIsNotNeeded) {
- setValue(newFieldValue, repaintIsNotNeeded, false);
- }
-
- /**
- * Sets the value of the field.
- *
- * @since 7.5.7
- * @param newFieldValue
- * the New value of the field.
- * @param repaintIsNotNeeded
- * True iff caller is sure that repaint is not needed.
- * @param ignoreReadOnly
- * True iff if the read-only check should be ignored
- * @throws Property.ReadOnlyException
- * @throws Converter.ConversionException
- * @throws InvalidValueException
- */
- protected void setValue(T newFieldValue, boolean repaintIsNotNeeded,
- boolean ignoreReadOnly) throws Property.ReadOnlyException,
- Converter.ConversionException, InvalidValueException {
-
- if (!SharedUtil.equals(newFieldValue, getInternalValue())) {
-
- // Read only fields can not be changed
- if (!ignoreReadOnly && isReadOnly()) {
- throw new Property.ReadOnlyException();
- }
- try {
- T doubleConvertedFieldValue = convertFromModel(convertToModel(newFieldValue));
- if (!SharedUtil
- .equals(newFieldValue, doubleConvertedFieldValue)) {
- newFieldValue = doubleConvertedFieldValue;
- repaintIsNotNeeded = false;
- }
- } catch (Throwable t) {
- // Ignore exceptions in the conversion at this stage. Any
- // conversion error will be handled later by validate().
- }
-
- // Repaint is needed even when the client thinks that it knows the
- // new state if validity of the component may change
- if (repaintIsNotNeeded
- && (isRequired() || hasValidators() || getConverter() != null)) {
- repaintIsNotNeeded = false;
- }
-
- if (!isInvalidAllowed()) {
- /*
- * If invalid values are not allowed the value must be validated
- * before it is set. If validation fails, the
- * InvalidValueException is thrown and the internal value is not
- * updated.
- */
- validate(newFieldValue);
- }
-
- // Changes the value
- setInternalValue(newFieldValue);
- setModified(dataSource != null);
-
- valueWasModifiedByDataSourceDuringCommit = false;
- // In not buffering, try to commit
- if (!isBuffered() && dataSource != null
- && (isInvalidCommitted() || isValid())) {
- try {
-
- // Commits the value to datasource
- committingValueToDataSource = true;
- getPropertyDataSource().setValue(
- convertToModel(newFieldValue));
-
- // The buffer is now unmodified
- setModified(false);
-
- } catch (final Throwable e) {
-
- // Sets the buffering state
- currentBufferedSourceException = new Buffered.SourceException(
- this, e);
- markAsDirty();
-
- // Throws the source exception
- throw currentBufferedSourceException;
- } finally {
- committingValueToDataSource = false;
- }
- }
-
- // If successful, remove set the buffering state to be ok
- if (getCurrentBufferedSourceException() != null) {
- setCurrentBufferedSourceException(null);
- }
-
- if (valueWasModifiedByDataSourceDuringCommit) {
- /*
- * Value was modified by datasource. Force repaint even if
- * repaint was not requested.
- */
- valueWasModifiedByDataSourceDuringCommit = repaintIsNotNeeded = false;
- }
-
- // Fires the value change
- fireValueChange(repaintIsNotNeeded);
-
- }
- }
-
- @Deprecated
- static boolean equals(Object value1, Object value2) {
- return SharedUtil.equals(value1, value2);
- }
-
- /* External data source */
-
- /**
- * Gets the current data source of the field, if any.
- *
- * @return the current data source as a Property, or null if
- * none defined.
- */
- @Override
- public Property getPropertyDataSource() {
- return dataSource;
- }
-
- /**
- *
- * Sets the specified Property as the data source for the field. All
- * uncommitted changes are replaced with a value from the new data source.
- *
- *
- *
- * If the datasource has any validators, the same validators are added to
- * the field. Because the default behavior of the field is to allow invalid
- * values, but not to allow committing them, this only adds visual error
- * messages to fields and do not allow committing them as long as the value
- * is invalid. After the value is valid, the error message is not shown and
- * the commit can be done normally.
- *
- *
- *
- * If the data source implements
- * {@link com.vaadin.data.Property.ValueChangeNotifier} and/or
- * {@link com.vaadin.data.Property.ReadOnlyStatusChangeNotifier}, the field
- * registers itself as a listener and updates itself according to the events
- * it receives. To avoid memory leaks caused by references to a field no
- * longer in use, the listener registrations are removed on
- * {@link AbstractField#detach() detach} and re-added on
- * {@link AbstractField#attach() attach}.
- *
- *
- *
- * Note: before 6.5 we actually called discard() method in the beginning of
- * the method. This was removed to simplify implementation, avoid excess
- * calls to backing property and to avoid odd value change events that were
- * previously fired (developer expects 0-1 value change events if this
- * method is called). Some complex field implementations might now need to
- * override this method to do housekeeping similar to discard().
- *
- *
- * @param newDataSource
- * the new data source Property.
- */
- @Override
- public void setPropertyDataSource(Property newDataSource) {
-
- // Saves the old value
- final Object oldValue = getInternalValue();
-
- // Stop listening to the old data source
- removePropertyListeners();
-
- // Sets the new data source
- dataSource = newDataSource;
- getState().propertyReadOnly = dataSource == null ? false : dataSource
- .isReadOnly();
-
- // Check if the current converter is compatible.
- if (newDataSource != null
- && !ConverterUtil.canConverterPossiblyHandle(getConverter(),
- getType(), newDataSource.getType())) {
- // There is no converter set or there is no way the current
- // converter can be compatible.
- setConverter(newDataSource.getType());
- }
- // Gets the value from source. This requires that a valid converter has
- // been set.
- try {
- if (dataSource != null) {
- T fieldValue = convertFromModel(getDataSourceValue());
- setInternalValue(fieldValue);
- }
- setModified(false);
- if (getCurrentBufferedSourceException() != null) {
- setCurrentBufferedSourceException(null);
- }
- } catch (final Throwable e) {
- setCurrentBufferedSourceException(new Buffered.SourceException(
- this, e));
- setModified(true);
- throw getCurrentBufferedSourceException();
- }
-
- // Listen to new data source if possible
- addPropertyListeners();
-
- // Copy the validators from the data source
- if (dataSource instanceof Validatable) {
- final Collection validators = ((Validatable) dataSource)
- .getValidators();
- if (validators != null) {
- for (final Iterator i = validators.iterator(); i
- .hasNext();) {
- addValidator(i.next());
- }
- }
- }
-
- // Fires value change if the value has changed
- T value = getInternalValue();
- if ((value != oldValue)
- && ((value != null && !value.equals(oldValue)) || value == null)) {
- fireValueChange(false);
- }
- }
-
- /**
- * Retrieves a converter for the field from the converter factory defined
- * for the application. Clears the converter if no application reference is
- * available or if the factory returns null.
- *
- * @param datamodelType
- * The type of the data model that we want to be able to convert
- * from
- */
- public void setConverter(Class> datamodelType) {
- Converter c = (Converter) ConverterUtil.getConverter(
- getType(), datamodelType, getSession());
- setConverter(c);
- }
-
- /**
- * Convert the given value from the data source type to the UI type.
- *
- * @param newValue
- * The data source value to convert.
- * @return The converted value that is compatible with the UI type or the
- * original value if its type is compatible and no converter is set.
- * @throws Converter.ConversionException
- * if there is no converter and the type is not compatible with
- * the data source type.
- */
- private T convertFromModel(Object newValue) {
- return convertFromModel(newValue, getLocale());
- }
-
- /**
- * Convert the given value from the data source type to the UI type.
- *
- * @param newValue
- * The data source value to convert.
- * @return The converted value that is compatible with the UI type or the
- * original value if its type is compatible and no converter is set.
- * @throws Converter.ConversionException
- * if there is no converter and the type is not compatible with
- * the data source type.
- */
- private T convertFromModel(Object newValue, Locale locale) {
- return ConverterUtil.convertFromModel(newValue, getType(),
- getConverter(), locale);
- }
-
- /**
- * Convert the given value from the UI type to the data source type.
- *
- * @param fieldValue
- * The value to convert. Typically returned by
- * {@link #getFieldValue()}
- * @return The converted value that is compatible with the data source type.
- * @throws Converter.ConversionException
- * if there is no converter and the type is not compatible with
- * the data source type.
- */
- private Object convertToModel(T fieldValue)
- throws Converter.ConversionException {
- return convertToModel(fieldValue, getLocale());
- }
-
- /**
- * Convert the given value from the UI type to the data source type.
- *
- * @param fieldValue
- * The value to convert. Typically returned by
- * {@link #getFieldValue()}
- * @param locale
- * The locale to use for the conversion
- * @return The converted value that is compatible with the data source type.
- * @throws Converter.ConversionException
- * if there is no converter and the type is not compatible with
- * the data source type.
- */
- private Object convertToModel(T fieldValue, Locale locale)
- throws Converter.ConversionException {
- Class> modelType = getModelType();
- try {
- return ConverterUtil.convertToModel(fieldValue,
- (Class) modelType, getConverter(), locale);
- } catch (ConversionException e) {
- throw new ConversionException(getConversionError(modelType, e), e);
- }
- }
-
- /**
- * Retrieves the type of the currently used data model. If the field has no
- * data source then the model type of the converter is used.
- *
- * @since 7.1
- * @return The type of the currently used data model or null if no data
- * source or converter is set.
- */
- protected Class> getModelType() {
- Property> pd = getPropertyDataSource();
- if (pd != null) {
- return pd.getType();
- } else if (getConverter() != null) {
- return getConverter().getModelType();
- }
- return null;
- }
-
- /**
- * Returns the conversion error with {0} replaced by the data source type
- * and {1} replaced by the exception (localized) message.
- *
- * @since 7.1
- * @param dataSourceType
- * the type of the data source
- * @param e
- * a conversion exception which can provide additional
- * information
- * @return The value conversion error string with parameters replaced.
- */
- protected String getConversionError(Class> dataSourceType,
- ConversionException e) {
- String conversionError = getConversionError();
-
- if (conversionError != null) {
- if (dataSourceType != null) {
- conversionError = conversionError.replace("{0}",
- dataSourceType.getSimpleName());
- }
- if (e != null) {
- conversionError = conversionError.replace("{1}",
- e.getLocalizedMessage());
- }
- }
- return conversionError;
- }
-
- /**
- * Returns the current value (as returned by {@link #getValue()}) converted
- * to the data source type.
- *
- * This returns the same as {@link AbstractField#getValue()} if no converter
- * has been set. The value is not necessarily the same as the data source
- * value e.g. if the field is in buffered mode and has been modified.
- *
- *
- * @return The converted value that is compatible with the data source type
- */
- public Object getConvertedValue() {
- return convertToModel(getFieldValue());
- }
-
- /**
- * Sets the value of the field using a value of the data source type. The
- * value given is converted to the field type and then assigned to the
- * field. This will update the property data source in the same way as when
- * {@link #setValue(Object)} is called.
- *
- * @param value
- * The value to set. Must be the same type as the data source.
- */
- public void setConvertedValue(Object value) {
- setValue(convertFromModel(value));
- }
-
- /* Validation */
-
- /**
- * Adds a new validator for the field's value. All validators added to a
- * field are checked each time the its value changes.
- *
- * @param validator
- * the new validator to be added.
- */
- @Override
- public void addValidator(Validator validator) {
- if (validators == null) {
- validators = new LinkedList();
- }
- validators.add(validator);
- markAsDirty();
- }
-
- /**
- * Gets the validators of the field.
- *
- * @return An unmodifiable collection that holds all validators for the
- * field.
- */
- @Override
- public Collection getValidators() {
- if (validators == null) {
- return Collections.emptyList();
- } else {
- return Collections.unmodifiableCollection(validators);
- }
- }
-
- private boolean hasValidators() {
- return validators != null && !validators.isEmpty();
- }
-
- /**
- * Removes the validator from the field.
- *
- * @param validator
- * the validator to remove.
- */
- @Override
- public void removeValidator(Validator validator) {
- if (validators != null) {
- validators.remove(validator);
- }
- markAsDirty();
- }
-
- /**
- * Removes all validators from the field.
- */
- @Override
- public void removeAllValidators() {
- if (validators != null) {
- validators.clear();
- }
- markAsDirty();
- }
-
- /**
- * Tests the current value against registered validators if the field is not
- * empty. If the field is empty it is considered valid if it is not required
- * and invalid otherwise. Validators are never checked for empty fields.
- *
- * In most cases, {@link #validate()} should be used instead of
- * {@link #isValid()} to also get the error message.
- *
- * @return true if all registered validators claim that the
- * current value is valid or if the field is empty and not required,
- * false otherwise.
- */
- @Override
- public boolean isValid() {
-
- try {
- validate();
- return true;
- } catch (InvalidValueException e) {
- return false;
- }
- }
-
- /**
- * Checks the validity of the Field.
- *
- * A field is invalid if it is set as required (using
- * {@link #setRequired(boolean)} and is empty, if one or several of the
- * validators added to the field indicate it is invalid or if the value
- * cannot be converted provided a converter has been set.
- *
- * The "required" validation is a built-in validation feature. If the field
- * is required and empty this method throws an EmptyValueException with the
- * error message set using {@link #setRequiredError(String)}.
- *
- * @see com.vaadin.data.Validatable#validate()
- */
- @Override
- public void validate() throws Validator.InvalidValueException {
-
- if (isRequired() && isEmpty()) {
- throw new Validator.EmptyValueException(requiredError);
- }
- validate(getFieldValue());
- }
-
- /**
- * Validates that the given value pass the validators for the field.
- *
- * This method does not check the requiredness of the field.
- *
- * @param fieldValue
- * The value to check
- * @throws Validator.InvalidValueException
- * if one or several validators fail
- */
- protected void validate(T fieldValue)
- throws Validator.InvalidValueException {
-
- Object valueToValidate = fieldValue;
-
- // If there is a converter we start by converting the value as we want
- // to validate the converted value
- if (getConverter() != null) {
- try {
- valueToValidate = getConverter().convertToModel(fieldValue,
- getModelType(), getLocale());
- } catch (ConversionException e) {
- throw new InvalidValueException(getConversionError(
- getConverter().getModelType(), e));
- }
- }
-
- List validationExceptions = new ArrayList();
- if (validators != null) {
- // Gets all the validation errors
- for (Validator v : validators) {
- try {
- v.validate(valueToValidate);
- } catch (final Validator.InvalidValueException e) {
- validationExceptions.add(e);
- }
- }
- }
-
- // If there were no errors
- if (validationExceptions.isEmpty()) {
- return;
- }
-
- // If only one error occurred, throw it forwards
- if (validationExceptions.size() == 1) {
- throw validationExceptions.get(0);
- }
-
- InvalidValueException[] exceptionArray = validationExceptions
- .toArray(new InvalidValueException[validationExceptions.size()]);
-
- // Create a composite validator and include all exceptions
- throw new Validator.InvalidValueException(null, exceptionArray);
- }
-
- /**
- * Fields allow invalid values by default. In most cases this is wanted,
- * because the field otherwise visually forget the user input immediately.
- *
- * @return true iff the invalid values are allowed.
- * @see com.vaadin.data.Validatable#isInvalidAllowed()
- */
- @Override
- public boolean isInvalidAllowed() {
- return invalidAllowed;
- }
-
- /**
- * Fields allow invalid values by default. In most cases this is wanted,
- * because the field otherwise visually forget the user input immediately.
- *
- * In common setting where the user wants to assure the correctness of the
- * datasource, but allow temporarily invalid contents in the field, the user
- * should add the validators to datasource, that should not allow invalid
- * values. The validators are automatically copied to the field when the
- * datasource is set.
- *
- *
- * @see com.vaadin.data.Validatable#setInvalidAllowed(boolean)
- */
- @Override
- public void setInvalidAllowed(boolean invalidAllowed)
- throws UnsupportedOperationException {
- this.invalidAllowed = invalidAllowed;
- }
-
- /**
- * Error messages shown by the fields are composites of the error message
- * thrown by the superclasses (that is the component error message),
- * validation errors and buffered source errors.
- *
- * @see com.vaadin.ui.AbstractComponent#getErrorMessage()
- */
- @Override
- public ErrorMessage getErrorMessage() {
-
- /*
- * Check validation errors only if automatic validation is enabled.
- * Empty, required fields will generate a validation error containing
- * the requiredError string. For these fields the exclamation mark will
- * be hidden but the error must still be sent to the client.
- */
- Validator.InvalidValueException validationError = null;
- if (isValidationVisible()) {
- try {
- validate();
- } catch (Validator.InvalidValueException e) {
- if (!e.isInvisible()) {
- validationError = e;
- }
- }
- }
-
- // Check if there are any systems errors
- final ErrorMessage superError = super.getErrorMessage();
-
- // Return if there are no errors at all
- if (superError == null && validationError == null
- && getCurrentBufferedSourceException() == null) {
- return null;
- }
-
- // Throw combination of the error types
- return new CompositeErrorMessage(
- new ErrorMessage[] {
- superError,
- AbstractErrorMessage
- .getErrorMessageForException(validationError),
- AbstractErrorMessage
- .getErrorMessageForException(getCurrentBufferedSourceException()) });
-
- }
-
- /* Value change events */
-
- private static final Method VALUE_CHANGE_METHOD;
-
- static {
- try {
- VALUE_CHANGE_METHOD = Property.ValueChangeListener.class
- .getDeclaredMethod("valueChange",
- new Class[] { Property.ValueChangeEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in AbstractField");
- }
- }
-
- /*
- * Adds a value change listener for the field. Don't add a JavaDoc comment
- * here, we use the default documentation from the implemented interface.
- */
- @Override
- public void addValueChangeListener(Property.ValueChangeListener listener) {
- addListener(AbstractField.ValueChangeEvent.class, listener,
- VALUE_CHANGE_METHOD);
- // ensure "automatic immediate handling" works
- markAsDirty();
- }
-
- /**
- * @deprecated As of 7.0, replaced by
- * {@link #addValueChangeListener(com.vaadin.data.Property.ValueChangeListener)}
- **/
- @Override
- @Deprecated
- public void addListener(Property.ValueChangeListener listener) {
- addValueChangeListener(listener);
- }
-
- /*
- * Removes a value change listener from the field. Don't add a JavaDoc
- * comment here, we use the default documentation from the implemented
- * interface.
- */
- @Override
- public void removeValueChangeListener(Property.ValueChangeListener listener) {
- removeListener(AbstractField.ValueChangeEvent.class, listener,
- VALUE_CHANGE_METHOD);
- // ensure "automatic immediate handling" works
- markAsDirty();
- }
-
- /**
- * @deprecated As of 7.0, replaced by
- * {@link #removeValueChangeListener(com.vaadin.data.Property.ValueChangeListener)}
- **/
- @Override
- @Deprecated
- public void removeListener(Property.ValueChangeListener listener) {
- removeValueChangeListener(listener);
- }
-
- /**
- * Emits the value change event. The value contained in the field is
- * validated before the event is created.
- */
- protected void fireValueChange(boolean repaintIsNotNeeded) {
- fireEvent(new AbstractField.ValueChangeEvent(this));
- if (!repaintIsNotNeeded) {
- markAsDirty();
- }
- }
-
- /* Read-only status change events */
-
- private static final Method READ_ONLY_STATUS_CHANGE_METHOD;
-
- static {
- try {
- READ_ONLY_STATUS_CHANGE_METHOD = Property.ReadOnlyStatusChangeListener.class
- .getDeclaredMethod(
- "readOnlyStatusChange",
- new Class[] { Property.ReadOnlyStatusChangeEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in AbstractField");
- }
- }
-
- /**
- * React to read only status changes of the property by requesting a
- * repaint.
- *
- * @see Property.ReadOnlyStatusChangeListener
- */
- @Override
- public void readOnlyStatusChange(Property.ReadOnlyStatusChangeEvent event) {
- boolean readOnly = event.getProperty().isReadOnly();
-
- boolean shouldFireChange = isReadOnly() != readOnly
- || getState().propertyReadOnly != readOnly;
-
- getState().propertyReadOnly = readOnly;
-
- if (shouldFireChange) {
- fireReadOnlyStatusChange();
- }
- }
-
- /**
- * An Event object specifying the Property whose read-only
- * status has changed.
- *
- * @author Vaadin Ltd.
- * @since 3.0
- */
- public static class ReadOnlyStatusChangeEvent extends Component.Event
- implements Property.ReadOnlyStatusChangeEvent, Serializable {
-
- /**
- * New instance of text change event.
- *
- * @param source
- * the Source of the event.
- */
- public ReadOnlyStatusChangeEvent(AbstractField source) {
- super(source);
- }
-
- /**
- * Property where the event occurred.
- *
- * @return the Source of the event.
- */
- @Override
- public Property getProperty() {
- return (Property) getSource();
- }
- }
-
- /*
- * Adds a read-only status change listener for the field. Don't add a
- * JavaDoc comment here, we use the default documentation from the
- * implemented interface.
- */
- @Override
- public void addReadOnlyStatusChangeListener(
- Property.ReadOnlyStatusChangeListener listener) {
- addListener(Property.ReadOnlyStatusChangeEvent.class, listener,
- READ_ONLY_STATUS_CHANGE_METHOD);
- }
-
- /**
- * @deprecated As of 7.0, replaced by
- * {@link #addReadOnlyStatusChangeListener(com.vaadin.data.Property.ReadOnlyStatusChangeListener)}
- **/
- @Override
- @Deprecated
- public void addListener(Property.ReadOnlyStatusChangeListener listener) {
- addReadOnlyStatusChangeListener(listener);
- }
-
- /*
- * Removes a read-only status change listener from the field. Don't add a
- * JavaDoc comment here, we use the default documentation from the
- * implemented interface.
- */
- @Override
- public void removeReadOnlyStatusChangeListener(
- Property.ReadOnlyStatusChangeListener listener) {
- removeListener(Property.ReadOnlyStatusChangeEvent.class, listener,
- READ_ONLY_STATUS_CHANGE_METHOD);
- }
-
- /**
- * @deprecated As of 7.0, replaced by
- * {@link #removeReadOnlyStatusChangeListener(com.vaadin.data.Property.ReadOnlyStatusChangeListener)}
- **/
- @Override
- @Deprecated
- public void removeListener(Property.ReadOnlyStatusChangeListener listener) {
- removeReadOnlyStatusChangeListener(listener);
- }
-
- /**
- * Emits the read-only status change event. The value contained in the field
- * is validated before the event is created.
- */
- protected void fireReadOnlyStatusChange() {
- fireEvent(new AbstractField.ReadOnlyStatusChangeEvent(this));
- }
-
- /**
- * This method listens to data source value changes and passes the changes
- * forwards.
- *
- * Changes are not forwarded to the listeners of the field during internal
- * operations of the field to avoid duplicate notifications.
- *
- * @param event
- * the value change event telling the data source contents have
- * changed.
- */
- @Override
- public void valueChange(Property.ValueChangeEvent event) {
- if (!isBuffered()) {
- if (committingValueToDataSource) {
- boolean propertyNotifiesOfTheBufferedValue = SharedUtil.equals(
- event.getProperty().getValue(), getInternalValue());
- if (!propertyNotifiesOfTheBufferedValue) {
- /*
- * Property (or chained property like PropertyFormatter) now
- * reports different value than the one the field has just
- * committed to it. In this case we respect the property
- * value.
- *
- * Still, we don't fire value change yet, but instead
- * postpone it until "commit" is done. See setValue(Object,
- * boolean) and commit().
- */
- readValueFromProperty(event);
- valueWasModifiedByDataSourceDuringCommit = true;
- }
- } else if (!isModified()) {
- readValueFromProperty(event);
- fireValueChange(false);
- }
- }
- }
-
- private void readValueFromProperty(Property.ValueChangeEvent event) {
- setInternalValue(convertFromModel(event.getProperty().getValue()));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void focus() {
- super.focus();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component.Focusable#getTabIndex()
- */
- @Override
- public int getTabIndex() {
- return getState(false).tabIndex;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component.Focusable#setTabIndex(int)
- */
- @Override
- public void setTabIndex(int tabIndex) {
- getState().tabIndex = tabIndex;
- }
-
- /**
- * Returns the internal field value, which might not match the data source
- * value e.g. if the field has been modified and is not in write-through
- * mode.
- *
- * This method can be overridden by subclasses together with
- * {@link #setInternalValue(Object)} to compute internal field value at
- * runtime. When doing so, typically also {@link #isModified()} needs to be
- * overridden and care should be taken in the management of the empty state
- * and buffering support.
- *
- * @return internal field value
- */
- protected T getInternalValue() {
- return value;
- }
-
- /**
- * Sets the internal field value. This is purely used by AbstractField to
- * change the internal Field value. It does not trigger valuechange events.
- * It can be overridden by the inheriting classes to update all dependent
- * variables.
- *
- * Subclasses can also override {@link #getInternalValue()} if necessary.
- *
- * @param newValue
- * the new value to be set.
- */
- protected void setInternalValue(T newValue) {
- value = newValue;
- valueLocale = getLocale();
- if (validators != null && !validators.isEmpty()) {
- markAsDirty();
- }
- }
-
- /**
- * Notifies the component that it is connected to an application.
- *
- * @see com.vaadin.ui.Component#attach()
- */
- @Override
- public void attach() {
- super.attach();
-
- localeMightHaveChanged();
- if (!isListeningToPropertyEvents) {
- addPropertyListeners();
- if (!isModified() && !isBuffered()) {
- // Update value from data source
- updateValueFromDataSource();
- }
- }
- }
-
- @Override
- public void setLocale(Locale locale) {
- super.setLocale(locale);
- localeMightHaveChanged();
- }
-
- private void localeMightHaveChanged() {
- if (!SharedUtil.equals(valueLocale, getLocale())) {
- // The locale HAS actually changed
-
- if (dataSource != null && !isModified()) {
- // When we have a data source and the internal value is directly
- // read from that we want to update the value
- T newInternalValue = convertFromModel(getPropertyDataSource()
- .getValue());
- if (!SharedUtil.equals(newInternalValue, getInternalValue())) {
- setInternalValue(newInternalValue);
- fireValueChange(false);
- }
- } else if (dataSource == null && converter != null) {
- /*
- * No data source but a converter has been set. The same issues
- * as above but we cannot use propertyDataSource. Convert the
- * current value back to a model value using the old locale and
- * then convert back using the new locale. If this does not
- * match the field value we need to set the converted value
- * again.
- */
- Object convertedValue = convertToModel(getInternalValue(),
- valueLocale);
- T newinternalValue = convertFromModel(convertedValue);
- if (!SharedUtil.equals(getInternalValue(), newinternalValue)) {
- setInternalValue(newinternalValue);
- fireValueChange(false);
- }
- }
- }
- }
-
- @Override
- public void detach() {
- super.detach();
- // Stop listening to data source events on detach to avoid a potential
- // memory leak. See #6155.
- removePropertyListeners();
- }
-
- /**
- * Is this field required. Required fields must filled by the user.
- *
- * If the field is required, it is visually indicated in the user interface.
- * Furthermore, setting field to be required implicitly adds "non-empty"
- * validator and thus isValid() == false or any isEmpty() fields. In those
- * cases validation errors are not painted as it is obvious that the user
- * must fill in the required fields.
- *
- * On the other hand, for the non-required fields isValid() == true if the
- * field isEmpty() regardless of any attached validators.
- *
- *
- * @return true if the field is required, otherwise
- * false.
- */
- @Override
- public boolean isRequired() {
- return getState(false).required;
- }
-
- /**
- * Sets the field required. Required fields must filled by the user.
- *
- * If the field is required, it is visually indicated in the user interface.
- * Furthermore, setting field to be required implicitly adds "non-empty"
- * validator and thus isValid() == false or any isEmpty() fields. In those
- * cases validation errors are not painted as it is obvious that the user
- * must fill in the required fields.
- *
- * On the other hand, for the non-required fields isValid() == true if the
- * field isEmpty() regardless of any attached validators.
- *
- * @param required
- * Is the field required.
- */
- @Override
- public void setRequired(boolean required) {
- getState().required = required;
- }
-
- /**
- * Set the error that is show if this field is required, but empty. When
- * setting requiredMessage to be "" or null, no error pop-up or exclamation
- * mark is shown for a empty required field. This faults to "". Even in
- * those cases isValid() returns false for empty required fields.
- *
- * @param requiredMessage
- * Message to be shown when this field is required, but empty.
- */
- @Override
- public void setRequiredError(String requiredMessage) {
- requiredError = requiredMessage;
- markAsDirty();
- }
-
- @Override
- public String getRequiredError() {
- return requiredError;
- }
-
- /**
- * Gets the error that is shown if the field value cannot be converted to
- * the data source type.
- *
- * @return The error that is shown if conversion of the field value fails
- */
- public String getConversionError() {
- return conversionError;
- }
-
- /**
- * Sets the error that is shown if the field value cannot be converted to
- * the data source type. If {0} is present in the message, it will be
- * replaced by the simple name of the data source type. If {1} is present in
- * the message, it will be replaced by the ConversionException message.
- *
- * @param valueConversionError
- * Message to be shown when conversion of the value fails
- */
- public void setConversionError(String valueConversionError) {
- this.conversionError = valueConversionError;
- markAsDirty();
- }
-
- @Override
- public boolean isEmpty() {
- return (getFieldValue() == null);
- }
-
- @Override
- public void clear() {
- setValue(null);
- }
-
- /**
- * Is automatic, visible validation enabled?
- *
- * If automatic validation is enabled, any validators connected to this
- * component are evaluated while painting the component and potential error
- * messages are sent to client. If the automatic validation is turned off,
- * isValid() and validate() methods still work, but one must show the
- * validation in their own code.
- *
- * @return True, if automatic validation is enabled.
- */
- public boolean isValidationVisible() {
- return validationVisible;
- }
-
- /**
- * Enable or disable automatic, visible validation.
- *
- * If automatic validation is enabled, any validators connected to this
- * component are evaluated while painting the component and potential error
- * messages are sent to client. If the automatic validation is turned off,
- * isValid() and validate() methods still work, but one must show the
- * validation in their own code.
- *
- * @param validateAutomatically
- * True, if automatic validation is enabled.
- */
- public void setValidationVisible(boolean validateAutomatically) {
- if (validationVisible != validateAutomatically) {
- markAsDirty();
- validationVisible = validateAutomatically;
- }
- }
-
- /**
- * Sets the current buffered source exception.
- *
- * @param currentBufferedSourceException
- */
- public void setCurrentBufferedSourceException(
- Buffered.SourceException currentBufferedSourceException) {
- this.currentBufferedSourceException = currentBufferedSourceException;
- markAsDirty();
- }
-
- /**
- * Gets the current buffered source exception.
- *
- * @return The current source exception
- */
- protected Buffered.SourceException getCurrentBufferedSourceException() {
- return currentBufferedSourceException;
- }
-
- /**
- * A ready-made {@link ShortcutListener} that focuses the given
- * {@link Focusable} (usually a {@link Field}) when the keyboard shortcut is
- * invoked.
- *
- */
- public static class FocusShortcut extends ShortcutListener {
- protected Focusable focusable;
-
- /**
- * Creates a keyboard shortcut for focusing the given {@link Focusable}
- * using the shorthand notation defined in {@link ShortcutAction}.
- *
- * @param focusable
- * to focused when the shortcut is invoked
- * @param shorthandCaption
- * caption with keycode and modifiers indicated
- */
- public FocusShortcut(Focusable focusable, String shorthandCaption) {
- super(shorthandCaption);
- this.focusable = focusable;
- }
-
- /**
- * Creates a keyboard shortcut for focusing the given {@link Focusable}.
- *
- * @param focusable
- * to focused when the shortcut is invoked
- * @param keyCode
- * keycode that invokes the shortcut
- * @param modifiers
- * modifiers required to invoke the shortcut
- */
- public FocusShortcut(Focusable focusable, int keyCode, int... modifiers) {
- super(null, keyCode, modifiers);
- this.focusable = focusable;
- }
-
- /**
- * Creates a keyboard shortcut for focusing the given {@link Focusable}.
- *
- * @param focusable
- * to focused when the shortcut is invoked
- * @param keyCode
- * keycode that invokes the shortcut
- */
- public FocusShortcut(Focusable focusable, int keyCode) {
- this(focusable, keyCode, null);
- }
-
- @Override
- public void handleAction(Object sender, Object target) {
- focusable.focus();
- }
- }
-
- private void updateValueFromDataSource() {
- if (dataSource != null) {
-
- // Gets the correct value from datasource
- T newFieldValue;
- try {
-
- // Discards buffer by overwriting from datasource
- newFieldValue = convertFromModel(getDataSourceValue());
-
- // If successful, remove set the buffering state to be ok
- if (getCurrentBufferedSourceException() != null) {
- setCurrentBufferedSourceException(null);
- }
- } catch (final Throwable e) {
- // FIXME: What should really be done here if conversion fails?
-
- // Sets the buffering state
- currentBufferedSourceException = new Buffered.SourceException(
- this, e);
- markAsDirty();
-
- // Throws the source exception
- throw currentBufferedSourceException;
- }
-
- final boolean wasModified = isModified();
- setModified(false);
-
- // If the new value differs from the previous one
- if (!SharedUtil.equals(newFieldValue, getInternalValue())) {
- setInternalValue(newFieldValue);
- fireValueChange(false);
- } else if (wasModified) {
- // If the value did not change, but the modification status did
- markAsDirty();
- }
- }
- }
-
- /**
- * Gets the converter used to convert the property data source value to the
- * field value.
- *
- * @return The converter or null if none is set.
- */
- public Converter getConverter() {
- return converter;
- }
-
- /**
- * Sets the converter used to convert the field value to property data
- * source type. The converter must have a presentation type that matches the
- * field type.
- *
- * @param converter
- * The new converter to use.
- */
- public void setConverter(Converter converter) {
- this.converter = (Converter) converter;
- markAsDirty();
- }
-
- @Override
- protected AbstractFieldState getState() {
- return (AbstractFieldState) super.getState();
- }
-
- @Override
- protected AbstractFieldState getState(boolean markAsDirty) {
- return (AbstractFieldState) super.getState(markAsDirty);
- }
-
- @Override
- public void beforeClientResponse(boolean initial) {
- super.beforeClientResponse(initial);
-
- // Hide the error indicator if needed
- getState().hideErrors = shouldHideErrors();
- }
-
- /**
- * Registers this as an event listener for events sent by the data source
- * (if any). Does nothing if
- * isListeningToPropertyEvents == true.
- */
- private void addPropertyListeners() {
- if (!isListeningToPropertyEvents) {
- if (dataSource instanceof Property.ValueChangeNotifier) {
- ((Property.ValueChangeNotifier) dataSource).addListener(this);
- }
- if (dataSource instanceof Property.ReadOnlyStatusChangeNotifier) {
- ((Property.ReadOnlyStatusChangeNotifier) dataSource)
- .addListener(this);
- }
- isListeningToPropertyEvents = true;
- }
- }
-
- /**
- * Stops listening to events sent by the data source (if any). Does nothing
- * if isListeningToPropertyEvents == false.
- */
- private void removePropertyListeners() {
- if (isListeningToPropertyEvents) {
- if (dataSource instanceof Property.ValueChangeNotifier) {
- ((Property.ValueChangeNotifier) dataSource)
- .removeListener(this);
- }
- if (dataSource instanceof Property.ReadOnlyStatusChangeNotifier) {
- ((Property.ReadOnlyStatusChangeNotifier) dataSource)
- .removeListener(this);
- }
- isListeningToPropertyEvents = false;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * Fields are automatically set to immediate if validators have been added.
- */
- @Override
- public boolean isImmediate() {
- if (getExplicitImmediateValue() != null) {
- return getExplicitImmediateValue();
- }
- // Make field immediate when there is some kind of validation present
- // (validator or required). This will avoid the UI being in a wrong
- // state, e.g. user entered valid data but old validation error is still
- // shown
- return super.isImmediate() || !getValidators().isEmpty()
- || isRequired();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.AbstractComponent#readDesign(org.jsoup.nodes .Element,
- * com.vaadin.ui.declarative.DesignContext)
- */
- @Override
- public void readDesign(Element design, DesignContext designContext) {
- super.readDesign(design, designContext);
- Attributes attr = design.attributes();
- if (design.hasAttr("readonly")) {
- setReadOnly(DesignAttributeHandler.readAttribute("readonly", attr,
- Boolean.class));
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.AbstractComponent#getCustomAttributes()
- */
- @Override
- protected Collection getCustomAttributes() {
- Collection attributes = super.getCustomAttributes();
- attributes.add("readonly");
- // must be handled by subclasses
- attributes.add("value");
- attributes.add("converted-value");
- return attributes;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.AbstractComponent#writeDesign(org.jsoup.nodes.Element
- * , com.vaadin.ui.declarative.DesignContext)
- */
- @Override
- public void writeDesign(Element design, DesignContext designContext) {
- super.writeDesign(design, designContext);
- AbstractField def = (AbstractField) designContext
- .getDefaultInstance(this);
- Attributes attr = design.attributes();
- // handle readonly
- DesignAttributeHandler.writeAttribute("readonly", attr,
- super.isReadOnly(), def.isReadOnly(), Boolean.class);
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(AbstractField.class.getName());
- }
-}
diff --git a/server/src/main/java/com/vaadin/ui/AbstractSelect.java b/server/src/main/java/com/vaadin/ui/AbstractSelect.java
index 882458c531..bf0e7274f4 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractSelect.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractSelect.java
@@ -47,6 +47,7 @@ import com.vaadin.event.dd.TargetDetailsImpl;
import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion;
import com.vaadin.event.dd.acceptcriteria.ContainsDataFlavor;
import com.vaadin.event.dd.acceptcriteria.TargetDetailIs;
+import com.vaadin.legacy.ui.LegacyAbstractField;
import com.vaadin.server.KeyMapper;
import com.vaadin.server.PaintException;
import com.vaadin.server.PaintTarget;
@@ -78,7 +79,7 @@ import com.vaadin.ui.declarative.DesignFormatter;
*/
@SuppressWarnings("serial")
// TODO currently cannot specify type more precisely in case of multi-select
-public abstract class AbstractSelect extends AbstractField implements
+public abstract class AbstractSelect extends LegacyAbstractField implements
Container, Container.Viewer, Container.PropertySetChangeListener,
Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier,
Container.ItemSetChangeListener, LegacyComponent {
@@ -646,7 +647,7 @@ public abstract class AbstractSelect extends AbstractField implements
/**
* Gets the selected item id or in multiselect mode a set of selected ids.
*
- * @see com.vaadin.ui.AbstractField#getValue()
+ * @see com.vaadin.legacy.ui.LegacyAbstractField#getValue()
*/
@Override
public Object getValue() {
@@ -686,7 +687,7 @@ public abstract class AbstractSelect extends AbstractField implements
*
* @param newValue
* the New selected item or collection of selected items.
- * @see com.vaadin.ui.AbstractField#setValue(java.lang.Object)
+ * @see com.vaadin.legacy.ui.LegacyAbstractField#setValue(java.lang.Object)
*/
@Override
public void setValue(Object newValue) throws Property.ReadOnlyException {
@@ -713,7 +714,7 @@ public abstract class AbstractSelect extends AbstractField implements
* True if caller is sure that repaint is not needed.
* @param ignoreReadOnly
* True if read-only check should be omitted.
- * @see com.vaadin.ui.AbstractField#setValue(java.lang.Object,
+ * @see com.vaadin.legacy.ui.LegacyAbstractField#setValue(java.lang.Object,
* java.lang.Boolean)
*/
@Override
@@ -1788,7 +1789,7 @@ public abstract class AbstractSelect extends AbstractField implements
* For multi-selectable fields, also an empty collection of values is
* considered to be an empty field.
*
- * @see AbstractField#isEmpty().
+ * @see LegacyAbstractField#isEmpty().
*/
@Override
public boolean isEmpty() {
@@ -1875,7 +1876,7 @@ public abstract class AbstractSelect extends AbstractField implements
/**
* Notifies the component that it is connected to an application.
*
- * @see com.vaadin.ui.AbstractField#attach()
+ * @see com.vaadin.legacy.ui.LegacyAbstractField#attach()
*/
@Override
public void attach() {
diff --git a/server/src/main/java/com/vaadin/ui/AbstractTextField.java b/server/src/main/java/com/vaadin/ui/AbstractTextField.java
index 5fbe60937a..c3b911a56b 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractTextField.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractTextField.java
@@ -31,6 +31,7 @@ import com.vaadin.event.FieldEvents.FocusNotifier;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
import com.vaadin.event.FieldEvents.TextChangeNotifier;
+import com.vaadin.legacy.ui.LegacyAbstractField;
import com.vaadin.server.PaintException;
import com.vaadin.server.PaintTarget;
import com.vaadin.shared.ui.textfield.AbstractTextFieldState;
@@ -38,7 +39,7 @@ import com.vaadin.shared.ui.textfield.TextFieldConstants;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
-public abstract class AbstractTextField extends AbstractField implements
+public abstract class AbstractTextField extends LegacyAbstractField implements
BlurNotifier, FocusNotifier, TextChangeNotifier, LegacyComponent {
/**
@@ -457,7 +458,7 @@ public abstract class AbstractTextField extends AbstractField implements
* Make sure w reset lastKnownTextContent field on value change. The
* clearing must happen here as well because TextChangeListener can
* revert the original value. Client must respect the value in this
- * case. AbstractField optimizes value change if the existing value is
+ * case. LegacyAbstractField optimizes value change if the existing value is
* reset. Also we need to force repaint if the flag is on.
*/
if (lastKnownTextContent != null) {
diff --git a/server/src/main/java/com/vaadin/ui/CheckBox.java b/server/src/main/java/com/vaadin/ui/CheckBox.java
index 8b31edcbb4..e9e9b0d4b9 100644
--- a/server/src/main/java/com/vaadin/ui/CheckBox.java
+++ b/server/src/main/java/com/vaadin/ui/CheckBox.java
@@ -27,13 +27,14 @@ import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.FocusAndBlurServerRpcImpl;
import com.vaadin.event.FieldEvents.FocusEvent;
import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.legacy.ui.LegacyAbstractField;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.ui.checkbox.CheckBoxServerRpc;
import com.vaadin.shared.ui.checkbox.CheckBoxState;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;
-public class CheckBox extends AbstractField {
+public class CheckBox extends LegacyAbstractField {
private CheckBoxServerRpc rpc = new CheckBoxServerRpc() {
@@ -129,8 +130,8 @@ public class CheckBox extends AbstractField {
}
/*
- * Overridden to keep the shared state in sync with the AbstractField
- * internal value. Should be removed once AbstractField is refactored to use
+ * Overridden to keep the shared state in sync with the LegacyAbstractField
+ * internal value. Should be removed once LegacyAbstractField is refactored to use
* shared state.
*
* See tickets #10921 and #11064.
diff --git a/server/src/main/java/com/vaadin/ui/Component.java b/server/src/main/java/com/vaadin/ui/Component.java
index 5db48806c3..0e8b385128 100644
--- a/server/src/main/java/com/vaadin/ui/Component.java
+++ b/server/src/main/java/com/vaadin/ui/Component.java
@@ -24,6 +24,7 @@ import org.jsoup.nodes.Element;
import com.vaadin.event.ConnectorEvent;
import com.vaadin.event.ConnectorEventListener;
import com.vaadin.event.FieldEvents;
+import com.vaadin.legacy.ui.LegacyField;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.ErrorMessage;
import com.vaadin.server.Resource;
@@ -378,7 +379,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
/**
* Tests whether the component is in the read-only mode. The user can not
- * change the value of a read-only component. As only {@link Field}
+ * change the value of a read-only component. As only {@link LegacyField}
* components normally have a value that can be input or changed by the
* user, this is mostly relevant only to field components, though not
* restricted to them.
@@ -405,7 +406,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
* can not change the value of a read-only component.
*
*
- * As only {@link Field} components normally have a value that can be input
+ * As only {@link LegacyField} components normally have a value that can be input
* or changed by the user, this is mostly relevant only to field components,
* though not restricted to them.
*
@@ -1021,13 +1022,13 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
/**
* A sub-interface implemented by components that can obtain input focus.
- * This includes all {@link Field} components as well as some other
+ * This includes all {@link LegacyField} components as well as some other
* components, such as {@link Upload}.
*
*
* Focus can be set with {@link #focus()}. This interface does not provide
* an accessor that would allow finding out the currently focused component;
- * focus information can be acquired for some (but not all) {@link Field}
+ * focus information can be acquired for some (but not all) {@link LegacyField}
* components through the {@link com.vaadin.event.FieldEvents.FocusListener}
* and {@link com.vaadin.event.FieldEvents.BlurListener} interfaces.
*
* Notice that this interface does not provide an accessor that would
* allow finding out the currently focused component. Focus information
- * can be acquired for some (but not all) {@link Field} components
+ * can be acquired for some (but not all) {@link LegacyField} components
* through the {@link com.vaadin.event.FieldEvents.FocusListener} and
* {@link com.vaadin.event.FieldEvents.BlurListener} interfaces.
*
diff --git a/server/src/main/java/com/vaadin/ui/CustomField.java b/server/src/main/java/com/vaadin/ui/CustomField.java
index 12f00ac23f..311a2069a3 100644
--- a/server/src/main/java/com/vaadin/ui/CustomField.java
+++ b/server/src/main/java/com/vaadin/ui/CustomField.java
@@ -20,9 +20,11 @@ import java.io.Serializable;
import java.util.Iterator;
import com.vaadin.data.Property;
+import com.vaadin.legacy.ui.LegacyField;
+import com.vaadin.legacy.ui.LegacyAbstractField;
/**
- * A {@link Field} whose UI content can be constructed by the user, enabling the
+ * A {@link LegacyField} whose UI content can be constructed by the user, enabling the
* creation of e.g. form fields by composing Vaadin components. Customization of
* both the visual presentation and the logic of the field is possible.
*
@@ -43,7 +45,7 @@ import com.vaadin.data.Property;
*
* @since 7.0
*/
-public abstract class CustomField extends AbstractField implements
+public abstract class CustomField extends LegacyAbstractField implements
HasComponents {
/**
diff --git a/server/src/main/java/com/vaadin/ui/DateField.java b/server/src/main/java/com/vaadin/ui/DateField.java
index 052539cd28..6ceae9962c 100644
--- a/server/src/main/java/com/vaadin/ui/DateField.java
+++ b/server/src/main/java/com/vaadin/ui/DateField.java
@@ -38,6 +38,8 @@ import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.FocusEvent;
import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.legacy.ui.LegacyAbstractField;
+import com.vaadin.legacy.ui.LegacyField;
import com.vaadin.server.PaintException;
import com.vaadin.server.PaintTarget;
import com.vaadin.shared.ui.datefield.DateFieldConstants;
@@ -52,20 +54,20 @@ import com.vaadin.ui.declarative.DesignContext;
* compatible with java.util.Date.
*
*
- * Since DateField extends AbstractField it implements
- * the {@link com.vaadin.data.Buffered}interface.
+ * Since DateField extends LegacyAbstractField it
+ * implements the {@link com.vaadin.data.Buffered}interface.
*
*
* A DateField is in write-through mode by default, so
- * {@link com.vaadin.ui.AbstractField#setWriteThrough(boolean)}must be called to
- * enable buffering.
+ * {@link com.vaadin.legacy.ui.LegacyAbstractField#setWriteThrough(boolean)}must
+ * be called to enable buffering.
*
*
* @author Vaadin Ltd.
* @since 3.0
*/
@SuppressWarnings("serial")
-public class DateField extends AbstractField implements
+public class DateField extends LegacyAbstractField implements
FieldEvents.BlurNotifier, FieldEvents.FocusNotifier, LegacyComponent {
/**
@@ -152,7 +154,7 @@ public class DateField extends AbstractField implements
private TimeZone timeZone = null;
- private static Map variableNameForResolution = new HashMap();
+ private static Map variableNameForResolution = new HashMap<>();
private String dateOutOfRangeMessage = "Date is out of allowed range";
@@ -485,7 +487,7 @@ public class DateField extends AbstractField implements
|| variables.containsKey("min")
|| variables.containsKey("sec")
|| variables.containsKey("msec") || variables
- .containsKey("dateString"))) {
+ .containsKey("dateString"))) {
// Old and new dates
final Date oldDate = getValue();
@@ -497,7 +499,7 @@ public class DateField extends AbstractField implements
// Gets the new date in parts
boolean hasChanges = false;
- Map calendarFieldChanges = new HashMap();
+ Map calendarFieldChanges = new HashMap<>();
for (Resolution r : Resolution
.getResolutionsHigherOrEqualTo(resolution)) {
@@ -543,7 +545,8 @@ public class DateField extends AbstractField implements
newDate = cal.getTime();
}
- if (newDate == null && dateString != null && !"".equals(dateString)) {
+ if (newDate == null && dateString != null && !"".equals(
+ dateString)) {
try {
Date parsedDate = handleUnparsableDateString(dateString);
setValue(parsedDate, true);
@@ -731,7 +734,7 @@ public class DateField extends AbstractField implements
Form f = (Form) parenOfDateField;
Collection> visibleItemProperties = f.getItemPropertyIds();
for (Object fieldId : visibleItemProperties) {
- Field> field = f.getField(fieldId);
+ LegacyField> field = f.getField(fieldId);
if (equals(field)) {
/*
* this datefield is logically in a form. Do the same
@@ -813,7 +816,8 @@ public class DateField extends AbstractField implements
// Start by a zeroed calendar to avoid having values for lower
// resolution variables e.g. time when resolution is day
int min, field;
- for (Resolution r : Resolution.getResolutionsLowerThan(resolution)) {
+ for (Resolution r : Resolution.getResolutionsLowerThan(
+ resolution)) {
field = r.getCalendarField();
min = calendar.getActualMinimum(field);
calendar.set(field, min);
@@ -981,7 +985,7 @@ public class DateField extends AbstractField implements
* invalid if it contains text typed in by the user that couldn't be parsed
* into a Date value.
*
- * @see com.vaadin.ui.AbstractField#validate()
+ * @see com.vaadin.legacy.ui.LegacyAbstractField#validate()
*/
@Override
public void validate() throws InvalidValueException {
diff --git a/server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java b/server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java
index 535943bcd5..85ad1743ea 100644
--- a/server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java
+++ b/server/src/main/java/com/vaadin/ui/DefaultFieldFactory.java
@@ -20,6 +20,7 @@ import java.util.Date;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
+import com.vaadin.legacy.ui.LegacyField;
import com.vaadin.shared.util.SharedUtil;
/**
@@ -49,21 +50,21 @@ public class DefaultFieldFactory implements FormFieldFactory, TableFieldFactory
}
@Override
- public Field> createField(Item item, Object propertyId,
+ public LegacyField> createField(Item item, Object propertyId,
Component uiContext) {
Class> type = item.getItemProperty(propertyId).getType();
- Field> field = createFieldByPropertyType(type);
+ LegacyField> field = createFieldByPropertyType(type);
field.setCaption(createCaptionByPropertyId(propertyId));
return field;
}
@Override
- public Field createField(Container container, Object itemId,
+ public LegacyField createField(Container container, Object itemId,
Object propertyId, Component uiContext) {
Property containerProperty = container.getContainerProperty(itemId,
propertyId);
Class> type = containerProperty.getType();
- Field> field = createFieldByPropertyType(type);
+ LegacyField> field = createFieldByPropertyType(type);
field.setCaption(createCaptionByPropertyId(propertyId));
return field;
}
@@ -93,9 +94,9 @@ public class DefaultFieldFactory implements FormFieldFactory, TableFieldFactory
*
* @param type
* the type of the property
- * @return the most suitable generic {@link Field} for given type
+ * @return the most suitable generic {@link LegacyField} for given type
*/
- public static Field> createFieldByPropertyType(Class> type) {
+ public static LegacyField> createFieldByPropertyType(Class> type) {
// Null typed properties can not be edited
if (type == null) {
return null;
diff --git a/server/src/main/java/com/vaadin/ui/Field.java b/server/src/main/java/com/vaadin/ui/Field.java
deleted file mode 100644
index 8a9acd570f..0000000000
--- a/server/src/main/java/com/vaadin/ui/Field.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2000-2014 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.vaadin.ui;
-
-import com.vaadin.data.BufferedValidatable;
-import com.vaadin.data.Property;
-import com.vaadin.ui.Component.Focusable;
-
-/**
- * Field interface is implemented by all classes (field components) that have a
- * value that the user can change through the user interface.
- *
- * Field components are built upon the framework defined in the Field interface
- * and the {@link com.vaadin.AbstractField} base class.
- *
- * The Field interface inherits the {@link com.vaadin.ui.Component}
- * superinterface and also the {@link com.vaadin.ui.Property} interface to have
- * a value for the field.
- *
- *
- * @author Vaadin Ltd.
- *
- * @param T
- * the type of values in the field, which might not be the same type
- * as that of the data source if converters are used
- *
- * @author IT Mill Ltd.
- */
-public interface Field extends Component, BufferedValidatable, Property,
- Property.ValueChangeNotifier, Property.ValueChangeListener,
- Property.Editor, Focusable {
-
- /**
- * Is this field required.
- *
- * Required fields must filled by the user.
- *
- * @return true if the field is required,otherwise
- * false.
- * @since 3.1
- */
- public boolean isRequired();
-
- /**
- * Sets the field required. Required fields must filled by the user.
- *
- * @param required
- * Is the field required.
- * @since 3.1
- */
- public void setRequired(boolean required);
-
- /**
- * Sets the error message to be displayed if a required field is empty.
- *
- * @param requiredMessage
- * Error message.
- * @since 5.2.6
- */
- public void setRequiredError(String requiredMessage);
-
- /**
- * Gets the error message that is to be displayed if a required field is
- * empty.
- *
- * @return Error message.
- * @since 5.2.6
- */
- public String getRequiredError();
-
- /**
- * An Event object specifying the Field whose value has been
- * changed.
- *
- * @author Vaadin Ltd.
- * @since 3.0
- */
- @SuppressWarnings("serial")
- public static class ValueChangeEvent extends Component.Event implements
- Property.ValueChangeEvent {
-
- /**
- * Constructs a new event object with the specified source field object.
- *
- * @param source
- * the field that caused the event.
- */
- public ValueChangeEvent(Field source) {
- super(source);
- }
-
- /**
- * Gets the Property which triggered the event.
- *
- * @return the Source Property of the event.
- */
- @Override
- public Property getProperty() {
- return (Property) getSource();
- }
- }
-
- /**
- * Is the field empty?
- *
- * In general, "empty" state is same as null. As an exception, TextField
- * also treats empty string as "empty".
- *
- * @since 7.4
- * @return true if the field is empty, false otherwise
- */
- public boolean isEmpty();
-
- /**
- * Clears the value of the field.
- *
- * The field value is typically reset to the initial value of the field.
- * Calling {@link #isEmpty()} on a cleared field must always returns true.
- *
- * @since 7.4
- */
- public void clear();
-
-}
diff --git a/server/src/main/java/com/vaadin/ui/Form.java b/server/src/main/java/com/vaadin/ui/Form.java
index 45532756e5..606f6ee5f9 100644
--- a/server/src/main/java/com/vaadin/ui/Form.java
+++ b/server/src/main/java/com/vaadin/ui/Form.java
@@ -36,6 +36,8 @@ import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.Action.ShortcutNotifier;
import com.vaadin.event.ActionManager;
+import com.vaadin.legacy.ui.LegacyAbstractField;
+import com.vaadin.legacy.ui.LegacyField;
import com.vaadin.server.AbstractErrorMessage;
import com.vaadin.server.CompositeErrorMessage;
import com.vaadin.server.ErrorMessage;
@@ -48,7 +50,7 @@ import com.vaadin.shared.ui.form.FormState;
* Form component provides easy way of creating and managing sets fields.
*
*
- * Form is a container for fields implementing {@link Field}
+ * Form is a container for fields implementing {@link LegacyField}
* interface. It provides support for any layouts and provides buffering
* interface for easy connection of commit and discard buttons. All the form
* fields can be customized by adding validators, setting captions and icons,
@@ -76,7 +78,7 @@ import com.vaadin.shared.ui.form.FormState;
* more flexibility.
*/
@Deprecated
-public class Form extends AbstractField implements Item.Editor,
+public class Form extends LegacyAbstractField implements Item.Editor,
Buffered, Item, Validatable, Action.Notifier, HasComponents,
LegacyComponent {
@@ -90,7 +92,7 @@ public class Form extends AbstractField implements Item.Editor,
/**
* Ordered list of property ids in this editor.
*/
- private final LinkedList propertyIds = new LinkedList();
+ private final LinkedList propertyIds = new LinkedList<>();
/**
* Current buffered source exception.
@@ -105,12 +107,12 @@ public class Form extends AbstractField implements Item.Editor,
/**
* Mapping from propertyName to corresponding field.
*/
- private final HashMap> fields = new HashMap>();
+ private final HashMap> fields = new HashMap<>();
/**
* Form may act as an Item, its own properties are stored here.
*/
- private final HashMap> ownProperties = new HashMap>();
+ private final HashMap> ownProperties = new HashMap<>();
/**
* Field factory for this form.
@@ -131,7 +133,8 @@ public class Form extends AbstractField implements Item.Editor,
*/
private final ValueChangeListener fieldValueChangeListener = new ValueChangeListener() {
@Override
- public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
+ public void valueChange(
+ com.vaadin.data.Property.ValueChangeEvent event) {
markAsDirty();
}
};
@@ -147,9 +150,9 @@ public class Form extends AbstractField implements Item.Editor,
/**
* Keeps track of the Actions added to this component, and manages the
- * painting and handling as well. Note that the extended AbstractField is a
- * {@link ShortcutNotifier} and has a actionManager that delegates actions
- * to the containing window. This one does not delegate.
+ * painting and handling as well. Note that the extended LegacyAbstractField
+ * is a {@link ShortcutNotifier} and has a actionManager that delegates
+ * actions to the containing window. This one does not delegate.
*/
private ActionManager ownActionManager = new ActionManager(this);
@@ -236,7 +239,8 @@ public class Form extends AbstractField implements Item.Editor,
// getErrorMessage() recursively instead of validate().
ErrorMessage validationError = null;
if (isValidationVisible()) {
- for (final Iterator i = propertyIds.iterator(); i.hasNext();) {
+ for (final Iterator i = propertyIds.iterator(); i
+ .hasNext();) {
Object f = fields.get(i.next());
if (f instanceof AbstractComponent) {
AbstractComponent field = (AbstractComponent) f;
@@ -248,7 +252,8 @@ public class Form extends AbstractField implements Item.Editor,
validationError = new UserError(field.getCaption());
}
break;
- } else if (f instanceof Field && !((Field>) f).isValid()) {
+ } else if (f instanceof LegacyField && !((LegacyField>) f)
+ .isValid()) {
// Something is wrong with the field, but no proper
// error is given. Generate one.
validationError = new UserError(field.getCaption());
@@ -270,7 +275,8 @@ public class Form extends AbstractField implements Item.Editor,
getComponentError(),
validationError,
AbstractErrorMessage
- .getErrorMessageForException(currentBufferedSourceException) });
+ .getErrorMessageForException(
+ currentBufferedSourceException) });
}
/**
@@ -308,7 +314,8 @@ public class Form extends AbstractField implements Item.Editor,
* use the default one from the interface.
*/
@Override
- public void commit() throws Buffered.SourceException, InvalidValueException {
+ public void commit() throws Buffered.SourceException,
+ InvalidValueException {
LinkedList problems = null;
@@ -329,14 +336,14 @@ public class Form extends AbstractField implements Item.Editor,
// Try to commit all
for (final Iterator i = propertyIds.iterator(); i.hasNext();) {
try {
- final Field> f = (fields.get(i.next()));
+ final LegacyField> f = (fields.get(i.next()));
// Commit only non-readonly fields.
if (!f.isReadOnly()) {
f.commit();
}
} catch (final Buffered.SourceException e) {
if (problems == null) {
- problems = new LinkedList();
+ problems = new LinkedList<>();
}
problems.add(e);
}
@@ -380,7 +387,7 @@ public class Form extends AbstractField implements Item.Editor,
(fields.get(i.next())).discard();
} catch (final Buffered.SourceException e) {
if (problems == null) {
- problems = new LinkedList();
+ problems = new LinkedList<>();
}
problems.add(e);
}
@@ -416,7 +423,7 @@ public class Form extends AbstractField implements Item.Editor,
@Override
public boolean isModified() {
for (final Iterator i = propertyIds.iterator(); i.hasNext();) {
- final Field> f = fields.get(i.next());
+ final LegacyField> f = fields.get(i.next());
if (f != null && f.isModified()) {
return true;
}
@@ -433,7 +440,8 @@ public class Form extends AbstractField implements Item.Editor,
public void setBuffered(boolean buffered) {
if (buffered != this.buffered) {
this.buffered = buffered;
- for (final Iterator i = propertyIds.iterator(); i.hasNext();) {
+ for (final Iterator i = propertyIds.iterator(); i
+ .hasNext();) {
(fields.get(i.next())).setBuffered(buffered);
}
}
@@ -461,7 +469,7 @@ public class Form extends AbstractField implements Item.Editor,
ownProperties.put(id, property);
// Gets suitable field
- final Field> field = fieldFactory.createField(this, id, this);
+ final LegacyField> field = fieldFactory.createField(this, id, this);
if (field == null) {
return false;
}
@@ -484,7 +492,7 @@ public class Form extends AbstractField implements Item.Editor,
*
*
* This field is added to the layout using the
- * {@link #attachField(Object, Field)} method.
+ * {@link #attachField(Object, LegacyField)} method.
*
*
* @param propertyId
@@ -492,7 +500,7 @@ public class Form extends AbstractField implements Item.Editor,
* @param field
* the field which should be added to the form.
*/
- public void addField(Object propertyId, Field> field) {
+ public void addField(Object propertyId, LegacyField> field) {
registerField(propertyId, field);
attachField(propertyId, field);
markAsDirty();
@@ -510,9 +518,9 @@ public class Form extends AbstractField implements Item.Editor,
* @param propertyId
* the Property id of the field.
* @param field
- * the Field that should be registered
+ * the LegacyField that should be registered
*/
- private void registerField(Object propertyId, Field> field) {
+ private void registerField(Object propertyId, LegacyField> field) {
if (propertyId == null || field == null) {
return;
}
@@ -550,7 +558,7 @@ public class Form extends AbstractField implements Item.Editor,
* @param propertyId
* @param field
*/
- protected void attachField(Object propertyId, Field field) {
+ protected void attachField(Object propertyId, LegacyField field) {
if (propertyId == null || field == null) {
return;
}
@@ -577,7 +585,7 @@ public class Form extends AbstractField implements Item.Editor,
*/
@Override
public Property getItemProperty(Object id) {
- final Field> field = fields.get(id);
+ final LegacyField> field = fields.get(id);
if (field == null) {
// field does not exist or it is not (yet) created for this property
return ownProperties.get(id);
@@ -597,7 +605,7 @@ public class Form extends AbstractField implements Item.Editor,
* @param propertyId
* the id of the property.
*/
- public Field getField(Object propertyId) {
+ public LegacyField getField(Object propertyId) {
return fields.get(propertyId);
}
@@ -616,7 +624,7 @@ public class Form extends AbstractField implements Item.Editor,
public boolean removeItemProperty(Object id) {
ownProperties.remove(id);
- final Field> field = fields.get(id);
+ final LegacyField> field = fields.get(id);
if (field != null) {
propertyIds.remove(id);
@@ -640,7 +648,7 @@ public class Form extends AbstractField implements Item.Editor,
* @param field
* the field to be detached from the forms layout.
*/
- protected void detachField(final Field field) {
+ protected void detachField(final LegacyField field) {
Component p = field.getParent();
if (p instanceof ComponentContainer) {
((ComponentContainer) p).removeComponent(field);
@@ -701,7 +709,8 @@ public class Form extends AbstractField implements Item.Editor,
*
* @see com.vaadin.data.Item.Viewer#setItemDataSource(Item)
*/
- public void setItemDataSource(Item newDataSource, Collection> propertyIds) {
+ public void setItemDataSource(Item newDataSource,
+ Collection> propertyIds) {
if (getLayout() instanceof GridLayout) {
GridLayout gl = (GridLayout) getLayout();
@@ -733,7 +742,8 @@ public class Form extends AbstractField implements Item.Editor,
final Object id = i.next();
final Property> property = itemDatasource.getItemProperty(id);
if (id != null && property != null) {
- final Field> f = fieldFactory.createField(itemDatasource, id,
+ final LegacyField> f = fieldFactory.createField(
+ itemDatasource, id,
this);
if (f != null) {
bindPropertyToField(id, property, f);
@@ -745,7 +755,7 @@ public class Form extends AbstractField implements Item.Editor,
/**
* Binds an item property to a field. The default behavior is to bind
- * property straight to Field. If Property.Viewer type property (e.g.
+ * property straight to LegacyField. If Property.Viewer type property (e.g.
* PropertyFormatter) is already set for field, the property is bound to
* that Property.Viewer.
*
@@ -755,7 +765,7 @@ public class Form extends AbstractField implements Item.Editor,
* @since 6.7.3
*/
protected void bindPropertyToField(final Object propertyId,
- final Property property, final Field field) {
+ final Property property, final LegacyField field) {
// check if field has a property that is Viewer set. In that case we
// expect developer has e.g. PropertyFormatter that he wishes to use and
// assign the property to the Viewer instead.
@@ -808,7 +818,7 @@ public class Form extends AbstractField implements Item.Editor,
if (getLayout() != null) {
final Object[] properties = propertyIds.toArray();
for (int i = 0; i < properties.length; i++) {
- Field> f = getField(properties[i]);
+ LegacyField> f = getField(properties[i]);
detachField(f);
if (layout instanceof CustomLayout) {
((CustomLayout) layout).addComponent(f,
@@ -857,10 +867,11 @@ public class Form extends AbstractField implements Item.Editor,
}
// Gets the old field
- final Field> oldField = fields.get(propertyId);
+ final LegacyField> oldField = fields.get(propertyId);
if (oldField == null) {
- throw new IllegalArgumentException("Field with given propertyid '"
- + propertyId.toString() + "' can not be found.");
+ throw new IllegalArgumentException(
+ "Field with given propertyid '"
+ + propertyId.toString() + "' can not be found.");
}
final Object value = oldField.getPropertyDataSource() == null ? oldField
.getValue() : oldField.getPropertyDataSource().getValue();
@@ -877,8 +888,9 @@ public class Form extends AbstractField implements Item.Editor,
}
if (value != null && !found) {
if (value instanceof Collection) {
- for (final Iterator> it = ((Collection>) value).iterator(); it
- .hasNext();) {
+ for (final Iterator> it = ((Collection>) value)
+ .iterator(); it
+ .hasNext();) {
final Object val = it.next();
found = false;
for (int i = 0; i < values.length && !found; i++) {
@@ -1000,7 +1012,7 @@ public class Form extends AbstractField implements Item.Editor,
*
* @param fieldFactory
* the new factory used to create the fields.
- * @see Field
+ * @see LegacyField
* @see FormFieldFactory
*/
public void setFormFieldFactory(FormFieldFactory fieldFactory) {
@@ -1019,7 +1031,7 @@ public class Form extends AbstractField implements Item.Editor,
/**
* Gets the field type.
*
- * @see com.vaadin.ui.AbstractField#getType()
+ * @see com.vaadin.legacy.ui.LegacyAbstractField#getType()
*/
@Override
public Class> getType() {
@@ -1032,9 +1044,9 @@ public class Form extends AbstractField implements Item.Editor,
/**
* Sets the internal value.
*
- * This is relevant when the Form is used as Field.
+ * This is relevant when the Form is used as LegacyField.
*
- * @see com.vaadin.ui.AbstractField#setInternalValue(java.lang.Object)
+ * @see com.vaadin.legacy.ui.LegacyAbstractField#setInternalValue(java.lang.Object)
*/
@Override
protected void setInternalValue(Object newValue) {
@@ -1056,14 +1068,14 @@ public class Form extends AbstractField implements Item.Editor,
* non-read-only fields, the first one of them is returned. Otherwise, the
* field for the first property (or null if none) is returned.
*
- * @return the Field.
+ * @return the LegacyField.
*/
- private Field> getFirstFocusableField() {
+ private LegacyField> getFirstFocusableField() {
Collection> itemPropertyIds = getItemPropertyIds();
if (itemPropertyIds != null && itemPropertyIds.size() > 0) {
for (Object id : itemPropertyIds) {
if (id != null) {
- Field> field = getField(id);
+ LegacyField> field = getField(id);
if (field.isConnectorEnabled() && !field.isReadOnly()) {
return field;
}
@@ -1094,7 +1106,7 @@ public class Form extends AbstractField implements Item.Editor,
if (data instanceof Item) {
item = (Item) data;
} else if (data != null) {
- item = new BeanItem(data);
+ item = new BeanItem<>(data);
}
// Sets the datasource to form
@@ -1138,7 +1150,7 @@ public class Form extends AbstractField implements Item.Editor,
* the visibleProperties to set.
*/
public void setVisibleItemProperties(Object... visibleProperties) {
- LinkedList v = new LinkedList();
+ LinkedList v = new LinkedList<>();
for (int i = 0; i < visibleProperties.length; i++) {
v.add(visibleProperties[i]);
}
@@ -1152,7 +1164,7 @@ public class Form extends AbstractField implements Item.Editor,
*/
@Override
public void focus() {
- final Field> f = getFirstFocusableField();
+ final LegacyField> f = getFirstFocusableField();
if (f != null) {
f.focus();
}
@@ -1166,7 +1178,8 @@ public class Form extends AbstractField implements Item.Editor,
@Override
public void setTabIndex(int tabIndex) {
super.setTabIndex(tabIndex);
- for (final Iterator> i = getItemPropertyIds().iterator(); i.hasNext();) {
+ for (final Iterator> i = getItemPropertyIds().iterator(); i
+ .hasNext();) {
(getField(i.next())).setTabIndex(tabIndex);
}
}
@@ -1178,8 +1191,9 @@ public class Form extends AbstractField implements Item.Editor,
@Override
public void setImmediate(boolean immediate) {
super.setImmediate(immediate);
- for (Iterator> i = fields.values().iterator(); i.hasNext();) {
- Field> f = i.next();
+ for (Iterator> i = fields.values().iterator(); i
+ .hasNext();) {
+ LegacyField> f = i.next();
if (f instanceof AbstractComponent) {
((AbstractComponent) f).setImmediate(immediate);
}
@@ -1195,10 +1209,11 @@ public class Form extends AbstractField implements Item.Editor,
@Override
public boolean isEmpty() {
- for (Iterator> i = fields.values().iterator(); i.hasNext();) {
- Field> f = i.next();
- if (f instanceof AbstractField) {
- if (!((AbstractField>) f).isEmpty()) {
+ for (Iterator> i = fields.values().iterator(); i
+ .hasNext();) {
+ LegacyField> f = i.next();
+ if (f instanceof LegacyAbstractField) {
+ if (!((LegacyAbstractField>) f).isEmpty()) {
return false;
}
}
@@ -1214,10 +1229,11 @@ public class Form extends AbstractField implements Item.Editor,
*/
@Override
public void clear() {
- for (Iterator> i = fields.values().iterator(); i.hasNext();) {
- Field> f = i.next();
- if (f instanceof AbstractField) {
- ((AbstractField>) f).clear();
+ for (Iterator> i = fields.values().iterator(); i
+ .hasNext();) {
+ LegacyField> f = i.next();
+ if (f instanceof LegacyAbstractField) {
+ ((LegacyAbstractField>) f).clear();
}
}
}
@@ -1279,9 +1295,10 @@ public class Form extends AbstractField implements Item.Editor,
* Gets the {@link ActionManager} responsible for handling {@link Action}s
* added to this Form.
* Note that Form has another ActionManager inherited from
- * {@link AbstractField}. The ownActionManager handles Actions attached to
- * this Form specifically, while the ActionManager in AbstractField
- * delegates to the containing Window (i.e global Actions).
+ * {@link LegacyAbstractField}. The ownActionManager handles Actions
+ * attached to this Form specifically, while the ActionManager in
+ * LegacyAbstractField delegates to the containing Window (i.e global
+ * Actions).
*
* @return
*/
diff --git a/server/src/main/java/com/vaadin/ui/FormFieldFactory.java b/server/src/main/java/com/vaadin/ui/FormFieldFactory.java
index 124e0fcb9a..5483b7a904 100644
--- a/server/src/main/java/com/vaadin/ui/FormFieldFactory.java
+++ b/server/src/main/java/com/vaadin/ui/FormFieldFactory.java
@@ -19,6 +19,7 @@ import java.io.Serializable;
import com.vaadin.data.Item;
import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.legacy.ui.LegacyField;
/**
* Factory interface for creating new Field-instances based on {@link Item},
@@ -49,7 +50,8 @@ public interface FormFieldFactory extends Serializable {
* is {@link Form}. uiContext will not necessary be the parent
* component of the field, but the one that is responsible for
* creating it.
- * @return Field the field suitable for editing the specified data.
+ * @return the field suitable for editing the specified data.
*/
- Field> createField(Item item, Object propertyId, Component uiContext);
+ LegacyField> createField(Item item, Object propertyId,
+ Component uiContext);
}
diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java
index 388d74aeee..09a3eecb73 100644
--- a/server/src/main/java/com/vaadin/ui/Grid.java
+++ b/server/src/main/java/com/vaadin/ui/Grid.java
@@ -73,6 +73,7 @@ import com.vaadin.event.SelectionEvent.SelectionNotifier;
import com.vaadin.event.SortEvent;
import com.vaadin.event.SortEvent.SortListener;
import com.vaadin.event.SortEvent.SortNotifier;
+import com.vaadin.legacy.ui.LegacyField;
import com.vaadin.server.AbstractClientConnector;
import com.vaadin.server.AbstractExtension;
import com.vaadin.server.EncodeResult;
@@ -157,14 +158,14 @@ import elemental.json.JsonValue;
*
Selection Modes and Models
*
* Grid supports three selection {@link SelectionMode modes} (single,
- * multi, none), and comes bundled with one
- * {@link SelectionModel model} for each of the modes. The distinction
- * between a selection mode and selection model is as follows: a mode
- * essentially says whether you can have one, many or no rows selected. The
- * model, however, has the behavioral details of each. A single selection model
- * may require that the user deselects one row before selecting another one. A
- * variant of a multiselect might have a configurable maximum of rows that may
- * be selected. And so on.
+ * multi, none), and comes bundled with one {@link SelectionModel
+ * model} for each of the modes. The distinction between a selection mode
+ * and selection model is as follows: a mode essentially says whether
+ * you can have one, many or no rows selected. The model, however, has the
+ * behavioral details of each. A single selection model may require that the
+ * user deselects one row before selecting another one. A variant of a
+ * multiselect might have a configurable maximum of rows that may be selected.
+ * And so on.
*
*
* Grid grid = new Grid(myContainer);
@@ -319,19 +320,19 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* client. Details components get destroyed once they scroll out of
* view.
*/
- private final Map itemIdToDetailsComponent = new HashMap();
+ private final Map itemIdToDetailsComponent = new HashMap<>();
/**
* Set of item ids that got null from DetailsGenerator when
* {@link DetailsGenerator#getDetails(RowReference)} was called.
*/
- private final Set emptyDetails = new HashSet();
+ private final Set emptyDetails = new HashSet<>();
/**
* Set of item IDs for all open details rows. Contains even the ones
* that are not currently visible on the client.
*/
- private final Set openDetails = new HashSet();
+ private final Set openDetails = new HashSet<>();
public DetailComponentManager(Grid grid) {
this(grid, DetailsGenerator.NULL);
@@ -416,7 +417,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* Recreates all visible details components.
*/
public void refreshDetails() {
- Set visibleItemIds = new HashSet(
+ Set visibleItemIds = new HashSet<>(
itemIdToDetailsComponent.keySet());
for (Object itemId : visibleItemIds) {
destroyDetails(itemId);
@@ -540,7 +541,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
@Override
- protected T build(String caption, Class> dataType,
+ protected T build(String caption,
+ Class> dataType,
Class fieldType) throws BindException {
T field = super.build(caption, dataType, fieldType);
if (field instanceof CheckBox) {
@@ -573,7 +575,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
@Override
- public T createField(Class> type, Class fieldType) {
+ public T createField(Class> type,
+ Class fieldType) {
T f = super.createField(type, fieldType);
if (f != null) {
f.setWidth("100%");
@@ -691,7 +694,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
private CommitException cause;
- private Set errorColumns = new HashSet();
+ private Set errorColumns = new HashSet<>();
private String userErrorMessage;
@@ -980,17 +983,17 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
@Override
public void commitError(CommitErrorEvent event) {
- Map, InvalidValueException> invalidFields = event
+ Map, InvalidValueException> invalidFields = event
.getCause().getInvalidFields();
if (!invalidFields.isEmpty()) {
Object firstErrorPropertyId = null;
- Field> firstErrorField = null;
+ LegacyField> firstErrorField = null;
FieldGroup fieldGroup = event.getCause().getFieldGroup();
for (Column column : getColumns()) {
Object propertyId = column.getPropertyId();
- Field> field = fieldGroup.getField(propertyId);
+ LegacyField> field = fieldGroup.getField(propertyId);
if (invalidFields.keySet().contains(field)) {
event.addErrorColumn(column);
@@ -1018,10 +1021,10 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
private Object getFirstPropertyId(FieldGroup fieldGroup,
- Set> keySet) {
+ Set> keySet) {
for (Column c : getColumns()) {
Object propertyId = c.getPropertyId();
- Field> f = fieldGroup.getField(propertyId);
+ LegacyField> f = fieldGroup.getField(propertyId);
if (keySet.contains(f)) {
return propertyId;
}
@@ -1339,7 +1342,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
*/
public static abstract class AbstractSelectionModel extends
AbstractGridExtension implements SelectionModel, DataGenerator {
- protected final LinkedHashSet selection = new LinkedHashSet();
+ protected final LinkedHashSet selection = new LinkedHashSet<>();
@Override
public boolean isSelected(final Object itemId) {
@@ -1348,7 +1351,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
@Override
public Collection getSelectedRows() {
- return new ArrayList(selection);
+ return new ArrayList<>(selection);
}
@Override
@@ -1586,7 +1589,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
@Override
public void select(List rowKeys) {
- List items = new ArrayList();
+ List items = new ArrayList<>();
for (String rowKey : rowKeys) {
items.add(getItemId(rowKey));
}
@@ -1595,7 +1598,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
@Override
public void deselect(List rowKeys) {
- List items = new ArrayList();
+ List items = new ArrayList<>();
for (String rowKey : rowKeys) {
items.add(getItemId(rowKey));
}
@@ -1649,7 +1652,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
final boolean selectionWillChange = !selection.containsAll(itemIds)
&& selection.size() < selectionLimit;
if (selectionWillChange) {
- final HashSet oldSelection = new HashSet(
+ final HashSet oldSelection = new HashSet<>(
selection);
if (selection.size() + itemIds.size() >= selectionLimit) {
// Add one at a time if there's a risk of overflow
@@ -1728,7 +1731,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
return deselect(itemIds, true);
}
- protected boolean deselect(final Collection> itemIds, boolean refresh) {
+ protected boolean deselect(final Collection> itemIds,
+ boolean refresh) {
if (itemIds == null) {
throw new IllegalArgumentException("itemIds may not be null");
}
@@ -1736,7 +1740,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
final boolean hasCommonElements = !Collections.disjoint(itemIds,
selection);
if (hasCommonElements) {
- final HashSet oldSelection = new HashSet(
+ final HashSet oldSelection = new HashSet<>(
selection);
selection.removeAll(itemIds);
fireSelectionEvent(oldSelection, selection);
@@ -1820,7 +1824,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
checkItemIdsExist(itemIds);
boolean changed = false;
- Set selectedRows = new HashSet(itemIds);
+ Set selectedRows = new HashSet<>(itemIds);
final Collection oldSelection = getSelectedRows();
Set added = getDifference(selectedRows, selection);
if (!added.isEmpty()) {
@@ -1861,7 +1865,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
*/
private static Set getDifference(Set set1,
Set set2) {
- Set diff = new HashSet(set1);
+ Set diff = new HashSet<>(set1);
diff.removeAll(set2);
return diff;
}
@@ -2162,7 +2166,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
if (cellDescriptionGenerator != null
&& cellDescriptions.keys().length > 0) {
- rowData.put(GridState.JSONKEY_CELLDESCRIPTION, cellDescriptions);
+ rowData.put(GridState.JSONKEY_CELLDESCRIPTION,
+ cellDescriptions);
}
if (cellStyleGenerator != null && cellStyles.keys().length > 0) {
@@ -2229,8 +2234,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
private RowState rowState = new RowState();
protected StaticSection> section;
- private Map cells = new LinkedHashMap();
- private Map, CELLTYPE> cellGroups = new HashMap, CELLTYPE>();
+ private Map cells = new LinkedHashMap<>();
+ private Map, CELLTYPE> cellGroups = new HashMap<>();
protected StaticRow(StaticSection> section) {
this.section = section;
@@ -2238,7 +2243,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
protected void addCell(Object propertyId) {
CELLTYPE cell = createCell();
- cell.setColumnId(section.grid.getColumn(propertyId).getState().id);
+ cell.setColumnId(section.grid.getColumn(propertyId)
+ .getState().id);
cells.put(propertyId, cell);
rowState.cells.add(cell.getCellState());
}
@@ -2314,7 +2320,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
public CELLTYPE join(Object... propertyIds) {
assert propertyIds.length > 1 : "You need to merge at least 2 properties";
- Set cells = new HashSet();
+ Set cells = new HashSet<>();
for (int i = 0; i < propertyIds.length; ++i) {
cells.add(getCell(propertyIds[i]));
}
@@ -2332,7 +2338,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
public CELLTYPE join(CELLTYPE... cells) {
assert cells.length > 1 : "You need to merge at least 2 cells";
- return join(new HashSet(Arrays.asList(cells)));
+ return join(new HashSet<>(Arrays.asList(cells)));
}
protected CELLTYPE join(Set cells) {
@@ -2349,7 +2355,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
// Create new cell data for the group
CELLTYPE newCell = createCell();
- Set columnGroup = new HashSet();
+ Set columnGroup = new HashSet<>();
for (CELLTYPE cell : cells) {
columnGroup.add(cell.getColumnId());
}
@@ -2398,7 +2404,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
*/
protected void writeDesign(Element trElement,
DesignContext designContext) {
- Set visited = new HashSet();
+ Set visited = new HashSet<>();
for (Grid.Column column : section.grid.getColumns()) {
CELLTYPE cell = getCell(column.getPropertyId());
if (visited.contains(cell)) {
@@ -2450,7 +2456,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
int colspan = DesignAttributeHandler.readAttribute(
"colspan", element.attributes(), 1, int.class);
- Set cells = new HashSet();
+ Set cells = new HashSet<>();
for (int c = 0; c < colspan; ++c) {
cells.add(getCell(section.grid.getColumns()
.get(columnIndex + c).getPropertyId()));
@@ -2687,7 +2693,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
protected Grid grid;
- protected List rows = new ArrayList();
+ protected List rows = new ArrayList<>();
/**
* Sets the visibility of the whole section.
@@ -3106,7 +3112,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
@Override
- protected void readDesign(Element trElement, DesignContext designContext) {
+ protected void readDesign(Element trElement,
+ DesignContext designContext) {
super.readDesign(trElement, designContext);
boolean defaultRow = DesignAttributeHandler.readAttribute(
@@ -3656,7 +3663,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
+ toString()
+ " sortable. The Container of Grid does not implement Sortable");
} else if (!((Sortable) grid.datasource)
- .getSortableContainerPropertyIds().contains(propertyId)) {
+ .getSortableContainerPropertyIds().contains(
+ propertyId)) {
throw new IllegalStateException(
"Can't set column "
+ toString()
@@ -3786,8 +3794,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
/**
* Sets the maximum width for this column.
*
- * This defines the maximum allowed pixel width of the column
- * when it is set to expand.
+ * This defines the maximum allowed pixel width of the column when
+ * it is set to expand.
*
* @param pixels
* the maximum width
@@ -3882,7 +3890,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* the editor field
* @return this column
*/
- public Column setEditorField(Field> editor) {
+ public Column setEditorField(LegacyField> editor) {
grid.setEditorField(getPropertyId(), editor);
return this;
}
@@ -3910,7 +3918,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* if no field has been configured and there is a problem
* building or binding
*/
- public Field> getEditorField() {
+ public LegacyField> getEditorField() {
return grid.getEditorField(getPropertyId());
}
@@ -4020,7 +4028,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* @param designContext
* the design context
*/
- protected void writeDesign(Element design, DesignContext designContext) {
+ protected void writeDesign(Element design,
+ DesignContext designContext) {
Attributes attributes = design.attributes();
GridColumnState def = new GridColumnState();
@@ -4222,7 +4231,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* @return an encoded value ready to be sent to the client
*/
public static JsonValue encodeValue(Object modelValue,
- Renderer renderer, Converter, ?> converter, Locale locale) {
+ Renderer renderer, Converter, ?> converter,
+ Locale locale) {
Class presentationType = renderer.getPresentationType();
T presentationValue;
@@ -4417,17 +4427,17 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
/**
* Property id to column instance mapping
*/
- private final Map columns = new HashMap();
+ private final Map columns = new HashMap<>();
/**
* Key generator for column server-to-client communication
*/
- private final KeyMapper columnKeys = new KeyMapper();
+ private final KeyMapper columnKeys = new KeyMapper<>();
/**
* The current sort order
*/
- private final List sortOrder = new ArrayList();
+ private final List sortOrder = new ArrayList<>();
/**
* Property listener for listening to changes in data source properties.
@@ -4440,7 +4450,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
.getContainerPropertyIds());
// Find columns that need to be removed.
- List