Browse Source

Remove conversions using String constructor from Properties (#8125).

ObjectProperty and MethodProperty no longer try to automatically convert
values using a String constructor of the property type. Related fixes to
tests.
tags/7.0.0.alpha1
Henri Sara 12 years ago
parent
commit
d62a07bd1b

+ 12
- 37
src/com/vaadin/data/util/MethodProperty.java View File

@@ -5,7 +5,6 @@
package com.vaadin.data.util;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
@@ -630,9 +629,10 @@ public class MethodProperty<T> extends AbstractProperty<T> {
}

/**
* Sets the value of the property. This method supports setting from
* <code>String</code>s if either <code>String</code> is directly assignable
* to property type, or the type class contains a string constructor.
* Sets the value of the property.
*
* Note that since Vaadin 7, no conversions are performed and the value must
* be of the correct type.
*
* @param newValue
* the New value of the property.
@@ -643,6 +643,7 @@ public class MethodProperty<T> extends AbstractProperty<T> {
* native type directly or through <code>String</code>.
* @see #invokeSetMethod(Object)
*/
@SuppressWarnings("unchecked")
public void setValue(Object newValue) throws Property.ReadOnlyException,
Property.ConversionException {

@@ -651,40 +652,14 @@ public class MethodProperty<T> extends AbstractProperty<T> {
throw new Property.ReadOnlyException();
}

Object value = convertValue(newValue, type);

invokeSetMethod(value);
fireValueChange();
}

/**
* Convert a value to the given type, using a constructor of the type that
* takes a single String parameter (toString() for the value) if necessary.
*
* @param value
* to convert
* @param type
* type into which the value should be converted
* @return converted value
*/
static Object convertValue(Object value, Class<?> type) {
if (null == value || type.isAssignableFrom(value.getClass())) {
return value;
// Checks the type of the value
if (newValue != null && !type.isAssignableFrom(newValue.getClass())) {
throw new Property.ConversionException(
"Invalid value type for ObjectProperty.");
}

// convert using a string constructor
try {
// Gets the string constructor
@SuppressWarnings("rawtypes")
final Constructor constr = type
.getConstructor(new Class[] { String.class });

// Create a new object from the string
return constr.newInstance(new Object[] { value.toString() });

} catch (final java.lang.Exception e) {
throw new Property.ConversionException(e);
}
invokeSetMethod((T) newValue);
fireValueChange();
}

/**
@@ -693,7 +668,7 @@ public class MethodProperty<T> extends AbstractProperty<T> {
*
* @param value
*/
protected void invokeSetMethod(Object value) {
protected void invokeSetMethod(T value) {

try {
// Construct a temporary argument array only if needed

+ 7
- 3
src/com/vaadin/data/util/NestedMethodProperty.java View File

@@ -213,9 +213,13 @@ public class NestedMethodProperty<T> extends AbstractProperty<T> {
throw new Property.ReadOnlyException();
}

Object value = MethodProperty.convertValue(newValue, type);
// Checks the type of the value
if (newValue != null && !type.isAssignableFrom(newValue.getClass())) {
throw new Property.ConversionException(
"Invalid value type for NestedMethodProperty.");
}

invokeSetMethod(value);
invokeSetMethod((T) newValue);
fireValueChange();
}

@@ -225,7 +229,7 @@ public class NestedMethodProperty<T> extends AbstractProperty<T> {
*
* @param value
*/
protected void invokeSetMethod(Object value) {
protected void invokeSetMethod(T value) {
try {
Object object = instance;
for (int i = 0; i < getMethods.size() - 1; i++) {

+ 14
- 29
src/com/vaadin/data/util/ObjectProperty.java View File

@@ -4,8 +4,6 @@

package com.vaadin.data.util;

import java.lang.reflect.Constructor;

import com.vaadin.data.Property;

/**
@@ -107,18 +105,19 @@ public class ObjectProperty<T> extends AbstractProperty<T> {
}

/**
* Sets the value of the property. This method supports setting from
* <code>String</code> if either <code>String</code> is directly assignable
* to property type, or the type class contains a string constructor.
* Sets the value of the property.
*
* Note that since Vaadin 7, no conversions are performed and the value must
* be of the correct type.
*
* @param newValue
* the New value of the property.
* @throws <code>Property.ReadOnlyException</code> if the object is in
* read-only mode
* @throws <code>Property.ConversionException</code> if the newValue can't
* be converted into the Property's native type directly or through
* <code>String</code>
* @throws <code>Property.ConversionException</code> if the newValue is not
* of a correct type
*/
@SuppressWarnings("unchecked")
public void setValue(Object newValue) throws Property.ReadOnlyException,
Property.ConversionException {

@@ -127,29 +126,15 @@ public class ObjectProperty<T> extends AbstractProperty<T> {
throw new Property.ReadOnlyException();
}

// Tries to assign the compatible value directly
if (newValue == null || type.isAssignableFrom(newValue.getClass())) {
@SuppressWarnings("unchecked")
// the cast is safe after an isAssignableFrom check
T value = (T) newValue;
this.value = value;
} else {
try {

// Gets the string constructor
final Constructor<T> constr = getType().getConstructor(
new Class[] { String.class });

// Creates new object from the string
value = constr
.newInstance(new Object[] { newValue.toString() });

} catch (final java.lang.Exception e) {
throw new Property.ConversionException(e);
}
// Checks the type of the value
if (newValue != null && !type.isAssignableFrom(newValue.getClass())) {
throw new Property.ConversionException(
"Invalid value type for ObjectProperty.");
}

// the cast is safe after an isAssignableFrom check
this.value = (T) newValue;

fireValueChange();
}

}

+ 8
- 8
tests/server-side/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java View File

@@ -6,7 +6,7 @@ import junit.framework.TestCase;
import com.vaadin.data.util.MethodProperty;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.converter.NumberToStringConverter;
import com.vaadin.data.util.converter.IntegerToStringConverter;
import com.vaadin.tests.data.bean.Address;
import com.vaadin.tests.data.bean.Country;
import com.vaadin.tests.data.bean.Person;
@@ -22,7 +22,7 @@ public class AbstractFieldValueConversions extends TestCase {
public void testWithoutConversion() {
TextField tf = new TextField();
tf.setPropertyDataSource(new MethodProperty<Person>(paulaBean,
tf.setPropertyDataSource(new MethodProperty<String>(paulaBean,
"firstName"));
assertEquals("Paula", tf.getValue());
assertEquals("Paula", tf.getPropertyDataSource().getValue());
@@ -52,7 +52,7 @@ public class AbstractFieldValueConversions extends TestCase {
return String.class;
}
});
tf.setPropertyDataSource(new MethodProperty<Person>(paulaBean,
tf.setPropertyDataSource(new MethodProperty<String>(paulaBean,
"firstName"));
assertEquals("Paula", tf.getValue());
assertEquals("Paula", tf.getPropertyDataSource().getValue());
@@ -95,8 +95,8 @@ public class AbstractFieldValueConversions extends TestCase {
public void testIntegerStringConversion() {
TextField tf = new TextField();
tf.setValueConverter(new NumberToStringConverter());
tf.setPropertyDataSource(new MethodProperty<Person>(paulaBean, "age"));
tf.setValueConverter(new IntegerToStringConverter());
tf.setPropertyDataSource(new MethodProperty<Integer>(paulaBean, "age"));
assertEquals(34, tf.getPropertyDataSource().getValue());
assertEquals("34", tf.getValue());
tf.setValue("12");
@@ -138,10 +138,10 @@ public class AbstractFieldValueConversions extends TestCase {
}
});
MethodProperty<Person> property = new MethodProperty<Person>(paulaBean,
"deceased");
MethodProperty<Boolean> property = new MethodProperty<Boolean>(
paulaBean, "deceased");
cb.setPropertyDataSource(property);
assertNull(property.getValue());
assertEquals(Boolean.FALSE, property.getValue());
assertEquals(Boolean.FALSE, cb.getValue());
Boolean newDmValue = cb.getValueConverter().convertFromSourceToTarget(
cb.getValue(), new Locale("fi", "FI"));

+ 2
- 2
tests/testbench/com/vaadin/tests/components/abstractfield/DoubleInTextField.java View File

@@ -17,12 +17,12 @@ public class DoubleInTextField extends AbstractComponentDataBindingTest {
TextField salary = new TextField("Vaadin 7 - TextField with Double");
addComponent(salary);
salary.setPropertyDataSource(new MethodProperty<Person>(person,
salary.setPropertyDataSource(new MethodProperty<Double>(person,
"salaryDouble"));
TextField salary6 = new TextField("Vaadin 6 - TextField with Double");
addComponent(salary6);
salary6.setPropertyDataSource(new MethodProperty<Person>(person,
salary6.setPropertyDataSource(new MethodProperty<Double>(person,
"salaryDouble"));
salary6.setValueConverter(new Vaadin6ImplicitDoubleConverter());

Loading…
Cancel
Save