summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2012-06-19 16:14:06 +0300
committerArtur Signell <artur@vaadin.com>2012-06-21 17:11:26 +0300
commitd627ad58d2d11a09947a8eac4cd12b72c3d02669 (patch)
treeefbc546a39efdbed49aea70a44d69e32cf07ff2b /src/com/vaadin
parent71abc602b00089b17b247c64729588a0d187eafd (diff)
downloadvaadin-framework-d627ad58d2d11a09947a8eac4cd12b72c3d02669.tar.gz
vaadin-framework-d627ad58d2d11a09947a8eac4cd12b72c3d02669.zip
Converter support and updated data source logic (#8990, #8991)
Diffstat (limited to 'src/com/vaadin')
-rw-r--r--src/com/vaadin/data/util/converter/ConverterUtil.java31
-rw-r--r--src/com/vaadin/ui/AbstractField.java4
-rw-r--r--src/com/vaadin/ui/Label.java86
3 files changed, 95 insertions, 26 deletions
diff --git a/src/com/vaadin/data/util/converter/ConverterUtil.java b/src/com/vaadin/data/util/converter/ConverterUtil.java
index 8be8ae799e..5fe3101db2 100644
--- a/src/com/vaadin/data/util/converter/ConverterUtil.java
+++ b/src/com/vaadin/data/util/converter/ConverterUtil.java
@@ -3,11 +3,12 @@
*/
package com.vaadin.data.util.converter;
+import java.io.Serializable;
import java.util.Locale;
import com.vaadin.Application;
-public class ConverterUtil {
+public class ConverterUtil implements Serializable {
public static <UITYPE, MODELTYPE> Converter<UITYPE, MODELTYPE> getConverter(
Class<UITYPE> uiType, Class<MODELTYPE> modelType) {
@@ -110,4 +111,32 @@ public class ConverterUtil {
}
+ /**
+ * Checks if the given converter can handle conversion between the given
+ * presentation and model type
+ *
+ * @param converter
+ * The converter to check
+ * @param presentationType
+ * The presentation type
+ * @param modelType
+ * The model type
+ * @return true if the converter supports conversion between the given
+ * presentation and model type, false otherwise
+ */
+ public static boolean canConverterHandle(Converter<?, ?> converter,
+ Class<?> presentationType, Class<?> modelType) {
+ if (converter == null) {
+ return false;
+ }
+
+ if (!modelType.isAssignableFrom(converter.getModelType())) {
+ return false;
+ }
+ if (!presentationType.isAssignableFrom(converter.getPresentationType())) {
+ return false;
+ }
+
+ return true;
+ }
}
diff --git a/src/com/vaadin/ui/AbstractField.java b/src/com/vaadin/ui/AbstractField.java
index 3c78c21b53..b74dba6d65 100644
--- a/src/com/vaadin/ui/AbstractField.java
+++ b/src/com/vaadin/ui/AbstractField.java
@@ -701,8 +701,8 @@ public abstract class AbstractField<T> extends AbstractComponent implements
// Check if the current converter is compatible.
if (newDataSource != null
- && (getConverter() == null || !newDataSource.getType()
- .isAssignableFrom(getConverter().getModelType()))) {
+ && !ConverterUtil.canConverterHandle(getConverter(), getType(),
+ newDataSource.getType())) {
// Changing from e.g. Number -> Double should set a new converter,
// changing from Double -> Number can keep the old one (Property
// accepts Number)
diff --git a/src/com/vaadin/ui/Label.java b/src/com/vaadin/ui/Label.java
index 12b9aeab66..12e1f9590e 100644
--- a/src/com/vaadin/ui/Label.java
+++ b/src/com/vaadin/ui/Label.java
@@ -7,7 +7,8 @@ package com.vaadin.ui;
import java.lang.reflect.Method;
import com.vaadin.data.Property;
-import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ConverterUtil;
import com.vaadin.terminal.gwt.client.ui.label.ContentMode;
import com.vaadin.terminal.gwt.client.ui.label.LabelState;
@@ -76,9 +77,13 @@ public class Label extends AbstractComponent implements Property<String>,
@Deprecated
public static final ContentMode CONTENT_DEFAULT = ContentMode.TEXT;
- private static final String DATASOURCE_MUST_BE_SET = "Datasource must be set";
+ /**
+ * A converter used to convert from the data model type to the field type
+ * and vice versa. Label type is always String.
+ */
+ private Converter<String, Object> converter = null;
- private Property<String> dataSource;
+ private Property<String> dataSource = null;
/**
* Creates an empty Label.
@@ -113,7 +118,9 @@ public class Label extends AbstractComponent implements Property<String>,
* @param contentMode
*/
public Label(String content, ContentMode contentMode) {
- this(new ObjectProperty<String>(content, String.class), contentMode);
+ setValue(content);
+ setContentMode(contentMode);
+ setWidth(100, Unit.PERCENTAGE);
}
/**
@@ -126,15 +133,7 @@ public class Label extends AbstractComponent implements Property<String>,
public Label(Property contentSource, ContentMode contentMode) {
setPropertyDataSource(contentSource);
setContentMode(contentMode);
- setWidth(100, UNITS_PERCENTAGE);
- }
-
- @Override
- public void updateState() {
- super.updateState();
- // We don't know when the text is updated so update it here before
- // sending the state to the client
- getState().setText(getValue());
+ setWidth(100, Unit.PERCENTAGE);
}
@Override
@@ -149,24 +148,34 @@ public class Label extends AbstractComponent implements Property<String>,
* @return the Value of the label.
*/
public String getValue() {
- if (dataSource == null) {
- throw new IllegalStateException(DATASOURCE_MUST_BE_SET);
+ if (getPropertyDataSource() == null) {
+ // Use internal value if we are running without a data source
+ return getState().getText();
}
- return dataSource.getValue();
+ return ConverterUtil.convertFromModel(getPropertyDataSource()
+ .getValue(), String.class, getConverter(), getLocale());
}
/**
* Set the value of the label. Value of the label is the XML contents of the
* label.
*
- * @param newValue
+ * @param newStringValue
* the New value of the label.
*/
- public void setValue(Object newValue) {
- if (dataSource == null) {
- throw new IllegalStateException(DATASOURCE_MUST_BE_SET);
+ public void setValue(Object newStringValue) {
+ if (newStringValue != null && newStringValue.getClass() != String.class) {
+ throw new Converter.ConversionException("Value of type "
+ + newStringValue.getClass() + " cannot be assigned to "
+ + String.class.getName());
+ }
+ if (getPropertyDataSource() == null) {
+ getState().setText((String) newStringValue);
+ requestRepaint();
+ } else {
+ throw new IllegalStateException(
+ "Label is only a Property.Viewer and cannot update its data source");
}
- dataSource.setValue(newValue);
}
/**
@@ -215,7 +224,13 @@ public class Label extends AbstractComponent implements Property<String>,
((Property.ValueChangeNotifier) dataSource).removeListener(this);
}
- // Sets the new data source
+ if (!ConverterUtil.canConverterHandle(getConverter(), String.class,
+ newDataSource.getType())) {
+ // Try to find a converter
+ Converter<String, ?> c = ConverterUtil.getConverter(String.class,
+ newDataSource.getType());
+ setConverter(c);
+ }
dataSource = newDataSource;
// Listens the new data source if possible
@@ -331,7 +346,6 @@ public class Label extends AbstractComponent implements Property<String>,
protected void fireValueChange() {
// Set the error message
fireEvent(new Label.ValueChangeEvent(this));
- requestRepaint();
}
/**
@@ -340,6 +354,10 @@ public class Label extends AbstractComponent implements Property<String>,
* @see com.vaadin.data.Property.ValueChangeListener#valueChange(Property.ValueChangeEvent)
*/
public void valueChange(Property.ValueChangeEvent event) {
+ // Update the internal value from the data source
+ getState().setText(getValue());
+ requestRepaint();
+
fireValueChange();
}
@@ -418,4 +436,26 @@ public class Label extends AbstractComponent implements Property<String>,
return res.toString();
}
+ /**
+ * Gets the converter used to convert the property data source value to the
+ * label value.
+ *
+ * @return The converter or null if none is set.
+ */
+ public Converter<String, Object> getConverter() {
+ return converter;
+ }
+
+ /**
+ * Sets the converter used to convert the label value to the property data
+ * source type. The converter must have a presentation type of String.
+ *
+ * @param converter
+ * The new converter to use.
+ */
+ public void setConverter(Converter<String, ?> converter) {
+ this.converter = (Converter<String, Object>) converter;
+ requestRepaint();
+ }
+
}