aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorMatti Hosio <mhosio@vaadin.com>2014-12-17 10:31:33 +0200
committerMatti Hosio <mhosio@vaadin.com>2014-12-17 10:31:33 +0200
commite547f024533bef83b8c8c8e522240f34765c894d (patch)
tree4610ad629b996df6d7882a8f9190922a467046d2 /server
parent8a0a1bdb4630f39214a039a2689bfa5a1431a413 (diff)
parenta9f24b00e9ddcd5ca19ac2907e0bf2413f036af4 (diff)
downloadvaadin-framework-e547f024533bef83b8c8c8e522240f34765c894d.tar.gz
vaadin-framework-e547f024533bef83b8c8c8e522240f34765c894d.zip
Merge remote-tracking branch 'origin/master' into declarative
Conflicts: server/src/com/vaadin/ui/TextField.java Change-Id: I289cb9ec80d494ab79aec11a43708abf5b403a00
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java65
-rw-r--r--server/src/com/vaadin/data/fieldgroup/FieldGroup.java89
-rw-r--r--server/src/com/vaadin/data/util/AbstractBeanContainer.java10
-rw-r--r--server/src/com/vaadin/data/util/BeanItem.java132
-rw-r--r--server/src/com/vaadin/data/util/BeanUtil.java177
-rw-r--r--server/src/com/vaadin/data/util/MethodProperty.java10
-rw-r--r--server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java1
-rw-r--r--server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java7
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java11
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToByteConverter.java2
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToEnumConverter.java78
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToShortConverter.java2
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java27
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java6
-rw-r--r--server/src/com/vaadin/navigator/Navigator.java7
-rw-r--r--server/src/com/vaadin/server/BootstrapHandler.java2
-rw-r--r--server/src/com/vaadin/server/FileResource.java3
-rw-r--r--server/src/com/vaadin/server/VaadinService.java8
-rw-r--r--server/src/com/vaadin/server/VaadinServlet.java28
-rw-r--r--server/src/com/vaadin/server/communication/UIInitHandler.java29
-rw-r--r--server/src/com/vaadin/ui/AbsoluteLayout.java2
-rw-r--r--server/src/com/vaadin/ui/AbstractComponentContainer.java2
-rw-r--r--server/src/com/vaadin/ui/AbstractField.java19
-rw-r--r--server/src/com/vaadin/ui/AbstractSelect.java19
-rw-r--r--server/src/com/vaadin/ui/AbstractSplitPanel.java16
-rw-r--r--server/src/com/vaadin/ui/AbstractTextField.java2
-rw-r--r--server/src/com/vaadin/ui/ComboBox.java4
-rw-r--r--server/src/com/vaadin/ui/CssLayout.java4
-rw-r--r--server/src/com/vaadin/ui/CustomLayout.java4
-rw-r--r--server/src/com/vaadin/ui/DateField.java16
-rw-r--r--server/src/com/vaadin/ui/Field.java22
-rw-r--r--server/src/com/vaadin/ui/Form.java9
-rw-r--r--server/src/com/vaadin/ui/GridLayout.java3
-rw-r--r--server/src/com/vaadin/ui/RichTextArea.java2
-rw-r--r--server/src/com/vaadin/ui/TabSheet.java11
-rw-r--r--server/src/com/vaadin/ui/TextField.java15
-rw-r--r--server/src/com/vaadin/ui/UI.java8
-rw-r--r--server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java74
-rw-r--r--server/tests/src/com/vaadin/data/util/BeanContainerTest.java13
-rw-r--r--server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java55
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java188
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestDefaultConverterFactory.java128
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java28
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java16
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java14
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java15
-rw-r--r--server/tests/src/com/vaadin/tests/server/FileResourceTest.java36
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java21
-rw-r--r--server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java50
-rw-r--r--server/tests/src/com/vaadin/ui/AbstractSelectTest.java71
-rw-r--r--server/tests/src/com/vaadin/ui/RichTextAreaTest.java47
-rw-r--r--server/tests/src/com/vaadin/ui/TextAreaTest.java47
-rw-r--r--server/tests/src/com/vaadin/ui/UIThemeEscaping.java89
53 files changed, 1298 insertions, 446 deletions
diff --git a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
index e5d53b759d..23a72ee1e5 100644
--- a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
@@ -15,18 +15,20 @@
*/
package com.vaadin.data.fieldgroup;
+import java.beans.IntrospectionException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
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;
public class BeanFieldGroup<T> extends FieldGroup {
- private Class<T> beanType;
+ private final Class<T> beanType;
private static Boolean beanValidationImplementationAvailable = null;
private final Map<Field<?>, BeanValidator> defaultValidators;
@@ -47,17 +49,20 @@ public class BeanFieldGroup<T> extends FieldGroup {
* form "fieldName" or "fieldName.subField[.subField2]" but the
* method declaration comes from parent.
*/
- java.lang.reflect.Field f;
try {
- f = getField(beanType, propertyId.toString());
- return f.getType();
- } catch (SecurityException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'.", e);
- } catch (NoSuchFieldException e) {
+ Class<?> type = BeanUtil.getPropertyType(beanType,
+ propertyId.toString());
+ if (type == null) {
+ throw new BindException(
+ "Cannot determine type of propertyId '"
+ + propertyId
+ + "'. The propertyId was not found in "
+ + beanType.getName());
+ }
+ return type;
+ } catch (IntrospectionException e) {
throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'. The propertyId was not found in "
- + beanType.getName(), e);
+ + propertyId + "'. Unable to introspect " + beanType, e);
}
}
}
@@ -79,32 +84,6 @@ public class BeanFieldGroup<T> extends FieldGroup {
return null;
}
- private static java.lang.reflect.Field getField(Class<?> cls,
- String propertyId) throws SecurityException, NoSuchFieldException {
- if (propertyId.contains(".")) {
- String[] parts = propertyId.split("\\.", 2);
- // Get the type of the field in the "cls" class
- java.lang.reflect.Field field1 = getField(cls, parts[0]);
- // Find the rest from the sub type
- return getField(field1.getType(), parts[1]);
- } else {
- try {
- // Try to find the field directly in the given class
- java.lang.reflect.Field field1 = cls
- .getDeclaredField(propertyId);
- return field1;
- } catch (NoSuchFieldException e) {
- // Try super classes until we reach Object
- Class<?> superClass = cls.getSuperclass();
- if (superClass != null && superClass != Object.class) {
- return getField(superClass, propertyId);
- } else {
- throw e;
- }
- }
- }
- }
-
private static String getFieldName(Class<?> cls, String propertyId)
throws SecurityException, NoSuchFieldException {
for (java.lang.reflect.Field field1 : cls.getDeclaredFields()) {
@@ -125,21 +104,29 @@ public class BeanFieldGroup<T> extends FieldGroup {
* Helper method for setting the data source directly using a bean. This
* method wraps the bean in a {@link BeanItem} and calls
* {@link #setItemDataSource(Item)}.
+ * <p>
+ * For null values, a null item is passed to
+ * {@link #setItemDataSource(Item)} to be properly clear fields.
*
* @param bean
* The bean to use as data source.
*/
public void setItemDataSource(T bean) {
- setItemDataSource(new BeanItem(bean));
+ if (bean == null) {
+ setItemDataSource((Item) null);
+ } else {
+ setItemDataSource(new BeanItem<T>(bean, beanType));
+ }
}
@Override
public void setItemDataSource(Item item) {
- if (!(item instanceof BeanItem)) {
+ if (item == null || (item instanceof BeanItem)) {
+ super.setItemDataSource(item);
+ } else {
throw new RuntimeException(getClass().getSimpleName()
+ " only supports BeanItems as item data source");
}
- super.setItemDataSource(item);
}
@Override
diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
index 5a4e877554..c89b94ace9 100644
--- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
@@ -255,6 +255,9 @@ public class FieldGroup implements Serializable {
fieldToPropertyId.put(field, propertyId);
propertyIdToField.put(propertyId, field);
if (itemDataSource == null) {
+ // Clear any possible existing binding to clear the field
+ field.setPropertyDataSource(null);
+ field.clear();
// Will be bound when data source is set
return;
}
@@ -452,6 +455,56 @@ public class FieldGroup implements Serializable {
// Not using buffered mode, nothing to do
return;
}
+
+ startTransactions();
+
+ try {
+ firePreCommitEvent();
+
+ List<InvalidValueException> invalidValueExceptions = commitFields();
+
+ if (invalidValueExceptions.isEmpty()) {
+ firePostCommitEvent();
+ commitTransactions();
+ } else {
+ throwInvalidValueException(invalidValueExceptions);
+ }
+ } catch (Exception e) {
+ rollbackTransactions();
+
+ throw new CommitException("Commit failed", e);
+ }
+
+ }
+
+ private List<InvalidValueException> commitFields() {
+ List<InvalidValueException> invalidValueExceptions = new ArrayList<InvalidValueException>();
+
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ try {
+ f.commit();
+ } catch (InvalidValueException e) {
+ invalidValueExceptions.add(e);
+ }
+ }
+
+ return invalidValueExceptions;
+ }
+
+ private void throwInvalidValueException(
+ List<InvalidValueException> invalidValueExceptions) {
+ if (invalidValueExceptions.size() == 1) {
+ throw invalidValueExceptions.get(0);
+ } else {
+ InvalidValueException[] causes = invalidValueExceptions
+ .toArray(new InvalidValueException[invalidValueExceptions
+ .size()]);
+
+ throw new InvalidValueException(null, causes);
+ }
+ }
+
+ private void startTransactions() throws CommitException {
for (Field<?> f : fieldToPropertyId.keySet()) {
Property.Transactional<?> property = (Property.Transactional<?>) f
.getPropertyDataSource();
@@ -462,33 +515,23 @@ public class FieldGroup implements Serializable {
}
property.startTransaction();
}
- try {
- firePreCommitEvent();
- // Commit the field values to the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- f.commit();
- }
- firePostCommitEvent();
+ }
- // Commit the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .commit();
- }
+ private void commitTransactions() {
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ ((Property.Transactional<?>) f.getPropertyDataSource()).commit();
+ }
+ }
- } catch (Exception e) {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .rollback();
- } catch (Exception rollbackException) {
- // FIXME: What to do ?
- }
+ private void rollbackTransactions() {
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ try {
+ ((Property.Transactional<?>) f.getPropertyDataSource())
+ .rollback();
+ } catch (Exception rollbackException) {
+ // FIXME: What to do ?
}
-
- throw new CommitException("Commit failed", e);
}
-
}
/**
diff --git a/server/src/com/vaadin/data/util/AbstractBeanContainer.java b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
index adf6313770..fad0934e53 100644
--- a/server/src/com/vaadin/data/util/AbstractBeanContainer.java
+++ b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
@@ -152,7 +152,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
* A description of the properties found in beans of type {@link #type}.
* Determines the property ids that are present in the container.
*/
- private LinkedHashMap<String, VaadinPropertyDescriptor<BEANTYPE>> model;
+ private final LinkedHashMap<String, VaadinPropertyDescriptor<BEANTYPE>> model;
/**
* Constructs a {@code AbstractBeanContainer} for beans of the given type.
@@ -178,7 +178,11 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
*/
@Override
public Class<?> getType(Object propertyId) {
- return model.get(propertyId).getPropertyType();
+ VaadinPropertyDescriptor<BEANTYPE> descriptor = model.get(propertyId);
+ if (descriptor == null) {
+ return null;
+ }
+ return descriptor.getPropertyType();
}
/**
@@ -876,7 +880,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
model.put(qualifiedPropertyId, pd);
model.remove(propertyId);
for (BeanItem<BEANTYPE> item : itemIdToItem.values()) {
- item.addItemProperty(propertyId,
+ item.addItemProperty(qualifiedPropertyId,
pd.createProperty(item.getBean()));
item.removeItemProperty(propertyId);
}
diff --git a/server/src/com/vaadin/data/util/BeanItem.java b/server/src/com/vaadin/data/util/BeanItem.java
index 12d9b23d0a..1be8b70f47 100644
--- a/server/src/com/vaadin/data/util/BeanItem.java
+++ b/server/src/com/vaadin/data/util/BeanItem.java
@@ -16,12 +16,8 @@
package com.vaadin.data.util;
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
@@ -62,7 +58,30 @@ public class BeanItem<BT> extends PropertysetItem {
*
*/
public BeanItem(BT bean) {
- this(bean, getPropertyDescriptors((Class<BT>) bean.getClass()));
+ this(bean, (Class<BT>) bean.getClass());
+ }
+
+ /**
+ * <p>
+ * Creates a new instance of <code>BeanItem</code> and adds all properties
+ * of a Java Bean to it. The properties are identified by their respective
+ * bean names.
+ * </p>
+ *
+ * <p>
+ * Note : This version only supports introspectable bean properties and
+ * their getter and setter methods. Stand-alone <code>is</code> and
+ * <code>are</code> methods are not supported.
+ * </p>
+ *
+ * @param bean
+ * the Java Bean to copy properties from.
+ * @param beanClass
+ * class of the {@code bean}
+ *
+ */
+ public BeanItem(BT bean, Class<BT> beanClass) {
+ this(bean, getPropertyDescriptors(beanClass));
}
/**
@@ -166,7 +185,8 @@ public class BeanItem<BT> extends PropertysetItem {
// Try to introspect, if it fails, we just have an empty Item
try {
- List<PropertyDescriptor> propertyDescriptors = getBeanPropertyDescriptor(beanClass);
+ List<PropertyDescriptor> propertyDescriptors = BeanUtil
+ .getBeanPropertyDescriptor(beanClass);
// Add all the bean properties as MethodProperties to this Item
// later entries on the list overwrite earlier ones
@@ -187,106 +207,6 @@ public class BeanItem<BT> extends PropertysetItem {
}
/**
- * Returns the property descriptors of a class or an interface.
- *
- * For an interface, superinterfaces are also iterated as Introspector does
- * not take them into account (Oracle Java bug 4275879), but in that case,
- * both the setter and the getter for a property must be in the same
- * interface and should not be overridden in subinterfaces for the discovery
- * to work correctly.
- *
- * For interfaces, the iteration is depth first and the properties of
- * superinterfaces are returned before those of their subinterfaces.
- *
- * @param beanClass
- * @return
- * @throws IntrospectionException
- */
- private static List<PropertyDescriptor> getBeanPropertyDescriptor(
- final Class<?> beanClass) throws IntrospectionException {
- // Oracle bug 4275879: Introspector does not consider superinterfaces of
- // an interface
- if (beanClass.isInterface()) {
- List<PropertyDescriptor> propertyDescriptors = new ArrayList<PropertyDescriptor>();
-
- for (Class<?> cls : beanClass.getInterfaces()) {
- propertyDescriptors.addAll(getBeanPropertyDescriptor(cls));
- }
-
- BeanInfo info = Introspector.getBeanInfo(beanClass);
- propertyDescriptors.addAll(getPropertyDescriptors(info));
-
- return propertyDescriptors;
- } else {
- BeanInfo info = Introspector.getBeanInfo(beanClass);
- return getPropertyDescriptors(info);
- }
- }
-
- // Workaround for Java6 bug JDK-6788525. Do nothing for JDK7+.
- private static List<PropertyDescriptor> getPropertyDescriptors(
- BeanInfo beanInfo) {
- PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
- List<PropertyDescriptor> result = new ArrayList<PropertyDescriptor>(
- descriptors.length);
- for (PropertyDescriptor descriptor : descriptors) {
- try {
- Method readMethod = getMethodFromBridge(descriptor
- .getReadMethod());
- if (readMethod != null) {
- Method writeMethod = getMethodFromBridge(
- descriptor.getWriteMethod(),
- readMethod.getReturnType());
- if (writeMethod == null) {
- writeMethod = descriptor.getWriteMethod();
- }
- PropertyDescriptor descr = new PropertyDescriptor(
- descriptor.getName(), readMethod, writeMethod);
- result.add(descr);
- } else {
- result.add(descriptor);
- }
- } catch (SecurityException ignore) {
- // handle next descriptor
- } catch (IntrospectionException e) {
- result.add(descriptor);
- }
- }
- return result;
- }
-
- /**
- * Return not bridged method for bridge {@code bridgeMethod} method. If
- * method {@code bridgeMethod} is not bridge method then return null.
- */
- private static Method getMethodFromBridge(Method bridgeMethod)
- throws SecurityException {
- if (bridgeMethod == null) {
- return null;
- }
- return getMethodFromBridge(bridgeMethod,
- bridgeMethod.getParameterTypes());
- }
-
- /**
- * Return not bridged method for bridge {@code bridgeMethod} method and
- * declared {@code paramTypes}. If method {@code bridgeMethod} is not bridge
- * method then return null.
- */
- private static Method getMethodFromBridge(Method bridgeMethod,
- Class<?>... paramTypes) throws SecurityException {
- if (bridgeMethod == null || !bridgeMethod.isBridge()) {
- return null;
- }
- try {
- return bridgeMethod.getDeclaringClass().getMethod(
- bridgeMethod.getName(), paramTypes);
- } catch (NoSuchMethodException e) {
- return null;
- }
- }
-
- /**
* Expands nested bean properties by replacing a top-level property with
* some or all of its sub-properties. The expansion is not recursive.
*
diff --git a/server/src/com/vaadin/data/util/BeanUtil.java b/server/src/com/vaadin/data/util/BeanUtil.java
new file mode 100644
index 0000000000..e2f85a765c
--- /dev/null
+++ b/server/src/com/vaadin/data/util/BeanUtil.java
@@ -0,0 +1,177 @@
+/*
+ * 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.data.util;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class for Java Beans information access.
+ *
+ * @author Vaadin Ltd
+ */
+public final class BeanUtil implements Serializable {
+ // Prevent instantiation of util class
+ private BeanUtil() {
+ }
+
+ /**
+ * Returns the property descriptors of a class or an interface.
+ *
+ * For an interface, superinterfaces are also iterated as Introspector does
+ * not take them into account (Oracle Java bug 4275879), but in that case,
+ * both the setter and the getter for a property must be in the same
+ * interface and should not be overridden in subinterfaces for the discovery
+ * to work correctly.
+ *
+ * NOTE : This utility method relies on introspection (and returns
+ * PropertyDescriptor) which is a part of java.beans package. The latter
+ * package could require bigger JDK in the future (with Java 9+). So it may
+ * be changed in the future.
+ *
+ * For interfaces, the iteration is depth first and the properties of
+ * superinterfaces are returned before those of their subinterfaces.
+ *
+ * @param beanClass
+ * @return
+ * @throws IntrospectionException
+ */
+ public static List<PropertyDescriptor> getBeanPropertyDescriptor(
+ final Class<?> beanClass) throws IntrospectionException {
+ // Oracle bug 4275879: Introspector does not consider superinterfaces of
+ // an interface
+ if (beanClass.isInterface()) {
+ List<PropertyDescriptor> propertyDescriptors = new ArrayList<PropertyDescriptor>();
+
+ for (Class<?> cls : beanClass.getInterfaces()) {
+ propertyDescriptors.addAll(getBeanPropertyDescriptor(cls));
+ }
+
+ BeanInfo info = Introspector.getBeanInfo(beanClass);
+ propertyDescriptors.addAll(getPropertyDescriptors(info));
+
+ return propertyDescriptors;
+ } else {
+ BeanInfo info = Introspector.getBeanInfo(beanClass);
+ return getPropertyDescriptors(info);
+ }
+ }
+
+ /**
+ * Returns {@code propertyId} class for property declared in {@code clazz}.
+ * Property could be of form "property.subProperty[.subProperty2]" i.e.
+ * refer to some nested property.
+ *
+ * @param clazz
+ * class where property is declared
+ * @param propertyId
+ * property of form "property" or
+ * "property.subProperty[.subProperty2]"
+ * @return class of the property
+ * @throws IntrospectionException
+ */
+ public static Class<?> getPropertyType(Class<?> clazz, String propertyId)
+ throws IntrospectionException {
+ if (propertyId.contains(".")) {
+ String[] parts = propertyId.split("\\.", 2);
+ // Get the type of the field in the "cls" class
+ Class<?> propertyBean = getPropertyType(clazz, parts[0]);
+ // Find the rest from the sub type
+ return getPropertyType(propertyBean, parts[1]);
+ } else {
+ List<PropertyDescriptor> descriptors = getBeanPropertyDescriptor(clazz);
+
+ for (PropertyDescriptor descriptor : descriptors) {
+ final Method getMethod = descriptor.getReadMethod();
+ if (descriptor.getName().equals(propertyId)
+ && getMethod != null
+ && getMethod.getDeclaringClass() != Object.class) {
+ return descriptor.getPropertyType();
+ }
+ }
+ return null;
+ }
+ }
+
+ // Workaround for Java6 bug JDK-6788525. Do nothing for JDK7+.
+ private static List<PropertyDescriptor> getPropertyDescriptors(
+ BeanInfo beanInfo) {
+ PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
+ List<PropertyDescriptor> result = new ArrayList<PropertyDescriptor>(
+ descriptors.length);
+ for (PropertyDescriptor descriptor : descriptors) {
+ try {
+ Method readMethod = getMethodFromBridge(descriptor
+ .getReadMethod());
+ if (readMethod != null) {
+ Method writeMethod = getMethodFromBridge(
+ descriptor.getWriteMethod(),
+ readMethod.getReturnType());
+ if (writeMethod == null) {
+ writeMethod = descriptor.getWriteMethod();
+ }
+ PropertyDescriptor descr = new PropertyDescriptor(
+ descriptor.getName(), readMethod, writeMethod);
+ result.add(descr);
+ } else {
+ result.add(descriptor);
+ }
+ } catch (SecurityException ignore) {
+ // handle next descriptor
+ } catch (IntrospectionException e) {
+ result.add(descriptor);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return declared method for which {@code bridgeMethod} is generated. If
+ * {@code bridgeMethod} is not a bridge method then return null.
+ */
+ private static Method getMethodFromBridge(Method bridgeMethod)
+ throws SecurityException {
+ if (bridgeMethod == null) {
+ return null;
+ }
+ return getMethodFromBridge(bridgeMethod,
+ bridgeMethod.getParameterTypes());
+ }
+
+ /**
+ * Return declared method for which {@code bridgeMethod} is generated using
+ * its {@code paramTypes}. If {@code bridgeMethod} is not a bridge method
+ * then return null.
+ */
+ private static Method getMethodFromBridge(Method bridgeMethod,
+ Class<?>... paramTypes) throws SecurityException {
+ if (bridgeMethod == null || !bridgeMethod.isBridge()) {
+ return null;
+ }
+ try {
+ return bridgeMethod.getDeclaringClass().getMethod(
+ bridgeMethod.getName(), paramTypes);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+}
diff --git a/server/src/com/vaadin/data/util/MethodProperty.java b/server/src/com/vaadin/data/util/MethodProperty.java
index 5e6b731571..853f68b711 100644
--- a/server/src/com/vaadin/data/util/MethodProperty.java
+++ b/server/src/com/vaadin/data/util/MethodProperty.java
@@ -132,7 +132,7 @@ public class MethodProperty<T> extends AbstractProperty<T> {
setArguments(getArgs, setArgs, setArgumentIndex);
String name = (String) in.readObject();
Class<?>[] paramTypes = SerializerHelper.readClassArray(in);
- if (name != null) {
+ if (instance != null && name != null) {
setMethod = instance.getClass().getMethod(name, paramTypes);
} else {
setMethod = null;
@@ -140,7 +140,7 @@ public class MethodProperty<T> extends AbstractProperty<T> {
name = (String) in.readObject();
paramTypes = SerializerHelper.readClassArray(in);
- if (name != null) {
+ if (instance != null && name != null) {
getMethod = instance.getClass().getMethod(name, paramTypes);
} else {
getMethod = null;
@@ -589,7 +589,11 @@ public class MethodProperty<T> extends AbstractProperty<T> {
@Override
public T getValue() {
try {
- return (T) getMethod.invoke(instance, getArgs);
+ if (instance == null) {
+ return null;
+ } else {
+ return (T) getMethod.invoke(instance, getArgs);
+ }
} catch (final Throwable e) {
throw new MethodException(this, e);
}
diff --git a/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java b/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
index 9054f258c7..81f1a85f89 100644
--- a/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
+++ b/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
@@ -88,6 +88,7 @@ public abstract class AbstractStringToNumberConverter<T> implements
// Convert "" to null
return null;
}
+
return parsedValue;
}
diff --git a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
index 26613c5d02..3a1f1a4252 100644
--- a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
+++ b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
@@ -17,6 +17,7 @@
package com.vaadin.data.util.converter;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.Date;
import java.util.logging.Logger;
@@ -112,6 +113,12 @@ public class DefaultConverterFactory implements ConverterFactory {
return new StringToDateConverter();
} else if (Enum.class.isAssignableFrom(sourceType)) {
return new StringToEnumConverter();
+ } else if (BigInteger.class.isAssignableFrom(sourceType)) {
+ return new StringToBigIntegerConverter();
+ } else if (Short.class.isAssignableFrom(sourceType)) {
+ return new StringToShortConverter();
+ } else if (Byte.class.isAssignableFrom(sourceType)) {
+ return new StringToByteConverter();
} else {
return null;
}
diff --git a/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java b/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java
index 1e830c1fd2..d176ac2e0d 100644
--- a/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java
@@ -15,6 +15,7 @@
*/
package com.vaadin.data.util.converter;
+import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.NumberFormat;
@@ -32,7 +33,7 @@ import java.util.Locale;
* </p>
*
* @author Vaadin Ltd
- * @since 7.3.1
+ * @since
*/
public class StringToBigIntegerConverter extends
AbstractStringToNumberConverter<BigInteger> {
@@ -41,7 +42,7 @@ public class StringToBigIntegerConverter extends
protected NumberFormat getFormat(Locale locale) {
NumberFormat numberFormat = super.getFormat(locale);
if (numberFormat instanceof DecimalFormat) {
- ((DecimalFormat) numberFormat).setParseIntegerOnly(true);
+ ((DecimalFormat) numberFormat).setParseBigDecimal(true);
}
return numberFormat;
@@ -51,7 +52,11 @@ public class StringToBigIntegerConverter extends
public BigInteger convertToModel(String value,
Class<? extends BigInteger> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
- return (BigInteger) convertToNumber(value, BigInteger.class, locale);
+
+ BigDecimal bigDecimalValue = (BigDecimal) convertToNumber(value,
+ BigDecimal.class, locale);
+
+ return (bigDecimalValue != null) ? bigDecimalValue.toBigInteger() : null;
}
@Override
diff --git a/server/src/com/vaadin/data/util/converter/StringToByteConverter.java b/server/src/com/vaadin/data/util/converter/StringToByteConverter.java
index b14182dc3f..26f52d108a 100644
--- a/server/src/com/vaadin/data/util/converter/StringToByteConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToByteConverter.java
@@ -28,7 +28,7 @@ import java.util.Locale;
* </p>
*
* @author Vaadin Ltd
- * @since 7.3.1
+ * @since
*/
public class StringToByteConverter extends
AbstractStringToNumberConverter<Byte> {
diff --git a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java b/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java
index a1328d831c..e91dd2a303 100644
--- a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java
@@ -34,9 +34,31 @@ public class StringToEnumConverter implements Converter<String, Enum> {
@Override
public Enum convertToModel(String value, Class<? extends Enum> targetType,
Locale locale) throws ConversionException {
- if (value == null) {
+ if (value == null || value.trim().equals("")) {
return null;
}
+
+ return stringToEnum(value, targetType, locale);
+ }
+
+ /**
+ * Converts the given string to the given enum type using the given locale
+ * <p>
+ * Compatible with {@link #enumToString(Enum, Locale)}
+ *
+ * @param value
+ * The string value to convert
+ * @param enumType
+ * The type of enum to create
+ * @param locale
+ * The locale to use for conversion. If null, the JVM default
+ * locale will be used
+ * @return The enum which matches the given string
+ * @throws ConversionException
+ * if the conversion fails
+ */
+ public static <T extends Enum<T>> T stringToEnum(String value,
+ Class<T> enumType, Locale locale) throws ConversionException {
if (locale == null) {
locale = Locale.getDefault();
}
@@ -45,31 +67,41 @@ public class StringToEnumConverter implements Converter<String, Enum> {
// Foo bar -> FOO_BAR
String result = value.replace(" ", "_").toUpperCase(locale);
try {
- return Enum.valueOf(targetType, result);
- } catch (IllegalArgumentException ee) {
+ return Enum.valueOf(enumType, result);
+ } catch (Exception ee) {
// There was no match. Try to compare the available values to see if
// the constant is using something else than all upper case
-
- EnumSet<?> set = EnumSet.allOf(targetType);
- for (Enum e : set) {
- if (e.name().toUpperCase(locale).equals(result)) {
- return e;
+ try {
+ EnumSet<T> set = EnumSet.allOf(enumType);
+ for (T e : set) {
+ if (e.name().toUpperCase(locale).equals(result)) {
+ return e;
+ }
}
+ } catch (Exception e) {
}
- // Fallback did not work either, re-throw original exception so user
- // knows what went wrong
+ // Fallback did not work either, re-throw original exception so
+ // user knows what went wrong
throw new ConversionException(ee);
}
}
- @Override
- public String convertToPresentation(Enum value,
- Class<? extends String> targetType, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
+ /**
+ * Converts the given enum to a human readable string using the given locale
+ * <p>
+ * Compatible with {@link #stringToEnum(String, Class, Locale)}
+ *
+ * @param value
+ * The enum value to convert
+ * @param locale
+ * The locale to use for conversion. If null, the JVM default
+ * locale will be used
+ * @return A human readable string based on the enum
+ * @throws ConversionException
+ * if the conversion fails
+ */
+ public static String enumToString(Enum<?> value, Locale locale) {
if (locale == null) {
locale = Locale.getDefault();
}
@@ -80,11 +112,21 @@ public class StringToEnumConverter implements Converter<String, Enum> {
// _FOO -> _foo
String result = enumString.substring(0, 1).toUpperCase(locale);
result += enumString.substring(1).toLowerCase(locale).replace('_', ' ');
-
return result;
}
@Override
+ public String convertToPresentation(Enum value,
+ Class<? extends String> targetType, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return enumToString(value, locale);
+ }
+
+ @Override
public Class<Enum> getModelType() {
return Enum.class;
}
diff --git a/server/src/com/vaadin/data/util/converter/StringToShortConverter.java b/server/src/com/vaadin/data/util/converter/StringToShortConverter.java
index 3761d11227..4ee085286f 100644
--- a/server/src/com/vaadin/data/util/converter/StringToShortConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToShortConverter.java
@@ -28,7 +28,7 @@ import java.util.Locale;
* </p>
*
* @author Vaadin Ltd
- * @since 7.3.1
+ * @since
*/
public class StringToShortConverter extends
AbstractStringToNumberConverter<Short> {
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
index 683140d279..c0c660c084 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
@@ -652,7 +652,6 @@ public class SQLContainer implements Container, Container.Filterable,
if (cachedItems.isEmpty()) {
getPage();
}
- int size = size();
// this protects against infinite looping
int counter = 0;
int oldIndex;
@@ -1020,18 +1019,20 @@ public class SQLContainer implements Container, Container.Filterable,
}
/* Perform buffered modifications */
for (RowItem item : modifiedItems) {
- if (queryDelegate.storeRow(item) > 0) {
- /*
- * Also reset the modified state in the item in case it is
- * reused e.g. in a form.
- */
- item.commit();
- } else {
- queryDelegate.rollback();
- refresh();
- throw new ConcurrentModificationException(
- "Item with the ID '" + item.getId()
- + "' has been externally modified.");
+ if (!removedItems.containsKey(item.getId())) {
+ if (queryDelegate.storeRow(item) > 0) {
+ /*
+ * Also reset the modified state in the item in case it
+ * is reused e.g. in a form.
+ */
+ item.commit();
+ } else {
+ queryDelegate.rollback();
+ refresh();
+ throw new ConcurrentModificationException(
+ "Item with the ID '" + item.getId()
+ + "' has been externally modified.");
+ }
}
}
/* Perform buffered additions */
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java b/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
index 84dfe9b865..21a486a017 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
@@ -262,6 +262,12 @@ public class DefaultSQLGenerator implements SQLGenerator {
count++;
}
if (versionColumn != null) {
+ if(!item.getItemPropertyIds().contains(versionColumn)) {
+ throw new IllegalArgumentException(String.format(
+ "Table '%s' does not contain version column '%s'.",
+ tableName, versionColumn));
+ }
+
query.append(String.format(" AND %s = ?",
QueryBuilder.quote(versionColumn)));
sh.addParameterValue(
diff --git a/server/src/com/vaadin/navigator/Navigator.java b/server/src/com/vaadin/navigator/Navigator.java
index 80dad2244e..591f73dc75 100644
--- a/server/src/com/vaadin/navigator/Navigator.java
+++ b/server/src/com/vaadin/navigator/Navigator.java
@@ -371,6 +371,7 @@ public class Navigator implements Serializable {
private View currentView = null;
private List<ViewChangeListener> listeners = new LinkedList<ViewChangeListener>();
private List<ViewProvider> providers = new LinkedList<ViewProvider>();
+ private String currentNavigationState = null;
private ViewProvider errorProvider;
/**
@@ -551,6 +552,11 @@ public class Navigator implements Serializable {
ViewChangeEvent event = new ViewChangeEvent(this, currentView, view,
viewName, parameters);
if (!fireBeforeViewChange(event)) {
+ // #10901. Revert URL to previous state if back-button navigation
+ // was canceled
+ if (currentNavigationState != null) {
+ getStateManager().setState(currentNavigationState);
+ }
return;
}
@@ -561,6 +567,7 @@ public class Navigator implements Serializable {
}
if (!navigationState.equals(getStateManager().getState())) {
getStateManager().setState(navigationState);
+ currentNavigationState = navigationState;
}
}
diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java
index f0666f63fc..c34e986fce 100644
--- a/server/src/com/vaadin/server/BootstrapHandler.java
+++ b/server/src/com/vaadin/server/BootstrapHandler.java
@@ -469,6 +469,8 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
JsonObject versionInfo = Json.createObject();
versionInfo.put("vaadinVersion", Version.getFullVersion());
+ versionInfo.put("atmosphereVersion",
+ org.atmosphere.util.Version.getRawVersion());
appConfig.put("versionInfo", versionInfo);
appConfig.put("widgetset", context.getWidgetsetName());
diff --git a/server/src/com/vaadin/server/FileResource.java b/server/src/com/vaadin/server/FileResource.java
index de14e2f0f2..b32905f972 100644
--- a/server/src/com/vaadin/server/FileResource.java
+++ b/server/src/com/vaadin/server/FileResource.java
@@ -57,6 +57,9 @@ public class FileResource implements ConnectorResource {
* the file that should be served.
*/
public FileResource(File sourceFile) {
+ if (sourceFile == null) {
+ throw new IllegalArgumentException("File cannot be null");
+ }
setSourceFile(sourceFile);
}
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index fb93a44d37..36d6910a7a 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -703,12 +703,12 @@ public abstract class VaadinService implements Serializable {
final boolean closeApplication = hasParameter(request,
URL_PARAMETER_CLOSE_APPLICATION);
- if (restartApplication) {
- closeSession(session, request.getWrappedSession(false));
- return createAndRegisterSession(request);
- } else if (closeApplication) {
+ if (closeApplication) {
closeSession(session, request.getWrappedSession(false));
return null;
+ } else if (restartApplication) {
+ closeSession(session, request.getWrappedSession(false));
+ return createAndRegisterSession(request);
} else {
return session;
}
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index 4656f9a672..d1242676da 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/com/vaadin/server/VaadinServlet.java
@@ -573,8 +573,8 @@ public class VaadinServlet extends HttpServlet implements Constants {
/**
* A helper method to strip away characters that might somehow be used for
- * XSS attacs. Leaves at least alphanumeric characters intact. Also removes
- * eg. ( and ), so values should be safe in javascript too.
+ * XSS attacks. Leaves at least alphanumeric characters intact. Also removes
+ * e.g. '(' and ')', so values should be safe in javascript too.
*
* @param themeName
* @return
@@ -583,7 +583,7 @@ public class VaadinServlet extends HttpServlet implements Constants {
* version
*/
@Deprecated
- protected static String stripSpecialChars(String themeName) {
+ public static String stripSpecialChars(String themeName) {
StringBuilder sb = new StringBuilder();
char[] charArray = themeName.toCharArray();
for (int i = 0; i < charArray.length; i++) {
@@ -704,6 +704,15 @@ public class VaadinServlet extends HttpServlet implements Constants {
return;
}
+ String cacheControl = "public, max-age=0, must-revalidate";
+ int resourceCacheTime = getCacheTime(filename);
+ if (resourceCacheTime > 0) {
+ cacheControl = "max-age=" + String.valueOf(resourceCacheTime);
+ }
+ response.setHeader("Cache-Control", cacheControl);
+ response.setDateHeader("Expires", System.currentTimeMillis()
+ + (resourceCacheTime * 1000));
+
// Find the modification timestamp
long lastModifiedTime = 0;
URLConnection connection = null;
@@ -714,6 +723,7 @@ public class VaadinServlet extends HttpServlet implements Constants {
// are not returned by the browser in the "If-Modified-Since"
// header).
lastModifiedTime = lastModifiedTime - lastModifiedTime % 1000;
+ response.setDateHeader("Last-Modified", lastModifiedTime);
if (browserHasNewestVersion(request, lastModifiedTime)) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
@@ -748,18 +758,6 @@ public class VaadinServlet extends HttpServlet implements Constants {
response.setContentType(mimetype);
}
- // Provide modification timestamp to the browser if it is known.
- if (lastModifiedTime > 0) {
- response.setDateHeader("Last-Modified", lastModifiedTime);
-
- String cacheControl = "public, max-age=0, must-revalidate";
- int resourceCacheTime = getCacheTime(filename);
- if (resourceCacheTime > 0) {
- cacheControl = "max-age=" + String.valueOf(resourceCacheTime);
- }
- response.setHeader("Cache-Control", cacheControl);
- }
-
writeStaticResourceResponse(request, response, resourceUrl);
}
diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java
index 356ad25219..1216d2b689 100644
--- a/server/src/com/vaadin/server/communication/UIInitHandler.java
+++ b/server/src/com/vaadin/server/communication/UIInitHandler.java
@@ -17,7 +17,7 @@
package com.vaadin.server.communication;
import java.io.IOException;
-import java.io.OutputStreamWriter;
+import java.io.OutputStream;
import java.io.StringWriter;
import java.util.List;
import java.util.logging.Level;
@@ -65,8 +65,6 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
@Override
public boolean synchronizedHandleRequest(VaadinSession session,
VaadinRequest request, VaadinResponse response) throws IOException {
- StringWriter stringWriter = new StringWriter();
-
try {
assert UI.getCurrent() == null;
@@ -82,14 +80,10 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
String initialUIDL = getInitialUidl(request, uI);
params.put("uidl", initialUIDL);
- stringWriter.write(JsonUtil.stringify(params));
+ return commitJsonResponse(request, response, JsonUtil.stringify(params));
} catch (JsonException e) {
throw new IOException("Error producing initial UIDL", e);
- } finally {
- stringWriter.close();
}
-
- return commitJsonResponse(request, response, stringWriter.toString());
}
/**
@@ -116,18 +110,13 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
// iOS 6 Safari requires this (#9732)
response.setHeader("Cache-Control", "no-cache");
- // NOTE! GateIn requires, for some weird reason, getOutputStream
- // to be used instead of getWriter() (it seems to interpret
- // application/json as a binary content type)
- OutputStreamWriter outputWriter = new OutputStreamWriter(
- response.getOutputStream(), "UTF-8");
- try {
- outputWriter.write(json);
- // NOTE GateIn requires the buffers to be flushed to work
- outputWriter.flush();
- } finally {
- outputWriter.close();
- }
+ byte[] b = json.getBytes("UTF-8");
+ response.setHeader("Content-Length", String.valueOf(b.length));
+
+ OutputStream outputStream = response.getOutputStream();
+ outputStream.write(b);
+ // NOTE GateIn requires the buffers to be flushed to work
+ outputStream.flush();
return true;
}
diff --git a/server/src/com/vaadin/ui/AbsoluteLayout.java b/server/src/com/vaadin/ui/AbsoluteLayout.java
index 27ddb86dad..39f00901fc 100644
--- a/server/src/com/vaadin/ui/AbsoluteLayout.java
+++ b/server/src/com/vaadin/ui/AbsoluteLayout.java
@@ -166,7 +166,6 @@ public class AbsoluteLayout extends AbstractLayout implements
internalRemoveComponent(c);
throw e;
}
- markAsDirty();
}
/**
@@ -210,7 +209,6 @@ public class AbsoluteLayout extends AbstractLayout implements
public void removeComponent(Component c) {
internalRemoveComponent(c);
super.removeComponent(c);
- markAsDirty();
}
/**
diff --git a/server/src/com/vaadin/ui/AbstractComponentContainer.java b/server/src/com/vaadin/ui/AbstractComponentContainer.java
index e70b0fa0ce..1095331602 100644
--- a/server/src/com/vaadin/ui/AbstractComponentContainer.java
+++ b/server/src/com/vaadin/ui/AbstractComponentContainer.java
@@ -209,6 +209,7 @@ public abstract class AbstractComponentContainer extends AbstractComponent
c.setParent(this);
fireComponentAttachEvent(c);
+ markAsDirty();
}
/**
@@ -223,6 +224,7 @@ public abstract class AbstractComponentContainer extends AbstractComponent
if (equals(c.getParent())) {
c.setParent(null);
fireComponentDetachEvent(c);
+ markAsDirty();
}
}
diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java
index 6d4b5ff2d7..9b9c7efd86 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/com/vaadin/ui/AbstractField.java
@@ -1508,25 +1508,12 @@ public abstract class AbstractField<T> extends AbstractComponent implements
markAsDirty();
}
- /**
- * Is the field empty?
- *
- * In general, "empty" state is same as null. As an exception, TextField
- * also treats empty string as "empty".
- */
- protected boolean isEmpty() {
+ @Override
+ public boolean isEmpty() {
return (getFieldValue() == null);
}
- /**
- * Clear the value of the field.
- * <p>
- * The field value is typically reset to the initial value of the field but
- * this is not mandatory. Calling {@link #isEmpty()} on a cleared field must
- * always returns true.
- *
- * @since
- */
+ @Override
public void clear() {
setValue(null);
}
diff --git a/server/src/com/vaadin/ui/AbstractSelect.java b/server/src/com/vaadin/ui/AbstractSelect.java
index 2c4dd5be5d..1a3eeb88a3 100644
--- a/server/src/com/vaadin/ui/AbstractSelect.java
+++ b/server/src/com/vaadin/ui/AbstractSelect.java
@@ -33,6 +33,8 @@ import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ConverterUtil;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.Transferable;
import com.vaadin.event.dd.DragAndDropEvent;
@@ -1181,7 +1183,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
switch (getItemCaptionMode()) {
case ID:
- caption = itemId.toString();
+ caption = idToCaption(itemId);
break;
case INDEX:
@@ -1207,7 +1209,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
case EXPLICIT_DEFAULTS_ID:
caption = itemCaptions.get(itemId);
if (caption == null) {
- caption = itemId.toString();
+ caption = idToCaption(itemId);
}
break;
@@ -1227,6 +1229,17 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
return caption != null ? caption : "";
}
+ private String idToCaption(Object itemId) {
+ try {
+ Converter<String, Object> c = (Converter<String, Object>) ConverterUtil
+ .getConverter(String.class, itemId.getClass(), getSession());
+ return ConverterUtil.convertFromModel(itemId, String.class, c,
+ getLocale());
+ } catch (Exception e) {
+ return itemId.toString();
+ }
+ }
+
/**
* Sets tqhe icon for an item.
*
@@ -1782,7 +1795,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
* @see AbstractField#isEmpty().
*/
@Override
- protected boolean isEmpty() {
+ public boolean isEmpty() {
if (!multiSelect) {
return super.isEmpty();
} else {
diff --git a/server/src/com/vaadin/ui/AbstractSplitPanel.java b/server/src/com/vaadin/ui/AbstractSplitPanel.java
index 29dbadecc4..e366c33593 100644
--- a/server/src/com/vaadin/ui/AbstractSplitPanel.java
+++ b/server/src/com/vaadin/ui/AbstractSplitPanel.java
@@ -221,7 +221,6 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer {
} else if (c == getSecondComponent()) {
getState().secondChild = null;
}
- markAsDirty();
}
/*
@@ -263,7 +262,6 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer {
} else if (oldComponent == getSecondComponent()) {
setSecondComponent(newComponent);
}
- markAsDirty();
}
/**
@@ -349,12 +347,26 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer {
* Returns the unit of position of the splitter
*
* @return unit of position of the splitter
+ * @see #setSplitPosition(float, Unit)
*/
public Unit getSplitPositionUnit() {
return posUnit;
}
/**
+ * Is the split position reversed. By default the split position is measured
+ * by the first region, but if split position is reversed the measuring is
+ * done by the second region instead.
+ *
+ * @since
+ * @return {@code true} if reversed, {@code false} otherwise.
+ * @see #setSplitPosition(float, boolean)
+ */
+ public boolean isSplitPositionReversed() {
+ return getSplitterState(false).positionReversed;
+ }
+
+ /**
* Sets the minimum split position to the given position and unit. If the
* split position is reversed, maximum and minimum are also reversed.
*
diff --git a/server/src/com/vaadin/ui/AbstractTextField.java b/server/src/com/vaadin/ui/AbstractTextField.java
index adeb1cb69f..93025ac0fd 100644
--- a/server/src/com/vaadin/ui/AbstractTextField.java
+++ b/server/src/com/vaadin/ui/AbstractTextField.java
@@ -323,7 +323,7 @@ public abstract class AbstractTextField extends AbstractField<String> implements
}
@Override
- protected boolean isEmpty() {
+ public boolean isEmpty() {
return super.isEmpty() || getValue().length() == 0;
}
diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/com/vaadin/ui/ComboBox.java
index c2b80fae35..4af93113f9 100644
--- a/server/src/com/vaadin/ui/ComboBox.java
+++ b/server/src/com/vaadin/ui/ComboBox.java
@@ -622,7 +622,7 @@ public class ComboBox extends AbstractSelect implements
if (caption == null || caption.equals("")) {
continue;
} else {
- caption = caption.toLowerCase();
+ caption = caption.toLowerCase(getLocale());
}
switch (filteringMode) {
case CONTAINS:
@@ -682,7 +682,7 @@ public class ComboBox extends AbstractSelect implements
currentPage = ((Integer) variables.get("page")).intValue();
filterstring = newFilter;
if (filterstring != null) {
- filterstring = filterstring.toLowerCase();
+ filterstring = filterstring.toLowerCase(getLocale());
}
requestRepaint();
} else if (isNewItemsAllowed()) {
diff --git a/server/src/com/vaadin/ui/CssLayout.java b/server/src/com/vaadin/ui/CssLayout.java
index 9a4da009e9..f3ae6c0695 100644
--- a/server/src/com/vaadin/ui/CssLayout.java
+++ b/server/src/com/vaadin/ui/CssLayout.java
@@ -121,7 +121,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
components.add(c);
try {
super.addComponent(c);
- markAsDirty();
} catch (IllegalArgumentException e) {
components.remove(c);
throw e;
@@ -144,7 +143,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
components.addFirst(c);
try {
super.addComponent(c);
- markAsDirty();
} catch (IllegalArgumentException e) {
components.remove(c);
throw e;
@@ -173,7 +171,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
components.add(index, c);
try {
super.addComponent(c);
- markAsDirty();
} catch (IllegalArgumentException e) {
components.remove(c);
throw e;
@@ -190,7 +187,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
public void removeComponent(Component c) {
components.remove(c);
super.removeComponent(c);
- markAsDirty();
}
/**
diff --git a/server/src/com/vaadin/ui/CustomLayout.java b/server/src/com/vaadin/ui/CustomLayout.java
index f4fe7fa66c..a9c266b0b9 100644
--- a/server/src/com/vaadin/ui/CustomLayout.java
+++ b/server/src/com/vaadin/ui/CustomLayout.java
@@ -144,8 +144,8 @@ public class CustomLayout extends AbstractLayout implements LegacyComponent {
}
slots.put(location, c);
getState().childLocations.put(c, location);
- c.setParent(this);
- fireComponentAttachEvent(c);
+
+ super.addComponent(c);
}
/**
diff --git a/server/src/com/vaadin/ui/DateField.java b/server/src/com/vaadin/ui/DateField.java
index 030bd5f6c2..3d683f4902 100644
--- a/server/src/com/vaadin/ui/DateField.java
+++ b/server/src/com/vaadin/ui/DateField.java
@@ -316,10 +316,11 @@ public class DateField extends AbstractField<Date> implements
throw new IllegalStateException(
"startDate cannot be later than endDate");
}
- getState().rangeStart = startDate;
- // rangeStart = startDate;
- // This has to be done to correct for the resolution
- // updateRangeState();
+
+ // Create a defensive copy against issues when using java.sql.Date (and
+ // also against mutable Date).
+ getState().rangeStart = startDate != null ? new Date(
+ startDate.getTime()) : null;
updateRangeValidator();
}
@@ -436,8 +437,11 @@ public class DateField extends AbstractField<Date> implements
throw new IllegalStateException(
"endDate cannot be earlier than startDate");
}
- // rangeEnd = endDate;
- getState().rangeEnd = endDate;
+
+ // Create a defensive copy against issues when using java.sql.Date (and
+ // also against mutable Date).
+ getState().rangeEnd = endDate != null ? new Date(endDate.getTime())
+ : null;
updateRangeValidator();
}
diff --git a/server/src/com/vaadin/ui/Field.java b/server/src/com/vaadin/ui/Field.java
index f191e1bdd7..6dee4de6cb 100644
--- a/server/src/com/vaadin/ui/Field.java
+++ b/server/src/com/vaadin/ui/Field.java
@@ -113,4 +113,26 @@ public interface Field<T> extends Component, BufferedValidatable, Property<T>,
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
+ * @return true if the field is empty, false otherwise
+ */
+ public boolean isEmpty();
+
+ /**
+ * Clears the value of the field.
+ * <p>
+ * 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
+ */
+ public void clear();
+
}
diff --git a/server/src/com/vaadin/ui/Form.java b/server/src/com/vaadin/ui/Form.java
index 48239b09e3..45532756e5 100644
--- a/server/src/com/vaadin/ui/Form.java
+++ b/server/src/com/vaadin/ui/Form.java
@@ -1186,9 +1186,14 @@ public class Form extends AbstractField<Object> implements Item.Editor,
}
}
- /** Form is empty if all of its fields are empty. */
+ /**
+ * {@inheritDoc}
+ * <p>
+ * A Form is empty if all of its fields are empty.
+ *
+ */
@Override
- protected boolean isEmpty() {
+ public boolean isEmpty() {
for (Iterator<Field<?>> i = fields.values().iterator(); i.hasNext();) {
Field<?> f = i.next();
diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/com/vaadin/ui/GridLayout.java
index 0dd16a03e7..96854c5b1b 100644
--- a/server/src/com/vaadin/ui/GridLayout.java
+++ b/server/src/com/vaadin/ui/GridLayout.java
@@ -255,8 +255,6 @@ public class GridLayout extends AbstractLayout implements
cursorY = row1;
}
}
-
- markAsDirty();
}
/**
@@ -390,7 +388,6 @@ public class GridLayout extends AbstractLayout implements
getState().childData.remove(component);
components.remove(component);
-
super.removeComponent(component);
}
diff --git a/server/src/com/vaadin/ui/RichTextArea.java b/server/src/com/vaadin/ui/RichTextArea.java
index 9d05181541..31327b3a6f 100644
--- a/server/src/com/vaadin/ui/RichTextArea.java
+++ b/server/src/com/vaadin/ui/RichTextArea.java
@@ -285,7 +285,7 @@ public class RichTextArea extends AbstractField<String> implements
}
@Override
- protected boolean isEmpty() {
+ public boolean isEmpty() {
return super.isEmpty() || getValue().length() == 0;
}
diff --git a/server/src/com/vaadin/ui/TabSheet.java b/server/src/com/vaadin/ui/TabSheet.java
index e4060528ee..5528ea2ee9 100644
--- a/server/src/com/vaadin/ui/TabSheet.java
+++ b/server/src/com/vaadin/ui/TabSheet.java
@@ -202,7 +202,6 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
if (component != null && components.contains(component)) {
int componentIndex = components.indexOf(component);
-
super.removeComponent(component);
keyMapper.remove(component);
components.remove(component);
@@ -239,7 +238,6 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
fireSelectedTabChange();
}
}
- markAsDirty();
}
}
@@ -401,8 +399,9 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
setSelected(tabComponent);
fireSelectedTabChange();
}
+
super.addComponent(tabComponent);
- markAsDirty();
+
return tab;
}
}
@@ -974,16 +973,16 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
/**
* Gets the icon alt text for the tab.
- *
+ *
* @since 7.2
*/
public String getIconAlternateText();
/**
* Sets the icon alt text for the tab.
- *
+ *
* @since 7.2
- *
+ *
* @param iconAltText
* the icon to set
*/
diff --git a/server/src/com/vaadin/ui/TextField.java b/server/src/com/vaadin/ui/TextField.java
index 563810c76a..2a61e93211 100644
--- a/server/src/com/vaadin/ui/TextField.java
+++ b/server/src/com/vaadin/ui/TextField.java
@@ -48,7 +48,7 @@ public class TextField extends AbstractTextField {
* Constructs an empty <code>TextField</code> with no caption.
*/
public TextField() {
- setValue("");
+ clear();
}
/**
@@ -107,7 +107,7 @@ public class TextField extends AbstractTextField {
/*
* (non-Javadoc)
*
- * @see com.vaadin.ui.AbstractField#readDesign(org.jsoup.nodes.Element ,
+ * @see com.vaadin.ui.AbstractTextField#readDesign(org.jsoup.nodes.Element,
* com.vaadin.ui.declarative.DesignContext)
*/
@Override
@@ -135,4 +135,15 @@ public class TextField extends AbstractTextField {
DesignAttributeHandler.writeAttribute("value", attr, getValue(),
def.getValue(), String.class);
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractField#clear()
+ */
+ @Override
+ public void clear() {
+ setValue("");
+ }
+
}
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 78cb5488e8..4bd4b67259 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -633,7 +633,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
this.embedId = embedId;
// Actual theme - used for finding CustomLayout templates
- getState().theme = request.getParameter("theme");
+ setTheme(request.getParameter("theme"));
getPage().init(request);
@@ -1164,7 +1164,11 @@ public abstract class UI extends AbstractSingleComponentContainer implements
* The new theme name
*/
public void setTheme(String theme) {
- getState().theme = theme;
+ if(theme == null) {
+ getState().theme = null;
+ } else {
+ getState().theme = VaadinServlet.stripSpecialChars(theme);
+ }
}
/**
diff --git a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
index fcaabcc079..2f51b21f7c 100644
--- a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
+++ b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
@@ -249,71 +249,33 @@ public class ContainerEventProvider implements CalendarEditableEventProvider,
@Override
public List<CalendarEvent> getEvents(Date startDate, Date endDate) {
eventCache.clear();
-
- int[] rangeIndexes = getFirstAndLastEventIndex(startDate, endDate);
- for (int i = rangeIndexes[0]; i <= rangeIndexes[1]
- && i < container.size(); i++) {
- eventCache.add(getEvent(i));
- }
- return Collections.unmodifiableList(eventCache);
- }
-
- /**
- * Get the first event for a date
- *
- * @param date
- * The date to search for, NUll returns first event in container
- * @return Returns an array where the first item is the start index and the
- * second item is the end item
- */
- private int[] getFirstAndLastEventIndex(Date start, Date end) {
- int startIndex = 0;
int size = container.size();
assert size >= 0;
- int endIndex = size - 1;
- if (start != null) {
- /*
- * Iterating from the start of the container, if range is in the end
- * of the container then this will be slow TODO This could be
- * improved by using some sort of divide and conquer algorithm
- */
- while (startIndex < size) {
- Object id = container.getIdByIndex(startIndex);
- Item item = container.getItem(id);
- Date d = (Date) item.getItemProperty(startDateProperty)
+ for (int i = 0; i < size; i++) {
+ Object id = container.getIdByIndex(i);
+ Item item = container.getItem(id);
+ boolean add = true;
+ if (startDate != null) {
+ Date eventEnd = (Date) item.getItemProperty(endDateProperty)
.getValue();
- if (d.compareTo(start) >= 0) {
- break;
+ if (eventEnd.compareTo(startDate) < 0) {
+ add = false;
}
- startIndex++;
}
- }
-
- if (end != null) {
- /*
- * Iterate from the start index until range ends
- */
- endIndex = startIndex;
- while (endIndex < size - 1) {
- Object id = container.getIdByIndex(endIndex);
- Item item = container.getItem(id);
- Date d = (Date) item.getItemProperty(endDateProperty)
- .getValue();
- if (d == null) {
- // No end date present, use start date
- d = (Date) item.getItemProperty(startDateProperty)
- .getValue();
+ if (add && endDate != null) {
+ Date eventStart = (Date) item
+ .getItemProperty(startDateProperty).getValue();
+ if (eventStart.compareTo(endDate) >= 0) {
+ break; // because container is sorted, all further events
+ // will be even later
}
- if (d.compareTo(end) >= 0) {
- endIndex--;
- break;
- }
- endIndex++;
+ }
+ if (add) {
+ eventCache.add(getEvent(i));
}
}
-
- return new int[] { startIndex, endIndex };
+ return Collections.unmodifiableList(eventCache);
}
/*
diff --git a/server/tests/src/com/vaadin/data/util/BeanContainerTest.java b/server/tests/src/com/vaadin/data/util/BeanContainerTest.java
index 4e0e98ec43..f22ab8478e 100644
--- a/server/tests/src/com/vaadin/data/util/BeanContainerTest.java
+++ b/server/tests/src/com/vaadin/data/util/BeanContainerTest.java
@@ -68,6 +68,19 @@ public class BeanContainerTest extends AbstractBeanContainerTest {
return false;
}
+ public void testGetType_existingProperty_typeReturned() {
+ BeanContainer<String, ClassName> container = getContainer();
+ Assert.assertEquals(
+ "Unexpected type is returned for property 'simpleName'",
+ String.class, container.getType("simpleName"));
+ }
+
+ public void testGetType_notExistingProperty_nullReturned() {
+ BeanContainer<String, ClassName> container = getContainer();
+ Assert.assertNull("Not null type is returned for property ''",
+ container.getType(""));
+ }
+
public void testBasicOperations() {
testBasicContainerOperations(getContainer());
}
diff --git a/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
index b58d962d96..514bf70416 100644
--- a/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
+++ b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
@@ -12,6 +12,7 @@ import org.junit.Assert;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
+import com.vaadin.data.util.NestedMethodPropertyTest.Address;
/**
* Test basic functionality of BeanItemContainer.
@@ -71,6 +72,19 @@ public class BeanItemContainerTest extends AbstractBeanContainerTest {
return false;
}
+ public void testGetType_existingProperty_typeReturned() {
+ BeanItemContainer<ClassName> container = getContainer();
+ Assert.assertEquals(
+ "Unexpected type is returned for property 'simpleName'",
+ String.class, container.getType("simpleName"));
+ }
+
+ public void testGetType_notExistingProperty_nullReturned() {
+ BeanItemContainer<ClassName> container = getContainer();
+ Assert.assertNull("Not null type is returned for property ''",
+ container.getType(""));
+ }
+
public void testBasicOperations() {
testBasicContainerOperations(getContainer());
}
@@ -727,4 +741,45 @@ public class BeanItemContainerTest extends AbstractBeanContainerTest {
assertNull(container.getContainerProperty(john, "address.street")
.getValue());
}
+
+ public void testAddNestedContainerBeanBeforeData() {
+ BeanItemContainer<NestedMethodPropertyTest.Person> container = new BeanItemContainer<NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+
+ container.addNestedContainerBean("address");
+
+ assertTrue(container.getContainerPropertyIds().contains(
+ "address.street"));
+
+ NestedMethodPropertyTest.Person john = new NestedMethodPropertyTest.Person(
+ "John", new Address("streetname", 12345));
+ container.addBean(john);
+
+ assertTrue(container.getItem(john).getItemPropertyIds()
+ .contains("address.street"));
+ assertEquals("streetname",
+ container.getItem(john).getItemProperty("address.street")
+ .getValue());
+
+ }
+
+ public void testAddNestedContainerBeanAfterData() {
+ BeanItemContainer<NestedMethodPropertyTest.Person> container = new BeanItemContainer<NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+
+ NestedMethodPropertyTest.Person john = new NestedMethodPropertyTest.Person(
+ "John", new Address("streetname", 12345));
+ container.addBean(john);
+
+ container.addNestedContainerBean("address");
+
+ assertTrue(container.getContainerPropertyIds().contains(
+ "address.street"));
+ assertTrue(container.getItem(john).getItemPropertyIds()
+ .contains("address.street"));
+ assertEquals("streetname",
+ container.getItem(john).getItemProperty("address.street")
+ .getValue());
+
+ }
}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
index d907f12321..f82ba49c3e 100644
--- a/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
@@ -24,11 +24,15 @@ import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
import com.vaadin.data.util.sqlcontainer.query.OrderBy;
import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+import static org.junit.Assert.assertTrue;
+
public class SQLContainerTableQueryTest {
private static final int offset = SQLTestsConstants.offset;
private static final String createGarbage = SQLTestsConstants.createGarbage;
private JDBCConnectionPool connectionPool;
+ private TableQuery peopleQuery;
+ private SQLContainer peopleContainer;
@Before
public void setUp() throws SQLException {
@@ -43,6 +47,10 @@ public class SQLContainerTableQueryTest {
}
DataGenerator.addPeopleToDatabase(connectionPool);
+
+ peopleQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ peopleContainer = new SQLContainer(peopleQuery);
}
@After
@@ -53,6 +61,24 @@ public class SQLContainerTableQueryTest {
}
@Test
+ public void itemWithExistingVersionColumnIsRemoved()
+ throws SQLException {
+ peopleContainer.setAutoCommit(true);
+ peopleQuery.setVersionColumn("ID");
+
+ assertTrue(peopleContainer.removeItem(peopleContainer.lastItemId()));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void itemWithNonExistingVersionColumnCannotBeRemoved() throws SQLException {
+ peopleQuery.setVersionColumn("version");
+
+ peopleContainer.removeItem(peopleContainer.lastItemId());
+
+ peopleContainer.commit();
+ }
+
+ @Test
public void constructor_withTableQuery_shouldSucceed() throws SQLException {
new SQLContainer(new TableQuery("people", connectionPool,
SQLTestsConstants.sqlGen));
@@ -63,8 +89,8 @@ public class SQLContainerTableQueryTest {
throws SQLException {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
- Assert.assertTrue(container.containsId(new RowId(
- new Object[] { 1 + offset })));
+ assertTrue(container.containsId(new RowId(
+ new Object[]{1 + offset})));
}
@Test
@@ -410,11 +436,11 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
if (SQLTestsConstants.db == DB.ORACLE) {
- Assert.assertTrue(container.isFirstId(new RowId(
- new Object[] { new BigDecimal(0 + offset) })));
+ assertTrue(container.isFirstId(new RowId(
+ new Object[]{new BigDecimal(0 + offset)})));
} else {
- Assert.assertTrue(container.isFirstId(new RowId(
- new Object[] { 0 + offset })));
+ assertTrue(container.isFirstId(new RowId(
+ new Object[]{0 + offset})));
}
}
@@ -449,11 +475,11 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
if (SQLTestsConstants.db == DB.ORACLE) {
- Assert.assertTrue(container.isLastId(new RowId(
- new Object[] { new BigDecimal(3 + offset) })));
+ assertTrue(container.isLastId(new RowId(
+ new Object[]{new BigDecimal(3 + offset)})));
} else {
- Assert.assertTrue(container.isLastId(new RowId(
- new Object[] { 3 + offset })));
+ assertTrue(container.isLastId(new RowId(
+ new Object[]{3 + offset})));
}
}
@@ -463,11 +489,11 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
if (SQLTestsConstants.db == DB.ORACLE) {
- Assert.assertTrue(container.isLastId(new RowId(
- new Object[] { new BigDecimal(4999 + offset) })));
+ assertTrue(container.isLastId(new RowId(
+ new Object[]{new BigDecimal(4999 + offset)})));
} else {
- Assert.assertTrue(container.isLastId(new RowId(
- new Object[] { 4999 + offset })));
+ assertTrue(container.isLastId(new RowId(
+ new Object[]{4999 + offset})));
}
}
@@ -478,7 +504,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
for (int i = 0; i < 5000; i++) {
- Assert.assertTrue(container.containsId(container.getIdByIndex(i)));
+ assertTrue(container.containsId(container.getIdByIndex(i)));
}
}
@@ -490,7 +516,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
container.setAutoCommit(true);
for (int i = 0; i < 5000; i++) {
- Assert.assertTrue(container.containsId(container.getIdByIndex(i)));
+ assertTrue(container.containsId(container.getIdByIndex(i)));
}
}
@@ -523,7 +549,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
container.setAutoCommit(true);
- Assert.assertTrue(container.isAutoCommit());
+ assertTrue(container.isAutoCommit());
container.setAutoCommit(false);
Assert.assertFalse(container.isAutoCommit());
}
@@ -613,7 +639,7 @@ public class SQLContainerTableQueryTest {
container.setAutoCommit(true);
Object itemId = container.addItem();
Assert.assertNotNull(itemId);
- Assert.assertTrue(itemId instanceof RowId);
+ assertTrue(itemId instanceof RowId);
Assert.assertFalse(itemId instanceof TemporaryRowId);
}
@@ -696,7 +722,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.getItemIds().contains(id));
+ assertTrue(container.getItemIds().contains(id));
}
@Test
@@ -717,7 +743,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.containsId(id));
+ assertTrue(container.containsId(id));
}
@Test
@@ -747,7 +773,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("garbage",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.isFirstId(id));
+ assertTrue(container.isFirstId(id));
}
@Test
@@ -756,7 +782,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.isLastId(id));
+ assertTrue(container.isLastId(id));
}
@Test
@@ -766,7 +792,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
container.addItem();
Object id2 = container.addItem();
- Assert.assertTrue(container.isLastId(id2));
+ assertTrue(container.isLastId(id2));
}
@Test
@@ -785,7 +811,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
int size = container.size();
Object id = container.firstItemId();
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNotSame(id, container.firstItemId());
Assert.assertEquals(size - 1, container.size());
}
@@ -795,7 +821,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.firstItemId();
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.containsId(id));
}
@@ -806,7 +832,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
int size = container.size();
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.containsId(id));
Assert.assertEquals(size - 1, container.size());
}
@@ -816,7 +842,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.firstItemId();
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNull(container.getItem(id));
}
@@ -826,7 +852,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
Assert.assertNotNull(container.getItem(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNull(container.getItem(id));
}
@@ -836,8 +862,8 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.firstItemId();
- Assert.assertTrue(container.getItemIds().contains(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.getItemIds().contains(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.getItemIds().contains(id));
}
@@ -847,8 +873,8 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.getItemIds().contains(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.getItemIds().contains(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.getItemIds().contains(id));
}
@@ -857,8 +883,8 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.firstItemId();
- Assert.assertTrue(container.containsId(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.containsId(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.containsId(id));
}
@@ -869,8 +895,8 @@ public class SQLContainerTableQueryTest {
SQLTestsConstants.sqlGen);
SQLContainer container = new SQLContainer(query);
Object id = container.addItem();
- Assert.assertTrue(container.containsId(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.containsId(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.containsId(id));
}
@@ -882,7 +908,7 @@ public class SQLContainerTableQueryTest {
Object first = container.getIdByIndex(0);
Object second = container.getIdByIndex(1);
Object third = container.getIdByIndex(2);
- Assert.assertTrue(container.removeItem(second));
+ assertTrue(container.removeItem(second));
Assert.assertEquals(third, container.nextItemId(first));
}
@@ -894,7 +920,7 @@ public class SQLContainerTableQueryTest {
Object first = container.lastItemId();
Object second = container.addItem();
Object third = container.addItem();
- Assert.assertTrue(container.removeItem(second));
+ assertTrue(container.removeItem(second));
Assert.assertEquals(third, container.nextItemId(first));
}
@@ -906,7 +932,7 @@ public class SQLContainerTableQueryTest {
Object first = container.getIdByIndex(0);
Object second = container.getIdByIndex(1);
Object third = container.getIdByIndex(2);
- Assert.assertTrue(container.removeItem(second));
+ assertTrue(container.removeItem(second));
Assert.assertEquals(first, container.prevItemId(third));
}
@@ -918,7 +944,7 @@ public class SQLContainerTableQueryTest {
Object first = container.lastItemId();
Object second = container.addItem();
Object third = container.addItem();
- Assert.assertTrue(container.removeItem(second));
+ assertTrue(container.removeItem(second));
Assert.assertEquals(first, container.prevItemId(third));
}
@@ -928,7 +954,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object first = container.firstItemId();
- Assert.assertTrue(container.removeItem(first));
+ assertTrue(container.removeItem(first));
Assert.assertNotSame(first, container.firstItemId());
}
@@ -941,7 +967,7 @@ public class SQLContainerTableQueryTest {
Object first = container.addItem();
Object second = container.addItem();
Assert.assertSame(first, container.firstItemId());
- Assert.assertTrue(container.removeItem(first));
+ assertTrue(container.removeItem(first));
Assert.assertSame(second, container.firstItemId());
}
@@ -951,7 +977,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object last = container.lastItemId();
- Assert.assertTrue(container.removeItem(last));
+ assertTrue(container.removeItem(last));
Assert.assertNotSame(last, container.lastItemId());
}
@@ -962,7 +988,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Object last = container.addItem();
Assert.assertSame(last, container.lastItemId());
- Assert.assertTrue(container.removeItem(last));
+ assertTrue(container.removeItem(last));
Assert.assertNotSame(last, container.lastItemId());
}
@@ -972,7 +998,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object first = container.firstItemId();
- Assert.assertTrue(container.removeItem(first));
+ assertTrue(container.removeItem(first));
Assert.assertFalse(container.isFirstId(first));
}
@@ -985,7 +1011,7 @@ public class SQLContainerTableQueryTest {
Object first = container.addItem();
container.addItem();
Assert.assertSame(first, container.firstItemId());
- Assert.assertTrue(container.removeItem(first));
+ assertTrue(container.removeItem(first));
Assert.assertFalse(container.isFirstId(first));
}
@@ -995,7 +1021,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object last = container.lastItemId();
- Assert.assertTrue(container.removeItem(last));
+ assertTrue(container.removeItem(last));
Assert.assertFalse(container.isLastId(last));
}
@@ -1006,7 +1032,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Object last = container.addItem();
Assert.assertSame(last, container.lastItemId());
- Assert.assertTrue(container.removeItem(last));
+ assertTrue(container.removeItem(last));
Assert.assertFalse(container.isLastId(last));
}
@@ -1015,7 +1041,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.getIdByIndex(2);
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertEquals(-1, container.indexOfId(id));
}
@@ -1025,8 +1051,8 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.indexOfId(id) != -1);
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.indexOfId(id) != -1);
+ assertTrue(container.removeItem(id));
Assert.assertEquals(-1, container.indexOfId(id));
}
@@ -1036,7 +1062,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.getIdByIndex(2);
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNotSame(id, container.getIdByIndex(2));
}
@@ -1048,7 +1074,7 @@ public class SQLContainerTableQueryTest {
Object id = container.addItem();
container.addItem();
int index = container.indexOfId(id);
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNotSame(id, container.getIdByIndex(index));
}
@@ -1056,7 +1082,7 @@ public class SQLContainerTableQueryTest {
public void removeAllItems_table_shouldSucceed() throws SQLException {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
- Assert.assertTrue(container.removeAllItems());
+ assertTrue(container.removeAllItems());
Assert.assertEquals(0, container.size());
}
@@ -1067,10 +1093,30 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
container.addItem();
container.addItem();
- Assert.assertTrue(container.removeAllItems());
+ assertTrue(container.removeAllItems());
Assert.assertEquals(0, container.size());
}
+ // Set timeout to ensure there is no infinite looping (#12882)
+ @Test(timeout = 1000)
+ public void removeAllItems_manyItems_commit_shouldSucceed()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, SQLTestsConstants.sqlGen));
+ final int itemNumber = (SQLContainer.CACHE_RATIO + 1)
+ * SQLContainer.DEFAULT_PAGE_LENGTH + 1;
+ container.removeAllItems();
+ Assert.assertEquals(container.size(), 0);
+ for (int i = 0; i < itemNumber; ++i) {
+ container.addItem();
+ }
+ container.commit();
+ Assert.assertEquals(container.size(), itemNumber);
+ assertTrue(container.removeAllItems());
+ container.commit();
+ Assert.assertEquals(container.size(), 0);
+ }
+
@Test
public void commit_tableAddedItem_shouldBeWrittenToDB() throws SQLException {
TableQuery query = new TableQuery("people", connectionPool,
@@ -1078,7 +1124,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(query);
Object id = container.addItem();
container.getContainerProperty(id, "NAME").setValue("New Name");
- Assert.assertTrue(id instanceof TemporaryRowId);
+ assertTrue(id instanceof TemporaryRowId);
Assert.assertSame(id, container.lastItemId());
container.commit();
Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId);
@@ -1097,7 +1143,7 @@ public class SQLContainerTableQueryTest {
Object id2 = container.addItem();
container.getContainerProperty(id, "NAME").setValue("Herbert");
container.getContainerProperty(id2, "NAME").setValue("Larry");
- Assert.assertTrue(id2 instanceof TemporaryRowId);
+ assertTrue(id2 instanceof TemporaryRowId);
Assert.assertSame(id2, container.lastItemId());
container.commit();
Object nextToLast = container.getIdByIndex(container.size() - 2);
@@ -1137,6 +1183,20 @@ public class SQLContainerTableQueryTest {
}
@Test
+ public void commit_removeModifiedItem_shouldSucceed() throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ int size = container.size();
+ Object key = container.firstItemId();
+ Item row = container.getItem(key);
+ row.getItemProperty("NAME").setValue("Pekka");
+ assertTrue(container.removeItem(key));
+ container.commit();
+ Assert.assertEquals(size - 1, container.size());
+ }
+
+ @Test
public void rollback_tableItemAdded_discardsAddedItem() throws SQLException {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
@@ -1183,7 +1243,7 @@ public class SQLContainerTableQueryTest {
Assert.assertFalse(container.isModified());
RowItem last = (RowItem) container.getItem(container.lastItemId());
container.itemChangeNotification(last);
- Assert.assertTrue(container.isModified());
+ assertTrue(container.isModified());
}
@Test
@@ -1239,7 +1299,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Assert.assertFalse(container.isModified());
container.removeItem(container.lastItemId());
- Assert.assertTrue(container.isModified());
+ assertTrue(container.isModified());
}
@Test
@@ -1248,7 +1308,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Assert.assertFalse(container.isModified());
container.addItem();
- Assert.assertTrue(container.isModified());
+ assertTrue(container.isModified());
}
@Test
@@ -1258,7 +1318,7 @@ public class SQLContainerTableQueryTest {
Assert.assertFalse(container.isModified());
container.getContainerProperty(container.lastItemId(), "NAME")
.setValue("foo");
- Assert.assertTrue(container.isModified());
+ assertTrue(container.isModified());
}
@Test
@@ -1267,9 +1327,9 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Collection<?> sortableIds = container.getSortableContainerPropertyIds();
- Assert.assertTrue(sortableIds.contains("ID"));
- Assert.assertTrue(sortableIds.contains("NAME"));
- Assert.assertTrue(sortableIds.contains("AGE"));
+ assertTrue(sortableIds.contains("ID"));
+ assertTrue(sortableIds.contains("NAME"));
+ assertTrue(sortableIds.contains("AGE"));
Assert.assertEquals(3, sortableIds.size());
if (SQLTestsConstants.db == DB.MSSQL
|| SQLTestsConstants.db == DB.ORACLE) {
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestDefaultConverterFactory.java b/server/tests/src/com/vaadin/tests/data/converter/TestDefaultConverterFactory.java
new file mode 100644
index 0000000000..e1becf43e1
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestDefaultConverterFactory.java
@@ -0,0 +1,128 @@
+/*
+ * 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.tests.data.converter;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.converter.DefaultConverterFactory;
+
+public class TestDefaultConverterFactory {
+
+ private DefaultConverterFactory factory = new DefaultConverterFactory();
+
+ @Test
+ public void stringToBigDecimal() {
+ assertConverter("14", new BigDecimal("14"));
+ }
+
+ @Test
+ public void stringToBigInteger() {
+ assertConverter("14", new BigInteger("14"));
+ }
+
+ @Test
+ public void stringToDouble() {
+ assertConverter("14", new Double("14"));
+ }
+
+ @Test
+ public void stringToFloat() {
+ assertConverter("14", new Float("14"));
+ }
+
+ @Test
+ public void stringToInteger() {
+ assertConverter("14", new Integer("14"));
+ }
+
+ @Test
+ public void stringToLong() {
+ assertConverter("14", new Long("14"));
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void stringToDate() {
+ assertConverter("Oct 12, 2014 12:00:00 AM", new Date(2014 - 1900,
+ 10 - 1, 12));
+ }
+
+ @Test
+ public void sqlDateToDate() {
+ long l = 1413071210000L;
+ assertConverter(new java.sql.Date(l), new java.util.Date(l));
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void longToDate() {
+ assertConverter(1413061200000L, new Date(2014 - 1900, 10 - 1, 12));
+ }
+
+ public enum Foo {
+ BAR, BAZ;
+ }
+
+ @Test
+ public void stringToEnum() {
+ assertConverter("Bar", Foo.BAR);
+ }
+
+ @Test
+ public void stringToShort() {
+ assertConverter("14", new Short("14"));
+ }
+
+ @Test
+ public void stringToByte() {
+ assertConverter("14", new Byte("14"));
+ }
+
+ private <T, U> void assertConverter(T t, U u) {
+ Class<T> tClass = (Class<T>) t.getClass();
+ Class<U> uClass = (Class<U>) u.getClass();
+
+ U tConvertedToU = factory.createConverter(tClass, uClass)
+ .convertToModel(t, uClass, Locale.ENGLISH);
+ Assert.assertEquals(
+ "Incorrect type of value converted from "
+ + tClass.getSimpleName() + " to "
+ + uClass.getSimpleName(), uClass,
+ tConvertedToU.getClass());
+ Assert.assertEquals(
+ "Incorrect conversion of " + t + " to "
+ + uClass.getSimpleName(), u, tConvertedToU);
+
+ T uConvertedToT = factory.createConverter(uClass, tClass)
+ .convertToModel(u, tClass, Locale.ENGLISH);
+ Assert.assertEquals(
+ "Incorrect type of value converted from "
+ + uClass.getSimpleName() + " to "
+ + tClass.getSimpleName(), tClass,
+ uConvertedToT.getClass());
+ Assert.assertEquals(
+ "Incorrect conversion of " + u + " to "
+ + tClass.getSimpleName(), t, uConvertedToT);
+
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java
index 641f18c865..8d493609fe 100644
--- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java
@@ -15,39 +15,43 @@
*/
package com.vaadin.tests.data.converter;
-import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.Locale;
import junit.framework.TestCase;
-import com.vaadin.data.util.converter.StringToBigDecimalConverter;
+import com.vaadin.data.util.converter.StringToBigIntegerConverter;
public class TestStringToBigIntegerConverter extends TestCase {
- StringToBigDecimalConverter converter = new StringToBigDecimalConverter();
+ StringToBigIntegerConverter converter = new StringToBigIntegerConverter();
public void testNullConversion() {
- assertEquals(null,
- converter.convertToModel(null, BigDecimal.class, null));
+ assertEquals("Null value was converted incorrectly", null,
+ converter.convertToModel(null, BigInteger.class, null));
}
public void testEmptyStringConversion() {
- assertEquals(null, converter.convertToModel("", BigDecimal.class, null));
+ assertEquals("Empty value was converted incorrectly", null,
+ converter.convertToModel("", BigInteger.class, null));
}
public void testValueParsing() {
- BigDecimal converted = converter.convertToModel("10", BigDecimal.class,
- null);
- BigDecimal expected = new BigDecimal(10);
- assertEquals(expected, converted);
+ String bigInt = "1180591620717411303424"; // 2^70 > 2^63 - 1
+ BigInteger converted = converter.convertToModel(bigInt,
+ BigInteger.class, null);
+ BigInteger expected = new BigInteger(bigInt);
+ assertEquals("Value bigger than max long was converted incorrectly",
+ expected, converted);
}
public void testValueFormatting() {
- BigDecimal bd = new BigDecimal(1000);
+ BigInteger bd = new BigInteger("1000");
String expected = "1.000";
String converted = converter.convertToPresentation(bd, String.class,
Locale.GERMAN);
- assertEquals(expected, converted);
+ assertEquals("Value with specific locale was converted incorrectly",
+ expected, converted);
}
}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java
index 440d056c06..19a68fbfdb 100644
--- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java
@@ -16,25 +16,28 @@ public class TestStringToByteConverter extends TestCase {
converter);
public void testNullConversion() {
- assertEquals(null, converter.convertToModel(null, Byte.class, null));
+ assertEquals("Null value was converted incorrectly", null,
+ converter.convertToModel(null, Byte.class, null));
}
public void testReverseNullConversion() {
- assertEquals(null,
+ assertEquals("Null value reversely was converted incorrectly", null,
reverseConverter.convertToModel(null, String.class, null));
}
public void testEmptyStringConversion() {
- assertEquals(null, converter.convertToModel("", Byte.class, null));
+ assertEquals("Empty value was converted incorrectly", null,
+ converter.convertToModel("", Byte.class, null));
}
public void testValueConversion() {
- assertEquals(Byte.valueOf((byte) 10),
+ assertEquals("Byte value was converted incorrectly",
+ Byte.valueOf((byte) 10),
converter.convertToModel("10", Byte.class, null));
}
public void testReverseValueConversion() {
- assertEquals(
+ assertEquals("Byte value reversely was converted incorrectly",
reverseConverter.convertToModel((byte) 10, String.class, null),
"10");
}
@@ -43,7 +46,8 @@ public class TestStringToByteConverter extends TestCase {
byte b = converter.convertToModel("127", Byte.class, null);
Assert.assertEquals(Byte.MAX_VALUE, b);
b = converter.convertToModel("-128", Byte.class, null);
- assertEquals(Byte.MIN_VALUE, b);
+ assertEquals("Min byte value was converted incorrectly",
+ Byte.MIN_VALUE, b);
}
public void testValueOutOfRange() {
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java
index 2b19395c08..5dc24ca43a 100644
--- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java
@@ -3,6 +3,7 @@ package com.vaadin.tests.data.converter;
import junit.framework.TestCase;
import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.Converter.ConversionException;
import com.vaadin.data.util.converter.ReverseConverter;
import com.vaadin.data.util.converter.StringToEnumConverter;
@@ -16,6 +17,19 @@ public class TestStringToEnumConverter extends TestCase {
Converter<Enum, String> reverseConverter = new ReverseConverter<Enum, String>(
converter);
+ public void testEmptyStringConversion() {
+ assertEquals(null, converter.convertToModel("", Enum.class, null));
+ }
+
+ public void testInvalidEnumClassConversion() {
+ try {
+ converter.convertToModel("Foo", Enum.class, null);
+ fail("No exception thrown");
+ } catch (ConversionException e) {
+ // OK
+ }
+ }
+
public void testNullConversion() {
assertEquals(null, converter.convertToModel(null, Enum.class, null));
}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java
index 35547d2570..542c580025 100644
--- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java
@@ -16,25 +16,29 @@ public class TestStringToShortConverter extends TestCase {
converter);
public void testNullConversion() {
- assertEquals(null, converter.convertToModel(null, Short.class, null));
+ assertEquals("Null value was converted incorrectly", null,
+ converter.convertToModel(null, Short.class, null));
}
public void testReverseNullConversion() {
- assertEquals(null,
+ assertEquals("Null value reversely was converted incorrectly", null,
reverseConverter.convertToModel(null, String.class, null));
}
public void testEmptyStringConversion() {
- assertEquals(null, converter.convertToModel("", Short.class, null));
+ assertEquals("Empty value was converted incorrectly", null,
+ converter.convertToModel("", Short.class, null));
}
public void testValueConversion() {
- assertEquals(Short.valueOf((short) 10),
+ assertEquals("Short value was converted incorrectly",
+ Short.valueOf((short) 10),
converter.convertToModel("10", Short.class, null));
}
public void testReverseValueConversion() {
assertEquals(
+ "Short value reversely was converted incorrectly",
reverseConverter.convertToModel((short) 10, String.class, null),
"10");
}
@@ -43,7 +47,8 @@ public class TestStringToShortConverter extends TestCase {
short b = converter.convertToModel("32767", Short.class, null);
Assert.assertEquals(Short.MAX_VALUE, b);
b = converter.convertToModel("-32768", Short.class, null);
- assertEquals(Short.MIN_VALUE, b);
+ assertEquals("Min short value was converted incorrectly",
+ Short.MIN_VALUE, b);
}
public void testValueOutOfRange() {
diff --git a/server/tests/src/com/vaadin/tests/server/FileResourceTest.java b/server/tests/src/com/vaadin/tests/server/FileResourceTest.java
new file mode 100644
index 0000000000..4798fb9f05
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/FileResourceTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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.tests.server;
+
+import java.io.File;
+
+import org.junit.Test;
+
+import com.vaadin.server.FileResource;
+
+public class FileResourceTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFile() {
+ new FileResource(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void nonExistingFile() {
+ new FileResource(new File("nonexisting")).getStream();
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java
index 112d36d884..9c37b91ef5 100644
--- a/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java
@@ -5,9 +5,11 @@ import static org.junit.Assert.assertEquals;
import org.junit.Assert;
import org.junit.Test;
+import com.vaadin.data.Item;
import com.vaadin.data.fieldgroup.BeanFieldGroup;
import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
import com.vaadin.data.fieldgroup.PropertyId;
+import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.Field;
import com.vaadin.ui.TextField;
@@ -133,4 +135,23 @@ public class BeanFieldGroupTest {
assertEquals(bean.nestedBean.hello, helloField.getValue().toString());
}
+ @Test
+ public void setDataSource_nullBean_nullBeanIsSetInDataSource() {
+ BeanFieldGroup<MyBean> group = new BeanFieldGroup<MyBean>(MyBean.class);
+
+ group.setItemDataSource((MyBean) null);
+
+ BeanItem<MyBean> dataSource = group.getItemDataSource();
+ Assert.assertNull("Data source is null for null bean", dataSource);
+ }
+
+ @Test
+ public void setDataSource_nullItem_nullDataSourceIsSet() {
+ BeanFieldGroup<MyBean> group = new BeanFieldGroup<MyBean>(MyBean.class);
+
+ group.setItemDataSource((Item) null);
+ BeanItem<MyBean> dataSource = group.getItemDataSource();
+ Assert.assertNull("Group returns not null data source", dataSource);
+ }
+
}
diff --git a/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java b/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
index df515795eb..d8b366ffbc 100644
--- a/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
+++ b/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
@@ -9,6 +9,7 @@ import com.vaadin.ui.AbsoluteLayout.ComponentPosition;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.CustomLayout;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.GridLayout.Area;
import com.vaadin.ui.HasComponents;
@@ -25,6 +26,7 @@ public class ComponentAttachDetachListenerTest extends TestCase {
private GridLayout gridlayout;
private AbsoluteLayout absolutelayout;
private CssLayout csslayout;
+ private CustomLayout customlayout;
// General variables
private int attachCounter = 0;
@@ -143,6 +145,10 @@ public class ComponentAttachDetachListenerTest extends TestCase {
csslayout = new CssLayout();
csslayout.addComponentAttachListener(new MyAttachListener());
csslayout.addComponentDetachListener(new MyDetachListener());
+
+ customlayout = new CustomLayout("<div location='loc'/>");
+ customlayout.addComponentAttachListener(new MyAttachListener());
+ customlayout.addComponentDetachListener(new MyDetachListener());
}
public void testOrderedLayoutAttachListener() {
@@ -342,4 +348,48 @@ public class ComponentAttachDetachListenerTest extends TestCase {
// The detached component should not be found in the container
assertFalse(foundInContainer);
}
+
+ public void testCustomLayoutAttachListener() {
+ // Reset state variables
+ resetVariables();
+
+ // Add component -> Should trigger attach listener
+ Component comp = new Label();
+ customlayout.addComponent(comp, "loc");
+
+ assertEquals("Attach counter should get incremented", 1, attachCounter);
+
+ assertSame("The attached component should be the label", comp,
+ attachedComponent);
+
+ assertSame("The attached target should be the layout", customlayout,
+ attachTarget);
+
+ assertTrue("The attached component should be found in the container",
+ foundInContainer);
+ }
+
+ public void testCustomLayoutDetachListener() {
+ // Add a component to detach
+ Component comp = new Label();
+ customlayout.addComponent(comp);
+
+ // Reset state variables (since they are set by the attach listener)
+ resetVariables();
+
+ // Detach the component -> triggers the detach listener
+ customlayout.removeComponent(comp);
+
+ assertEquals("Detach counter should get incremented", 1, detachCounter);
+
+ assertSame("The detached component should be the label", comp,
+ detachedComponent);
+
+ assertSame("The detached target should be the layout", customlayout,
+ detachedTarget);
+
+ assertFalse(
+ "The detached component should not be found in the container",
+ foundInContainer);
+ }
}
diff --git a/server/tests/src/com/vaadin/ui/AbstractSelectTest.java b/server/tests/src/com/vaadin/ui/AbstractSelectTest.java
index 83d66ee9d5..bd399f088c 100644
--- a/server/tests/src/com/vaadin/ui/AbstractSelectTest.java
+++ b/server/tests/src/com/vaadin/ui/AbstractSelectTest.java
@@ -16,10 +16,13 @@
package com.vaadin.ui;
import java.util.ArrayList;
+import java.util.HashSet;
import org.junit.Assert;
import org.junit.Test;
+import com.vaadin.data.util.ObjectProperty;
+
public class AbstractSelectTest {
@Test
@@ -73,4 +76,72 @@ public class AbstractSelectTest {
.toArray());
}
+
+ @Test
+ public void singleSelectInitiallyEmpty() {
+ AbstractSelect s = new ListSelect();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void singleSelectEmptyAfterClearUsingPDS() {
+ AbstractSelect s = new ListSelect();
+ s.addItem("foo");
+ s.addItem("bar");
+ s.setPropertyDataSource(new ObjectProperty<String>("foo"));
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void singleSelectEmptyAfterClear() {
+ AbstractSelect s = new ListSelect();
+ s.addItem("foo");
+ s.addItem("bar");
+ s.setValue("bar");
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void multiSelectInitiallyEmpty() {
+ AbstractSelect s = new ListSelect();
+ s.setMultiSelect(true);
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void multiSelectEmptyAfterClearUsingPDS() {
+ AbstractSelect s = new ListSelect();
+ s.setMultiSelect(true);
+ s.addItem("foo");
+ s.addItem("bar");
+ HashSet<String> sel = new HashSet<String>();
+ sel.add("foo");
+ sel.add("bar");
+ s.setPropertyDataSource(new ObjectProperty<HashSet>(sel));
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void multiSelectEmptyAfterClear() {
+ AbstractSelect s = new ListSelect();
+ s.setMultiSelect(true);
+ s.addItem("foo");
+ s.addItem("bar");
+ s.select("foo");
+ s.select("bar");
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
}
diff --git a/server/tests/src/com/vaadin/ui/RichTextAreaTest.java b/server/tests/src/com/vaadin/ui/RichTextAreaTest.java
new file mode 100644
index 0000000000..ce0dfdc696
--- /dev/null
+++ b/server/tests/src/com/vaadin/ui/RichTextAreaTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+
+public class RichTextAreaTest {
+ @Test
+ public void initiallyEmpty() {
+ RichTextArea tf = new RichTextArea();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearUsingPDS() {
+ RichTextArea tf = new RichTextArea(new ObjectProperty<String>("foo"));
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClear() {
+ RichTextArea tf = new RichTextArea();
+ tf.setValue("foobar");
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/ui/TextAreaTest.java b/server/tests/src/com/vaadin/ui/TextAreaTest.java
new file mode 100644
index 0000000000..e7e99c19e9
--- /dev/null
+++ b/server/tests/src/com/vaadin/ui/TextAreaTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+
+public class TextAreaTest {
+ @Test
+ public void initiallyEmpty() {
+ TextArea tf = new TextArea();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearUsingPDS() {
+ TextArea tf = new TextArea(new ObjectProperty<String>("foo"));
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClear() {
+ TextArea tf = new TextArea();
+ tf.setValue("foobar");
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/ui/UIThemeEscaping.java b/server/tests/src/com/vaadin/ui/UIThemeEscaping.java
new file mode 100644
index 0000000000..236f283823
--- /dev/null
+++ b/server/tests/src/com/vaadin/ui/UIThemeEscaping.java
@@ -0,0 +1,89 @@
+/*
+ * 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.server.VaadinRequest;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class UIThemeEscaping {
+
+ private UI ui;
+
+ private void initUiWithTheme(String theme) {
+ VaadinRequest request = getRequestWithTheme(theme);
+
+ ui.doInit(request, 1234, "foobar");
+ }
+
+ private VaadinRequest getRequestWithTheme(String theme) {
+ VaadinRequest request = mock(VaadinRequest.class);
+
+ when(request.getParameter("theme")).thenReturn(theme);
+
+ return request;
+ }
+
+ @Before
+ public void setup() {
+ ui = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ // Nothing to do
+ }
+ };
+ }
+
+ @Test
+ public void dangerousCharactersAreRemoved() {
+ ui.setTheme("a<å(_\"$");
+
+ assertThat(ui.getTheme(), is("aå_$"));
+ }
+
+ @Test
+ public void nullThemeIsSet() {
+ ui.setTheme("foobar");
+
+ ui.setTheme(null);
+
+ assertThat(ui.getTheme(), is(nullValue()));
+ }
+
+ @Test
+ public void themeIsSetOnInit() {
+ ui.setTheme("foobar");
+
+ initUiWithTheme("bar");
+
+ assertThat(ui.getTheme(), is("bar"));
+ }
+
+ @Test
+ public void nullThemeIsSetOnInit() {
+ ui.setTheme("foobar");
+
+ initUiWithTheme(null);
+
+ assertThat(ui.getTheme(), is(nullValue()));
+ }
+}