summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenri Sara <hesara@vaadin.com>2013-02-14 14:31:58 +0200
committerHenri Sara <hesara@vaadin.com>2013-02-14 14:31:58 +0200
commit50e53f0734042b2daebe99d6f1476fca0fa72151 (patch)
tree9e4e90876028f5820a23e6fde8b8570685fb25e6
parent9185ce0a26db5574079e6a196dd121af9c3286ae (diff)
parentb72934473733b543498ba3a3c1082a332f539961 (diff)
downloadvaadin-framework-50e53f0734042b2daebe99d6f1476fca0fa72151.tar.gz
vaadin-framework-50e53f0734042b2daebe99d6f1476fca0fa72151.zip
Merge remote-tracking branch 'origin/7.0'
Change-Id: I7428e1c57836f055a39b39425a3bcb6bada38d1e
-rw-r--r--client/src/com/vaadin/client/ui/VLabel.java3
-rw-r--r--server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java37
-rw-r--r--server/src/com/vaadin/data/fieldgroup/FieldGroup.java93
-rw-r--r--server/src/com/vaadin/data/util/IndexedContainer.java3
-rw-r--r--server/src/com/vaadin/server/VaadinPortletService.java7
-rw-r--r--server/src/com/vaadin/server/VaadinServletService.java7
-rw-r--r--server/src/com/vaadin/ui/AbstractField.java24
-rw-r--r--server/src/com/vaadin/ui/Label.java17
-rw-r--r--server/tests/src/com/vaadin/data/util/TestIndexedContainer.java8
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/fieldgroup/CaseInsensitiveBinding.java84
10 files changed, 223 insertions, 60 deletions
diff --git a/client/src/com/vaadin/client/ui/VLabel.java b/client/src/com/vaadin/client/ui/VLabel.java
index 83fc8e207e..8acd653778 100644
--- a/client/src/com/vaadin/client/ui/VLabel.java
+++ b/client/src/com/vaadin/client/ui/VLabel.java
@@ -16,7 +16,6 @@
package com.vaadin.client.ui;
-import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTML;
import com.vaadin.client.ApplicationConnection;
@@ -57,10 +56,8 @@ public class VLabel extends HTML {
super.setWidth(width);
if (width == null || width.equals("")) {
setStyleName(getElement(), CLASSNAME_UNDEFINED_WIDTH, true);
- getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
} else {
setStyleName(getElement(), CLASSNAME_UNDEFINED_WIDTH, false);
- getElement().getStyle().clearDisplay();
}
}
diff --git a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
index 7e44c26c9e..55bd3a4641 100644
--- a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
@@ -58,6 +58,23 @@ public class BeanFieldGroup<T> extends FieldGroup {
}
}
+ @Override
+ protected Object findPropertyId(java.lang.reflect.Field memberField) {
+ String fieldName = memberField.getName();
+ Item dataSource = getItemDataSource();
+ if (dataSource != null && dataSource.getItemProperty(fieldName) != null) {
+ return fieldName;
+ } else {
+ String minifiedFieldName = minifyFieldName(fieldName);
+ try {
+ return getFieldName(beanType, minifiedFieldName);
+ } catch (SecurityException e) {
+ } catch (NoSuchFieldException e) {
+ }
+ }
+ return null;
+ }
+
private static java.lang.reflect.Field getField(Class<?> cls,
String propertyId) throws SecurityException, NoSuchFieldException {
if (propertyId.contains(".")) {
@@ -75,7 +92,7 @@ public class BeanFieldGroup<T> extends FieldGroup {
} catch (NoSuchFieldError e) {
// Try super classes until we reach Object
Class<?> superClass = cls.getSuperclass();
- if (superClass != Object.class) {
+ if (superClass != null && superClass != Object.class) {
return getField(superClass, propertyId);
} else {
throw e;
@@ -84,6 +101,22 @@ public class BeanFieldGroup<T> extends FieldGroup {
}
}
+ private static String getFieldName(Class<?> cls, String propertyId)
+ throws SecurityException, NoSuchFieldException {
+ for (java.lang.reflect.Field field1 : cls.getDeclaredFields()) {
+ if (propertyId.equals(minifyFieldName(field1.getName()))) {
+ return field1.getName();
+ }
+ }
+ // Try super classes until we reach Object
+ Class<?> superClass = cls.getSuperclass();
+ if (superClass != null && superClass != Object.class) {
+ return getFieldName(superClass, propertyId);
+ } else {
+ throw new NoSuchFieldException();
+ }
+ }
+
/**
* Helper method for setting the data source directly using a bean. This
* method wraps the bean in a {@link BeanItem} and calls
@@ -166,4 +199,4 @@ public class BeanFieldGroup<T> extends FieldGroup {
}
return beanValidationImplementationAvailable;
}
-} \ No newline at end of file
+}
diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
index dc1fdbb78d..6c515dbdee 100644
--- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
@@ -733,11 +733,12 @@ public class FieldGroup implements Serializable {
* that have not been initialized.
* <p>
* This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory. All non-null fields for which a property id can
- * be determined are bound to the property id.
+ * {@link Field} 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
+ * field factory. All non-null fields for which a property id can be
+ * determined are bound to the property id.
* </p>
* <p>
* For example:
@@ -777,11 +778,12 @@ public class FieldGroup implements Serializable {
* member fields that have not been initialized.
* <p>
* This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory is buildFields is true. All non-null fields for
- * which a property id can be determined are bound to the property id.
+ * {@link Field} 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
+ * field factory is buildFields is true. All non-null fields for which a
+ * property id can be determined are bound to the property id.
* </p>
*
* @param objectWithMemberFields
@@ -812,7 +814,16 @@ public class FieldGroup implements Serializable {
// @PropertyId(propertyId) always overrides property id
propertyId = propertyIdAnnotation.value();
} else {
- propertyId = memberField.getName();
+ try {
+ propertyId = findPropertyId(memberField);
+ } catch (SearchException e) {
+ // Property id was not found, skip this field
+ continue;
+ }
+ if (propertyId == null) {
+ // Property id was not found, skip this field
+ continue;
+ }
}
// Ensure that the property id exists
@@ -873,6 +884,54 @@ public class FieldGroup implements Serializable {
}
}
+ /**
+ * Searches for a property id from the current itemDataSource that matches
+ * the given memberField.
+ * <p>
+ * If perfect match is not found, uses a case insensitive search that also
+ * ignores underscores. Returns null if no match is found. Throws a
+ * SearchException if no item data source has been set.
+ * </p>
+ * <p>
+ * The propertyId search logic used by
+ * {@link #buildAndBindMemberFields(Object, boolean)
+ * buildAndBindMemberFields} can easily be customized by overriding this
+ * method. No other changes are needed.
+ * </p>
+ *
+ * @param memberField
+ * The field an object id is searched for
+ * @return
+ */
+ protected Object findPropertyId(java.lang.reflect.Field memberField) {
+ String fieldName = memberField.getName();
+ if (getItemDataSource() == null) {
+ throw new SearchException(
+ "Property id type for field '"
+ + fieldName
+ + "' could not be determined. No item data source has been set.");
+ }
+ Item dataSource = getItemDataSource();
+ if (dataSource.getItemProperty(fieldName) != null) {
+ return fieldName;
+ } else {
+ String minifiedFieldName = minifyFieldName(fieldName);
+ for (Object itemPropertyId : dataSource.getItemPropertyIds()) {
+ if (itemPropertyId instanceof String) {
+ String itemPropertyName = (String) itemPropertyId;
+ if (minifiedFieldName.equals(minifyFieldName(itemPropertyName))) {
+ return itemPropertyName;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ protected static String minifyFieldName(String fieldName) {
+ return fieldName.toLowerCase().replace("_", "");
+ }
+
public static class CommitException extends Exception {
public CommitException() {
@@ -909,6 +968,18 @@ public class FieldGroup implements Serializable {
}
+ public static class SearchException extends RuntimeException {
+
+ public SearchException(String message) {
+ super(message);
+ }
+
+ public SearchException(String message, Throwable t) {
+ super(message, t);
+ }
+
+ }
+
/**
* Builds a field and binds it to the given property id using the field
* binder.
diff --git a/server/src/com/vaadin/data/util/IndexedContainer.java b/server/src/com/vaadin/data/util/IndexedContainer.java
index 1705365f60..306f9cf23b 100644
--- a/server/src/com/vaadin/data/util/IndexedContainer.java
+++ b/server/src/com/vaadin/data/util/IndexedContainer.java
@@ -166,7 +166,8 @@ public class IndexedContainer extends
public Property getContainerProperty(Object itemId, Object propertyId) {
// map lookup more efficient than propertyIds if there are many
// properties
- if (!containsId(itemId) || !types.containsKey(propertyId)) {
+ if (!containsId(itemId) || propertyId == null
+ || !types.containsKey(propertyId)) {
return null;
}
diff --git a/server/src/com/vaadin/server/VaadinPortletService.java b/server/src/com/vaadin/server/VaadinPortletService.java
index e59ea7fd5e..8c1e7af0fa 100644
--- a/server/src/com/vaadin/server/VaadinPortletService.java
+++ b/server/src/com/vaadin/server/VaadinPortletService.java
@@ -46,7 +46,12 @@ public class VaadinPortletService extends VaadinService {
}
}
- protected VaadinPortlet getPortlet() {
+ /**
+ * Retrieves a reference to the portlet associated with this service.
+ *
+ * @return A reference to the VaadinPortlet this service is using
+ */
+ public VaadinPortlet getPortlet() {
return portlet;
}
diff --git a/server/src/com/vaadin/server/VaadinServletService.java b/server/src/com/vaadin/server/VaadinServletService.java
index 71f47ea217..7120e3a5c5 100644
--- a/server/src/com/vaadin/server/VaadinServletService.java
+++ b/server/src/com/vaadin/server/VaadinServletService.java
@@ -44,7 +44,12 @@ public class VaadinServletService extends VaadinService {
}
}
- protected VaadinServlet getServlet() {
+ /**
+ * Retrieves a reference to the servlet associated with this service.
+ *
+ * @return A reference to the VaadinServlet this service is using
+ */
+ public VaadinServlet getServlet() {
return servlet;
}
diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java
index 422e0a1796..619d717d97 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/com/vaadin/ui/AbstractField.java
@@ -373,30 +373,6 @@ public abstract class AbstractField<T> extends AbstractComponent implements
/* Property interface implementation */
/**
- * Returns the (field) value converted to a String using toString().
- *
- * @see java.lang.Object#toString()
- * @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() {
- logger.warning("You are using AbstractField.toString() to get the value for a "
- + getClass().getSimpleName()
- + ". This will not be supported starting from Vaadin 7.1 "
- + "(your debugger might call toString() and cause this message to appear).");
- final Object value = getFieldValue();
- if (value == null) {
- return null;
- }
- return value.toString();
- }
-
- /**
* Gets the current value of the field.
*
* <p>
diff --git a/server/src/com/vaadin/ui/Label.java b/server/src/com/vaadin/ui/Label.java
index f49a1403cf..f413ea47f2 100644
--- a/server/src/com/vaadin/ui/Label.java
+++ b/server/src/com/vaadin/ui/Label.java
@@ -203,23 +203,6 @@ public class Label extends AbstractComponent implements Property<String>,
}
/**
- * Returns the value displayed by this label.
- *
- * @see java.lang.Object#toString()
- * @deprecated As of 7.0, use {@link #getValue()} to get the value of the
- * label or {@link #getPropertyDataSource()} .getValue() to get
- * the value of the data source.
- */
- @Deprecated
- @Override
- public String toString() {
- logger.warning("You are using Label.toString() to get the value for a "
- + getClass().getSimpleName()
- + ". This will not be supported starting from Vaadin 7.1 (your debugger might call toString() and cause this message to appear).");
- return getValue();
- }
-
- /**
* Gets the type of the Property.
*
* @see com.vaadin.data.Property#getType()
diff --git a/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
index 971cdb5f62..09e5a26c15 100644
--- a/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
+++ b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
@@ -384,4 +384,12 @@ public class TestIndexedContainer extends AbstractInMemoryContainerTest {
assertNull(ic.getContainerProperty(object1, "xyz"));
}
+ // test getting null property id (#10445)
+ public void testNullPropertyId() {
+ IndexedContainer ic = new IndexedContainer();
+ String object1 = new String("Obj1");
+ ic.addItem(object1);
+ assertNull(ic.getContainerProperty(object1, null));
+ }
+
}
diff --git a/server/tests/src/com/vaadin/tests/server/component/fieldgroup/CaseInsensitiveBinding.java b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/CaseInsensitiveBinding.java
new file mode 100644
index 0000000000..3f4368c295
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/CaseInsensitiveBinding.java
@@ -0,0 +1,84 @@
+package com.vaadin.tests.server.component.fieldgroup;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.TextField;
+
+public class CaseInsensitiveBinding {
+
+ @Test
+ public void caseInsensitivityAndUnderscoreRemoval() {
+ PropertysetItem item = new PropertysetItem();
+ item.addItemProperty("LastName", new ObjectProperty<String>("Sparrow"));
+
+ class MyForm extends FormLayout {
+ TextField lastName = new TextField("Last name");
+
+ public MyForm() {
+
+ // Should bind to the LastName property
+ addComponent(lastName);
+ }
+ }
+
+ MyForm form = new MyForm();
+
+ FieldGroup binder = new FieldGroup(item);
+ binder.bindMemberFields(form);
+
+ assertTrue("Sparrow".equals(form.lastName.getValue()));
+ }
+
+ @Test
+ public void UnderscoreRemoval() {
+ PropertysetItem item = new PropertysetItem();
+ item.addItemProperty("first_name", new ObjectProperty<String>("Jack"));
+
+ class MyForm extends FormLayout {
+ TextField firstName = new TextField("First name");
+
+ public MyForm() {
+ // Should bind to the first_name property
+ addComponent(firstName);
+ }
+ }
+
+ MyForm form = new MyForm();
+
+ FieldGroup binder = new FieldGroup(item);
+ binder.bindMemberFields(form);
+
+ assertTrue("Jack".equals(form.firstName.getValue()));
+ }
+
+ @Test
+ public void perfectMatchPriority() {
+ PropertysetItem item = new PropertysetItem();
+ item.addItemProperty("first_name", new ObjectProperty<String>(
+ "Not this"));
+ item.addItemProperty("firstName", new ObjectProperty<String>("This"));
+
+ class MyForm extends FormLayout {
+ TextField firstName = new TextField("First name");
+
+ public MyForm() {
+ // should bind to the firstName property, not first_name property
+ addComponent(firstName);
+ }
+ }
+
+ MyForm form = new MyForm();
+
+ FieldGroup binder = new FieldGroup(item);
+ binder.bindMemberFields(form);
+
+ assertTrue("This".equals(form.firstName.getValue()));
+ }
+
+} \ No newline at end of file