summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2014-04-23 20:45:14 +0300
committerArtur Signell <artur@vaadin.com>2014-04-23 20:45:39 +0300
commit41cb27e85f61f5abb029a98af66217ce400b2196 (patch)
tree609df412869abde48131079d45b2981bcb210744 /server
parent9f30eb285252348c349e9a759ac71098eb74a06a (diff)
parent0d4080ba5e5931fa928675ba6c95540e34b2f281 (diff)
downloadvaadin-framework-41cb27e85f61f5abb029a98af66217ce400b2196.tar.gz
vaadin-framework-41cb27e85f61f5abb029a98af66217ce400b2196.zip
Merge changes from origin/7.1
0d4080b ContainerEventProvider returns style names from container. Fixes #10718 6e91bdf Add test for TransactionalPropertyWrapper memory leaks f0aaf89 Fixed resetting of ComboBox if focused and new items allowed (#13413). e033fcd Always initialize WebBrowser for new sessions (#13571) 168de1f Revert "Drag image for text-area should contain text of text-area (#13557)" 35e2a34 Fix FieldGroup and TransactionalPropertyWrapper memory leaks (#13438) 7e5d44d Introduce a drag threshold for Drag and Drop (#13381) f227f0c Drag image for text-area should contain text of text-area (#13557). Change-Id: Idb01471f8ab0c7118fa884c364e6bc200d13948a
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/data/fieldgroup/FieldGroup.java8
-rw-r--r--server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java26
-rw-r--r--server/src/com/vaadin/server/BootstrapHandler.java4
-rw-r--r--server/src/com/vaadin/server/VaadinService.java3
-rw-r--r--server/src/com/vaadin/server/communication/UIInitHandler.java2
-rw-r--r--server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java4
-rw-r--r--server/tests/src/com/vaadin/data/util/TransactionalPropertyWrapperTest.java116
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/calendar/ContainerDataSource.java32
8 files changed, 181 insertions, 14 deletions
diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
index 7edcc9719c..6a2d1a125d 100644
--- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
@@ -312,12 +312,18 @@ public class FieldGroup implements Serializable {
"The given field is not part of this FieldBinder");
}
+ TransactionalPropertyWrapper<?> wrapper = null;
Property fieldDataSource = field.getPropertyDataSource();
if (fieldDataSource instanceof TransactionalPropertyWrapper) {
- fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource)
+ wrapper = (TransactionalPropertyWrapper<?>) fieldDataSource;
+ fieldDataSource = ((TransactionalPropertyWrapper<?>) fieldDataSource)
.getWrappedProperty();
+
}
if (fieldDataSource == getItemProperty(propertyId)) {
+ if (null != wrapper) {
+ wrapper.detachFromProperty();
+ }
field.setPropertyDataSource(null);
}
fieldToPropertyId.remove(field);
diff --git a/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java b/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
index 6b0119c503..3c52ab9afc 100644
--- a/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
+++ b/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
@@ -48,18 +48,32 @@ public class TransactionalPropertyWrapper<T> extends AbstractProperty<T>
private boolean inTransaction = false;
private boolean valueChangePending;
private T valueBeforeTransaction;
+ private final ValueChangeListener listener = new ValueChangeListener() {
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ fireValueChange();
+ }
+ };
public TransactionalPropertyWrapper(Property<T> wrappedProperty) {
this.wrappedProperty = wrappedProperty;
if (wrappedProperty instanceof ValueChangeNotifier) {
((ValueChangeNotifier) wrappedProperty)
- .addListener(new ValueChangeListener() {
+ .addValueChangeListener(listener);
+ }
+ }
- @Override
- public void valueChange(ValueChangeEvent event) {
- fireValueChange();
- }
- });
+ /**
+ * Removes the ValueChangeListener from wrapped Property that was added by
+ * TransactionalPropertyWrapper.
+ *
+ * @since 7.1.15
+ */
+ public void detachFromProperty() {
+ if (wrappedProperty instanceof ValueChangeNotifier) {
+ ((ValueChangeNotifier) wrappedProperty)
+ .removeValueChangeListener(listener);
}
}
diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java
index bfdbea3086..069cd61253 100644
--- a/server/src/com/vaadin/server/BootstrapHandler.java
+++ b/server/src/com/vaadin/server/BootstrapHandler.java
@@ -156,10 +156,6 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
public boolean synchronizedHandleRequest(VaadinSession session,
VaadinRequest request, VaadinResponse response) throws IOException {
try {
- // Update WebBrowser here only to make WebBrowser information
- // available in init for LegacyApplications
- session.getBrowser().updateRequestDetails(request);
-
List<UIProvider> uiProviders = session.getUIProviders();
UIClassSelectionEvent classSelectionEvent = new UIClassSelectionEvent(
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index b96e284e6e..6860166a11 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -750,6 +750,9 @@ public abstract class VaadinService implements Serializable {
session.storeInSession(this, request.getWrappedSession());
+ // Initial WebBrowser data comes from the request
+ session.getBrowser().updateRequestDetails(request);
+
// Initial locale comes from the request
Locale locale = request.getLocale();
session.setLocale(locale);
diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java
index 76460e153a..898368d53c 100644
--- a/server/src/com/vaadin/server/communication/UIInitHandler.java
+++ b/server/src/com/vaadin/server/communication/UIInitHandler.java
@@ -68,7 +68,7 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
try {
assert UI.getCurrent() == null;
- // Set browser information from the request
+ // Update browser information from the request
session.getBrowser().updateRequestDetails(request);
UI uI = getBrowserDetailsUI(request, session);
diff --git a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
index 37ea255d27..b025de6f9a 100644
--- a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
+++ b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
@@ -224,8 +224,8 @@ public class ContainerEventProvider implements CalendarEditableEventProvider,
}
if (styleNameProperty != null
&& item.getItemPropertyIds().contains(styleNameProperty)) {
- basicEvent.setDescription(String.valueOf(item.getItemProperty(
- descriptionProperty).getValue()));
+ basicEvent.setStyleName(String.valueOf(item.getItemProperty(
+ styleNameProperty).getValue()));
}
event = basicEvent;
}
diff --git a/server/tests/src/com/vaadin/data/util/TransactionalPropertyWrapperTest.java b/server/tests/src/com/vaadin/data/util/TransactionalPropertyWrapperTest.java
new file mode 100644
index 0000000000..8e83db5aef
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/TransactionalPropertyWrapperTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2013 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 static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.ui.TextField;
+
+/**
+ * Test verifying that TransactionalPropertyWrapper removes it's listener from
+ * wrapped Property
+ *
+ * @since 7.1.15
+ * @author Vaadin Ltd
+ */
+public class TransactionalPropertyWrapperTest {
+
+ @SuppressWarnings("serial")
+ public class TestingProperty<T extends Object> extends
+ ObjectProperty<Object> {
+
+ private List<ValueChangeListener> listeners = new ArrayList<ValueChangeListener>();
+
+ public TestingProperty(Object value) {
+ super(value);
+ }
+
+ @Override
+ public void addValueChangeListener(ValueChangeListener listener) {
+ super.addValueChangeListener(listener);
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeValueChangeListener(ValueChangeListener listener) {
+ super.removeValueChangeListener(listener);
+ if (listeners.contains(listener)) {
+ listeners.remove(listener);
+ }
+ }
+
+ public boolean hasListeners() {
+ return !listeners.isEmpty();
+ }
+ }
+
+ private final TextField nameField = new TextField("Name");
+ private final TextField ageField = new TextField("Age");
+ private final TextField unboundField = new TextField("No FieldGroup");
+ private final TestingProperty<String> unboundProp = new TestingProperty<String>(
+ "Hello World");
+ private final PropertysetItem item = new PropertysetItem();
+
+ @Test
+ public void fieldGroupBindAndUnbind() {
+ item.addItemProperty("name", new TestingProperty<String>(
+ "Just some text"));
+ item.addItemProperty("age", new TestingProperty<String>("42"));
+
+ final FieldGroup binder = new FieldGroup(item);
+ binder.setBuffered(false);
+
+ for (int i = 0; i < 2; ++i) {
+ binder.bind(nameField, "name");
+ binder.bind(ageField, "age");
+ unboundField.setPropertyDataSource(unboundProp);
+
+ assertTrue("No listeners in Properties", fieldsHaveListeners(true));
+
+ binder.unbind(nameField);
+ binder.unbind(ageField);
+ unboundField.setPropertyDataSource(null);
+
+ assertTrue("Listeners in Properties after unbinding",
+ fieldsHaveListeners(false));
+ }
+ }
+
+ /**
+ * Check that all listeners have same hasListeners() response
+ *
+ * @param expected
+ * expected response
+ * @return true if all are the same as expected. false if not
+ */
+ private boolean fieldsHaveListeners(boolean expected) {
+ for (Object id : item.getItemPropertyIds()) {
+ TestingProperty<?> itemProperty = (TestingProperty<?>) item
+ .getItemProperty(id);
+
+ if (itemProperty.hasListeners() != expected) {
+ return false;
+ }
+ }
+ return unboundProp.hasListeners() == expected;
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/calendar/ContainerDataSource.java b/server/tests/src/com/vaadin/tests/server/component/calendar/ContainerDataSource.java
index 2bc95e371c..d5b0d5d9c8 100644
--- a/server/tests/src/com/vaadin/tests/server/component/calendar/ContainerDataSource.java
+++ b/server/tests/src/com/vaadin/tests/server/component/calendar/ContainerDataSource.java
@@ -25,6 +25,7 @@ import org.junit.Test;
import com.vaadin.data.Container.Indexed;
import com.vaadin.data.Container.Sortable;
import com.vaadin.data.Item;
+import com.vaadin.data.Property;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Calendar;
@@ -327,6 +328,37 @@ public class ContainerDataSource extends TestCase {
assertEquals(0, calendar.getEvents(start, end).size());
}
+ @Test
+ public void testStyleNamePropertyRetrieved() {
+ IndexedContainer ic = (IndexedContainer) createTestIndexedContainer();
+ ic.addContainerProperty("testStyleName", String.class, "");
+ for (int i = 0; i < 10; i++) {
+ Item item = ic.getItem(ic.getIdByIndex(i));
+ @SuppressWarnings("unchecked")
+ Property<String> itemProperty = item
+ .getItemProperty("testStyleName");
+ itemProperty.setValue("testStyle");
+ }
+
+ ContainerEventProvider provider = new ContainerEventProvider(ic);
+ provider.setCaptionProperty("testCaption");
+ provider.setDescriptionProperty("testDescription");
+ provider.setStartDateProperty("testStartDate");
+ provider.setEndDateProperty("testEndDate");
+ provider.setStyleNameProperty("testStyleName");
+
+ calendar.setEventProvider(provider);
+ java.util.Calendar cal = java.util.Calendar.getInstance();
+ Date now = cal.getTime();
+ cal.add(java.util.Calendar.DAY_OF_MONTH, 20);
+ Date then = cal.getTime();
+ List<CalendarEvent> events = calendar.getEventProvider().getEvents(now,
+ then);
+ for (CalendarEvent ce : events) {
+ assertEquals("testStyle", ce.getStyleName());
+ }
+ }
+
private static Indexed createTestBeanItemContainer() {
BeanItemContainer<CalendarEvent> eventContainer = new BeanItemContainer<CalendarEvent>(
CalendarEvent.class);