From dac74189ededf7d004b309215f7e9f64a3e4550c Mon Sep 17 00:00:00 2001
From: Fabian Lange
Date: Mon, 24 Nov 2014 21:30:59 +0100
Subject: do not create a StringWriter when not needed (#15276)
Change-Id: I528f4034ef5cf375be31750bbad9baddcd3a2b64
---
server/src/com/vaadin/server/communication/UIInitHandler.java | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java
index 356ad25219..8e61370d85 100644
--- a/server/src/com/vaadin/server/communication/UIInitHandler.java
+++ b/server/src/com/vaadin/server/communication/UIInitHandler.java
@@ -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());
}
/**
--
cgit v1.2.3
From 75ca951246f4c40dbc6914539d2d2d4890d30089 Mon Sep 17 00:00:00 2001
From: Anna Koskinen
Date: Tue, 25 Nov 2014 17:23:45 +0200
Subject: Add getter to SplitterState.positionReversed (#15285)
Change-Id: I1e3783d21cb5f2832838dfe36c91c7f6a4ddb313
---
server/src/com/vaadin/ui/AbstractSplitPanel.java | 14 ++++++++++++++
1 file changed, 14 insertions(+)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/ui/AbstractSplitPanel.java b/server/src/com/vaadin/ui/AbstractSplitPanel.java
index 09f881cf46..e9b37f8cff 100644
--- a/server/src/com/vaadin/ui/AbstractSplitPanel.java
+++ b/server/src/com/vaadin/ui/AbstractSplitPanel.java
@@ -342,11 +342,25 @@ 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.
--
cgit v1.2.3
From f301dd8d759c5006cb411df0e424a876e04b84fb Mon Sep 17 00:00:00 2001
From: Fabian Lange
Date: Mon, 10 Nov 2014 19:07:12 +0100
Subject: set Cache-Control and Expires header even when not-modified (#8757)
Usually first a resource is served with the lower code block. this
provides cache-control, expires and last-modification headers to the
browser. But when a not-modified response was served, these headers
were missing. This effectively caused the caching to no longer work once
the not-modified responses are sent out.
Change-Id: I9b1f0cacc91734f88bb0384872da0d426d4b5fe0
---
server/src/com/vaadin/server/VaadinServlet.java | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index 4656f9a672..4fd1e97a40 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/com/vaadin/server/VaadinServlet.java
@@ -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);
}
--
cgit v1.2.3
From 58cf6113d02cb0331dae6d5ff46eb3e4a0ccdb01 Mon Sep 17 00:00:00 2001
From: Denis Anisimov
Date: Wed, 5 Nov 2014 19:37:31 +0200
Subject: Prevent NPE in AbstractBeanContainer.getType() method (#15173).
Change-Id: Ieaed329ed85c68d0da8bd169b4cc5c5886dde212
---
server/src/com/vaadin/data/util/AbstractBeanContainer.java | 8 ++++++--
.../tests/src/com/vaadin/data/util/BeanContainerTest.java | 13 +++++++++++++
.../src/com/vaadin/data/util/BeanItemContainerTest.java | 13 +++++++++++++
3 files changed, 32 insertions(+), 2 deletions(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/data/util/AbstractBeanContainer.java b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
index adf6313770..7d7d71c423 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 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> model;
+ private final LinkedHashMap> model;
/**
* Constructs a {@code AbstractBeanContainer} for beans of the given type.
@@ -178,7 +178,11 @@ public abstract class AbstractBeanContainer extends
*/
@Override
public Class> getType(Object propertyId) {
- return model.get(propertyId).getPropertyType();
+ VaadinPropertyDescriptor descriptor = model.get(propertyId);
+ if (descriptor == null) {
+ return null;
+ }
+ return descriptor.getPropertyType();
}
/**
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 container = getContainer();
+ Assert.assertEquals(
+ "Unexpected type is returned for property 'simpleName'",
+ String.class, container.getType("simpleName"));
+ }
+
+ public void testGetType_notExistingProperty_nullReturned() {
+ BeanContainer 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..01c282e294 100644
--- a/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
+++ b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
@@ -71,6 +71,19 @@ public class BeanItemContainerTest extends AbstractBeanContainerTest {
return false;
}
+ public void testGetType_existingProperty_typeReturned() {
+ BeanItemContainer container = getContainer();
+ Assert.assertEquals(
+ "Unexpected type is returned for property 'simpleName'",
+ String.class, container.getType("simpleName"));
+ }
+
+ public void testGetType_notExistingProperty_nullReturned() {
+ BeanItemContainer container = getContainer();
+ Assert.assertNull("Not null type is returned for property ''",
+ container.getType(""));
+ }
+
public void testBasicOperations() {
testBasicContainerOperations(getContainer());
}
--
cgit v1.2.3
From 53f87e5bf3014382f0bf9cd7acb18c56709ba1f7 Mon Sep 17 00:00:00 2001
From: Denis Anisimov
Date: Sun, 19 Oct 2014 14:54:47 +0300
Subject: Show push version information in debug window (#14904).
Change-Id: Id1761abbf2b2dc29b4138520f11ce51bb4d423fc
---
.../vaadin/client/ApplicationConfiguration.java | 45 +++++++++
.../vaadin/client/debug/internal/InfoSection.java | 8 ++
server/src/com/vaadin/server/BootstrapHandler.java | 2 +
.../com/vaadin/tests/debug/PushVersionInfo.java | 51 +++++++++++
.../vaadin/tests/debug/PushVersionInfoTest.java | 102 +++++++++++++++++++++
5 files changed, 208 insertions(+)
create mode 100644 uitest/src/com/vaadin/tests/debug/PushVersionInfo.java
create mode 100644 uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java
(limited to 'server/src')
diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java
index 12b1585292..4865e38a4a 100644
--- a/client/src/com/vaadin/client/ApplicationConfiguration.java
+++ b/client/src/com/vaadin/client/ApplicationConfiguration.java
@@ -172,6 +172,33 @@ public class ApplicationConfiguration implements EntryPoint {
return this.getConfig("versionInfo").vaadinVersion;
}-*/;
+ /**
+ * Gets the version of the Atmosphere framework.
+ *
+ * @return a string with the version
+ *
+ * @see org.atmosphere.util#getRawVersion()
+ */
+ private native String getAtmosphereVersion()
+ /*-{
+ return this.getConfig("versionInfo").atmosphereVersion;
+ }-*/;
+
+ /**
+ * Gets the JS version used in the Atmosphere framework.
+ *
+ * @return a string with the version
+ */
+ private native String getAtmosphereJSVersion()
+ /*-{
+ if ($wnd.jQueryVaadin != undefined){
+ return $wnd.jQueryVaadin.atmosphere.version;
+ }
+ else {
+ return null;
+ }
+ }-*/;
+
private native String getUIDL()
/*-{
return this.getConfig("uidl");
@@ -461,6 +488,24 @@ public class ApplicationConfiguration implements EntryPoint {
return getJsoConfiguration(id).getVaadinVersion();
}
+ /**
+ * Return Atmosphere version.
+ *
+ * @return Atmosphere version.
+ */
+ public String getAtmosphereVersion() {
+ return getJsoConfiguration(id).getAtmosphereVersion();
+ }
+
+ /**
+ * Return Atmosphere JS version.
+ *
+ * @return Atmosphere JS version.
+ */
+ public String getAtmosphereJSVersion() {
+ return getJsoConfiguration(id).getAtmosphereJSVersion();
+ }
+
public Class extends ServerConnector> getConnectorClassByEncodedTag(
int tag) {
Class extends ServerConnector> type = classes.get(tag);
diff --git a/client/src/com/vaadin/client/debug/internal/InfoSection.java b/client/src/com/vaadin/client/debug/internal/InfoSection.java
index a7a84f5f8f..dfb31cdd18 100644
--- a/client/src/com/vaadin/client/debug/internal/InfoSection.java
+++ b/client/src/com/vaadin/client/debug/internal/InfoSection.java
@@ -193,6 +193,9 @@ public class InfoSection implements Section {
ApplicationConfiguration applicationConfiguration) {
String clientVersion = Version.getFullVersion();
String servletVersion = applicationConfiguration.getServletVersion();
+ String atmosphereVersion = applicationConfiguration
+ .getAtmosphereVersion();
+ String jsVersion = applicationConfiguration.getAtmosphereJSVersion();
String themeVersion;
boolean themeOk;
@@ -213,6 +216,11 @@ public class InfoSection implements Section {
addRow("Server engine version", servletVersion, servletOk ? null
: ERROR_STYLE);
addRow("Theme version", themeVersion, themeOk ? null : ERROR_STYLE);
+ if (jsVersion != null) {
+ addRow("Push server version", atmosphereVersion);
+ addRow("Push client version", jsVersion
+ + " (note: does not need to match server version)");
+ }
}
/**
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/uitest/src/com/vaadin/tests/debug/PushVersionInfo.java b/uitest/src/com/vaadin/tests/debug/PushVersionInfo.java
new file mode 100644
index 0000000000..d8c23a390f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/debug/PushVersionInfo.java
@@ -0,0 +1,51 @@
+/*
+ * 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.debug;
+
+import org.atmosphere.util.Version;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.communication.PushMode;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Label;
+
+/**
+ * Test UI for PUSH version string in debug window.
+ *
+ * @author Vaadin Ltd
+ */
+public class PushVersionInfo extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ if (request.getParameter("enablePush") != null) {
+ getPushConfiguration().setPushMode(PushMode.AUTOMATIC);
+ Label label = new Label(Version.getRawVersion());
+ label.addStyleName("atmosphere-version");
+ addComponent(label);
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Debug window shows Push version in info Tab.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14904;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java b/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java
new file mode 100644
index 0000000000..90ea645ab8
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.debug;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.tests.annotations.TestCategory;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Test for PUSH version string in debug window.
+ *
+ * @author Vaadin Ltd
+ */
+@TestCategory("push")
+public class PushVersionInfoTest extends MultiBrowserTest {
+
+ @Test
+ public void testDisabledPush() {
+ setDebug(true);
+ openTestURL();
+
+ selectInfoTab();
+ Assert.assertNull("Found push info server string for disabled Push",
+ getPushRowValue("Push server version"));
+ Assert.assertNull("Found push info client string for disabled Push",
+ getPushRowValue("Push client version"));
+ }
+
+ @Test
+ public void testEnabledPush() {
+ setDebug(true);
+ openTestURL("enablePush=true");
+
+ selectInfoTab();
+ WebElement pushRow = getPushRowValue("Push server version");
+ String atmVersion = findElement(By.className("atmosphere-version"))
+ .getText();
+ Assert.assertTrue("Push row doesn't contain Atmosphere version",
+ pushRow.getText().contains(atmVersion));
+ String jsString = getPushRowValue("Push client version").getText();
+ Assert.assertTrue(
+ "Push client version doesn't contain 'vaadin' string",
+ jsString.contains("vaadin"));
+ Assert.assertTrue(
+ "Push client version doesn't contain 'jquery' string",
+ jsString.contains("jquery"));
+ }
+
+ private void selectInfoTab() {
+ if (isElementPresent(By.className("v-ie8"))) {
+
+ int size = findElements(By.className("v-debugwindow-tab")).size();
+ for (int i = 0; i < size; i++) {
+ WebElement tab = findElement(By
+ .className("v-debugwindow-tab-selected"));
+ String title = tab.getAttribute("title");
+ if (title != null && title.startsWith("General information")) {
+ break;
+ }
+ Actions actions = new Actions(getDriver());
+ actions.sendKeys(Keys.TAB);
+ actions.sendKeys(Keys.SPACE);
+ actions.build().perform();
+ }
+ } else {
+ findElements(By.className("v-debugwindow-tab")).get(0).click();
+ findElements(By.className("v-debugwindow-tab")).get(1).click();
+ }
+ }
+
+ private WebElement getPushRowValue(String key) {
+ List rows = findElements(By.className("v-debugwindow-row"));
+ for (WebElement row : rows) {
+ WebElement caption = row.findElement(By.className("caption"));
+ if (caption.getText().startsWith(key)) {
+ return row.findElement(By.className("value"));
+ }
+ }
+ return null;
+ }
+}
--
cgit v1.2.3
From 654846837379db9a76823f5d0e73e5e6bfa8115d Mon Sep 17 00:00:00 2001
From: Denis Anisimov
Date: Mon, 29 Sep 2014 20:40:36 +0300
Subject: Allow BeanFieldGroup.setItemDataSource() method accept null (#14731).
Change-Id: I7a451f428f0aa3ea7fc322cac6b0e62d830d7987
---
.../com/vaadin/data/fieldgroup/BeanFieldGroup.java | 7 ++---
server/src/com/vaadin/data/util/BeanItem.java | 25 ++++++++++++++++-
.../src/com/vaadin/data/util/MethodProperty.java | 10 ++++---
.../component/fieldgroup/BeanFieldGroupTest.java | 31 ++++++++++++++++++++++
4 files changed, 66 insertions(+), 7 deletions(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
index e5d53b759d..1f3ee36d58 100644
--- a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
@@ -130,16 +130,17 @@ public class BeanFieldGroup extends FieldGroup {
* The bean to use as data source.
*/
public void setItemDataSource(T bean) {
- setItemDataSource(new BeanItem(bean));
+ setItemDataSource(new BeanItem(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/util/BeanItem.java b/server/src/com/vaadin/data/util/BeanItem.java
index 12d9b23d0a..64f30261c2 100644
--- a/server/src/com/vaadin/data/util/BeanItem.java
+++ b/server/src/com/vaadin/data/util/BeanItem.java
@@ -62,7 +62,30 @@ public class BeanItem extends PropertysetItem {
*
*/
public BeanItem(BT bean) {
- this(bean, getPropertyDescriptors((Class) bean.getClass()));
+ this(bean, (Class) bean.getClass());
+ }
+
+ /**
+ *
+ * Creates a new instance of BeanItem and adds all properties
+ * of a Java Bean to it. The properties are identified by their respective
+ * bean names.
+ *
+ *
+ *
+ * Note : This version only supports introspectable bean properties and
+ * their getter and setter methods. Stand-alone is and
+ * are methods are not supported.
+ *
+ *
+ * @param bean
+ * the Java Bean to copy properties from.
+ * @param beanClass
+ * class of the {@code bean}
+ *
+ */
+ public BeanItem(BT bean, Class beanClass) {
+ this(bean, getPropertyDescriptors(beanClass));
}
/**
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 extends AbstractProperty {
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 extends AbstractProperty {
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 extends AbstractProperty {
@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/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java
index 112d36d884..965fb49479 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
@@ -2,12 +2,16 @@ package com.vaadin.tests.server.component.fieldgroup;
import static org.junit.Assert.assertEquals;
+import java.util.Collection;
+
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 +137,31 @@ public class BeanFieldGroupTest {
assertEquals(bean.nestedBean.hello, helloField.getValue().toString());
}
+ @Test
+ public void setDataSource_nullBean_nullBeanIsSetInDataSource() {
+ BeanFieldGroup group = new BeanFieldGroup(MyBean.class);
+
+ group.setItemDataSource((MyBean) null);
+
+ BeanItem dataSource = group.getItemDataSource();
+ Assert.assertNotNull("Data source is null for null bean", dataSource);
+
+ Collection> itemPropertyIds = dataSource.getItemPropertyIds();
+ Assert.assertEquals("Unexpected number of properties", 3,
+ itemPropertyIds.size());
+ for (Object id : itemPropertyIds) {
+ Assert.assertNull("Value for property " + id + " is not null",
+ dataSource.getItemProperty(id).getValue());
+ }
+ }
+
+ @Test
+ public void setDataSource_nullItem_nullDataSourceIsSet() {
+ BeanFieldGroup group = new BeanFieldGroup(MyBean.class);
+
+ group.setItemDataSource((Item) null);
+ BeanItem dataSource = group.getItemDataSource();
+ Assert.assertNull("Group returns not null data source", dataSource);
+ }
+
}
--
cgit v1.2.3
From 3c59a1f08d6e2288c4bcd0ac74273ae14c4d4e0b Mon Sep 17 00:00:00 2001
From: Leif Åstrand
Date: Fri, 14 Nov 2014 15:27:49 +0200
Subject: Escape dynamic and configured theme names in the same way. (#15309)
Change-Id: Ib7fd42e6017d0b78e6d5e6bd7f531f0cd6c8c0ab
---
server/src/com/vaadin/server/VaadinServlet.java | 6 +--
server/src/com/vaadin/ui/UI.java | 8 +++-
.../tests/src/com/vaadin/ui/UIThemeEscaping.java | 43 ++++++++++++++++++++++
3 files changed, 52 insertions(+), 5 deletions(-)
create mode 100644 server/tests/src/com/vaadin/ui/UIThemeEscaping.java
(limited to 'server/src')
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index 4fd1e97a40..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++) {
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 78cb5488e8..44948dfb6f 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -633,7 +633,11 @@ public abstract class UI extends AbstractSingleComponentContainer implements
this.embedId = embedId;
// Actual theme - used for finding CustomLayout templates
- getState().theme = request.getParameter("theme");
+ String unescapedThemeName = request.getParameter("theme");
+ if (unescapedThemeName != null) {
+ // Set theme escapes the name
+ setTheme(unescapedThemeName);
+ }
getPage().init(request);
@@ -1164,7 +1168,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
* The new theme name
*/
public void setTheme(String theme) {
- getState().theme = theme;
+ getState().theme = VaadinServlet.stripSpecialChars(theme);
}
/**
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..ca6782952d
--- /dev/null
+++ b/server/tests/src/com/vaadin/ui/UIThemeEscaping.java
@@ -0,0 +1,43 @@
+/*
+ * 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.server.VaadinRequest;
+
+public class UIThemeEscaping {
+
+ @Test
+ public void testThemeEscaping() {
+ UI ui = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ // Nothing to do
+ }
+ };
+
+ ui.setTheme("a<å(_\"$");
+
+ String theme = ui.getTheme();
+
+ Assert.assertEquals(
+ "Dangerous characters should be removed from the theme name",
+ "aå_$", theme);
+ }
+
+}
--
cgit v1.2.3
From 758300e27e0110f58794e42bafac6e806ffdfb24 Mon Sep 17 00:00:00 2001
From: Sauli Tähkäpää
Date: Thu, 4 Dec 2014 14:36:11 +0200
Subject: Add null check to UI.setTheme. (#15326)
Change-Id: I2ab2d24ec05bb618969f59ea15d3a971f88009ca
---
server/src/com/vaadin/ui/UI.java | 12 ++--
.../tests/src/com/vaadin/ui/UIThemeEscaping.java | 64 +++++++++++++++++++---
2 files changed, 61 insertions(+), 15 deletions(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 44948dfb6f..4bd4b67259 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -633,11 +633,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
this.embedId = embedId;
// Actual theme - used for finding CustomLayout templates
- String unescapedThemeName = request.getParameter("theme");
- if (unescapedThemeName != null) {
- // Set theme escapes the name
- setTheme(unescapedThemeName);
- }
+ setTheme(request.getParameter("theme"));
getPage().init(request);
@@ -1168,7 +1164,11 @@ public abstract class UI extends AbstractSingleComponentContainer implements
* The new theme name
*/
public void setTheme(String theme) {
- getState().theme = VaadinServlet.stripSpecialChars(theme);
+ if(theme == null) {
+ getState().theme = null;
+ } else {
+ getState().theme = VaadinServlet.stripSpecialChars(theme);
+ }
}
/**
diff --git a/server/tests/src/com/vaadin/ui/UIThemeEscaping.java b/server/tests/src/com/vaadin/ui/UIThemeEscaping.java
index ca6782952d..236f283823 100644
--- a/server/tests/src/com/vaadin/ui/UIThemeEscaping.java
+++ b/server/tests/src/com/vaadin/ui/UIThemeEscaping.java
@@ -15,29 +15,75 @@
*/
package com.vaadin.ui;
-import org.junit.Assert;
+import com.vaadin.server.VaadinRequest;
+import org.junit.Before;
import org.junit.Test;
-import com.vaadin.server.VaadinRequest;
+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 {
- @Test
- public void testThemeEscaping() {
- UI ui = new UI() {
+ 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<å(_\"$");
- String theme = ui.getTheme();
+ assertThat(ui.getTheme(), is("aå_$"));
+ }
+
+ @Test
+ public void nullThemeIsSet() {
+ ui.setTheme("foobar");
+
+ ui.setTheme(null);
- Assert.assertEquals(
- "Dangerous characters should be removed from the theme name",
- "aå_$", theme);
+ 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()));
+ }
}
--
cgit v1.2.3
From 66c3dd2bf87ac3b021365b7a7d89180fb4304d8c Mon Sep 17 00:00:00 2001
From: Ilya Ermakov
Date: Fri, 28 Nov 2014 13:09:38 +0300
Subject: SQLContainer removeItem Error when isModified (#8802)
This patch makes commit() work properly if an item was modified and later deleted.
Change-Id: I5a00024112e7b6bb7ab3750c292a872937f03af9
---
.../data/util/sqlcontainer/SQLContainer.java | 26 ++++++++++++----------
.../sqlcontainer/SQLContainerTableQueryTest.java | 14 ++++++++++++
2 files changed, 28 insertions(+), 12 deletions(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
index 683140d279..70b392ab80 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
@@ -1020,18 +1020,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/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
index d907f12321..93a27352a5 100644
--- a/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
@@ -1136,6 +1136,20 @@ public class SQLContainerTableQueryTest {
.getValue());
}
+ @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");
+ Assert.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",
--
cgit v1.2.3
From bf4e325ac6387cac0afc8096b3ca65b88bf9fdfd Mon Sep 17 00:00:00 2001
From: Fabian Lange
Date: Mon, 24 Nov 2014 12:11:08 +0100
Subject: UIInitHandler emits Content-Length when writing json response
(#15271)
This prevents chunked-transfer mode and allows server infrastructure to
decide correctly on things like compression which benefits from knowing
a content length.
Change-Id: I4e969e0874b506d0f61526662ee78418987937c4
---
.../vaadin/server/communication/UIInitHandler.java | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java
index 8e61370d85..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;
@@ -110,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;
}
--
cgit v1.2.3
From a28d6c2098e738dfd78e1df929ce689a2ceb6c2a Mon Sep 17 00:00:00 2001
From: Anna Miroshnik
Date: Thu, 4 Dec 2014 15:52:27 +0300
Subject: Add new StringTo Converters (#14583)
DefaultConverterFactory was updated, added missed types.
Change-Id: I65cffc7f91df6f40e132b45e325e15f029f9848c
---
.../converter/AbstractStringToNumberConverter.java | 1 +
.../util/converter/DefaultConverterFactory.java | 7 ++++++
.../converter/StringToBigIntegerConverter.java | 11 ++++++---
.../data/util/converter/StringToByteConverter.java | 2 +-
.../util/converter/StringToShortConverter.java | 2 +-
.../converter/TestStringToBigIntegerConverter.java | 28 ++++++++++++----------
.../data/converter/TestStringToByteConverter.java | 16 ++++++++-----
.../data/converter/TestStringToShortConverter.java | 15 ++++++++----
8 files changed, 54 insertions(+), 28 deletions(-)
(limited to 'server/src')
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 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;
*
*
* @author Vaadin Ltd
- * @since 7.3.1
+ * @since
*/
public class StringToBigIntegerConverter extends
AbstractStringToNumberConverter {
@@ -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;
*
*
* @author Vaadin Ltd
- * @since 7.3.1
+ * @since
*/
public class StringToByteConverter extends
AbstractStringToNumberConverter {
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;
*
*
* @author Vaadin Ltd
- * @since 7.3.1
+ * @since
*/
public class StringToShortConverter extends
AbstractStringToNumberConverter {
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/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() {
--
cgit v1.2.3
From 7e8b23a73a5dd1bef54b8fc5ddc4d3c431c298af Mon Sep 17 00:00:00 2001
From: Anna Miroshnik
Date: Mon, 8 Dec 2014 17:25:00 +0300
Subject: Hierarchy change markAsDirty to AbstractComponentContainer (#14227)
Change-Id: I7a05ad72dfa3d16d85aa4d0cdd235572ec01e31a
---
server/src/com/vaadin/ui/AbsoluteLayout.java | 2 -
.../com/vaadin/ui/AbstractComponentContainer.java | 2 +
server/src/com/vaadin/ui/AbstractSplitPanel.java | 2 -
server/src/com/vaadin/ui/CssLayout.java | 4 --
server/src/com/vaadin/ui/CustomLayout.java | 4 +-
server/src/com/vaadin/ui/GridLayout.java | 3 --
server/src/com/vaadin/ui/TabSheet.java | 11 +++--
.../ComponentAttachDetachListenerTest.java | 50 ++++++++++++++++++++++
.../tests/minitutorials/v7a2/WidgetContainer.java | 2 -
9 files changed, 59 insertions(+), 21 deletions(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/ui/AbsoluteLayout.java b/server/src/com/vaadin/ui/AbsoluteLayout.java
index afc73f5ecc..af47981db6 100644
--- a/server/src/com/vaadin/ui/AbsoluteLayout.java
+++ b/server/src/com/vaadin/ui/AbsoluteLayout.java
@@ -153,7 +153,6 @@ public class AbsoluteLayout extends AbstractLayout implements
internalRemoveComponent(c);
throw e;
}
- markAsDirty();
}
/**
@@ -197,7 +196,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/AbstractSplitPanel.java b/server/src/com/vaadin/ui/AbstractSplitPanel.java
index e9b37f8cff..a78f192fa2 100644
--- a/server/src/com/vaadin/ui/AbstractSplitPanel.java
+++ b/server/src/com/vaadin/ui/AbstractSplitPanel.java
@@ -214,7 +214,6 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer {
} else if (c == getSecondComponent()) {
getState().secondChild = null;
}
- markAsDirty();
}
/*
@@ -256,7 +255,6 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer {
} else if (oldComponent == getSecondComponent()) {
setSecondComponent(newComponent);
}
- markAsDirty();
}
/**
diff --git a/server/src/com/vaadin/ui/CssLayout.java b/server/src/com/vaadin/ui/CssLayout.java
index e7b63cc87a..350423576f 100644
--- a/server/src/com/vaadin/ui/CssLayout.java
+++ b/server/src/com/vaadin/ui/CssLayout.java
@@ -118,7 +118,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
components.add(c);
try {
super.addComponent(c);
- markAsDirty();
} catch (IllegalArgumentException e) {
components.remove(c);
throw e;
@@ -141,7 +140,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
components.addFirst(c);
try {
super.addComponent(c);
- markAsDirty();
} catch (IllegalArgumentException e) {
components.remove(c);
throw e;
@@ -170,7 +168,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;
@@ -187,7 +184,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/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/TabSheet.java b/server/src/com/vaadin/ui/TabSheet.java
index d3410464a2..88002104b1 100644
--- a/server/src/com/vaadin/ui/TabSheet.java
+++ b/server/src/com/vaadin/ui/TabSheet.java
@@ -195,7 +195,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);
@@ -232,7 +231,6 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
fireSelectedTabChange();
}
}
- markAsDirty();
}
}
@@ -394,8 +392,9 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
setSelected(tabComponent);
fireSelectedTabChange();
}
+
super.addComponent(tabComponent);
- markAsDirty();
+
return tab;
}
}
@@ -967,16 +966,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/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("");
+ 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/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java b/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java
index 8c14ba8bd7..850fa1044f 100644
--- a/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java
+++ b/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java
@@ -15,14 +15,12 @@ public class WidgetContainer extends AbstractComponentContainer {
public void addComponent(Component c) {
children.add(c);
super.addComponent(c);
- markAsDirty();
}
@Override
public void removeComponent(Component c) {
children.remove(c);
super.removeComponent(c);
- markAsDirty();
}
@Override
--
cgit v1.2.3
From 206055708b0a8e1c17a8c63d482a5e202d3ebf6d Mon Sep 17 00:00:00 2001
From: Teemu Pöntelin
Date: Mon, 8 Dec 2014 23:21:08 +0200
Subject: Fix issues when using java.sql.Date as DateField range (#15342)
Change-Id: I656cc0600f929239605e17ab9cf71dc1ba96582f
---
server/src/com/vaadin/ui/DateField.java | 14 +++---
.../components/datefield/DateRangeWithSqlDate.java | 54 ++++++++++++++++++++++
.../datefield/DateRangeWithSqlDateTest.java | 51 ++++++++++++++++++++
3 files changed, 113 insertions(+), 6 deletions(-)
create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java
create mode 100644 uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java
(limited to 'server/src')
diff --git a/server/src/com/vaadin/ui/DateField.java b/server/src/com/vaadin/ui/DateField.java
index 030bd5f6c2..d5700c4b65 100644
--- a/server/src/com/vaadin/ui/DateField.java
+++ b/server/src/com/vaadin/ui/DateField.java
@@ -316,10 +316,10 @@ public class DateField extends AbstractField 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 = new Date(startDate.getTime());
updateRangeValidator();
}
@@ -436,8 +436,10 @@ public class DateField extends AbstractField 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 = new Date(endDate.getTime());
updateRangeValidator();
}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java
new file mode 100644
index 0000000000..74d3e85892
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java
@@ -0,0 +1,54 @@
+/*
+ * 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.components.datefield;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.InlineDateField;
+
+public class DateRangeWithSqlDate extends AbstractTestUI {
+
+ // 2014-12-01
+ private static final java.sql.Date startDate = new java.sql.Date(
+ 1417467822699L);
+
+ // 2014-12-02
+ private static final java.sql.Date endDate = new java.sql.Date(
+ 1417554763317L);
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ DateField df = new InlineDateField();
+ df.setRangeStart(startDate);
+ df.setRangeEnd(endDate);
+
+ df.setValue(startDate);
+
+ addComponent(df);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Test that java.sql.Date can be given to specify date range start and end dates.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 15342;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java
new file mode 100644
index 0000000000..2352011585
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.components.datefield;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class DateRangeWithSqlDateTest extends MultiBrowserTest {
+
+ @Test
+ public void testDateRange() {
+ openTestURL();
+
+ // Get all cells of the inline datefield.
+ List cells = driver.findElements(By
+ .className("v-inline-datefield-calendarpanel-day"));
+
+ // Verify the range is rendered correctly.
+ assertCell(cells.get(0), "30", true);
+ assertCell(cells.get(1), "1", false);
+ assertCell(cells.get(2), "2", false);
+ assertCell(cells.get(3), "3", true);
+ }
+
+ private void assertCell(WebElement cell, String text, boolean outsideRange) {
+ assertEquals(text, cell.getText());
+ assertEquals(outsideRange,
+ cell.getAttribute("class").contains("outside-range"));
+ }
+
+}
--
cgit v1.2.3
From 153129d52d0167a4d54d7c133155eeec7d407a19 Mon Sep 17 00:00:00 2001
From: Alexey Fansky
Date: Wed, 3 Dec 2014 17:07:43 -0800
Subject: Returning all validation errors in the exception cause when
submitting a field group (#14742)
Following the similar logic as in AbstractField when multiple validation errors occur. Catching all InvalidValueExceptions and putting them together wrapped into the exception.
Change-Id: Ied08fd2155412539b28ef94bc74e6c989c62f709
---
.../src/com/vaadin/data/fieldgroup/FieldGroup.java | 86 ++++++++++++++++------
uitest/ivy.xml | 2 +
.../tests/fieldgroup/MultipleValidationErrors.java | 72 ++++++++++++++++++
.../fieldgroup/MultipleValidationErrorsTest.java | 37 ++++++++++
.../PersonBeanWithValidationAnnotations.java | 31 ++++++++
5 files changed, 205 insertions(+), 23 deletions(-)
create mode 100644 uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java
create mode 100644 uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java
create mode 100644 uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java
(limited to 'server/src')
diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
index 5a4e877554..bcfa8395df 100644
--- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
@@ -26,6 +26,7 @@ import java.util.List;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
+import com.vaadin.data.Validator;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.util.TransactionalPropertyWrapper;
import com.vaadin.ui.AbstractField;
@@ -452,6 +453,54 @@ public class FieldGroup implements Serializable {
// Not using buffered mode, nothing to do
return;
}
+
+ startTransactions();
+
+ try {
+ firePreCommitEvent();
+
+ List invalidValueExceptions = commitFields();
+
+ if(invalidValueExceptions.isEmpty()) {
+ firePostCommitEvent();
+ commitTransactions();
+ } else {
+ throwInvalidValueException(invalidValueExceptions);
+ }
+ } catch (Exception e) {
+ rollbackTransactions();
+
+ throw new CommitException("Commit failed", e);
+ }
+
+ }
+
+ private List commitFields() {
+ List invalidValueExceptions = new ArrayList();
+
+ for (Field> f : fieldToPropertyId.keySet()) {
+ try {
+ f.commit();
+ } catch (InvalidValueException e) {
+ invalidValueExceptions.add(e);
+ }
+ }
+
+ return invalidValueExceptions;
+ }
+
+ private void throwInvalidValueException(List 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 +511,24 @@ 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/uitest/ivy.xml b/uitest/ivy.xml
index 14c8bc6ce3..78171f9a9c 100644
--- a/uitest/ivy.xml
+++ b/uitest/ivy.xml
@@ -27,6 +27,8 @@
+
diff --git a/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java
new file mode 100644
index 0000000000..5110bf6dcf
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java
@@ -0,0 +1,72 @@
+package com.vaadin.tests.fieldgroup;
+
+import com.vaadin.data.Validator;
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.data.validator.BeanValidator;
+import com.vaadin.server.AbstractErrorMessage;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+import org.apache.commons.lang.StringEscapeUtils;
+
+public class MultipleValidationErrors extends AbstractTestUI {
+
+ public static final String FIRST_NAME_NOT_NULL_VALIDATION_MESSAGE = "first name is null";
+ public static final String LAST_NAME_NOT_NULL_VALIDATION_MESSAGE = "last name is null";
+ public static final String FIRST_NAME_NOT_EMPTY_VALIDATION_MESSAGE = "first name is empty";
+ public static final String LAST_NAME_NOT_EMPTY_VALIDATION_MESSAGE = "last name is empty";
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ BeanItem item = new BeanItem(
+ new PersonBeanWithValidationAnnotations());
+ final FieldGroup fieldGroup = new FieldGroup(item);
+
+ bindTextField(item, fieldGroup, "First Name", "firstName");
+ bindTextField(item, fieldGroup, "Last Name", "lastName");
+
+ final Label validationErrors = new Label();
+ validationErrors.setId("validationErrors");
+ addComponent(validationErrors);
+
+ addButton("Submit", new Button.ClickListener() {
+ @Override
+ public void buttonClick(Button.ClickEvent event) {
+ validationErrors.setValue("");
+ try {
+ fieldGroup.commit();
+ } catch (FieldGroup.CommitException e) {
+ if (e.getCause() != null && e.getCause() instanceof Validator.InvalidValueException) {
+ validationErrors.setValue(StringEscapeUtils.unescapeHtml(
+ AbstractErrorMessage.getErrorMessageForException(e.getCause()).getFormattedHtmlMessage()));
+ }
+ }
+
+
+ }
+ });
+ }
+
+ private void bindTextField(BeanItem item, FieldGroup fieldGroup,
+ String caption, String propertyId) {
+ TextField textfield = new TextField(caption, item.getItemProperty(propertyId));
+ textfield.addValidator(new BeanValidator(PersonBeanWithValidationAnnotations.class, propertyId));
+
+ fieldGroup.bind(textfield, propertyId);
+
+ addComponent(textfield);
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14742;
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "All validation errors should be included when committing a field group.";
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java
new file mode 100644
index 0000000000..175b650be6
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java
@@ -0,0 +1,37 @@
+package com.vaadin.tests.fieldgroup;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class MultipleValidationErrorsTest extends MultiBrowserTest {
+
+ private void commitTextFields() {
+ $(ButtonElement.class).caption("Submit").first().click();
+ }
+
+ private void clearTextField(String caption) {
+ TextFieldElement textField = $(TextFieldElement.class).caption(caption).first();
+ textField.clear();
+ }
+
+ @Test
+ public void validationErrorsIncludeBothErrors() {
+ openTestURL();
+
+ clearTextField("First Name");
+ clearTextField("Last Name");
+
+ commitTextFields();
+
+ String validationErrors = $(LabelElement.class).id("validationErrors").getText();
+
+ assertThat(validationErrors, containsString(MultipleValidationErrors.FIRST_NAME_NOT_EMPTY_VALIDATION_MESSAGE));
+ assertThat(validationErrors, containsString(MultipleValidationErrors.LAST_NAME_NOT_EMPTY_VALIDATION_MESSAGE));
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java b/uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java
new file mode 100644
index 0000000000..5f81ee248b
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java
@@ -0,0 +1,31 @@
+package com.vaadin.tests.fieldgroup;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+public class PersonBeanWithValidationAnnotations implements Serializable {
+ @NotNull(message = MultipleValidationErrors.FIRST_NAME_NOT_NULL_VALIDATION_MESSAGE)
+ @Size(min = 1, message = MultipleValidationErrors.FIRST_NAME_NOT_EMPTY_VALIDATION_MESSAGE)
+ private String firstName;
+
+ @NotNull(message = MultipleValidationErrors.LAST_NAME_NOT_NULL_VALIDATION_MESSAGE)
+ @Size(min = 1, message = MultipleValidationErrors.LAST_NAME_NOT_EMPTY_VALIDATION_MESSAGE)
+ private String lastName;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
\ No newline at end of file
--
cgit v1.2.3
From 52fb8cd941caad7d9c6277d7b154498abb6b99e6 Mon Sep 17 00:00:00 2001
From: Artur Signell
Date: Tue, 9 Dec 2014 21:18:50 +0200
Subject: Make addNestedContainerBean work with existing bean item container
items (#15355)
Change-Id: I04a91349fce452aa26c304413061440ad74465cc
---
.../vaadin/data/util/AbstractBeanContainer.java | 2 +-
.../vaadin/data/util/BeanItemContainerTest.java | 42 ++++++++++++++++++++++
2 files changed, 43 insertions(+), 1 deletion(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/data/util/AbstractBeanContainer.java b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
index 7d7d71c423..fad0934e53 100644
--- a/server/src/com/vaadin/data/util/AbstractBeanContainer.java
+++ b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
@@ -880,7 +880,7 @@ public abstract class AbstractBeanContainer extends
model.put(qualifiedPropertyId, pd);
model.remove(propertyId);
for (BeanItem item : itemIdToItem.values()) {
- item.addItemProperty(propertyId,
+ item.addItemProperty(qualifiedPropertyId,
pd.createProperty(item.getBean()));
item.removeItemProperty(propertyId);
}
diff --git a/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
index 01c282e294..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.
@@ -740,4 +741,45 @@ public class BeanItemContainerTest extends AbstractBeanContainerTest {
assertNull(container.getContainerProperty(john, "address.street")
.getValue());
}
+
+ public void testAddNestedContainerBeanBeforeData() {
+ BeanItemContainer container = new BeanItemContainer(
+ 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 container = new BeanItemContainer(
+ 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());
+
+ }
}
--
cgit v1.2.3
From f1f089772749a0eb4b031f1876b95bb684565473 Mon Sep 17 00:00:00 2001
From: Artur Signell
Date: Tue, 2 Dec 2014 21:19:06 +0200
Subject: Make TextField.clear() use empty string to be consistent with
constructor (#14755)
Change-Id: Ic50ff305277e54f50353fc948b31a89a6b3e083f
---
server/src/com/vaadin/ui/TextField.java | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
(limited to 'server/src')
diff --git a/server/src/com/vaadin/ui/TextField.java b/server/src/com/vaadin/ui/TextField.java
index fb1e4284a2..1fc10c6ced 100644
--- a/server/src/com/vaadin/ui/TextField.java
+++ b/server/src/com/vaadin/ui/TextField.java
@@ -43,7 +43,7 @@ public class TextField extends AbstractTextField {
* Constructs an empty TextField with no caption.
*/
public TextField() {
- setValue("");
+ clear();
}
/**
@@ -99,4 +99,14 @@ public class TextField extends AbstractTextField {
setCaption(caption);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractField#clear()
+ */
+ @Override
+ public void clear() {
+ setValue("");
+ }
+
}
--
cgit v1.2.3
From e1b335022ec359061e696cf2711327663267e704 Mon Sep 17 00:00:00 2001
From: Sergey Budkin
Date: Tue, 25 Nov 2014 19:35:13 +0200
Subject: Long events aren't displayed properly when using Container (#15242)
Rewrote event selection.
Change-Id: I8f0dd1c5ec736ea14037619b1656a79b7e3532be
---
.../calendar/ContainerEventProvider.java | 74 ++++++----------------
.../calendar/BeanItemContainerLongEventTest.java | 55 ++++++++++++++++
.../calendar/BeanItemContainerTestUI.java | 8 +++
3 files changed, 81 insertions(+), 56 deletions(-)
create mode 100644 uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java
(limited to 'server/src')
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 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/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java
new file mode 100644
index 0000000000..0ec196f266
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.components.calendar;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Tests if long event which began before the view period is shown (#15242)
+ */
+public class BeanItemContainerLongEventTest extends MultiBrowserTest {
+
+ @Override
+ protected String getDeploymentPath() {
+ return "/run/BeanItemContainerTestUI?restartApplication";
+ }
+
+ @Test
+ public void testEventDisplayedInWeekView() {
+ openTestURL();
+ WebElement target = driver.findElements(
+ By.className("v-calendar-week-number")).get(1);
+ target.click();
+ target = driver.findElement(By.className("v-calendar-event"));
+ Assert.assertEquals("Wrong event name", "Long event", target.getText());
+ }
+
+ @Test
+ public void testEventDisplayedInDayView() {
+ openTestURL();
+ WebElement target = driver.findElements(
+ By.className("v-calendar-day-number")).get(5);
+ target.click();
+ target = driver.findElement(By.className("v-calendar-event"));
+ Assert.assertEquals("Wrong event name", "Long event", target.getText());
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java
index 83fc4a03cb..bda3b34875 100644
--- a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java
+++ b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java
@@ -17,6 +17,7 @@ package com.vaadin.tests.components.calendar;
import java.util.Arrays;
import java.util.Date;
+import java.util.GregorianCalendar;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
@@ -69,6 +70,13 @@ public class BeanItemContainerTestUI extends UI {
table.setVisibleColumns(new Object[] { "caption", "description",
"start", "end" });
content.addComponent(table);
+
+ BasicEvent longEvent = new BasicEvent();
+ longEvent.setCaption("Long event");
+ longEvent.setAllDay(true);
+ longEvent.setStart(new GregorianCalendar(2000, 1, 3).getTime());
+ longEvent.setEnd(new GregorianCalendar(2000, 2, 5).getTime());
+ events.addBean(longEvent);
}
/**
--
cgit v1.2.3
From 22b20bc9fc4067a026cf08b5130bd20afa89d27e Mon Sep 17 00:00:00 2001
From: Artur Signell
Date: Tue, 9 Dec 2014 16:58:01 +0200
Subject: Add public Field.isEmpty() and clear() (#15354)
Change-Id: I6bda7ff2a66a9ad172c899d855ca868881600be4
---
server/src/com/vaadin/ui/AbstractField.java | 19 +-----
server/src/com/vaadin/ui/AbstractSelect.java | 2 +-
server/src/com/vaadin/ui/AbstractTextField.java | 2 +-
server/src/com/vaadin/ui/Field.java | 22 +++++++
server/src/com/vaadin/ui/Form.java | 9 ++-
server/src/com/vaadin/ui/RichTextArea.java | 2 +-
.../src/com/vaadin/ui/AbstractSelectTest.java | 71 ++++++++++++++++++++++
.../tests/src/com/vaadin/ui/RichTextAreaTest.java | 47 ++++++++++++++
server/tests/src/com/vaadin/ui/TextAreaTest.java | 47 ++++++++++++++
9 files changed, 200 insertions(+), 21 deletions(-)
create mode 100644 server/tests/src/com/vaadin/ui/RichTextAreaTest.java
create mode 100644 server/tests/src/com/vaadin/ui/TextAreaTest.java
(limited to 'server/src')
diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java
index 369ad1253c..df7bbb68a2 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/com/vaadin/ui/AbstractField.java
@@ -1502,25 +1502,12 @@ public abstract class AbstractField 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.
- *
- * 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..70f08c95d8 100644
--- a/server/src/com/vaadin/ui/AbstractSelect.java
+++ b/server/src/com/vaadin/ui/AbstractSelect.java
@@ -1782,7 +1782,7 @@ public abstract class AbstractSelect extends AbstractField