summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java18
-rw-r--r--server/src/com/vaadin/navigator/Navigator.java8
-rw-r--r--server/src/com/vaadin/server/ComponentSizeValidator.java41
-rw-r--r--server/src/com/vaadin/server/ConnectorResourceHandler.java36
-rw-r--r--server/src/com/vaadin/server/Constants.java2
-rw-r--r--server/src/com/vaadin/server/DownloadStream.java38
-rw-r--r--server/src/com/vaadin/server/FileDownloader.java14
-rw-r--r--server/src/com/vaadin/server/GAEVaadinServlet.java2
-rw-r--r--server/src/com/vaadin/server/ServerRpcManager.java12
-rw-r--r--server/src/com/vaadin/ui/AbstractComponent.java28
-rw-r--r--server/src/com/vaadin/ui/AbstractLayout.java91
-rw-r--r--server/src/com/vaadin/ui/AbstractOrderedLayout.java51
-rw-r--r--server/src/com/vaadin/ui/AbstractTextField.java33
-rw-r--r--server/src/com/vaadin/ui/ComboBox.java7
-rw-r--r--server/src/com/vaadin/ui/Grid.java86
-rw-r--r--server/src/com/vaadin/ui/GridLayout.java22
-rw-r--r--server/src/com/vaadin/ui/Table.java20
-rw-r--r--server/src/com/vaadin/ui/UI.java3
-rw-r--r--server/src/com/vaadin/ui/Window.java15
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java98
-rw-r--r--server/tests/src/com/vaadin/server/DownloadStreamTest.java39
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java104
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java72
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java48
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java16
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/grid/GridContainerTest.java54
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/grid/GridEditorTest.java8
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java10
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java7
-rw-r--r--server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java17
-rw-r--r--server/tests/src/com/vaadin/tests/util/MockUI.java46
-rw-r--r--server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java113
-rw-r--r--server/tests/src/com/vaadin/ui/LabelDataSourceTest.java14
33 files changed, 862 insertions, 311 deletions
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java b/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
index 79a5b6c067..6b800cb965 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
@@ -155,8 +155,13 @@ public class FreeformQuery extends AbstractTransactionalQuery implements
pstmt = c.prepareStatement(sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
rs = pstmt.executeQuery();
- rs.next();
- count = rs.getInt(1);
+ if (rs.next()) {
+ count = rs.getInt(1);
+ } else {
+ // The result can be empty when using group by and there
+ // are no matches (#18043)
+ count = 0;
+ }
} finally {
releaseConnection(c, pstmt, rs);
}
@@ -175,8 +180,13 @@ public class FreeformQuery extends AbstractTransactionalQuery implements
try {
statement = conn.createStatement();
rs = statement.executeQuery(countQuery);
- rs.next();
- count = rs.getInt(1);
+ if (rs.next()) {
+ count = rs.getInt(1);
+ } else {
+ // The result can be empty when using group by and there
+ // are no matches (#18043)
+ count = 0;
+ }
return count;
} finally {
releaseConnection(conn, statement, rs);
diff --git a/server/src/com/vaadin/navigator/Navigator.java b/server/src/com/vaadin/navigator/Navigator.java
index 65b3fec488..bd2b5711f8 100644
--- a/server/src/com/vaadin/navigator/Navigator.java
+++ b/server/src/com/vaadin/navigator/Navigator.java
@@ -745,9 +745,15 @@ public class Navigator implements Serializable {
* the requested view name is found.
*
* @param provider
- * provider to register
+ * provider to register, not <code>null</code>
+ * @throws IllegalArgumentException
+ * if the provided view provider is <code>null</code>
*/
public void addProvider(ViewProvider provider) {
+ if (provider == null) {
+ throw new IllegalArgumentException(
+ "Cannot add a null view provider");
+ }
providers.add(provider);
}
diff --git a/server/src/com/vaadin/server/ComponentSizeValidator.java b/server/src/com/vaadin/server/ComponentSizeValidator.java
index 2d88ae3b53..1fbd840932 100644
--- a/server/src/com/vaadin/server/ComponentSizeValidator.java
+++ b/server/src/com/vaadin/server/ComponentSizeValidator.java
@@ -415,7 +415,7 @@ public class ComponentSizeValidator implements Serializable {
// main window, valid situation
return true;
}
- if (parent.getHeight() < 0) {
+ if (isEffectiveUndefinedHeight(component)) {
// Undefined height
if (parent instanceof Window) {
// Sub window with undefined size has a min-height
@@ -513,10 +513,7 @@ public class ComponentSizeValidator implements Serializable {
// Sub window with undefined size has a min-width
return true;
}
-
- if (parent.getWidth() < 0) {
- // Undefined width
-
+ if (isEffectiveUndefinedWidth(parent)) {
if (parent instanceof AbstractOrderedLayout) {
AbstractOrderedLayout ol = (AbstractOrderedLayout) parent;
boolean horizontal = true;
@@ -591,6 +588,40 @@ public class ComponentSizeValidator implements Serializable {
}
+ /**
+ * Checks if this component will be rendered with undefined width, either
+ * because it has been set to undefined wide or because the parent forces it
+ * to be (100% inside undefined)
+ *
+ */
+ private static boolean isEffectiveUndefinedWidth(Component parent) {
+ if (parent == null) {
+ return false;
+ } else if (parent.getWidth() < 0) {
+ return true;
+ } else if (parent.getWidthUnits() == Unit.PERCENTAGE) {
+ return isEffectiveUndefinedWidth(parent.getParent());
+ }
+ return false;
+ }
+
+ /**
+ * Checks if this component will be rendered with undefined Height, either
+ * because it has been set to undefined wide or because the parent forces it
+ * to be (100% inside undefined)
+ *
+ */
+ private static boolean isEffectiveUndefinedHeight(Component parent) {
+ if (parent == null) {
+ return false;
+ } else if (parent.getHeight() < 0) {
+ return true;
+ } else if (parent.getHeightUnits() == Unit.PERCENTAGE) {
+ return isEffectiveUndefinedHeight(parent.getParent());
+ }
+ return false;
+ }
+
private static boolean hasNonRelativeWidthComponent(Form form) {
Layout layout = form.getLayout();
Layout footer = form.getFooter();
diff --git a/server/src/com/vaadin/server/ConnectorResourceHandler.java b/server/src/com/vaadin/server/ConnectorResourceHandler.java
index 6c486a2d65..8715134773 100644
--- a/server/src/com/vaadin/server/ConnectorResourceHandler.java
+++ b/server/src/com/vaadin/server/ConnectorResourceHandler.java
@@ -30,10 +30,11 @@ import com.vaadin.util.CurrentInstance;
public class ConnectorResourceHandler implements RequestHandler {
// APP/connector/[uiid]/[cid]/[filename.xyz]
+ private static final String CONNECTOR_RESOURCE_PREFIX = "/"
+ + ApplicationConstants.APP_PATH + "/"
+ + ConnectorResource.CONNECTOR_PATH + "/";
private static final Pattern CONNECTOR_RESOURCE_PATTERN = Pattern
- .compile("^/?" + ApplicationConstants.APP_PATH + '/'
- + ConnectorResource.CONNECTOR_PATH + '/'
- + "(\\d+)/(\\d+)/(.*)");
+ .compile("^" + CONNECTOR_RESOURCE_PREFIX + "(\\d+)/(\\d+)/(.*)");
private static Logger getLogger() {
return Logger.getLogger(ConnectorResourceHandler.class.getName());
@@ -44,12 +45,18 @@ public class ConnectorResourceHandler implements RequestHandler {
public boolean handleRequest(VaadinSession session, VaadinRequest request,
VaadinResponse response) throws IOException {
String requestPath = request.getPathInfo();
- if (requestPath == null) {
+ if (requestPath == null
+ || !requestPath.startsWith(CONNECTOR_RESOURCE_PREFIX)) {
return false;
}
Matcher matcher = CONNECTOR_RESOURCE_PATTERN.matcher(requestPath);
if (!matcher.matches()) {
- return false;
+ // This is a connector resource request based on the prefix but the
+ // pattern did not match
+ warnAboutInvalidURLEncoding(requestPath);
+ response.sendError(HttpServletResponse.SC_NOT_FOUND,
+ "Connector resource not found");
+ return true;
}
String uiId = matcher.group(1);
String cid = matcher.group(2);
@@ -102,6 +109,25 @@ public class ConnectorResourceHandler implements RequestHandler {
return true;
}
+ private boolean loggedDecodingWarning = false;
+
+ private void warnAboutInvalidURLEncoding(String requestPath) {
+ if (requestPath.contains("\n") || requestPath.indexOf(0x85) != -1) {
+ // What, path info should not contain a new line or UTF-8 Next Line
+ // (NEL) character, but it does in
+ // Tomcat 7 with default configuration in some cases (URL is encoded
+ // by the browser as UTF-8 and decoded as ISO-8859-1 by Tomcat)
+
+ if (!loggedDecodingWarning) {
+ loggedDecodingWarning = true;
+ getLogger()
+ .warning(
+ "Request path contains a new line character. This typically means that the server is incorrectly configured to use something else than UTF-8 for URL decoding (requestPath: "
+ + requestPath + ")");
+ }
+ }
+ }
+
private static boolean error(VaadinRequest request,
VaadinResponse response, String logMessage) throws IOException {
getLogger().log(Level.WARNING, logMessage);
diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java
index 122cce2e74..5a0d852299 100644
--- a/server/src/com/vaadin/server/Constants.java
+++ b/server/src/com/vaadin/server/Constants.java
@@ -67,7 +67,7 @@ public interface Constants {
// Keep the version number in sync with push/build.xml and other locations
// listed in that file
- static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.2.4.vaadin8";
+ static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.2.7.vaadin1";
static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n"
+ "=================================================================\n"
diff --git a/server/src/com/vaadin/server/DownloadStream.java b/server/src/com/vaadin/server/DownloadStream.java
index 681c438967..65ef560974 100644
--- a/server/src/com/vaadin/server/DownloadStream.java
+++ b/server/src/com/vaadin/server/DownloadStream.java
@@ -20,6 +20,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -40,6 +42,8 @@ import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class DownloadStream implements Serializable {
+ public static final String CONTENT_DISPOSITION = "Content-Disposition";
+
/**
* Maximum cache time.
*/
@@ -280,17 +284,14 @@ public class DownloadStream implements Serializable {
}
}
- // suggest local filename from DownloadStream if
- // Content-Disposition
- // not explicitly set
- String contentDispositionValue = getParameter("Content-Disposition");
- if (contentDispositionValue == null) {
- contentDispositionValue = "filename=\"" + getFileName()
- + "\"";
- response.setHeader("Content-Disposition",
- contentDispositionValue);
+ // Content-Disposition: attachment generally forces download
+ String contentDisposition = getParameter(CONTENT_DISPOSITION);
+ if (contentDisposition == null) {
+ contentDisposition = getContentDispositionFilename(getFileName());
}
+ response.setHeader(CONTENT_DISPOSITION, contentDisposition);
+
int bufferSize = getBufferSize();
if (bufferSize <= 0 || bufferSize > Constants.MAX_BUFFER_SIZE) {
bufferSize = Constants.DEFAULT_BUFFER_SIZE;
@@ -318,6 +319,25 @@ public class DownloadStream implements Serializable {
}
/**
+ * Returns the filename formatted for inclusion in a Content-Disposition
+ * header. Includes both a plain version of the name and a UTF-8 version
+ *
+ * @since 7.4.8
+ * @param filename
+ * The filename to include
+ * @return A value for inclusion in a Content-Disposition header
+ */
+ public static String getContentDispositionFilename(String filename) {
+ try {
+ String encodedFilename = URLEncoder.encode(filename, "UTF-8");
+ return String.format("filename=\"%s\"; filename*=utf-8''%s",
+ encodedFilename, encodedFilename);
+ } catch (UnsupportedEncodingException e) {
+ return null;
+ }
+ }
+
+ /**
* Helper method that tries to close an output stream and ignores any
* exceptions.
*
diff --git a/server/src/com/vaadin/server/FileDownloader.java b/server/src/com/vaadin/server/FileDownloader.java
index 42c2f76e1a..b0c3bb1120 100644
--- a/server/src/com/vaadin/server/FileDownloader.java
+++ b/server/src/com/vaadin/server/FileDownloader.java
@@ -141,12 +141,17 @@ public class FileDownloader extends AbstractExtension {
}
stream = ((ConnectorResource) resource).getStream();
- if (stream.getParameter("Content-Disposition") == null) {
- // Content-Disposition: attachment generally forces download
- stream.setParameter("Content-Disposition",
- "attachment; filename=\"" + stream.getFileName() + "\"");
+ String contentDisposition = stream
+ .getParameter(DownloadStream.CONTENT_DISPOSITION);
+ if (contentDisposition == null) {
+ contentDisposition = "attachment; "
+ + DownloadStream.getContentDispositionFilename(stream
+ .getFileName());
}
+ stream.setParameter(DownloadStream.CONTENT_DISPOSITION,
+ contentDisposition);
+
// Content-Type to block eager browser plug-ins from hijacking
// the file
if (isOverrideContentType()) {
@@ -158,4 +163,5 @@ public class FileDownloader extends AbstractExtension {
stream.writeResponse(request, response);
return true;
}
+
}
diff --git a/server/src/com/vaadin/server/GAEVaadinServlet.java b/server/src/com/vaadin/server/GAEVaadinServlet.java
index df7cd0a66e..6f5c15ebdd 100644
--- a/server/src/com/vaadin/server/GAEVaadinServlet.java
+++ b/server/src/com/vaadin/server/GAEVaadinServlet.java
@@ -57,7 +57,7 @@ import com.google.apphosting.api.DeadlineExceededException;
* &lt;servlet-name&gt;HelloWorld&lt;/servlet-name&gt;
* &lt;servlet-class&gt;com.vaadin.server.GAEApplicationServlet&lt;/servlet-class&gt;
* &lt;init-param&gt;
- * &lt;param-name&gt;application&lt;/param-name&gt;
+ * &lt;param-name&gt;UI&lt;/param-name&gt;
* &lt;param-value&gt;com.vaadin.demo.HelloWorld&lt;/param-value&gt;
* &lt;/init-param&gt;
* &lt;/servlet&gt;
diff --git a/server/src/com/vaadin/server/ServerRpcManager.java b/server/src/com/vaadin/server/ServerRpcManager.java
index 3a2cb3a32c..ae99622a4a 100644
--- a/server/src/com/vaadin/server/ServerRpcManager.java
+++ b/server/src/com/vaadin/server/ServerRpcManager.java
@@ -153,19 +153,9 @@ public class ServerRpcManager<T extends ServerRpc> implements Serializable {
public void applyInvocation(ServerRpcMethodInvocation invocation)
throws RpcInvocationException {
Method method = invocation.getMethod();
- Class<?>[] parameterTypes = method.getParameterTypes();
- Object[] args = new Object[parameterTypes.length];
Object[] arguments = invocation.getParameters();
- for (int i = 0; i < args.length; i++) {
- // no conversion needed for basic cases
- // Class<?> type = parameterTypes[i];
- // if (type.isPrimitive()) {
- // type = boxedTypes.get(type);
- // }
- args[i] = arguments[i];
- }
try {
- method.invoke(implementation, args);
+ method.invoke(implementation, arguments);
} catch (Exception e) {
throw new RpcInvocationException("Unable to invoke method "
+ invocation.getMethodName() + " in "
diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java
index 27d97d5e03..18c3509af7 100644
--- a/server/src/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/com/vaadin/ui/AbstractComponent.java
@@ -243,6 +243,34 @@ public abstract class AbstractComponent extends AbstractClientConnector
}
}
+ /**
+ * Adds or removes a style name. Multiple styles can be specified as a
+ * space-separated list of style names.
+ *
+ * If the {@code add} parameter is true, the style name is added to the
+ * component. If the {@code add} parameter is false, the style name is
+ * removed from the component.
+ * <p>
+ * Functionally this is equivalent to using {@link #addStyleName(String)} or
+ * {@link #removeStyleName(String)}
+ *
+ * @since 7.5
+ * @param style
+ * the style name to be added or removed
+ * @param add
+ * <code>true</code> to add the given style, <code>false</code>
+ * to remove it
+ * @see #addStyleName(String)
+ * @see #removeStyleName(String)
+ */
+ public void setStyleName(String style, boolean add) {
+ if (add) {
+ addStyleName(style);
+ } else {
+ removeStyleName(style);
+ }
+ }
+
/*
* Get's the component's caption. Don't add a JavaDoc comment here, we use
* the default documentation from implemented interface.
diff --git a/server/src/com/vaadin/ui/AbstractLayout.java b/server/src/com/vaadin/ui/AbstractLayout.java
index 9cdb0a326a..0770670680 100644
--- a/server/src/com/vaadin/ui/AbstractLayout.java
+++ b/server/src/com/vaadin/ui/AbstractLayout.java
@@ -16,7 +16,12 @@
package com.vaadin.ui;
+import org.jsoup.nodes.Element;
+
import com.vaadin.shared.ui.AbstractLayoutState;
+import com.vaadin.shared.ui.MarginInfo;
+import com.vaadin.ui.declarative.DesignAttributeHandler;
+import com.vaadin.ui.declarative.DesignContext;
/**
* An abstract class that defines default implementation for the {@link Layout}
@@ -33,4 +38,90 @@ public abstract class AbstractLayout extends AbstractComponentContainer
return (AbstractLayoutState) super.getState();
}
+ /**
+ * Reads margin attributes from a design into a MarginInfo object. This
+ * helper method should be called from the
+ * {@link #readDesign(Element, DesignContext) readDesign} method of layouts
+ * that implement {@link MarginHandler}.
+ *
+ * @since 7.5
+ *
+ * @param design
+ * the design from which to read
+ * @param defMargin
+ * the default margin state for edges that are not set in the
+ * design
+ * @param context
+ * the DesignContext instance used for parsing the design
+ * @return the margin info
+ */
+ protected MarginInfo readMargin(Element design, MarginInfo defMargin,
+ DesignContext context) {
+
+ if (design.hasAttr("margin")) {
+ boolean margin = DesignAttributeHandler.readAttribute("margin",
+ design.attributes(), boolean.class);
+ return new MarginInfo(margin);
+ } else {
+ boolean left = DesignAttributeHandler.readAttribute("margin-left",
+ design.attributes(), defMargin.hasLeft(), boolean.class);
+
+ boolean right = DesignAttributeHandler.readAttribute(
+ "margin-right", design.attributes(), defMargin.hasRight(),
+ boolean.class);
+
+ boolean top = DesignAttributeHandler.readAttribute("margin-top",
+ design.attributes(), defMargin.hasTop(), boolean.class);
+
+ boolean bottom = DesignAttributeHandler.readAttribute(
+ "margin-bottom", design.attributes(),
+ defMargin.hasBottom(), boolean.class);
+
+ return new MarginInfo(top, right, bottom, left);
+ }
+ }
+
+ /**
+ * Writes margin attributes from a MarginInfo object to a design. This
+ * helper method should be called from the
+ * {@link #readDesign(Element, DesignContext) writeDesign} method of layouts
+ * that implement {@link MarginHandler}.
+ *
+ *
+ * @since 7.5
+ *
+ * @param design
+ * the design to write to
+ * @param margin
+ * the margin state to write
+ * @param defMargin
+ * the default margin state to compare against
+ * @param context
+ * the DesignContext instance used for parsing the design
+ */
+ protected void writeMargin(Element design, MarginInfo margin,
+ MarginInfo defMargin, DesignContext context) {
+ if (margin.hasAll()) {
+ DesignAttributeHandler.writeAttribute("margin",
+ design.attributes(), margin.hasAll(), defMargin.hasAll(),
+ boolean.class);
+ } else {
+
+ DesignAttributeHandler.writeAttribute("margin-left",
+ design.attributes(), margin.hasLeft(), defMargin.hasLeft(),
+ boolean.class);
+
+ DesignAttributeHandler.writeAttribute("margin-right",
+ design.attributes(), margin.hasRight(),
+ defMargin.hasRight(), boolean.class);
+
+ DesignAttributeHandler.writeAttribute("margin-top",
+ design.attributes(), margin.hasTop(), defMargin.hasTop(),
+ boolean.class);
+
+ DesignAttributeHandler.writeAttribute("margin-bottom",
+ design.attributes(), margin.hasBottom(),
+ defMargin.hasBottom(), boolean.class);
+ }
+ }
}
diff --git a/server/src/com/vaadin/ui/AbstractOrderedLayout.java b/server/src/com/vaadin/ui/AbstractOrderedLayout.java
index 0214ff4be1..afe4717212 100644
--- a/server/src/com/vaadin/ui/AbstractOrderedLayout.java
+++ b/server/src/com/vaadin/ui/AbstractOrderedLayout.java
@@ -478,30 +478,7 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
// process default attributes
super.readDesign(design, designContext);
- // handle margins
- if (design.hasAttr("margin")) {
- setMargin(DesignAttributeHandler.readAttribute("margin",
- design.attributes(), Boolean.class));
- } else {
- boolean marginLeft = DesignAttributeHandler.readAttribute(
- "margin-left", design.attributes(), getMargin().hasLeft(),
- Boolean.class);
-
- boolean marginRight = DesignAttributeHandler.readAttribute(
- "margin-right", design.attributes(),
- getMargin().hasRight(), Boolean.class);
-
- boolean marginTop = DesignAttributeHandler.readAttribute(
- "margin-top", design.attributes(), getMargin().hasTop(),
- Boolean.class);
-
- boolean marginBottom = DesignAttributeHandler.readAttribute(
- "margin-bottom", design.attributes(), getMargin()
- .hasBottom(), Boolean.class);
-
- setMargin(new MarginInfo(marginTop, marginBottom, marginLeft,
- marginRight));
- }
+ setMargin(readMargin(design, getMargin(), designContext));
// handle children
for (Element childComponent : design.children()) {
@@ -557,31 +534,7 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
AbstractOrderedLayout def = (AbstractOrderedLayout) designContext
.getDefaultInstance(this);
- // handle margin
- MarginInfo marginInfo = getMargin();
-
- if (marginInfo.hasAll()) {
- DesignAttributeHandler.writeAttribute("margin",
- design.attributes(), marginInfo.hasAll(), def.getMargin()
- .hasAll(), Boolean.class);
- } else {
-
- DesignAttributeHandler.writeAttribute("margin-left", design
- .attributes(), marginInfo.hasLeft(), def.getMargin()
- .hasLeft(), Boolean.class);
-
- DesignAttributeHandler.writeAttribute("margin-right", design
- .attributes(), marginInfo.hasRight(), def.getMargin()
- .hasRight(), Boolean.class);
-
- DesignAttributeHandler.writeAttribute("margin-top", design
- .attributes(), marginInfo.hasTop(), def.getMargin()
- .hasTop(), Boolean.class);
-
- DesignAttributeHandler.writeAttribute("margin-bottom", design
- .attributes(), marginInfo.hasBottom(), def.getMargin()
- .hasBottom(), Boolean.class);
- }
+ writeMargin(design, getMargin(), def.getMargin(), designContext);
// handle children
if (!designContext.shouldWriteChildren(this, def)) {
diff --git a/server/src/com/vaadin/ui/AbstractTextField.java b/server/src/com/vaadin/ui/AbstractTextField.java
index 93025ac0fd..14c135228c 100644
--- a/server/src/com/vaadin/ui/AbstractTextField.java
+++ b/server/src/com/vaadin/ui/AbstractTextField.java
@@ -126,25 +126,22 @@ public abstract class AbstractTextField extends AbstractField<String> implements
selectionPosition = -1;
}
- if (hasListeners(TextChangeEvent.class)) {
- target.addAttribute(TextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE,
- getTextChangeEventMode().toString());
- target.addAttribute(TextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT,
- getTextChangeTimeout());
- if (lastKnownTextContent != null) {
- /*
- * The field has be repainted for some reason (e.g. caption,
- * size, stylename), but the value has not been changed since
- * the last text change event. Let the client side know about
- * the value the server side knows. Client side may then ignore
- * the actual value, depending on its state.
- */
- target.addAttribute(
- TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS,
- true);
- }
+ target.addAttribute(TextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE,
+ getTextChangeEventMode().toString());
+ target.addAttribute(TextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT,
+ getTextChangeTimeout());
+ if (lastKnownTextContent != null) {
+ /*
+ * The field has be repainted for some reason (e.g. caption, size,
+ * stylename), but the value has not been changed since the last
+ * text change event. Let the client side know about the value the
+ * server side knows. Client side may then ignore the actual value,
+ * depending on its state.
+ */
+ target.addAttribute(
+ TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS,
+ true);
}
-
}
@Override
diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/com/vaadin/ui/ComboBox.java
index 4af93113f9..033ec3cd14 100644
--- a/server/src/com/vaadin/ui/ComboBox.java
+++ b/server/src/com/vaadin/ui/ComboBox.java
@@ -288,6 +288,13 @@ public class ComboBox extends AbstractSelect implements
// Paint variables
target.addVariable(this, "selected", selectedKeys);
+ if (getValue() != null && selectedKeys[0] == null) {
+ // not always available, e.g. scrollToSelectedIndex=false
+ // Give the caption for selected item still, not to make it look
+ // like there is no selection at all
+ target.addAttribute("selectedCaption",
+ getItemCaption(getValue()));
+ }
if (isNewItemsAllowed()) {
target.addVariable(this, "newitem", "");
}
diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java
index 68676e5435..b0542352b9 100644
--- a/server/src/com/vaadin/ui/Grid.java
+++ b/server/src/com/vaadin/ui/Grid.java
@@ -57,7 +57,6 @@ import com.vaadin.data.RpcDataProviderExtension.DetailComponentManager;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.fieldgroup.DefaultFieldGroupFieldFactory;
import com.vaadin.data.fieldgroup.FieldGroup;
-import com.vaadin.data.fieldgroup.FieldGroup.BindException;
import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
import com.vaadin.data.fieldgroup.FieldGroupFieldFactory;
import com.vaadin.data.sort.Sort;
@@ -2536,9 +2535,10 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
private Converter<?, Object> converter;
/**
- * A check for allowing the {@link #Column(Grid, GridColumnState, Object)
- * constructor} to call {@link #setConverter(Converter)} with a
- * <code>null</code>, even if model and renderer aren't compatible.
+ * A check for allowing the
+ * {@link #Column(Grid, GridColumnState, Object) constructor} to call
+ * {@link #setConverter(Converter)} with a <code>null</code>, even if
+ * model and renderer aren't compatible.
*/
private boolean isFirstConverterAssignment = true;
@@ -2598,7 +2598,9 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
/**
- * Sets the caption of the header.
+ * Sets the caption of the header. This caption is also used as the
+ * hiding toggle caption, unless it is explicitly set via
+ * {@link #setHidingToggleCaption(String)}.
*
* @param caption
* the text to show in the caption
@@ -2610,6 +2612,9 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
public Column setHeaderCaption(String caption)
throws IllegalStateException {
checkColumnIsAttached();
+
+ state.headerCaption = caption;
+
HeaderRow row = grid.getHeader().getDefaultRow();
if (row != null) {
row.getCell(grid.getPropertyIdByColumnId(state.id)).setText(
@@ -2637,11 +2642,11 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* toggle for this column in the grid's sidebar when the column is
* {@link #isHidable() hidable}.
* <p>
- * By default, before triggering this setter, a user friendly version of
- * the column's {@link #getPropertyId() property id} is used.
+ * The default value is <code>null</code>, and in that case the column's
+ * {@link #getHeaderCaption() header caption} is used.
* <p>
- * <em>NOTE:</em> setting this to <code>null</code> or empty string
- * might cause the hiding toggle to not render correctly.
+ * <em>NOTE:</em> setting this to empty string might cause the hiding
+ * toggle to not render correctly.
*
* @since 7.5.0
* @param hidingToggleCaption
@@ -3302,9 +3307,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
DesignAttributeHandler.writeAttribute("hidden", attributes,
isHidden(), def.hidden, boolean.class);
DesignAttributeHandler.writeAttribute("hiding-toggle-caption",
- attributes, getHidingToggleCaption(),
- SharedUtil.propertyIdToHumanFriendly(getPropertyId()),
- String.class);
+ attributes, getHidingToggleCaption(), null, String.class);
DesignAttributeHandler.writeAttribute("property-id", attributes,
getPropertyId(), null, Object.class);
}
@@ -3372,7 +3375,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* currently extends the AbstractExtension superclass, but this fact should
* be regarded as an implementation detail and subject to change in a future
* major or minor Vaadin revision.
- *
+ *
* @param <T>
* the type this renderer knows how to present
*/
@@ -3445,7 +3448,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* is desired. For instance, a {@code Renderer<Date>} could first turn a
* date value into a formatted string and return
* {@code encode(dateString, String.class)}.
- *
+ *
* @param value
* the value to be encoded
* @param type
@@ -3460,7 +3463,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
/**
* An abstract base class for server-side Grid extensions.
- *
+ *
* @since 7.5
*/
public static abstract class AbstractGridExtension extends
@@ -3475,7 +3478,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
/**
* Constructs a new Grid extension and extends given Grid.
- *
+ *
* @param grid
* a grid instance
*/
@@ -3977,7 +3980,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
@Override
public void bind(int rowIndex) {
- boolean success = false;
+ Exception exception = null;
try {
Object id = getContainerDataSource().getIdByIndex(rowIndex);
if (!isEditorBuffered() || editedItemId == null) {
@@ -3986,12 +3989,19 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
if (editedItemId.equals(id)) {
doEditItem();
- success = true;
}
} catch (Exception e) {
- handleError(e);
+ exception = e;
+ }
+
+ if (exception != null) {
+ handleError(exception);
+ doCancelEditor();
+ getEditorRpc().confirmBind(false);
+ } else {
+ doEditItem();
+ getEditorRpc().confirmBind(true);
}
- getEditorRpc().confirmBind(success);
}
@Override
@@ -4248,8 +4258,18 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
if (datasource.getContainerPropertyIds().contains(propertyId)
&& !columns.containsKey(propertyId)) {
appendColumn(propertyId);
- } else {
+ } else if (defaultContainer) {
addColumnProperty(propertyId, String.class, "");
+ } else {
+ if (columns.containsKey(propertyId)) {
+ throw new IllegalStateException("A column for property id '"
+ + propertyId.toString()
+ + "' already exists in this grid");
+ } else {
+ throw new IllegalStateException("Property id '"
+ + propertyId.toString()
+ + "' does not exist in the container");
+ }
}
// Inform the data provider of this new column.
@@ -4418,7 +4438,6 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
String humanFriendlyPropertyId = SharedUtil
.propertyIdToHumanFriendly(String.valueOf(datasourcePropertyId));
column.setHeaderCaption(humanFriendlyPropertyId);
- column.setHidingToggleCaption(humanFriendlyPropertyId);
if (datasource instanceof Sortable
&& ((Sortable) datasource).getSortableContainerPropertyIds()
@@ -4628,8 +4647,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* @throws IllegalArgumentException
* if {@code rows} is zero or less
* @throws IllegalArgumentException
- * if {@code rows} is {@link Double#isInfinite(double)
- * infinite}
+ * if {@code rows} is {@link Double#isInfinite(double) infinite}
* @throws IllegalArgumentException
* if {@code rows} is {@link Double#isNaN(double) NaN}
*/
@@ -5803,13 +5821,20 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
Field<?> editor = editorFieldGroup.getField(propertyId);
- if (editor == null) {
- editor = editorFieldGroup.buildAndBind(propertyId);
- }
- if (editor.getParent() != Grid.this) {
- assert editor.getParent() == null;
- editor.setParent(this);
+ try {
+ if (editor == null) {
+ editor = editorFieldGroup.buildAndBind(propertyId);
+ }
+ } finally {
+ if (editor == null) {
+ editor = editorFieldGroup.getField(propertyId);
+ }
+
+ if (editor != null && editor.getParent() != Grid.this) {
+ assert editor.getParent() == null;
+ editor.setParent(this);
+ }
}
return editor;
}
@@ -5905,6 +5930,7 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
protected void doCancelEditor() {
editedItemId = null;
editorFieldGroup.discard();
+ editorFieldGroup.setItemDataSource(null);
}
void resetEditor() {
diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/com/vaadin/ui/GridLayout.java
index 35110b39ab..6ccb272704 100644
--- a/server/src/com/vaadin/ui/GridLayout.java
+++ b/server/src/com/vaadin/ui/GridLayout.java
@@ -782,7 +782,14 @@ public class GridLayout extends AbstractLayout implements
}
}
}
- // TODO forget expands for removed columns
+
+ // Forget expands for removed columns
+ if (columns < getColumns()) {
+ for (int i = columns - 1; i < getColumns(); i++) {
+ columnExpandRatio.remove(i);
+ getState().explicitColRatios.remove(i);
+ }
+ }
getState().columns = columns;
}
@@ -826,7 +833,13 @@ public class GridLayout extends AbstractLayout implements
}
}
}
- // TODO forget expands for removed rows
+ // Forget expands for removed rows
+ if (rows < getRows()) {
+ for (int i = rows - 1; i < getRows(); i++) {
+ rowExpandRatio.remove(i);
+ getState().explicitRowRatios.remove(i);
+ }
+ }
getState().rows = rows;
}
@@ -1304,6 +1317,8 @@ public class GridLayout extends AbstractLayout implements
public void readDesign(Element design, DesignContext designContext) {
super.readDesign(design, designContext);
+ setMargin(readMargin(design, getMargin(), designContext));
+
// Prepare a 2D map for reading column contents
Elements rowElements = design.getElementsByTag("row");
List<Map<Integer, Component>> rows = new ArrayList<Map<Integer, Component>>();
@@ -1434,6 +1449,9 @@ public class GridLayout extends AbstractLayout implements
super.writeDesign(design, designContext);
GridLayout def = designContext.getDefaultInstance(this);
+
+ writeMargin(design, getMargin(), def.getMargin(), designContext);
+
if (components.isEmpty()
|| !designContext.shouldWriteChildren(this, def)) {
return;
diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java
index cb61fa31ec..42c4beab6c 100644
--- a/server/src/com/vaadin/ui/Table.java
+++ b/server/src/com/vaadin/ui/Table.java
@@ -676,26 +676,6 @@ public class Table extends AbstractSelect implements Action.Container,
}
}
- // Removes alignments, icons and headers from hidden columns
- if (this.visibleColumns != null) {
- boolean disabledHere = disableContentRefreshing();
- try {
- for (final Iterator<Object> i = this.visibleColumns.iterator(); i
- .hasNext();) {
- final Object col = i.next();
- if (!newVC.contains(col)) {
- setColumnHeader(col, null);
- setColumnAlignment(col, (Align) null);
- setColumnIcon(col, null);
- }
- }
- } finally {
- if (disabledHere) {
- enableContentRefreshing(false);
- }
- }
- }
-
this.visibleColumns = newVC;
// Assures visual refresh
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index b16d7e32d3..2129db614b 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -718,6 +718,9 @@ public abstract class UI extends AbstractSingleComponentContainer implements
page.init(request);
+ // Reset heartbeat timeout to avoid surprise if it's almost expired
+ setLastHeartbeatTimestamp(System.currentTimeMillis());
+
refresh(request);
URI newLocation = page.getLocation();
diff --git a/server/src/com/vaadin/ui/Window.java b/server/src/com/vaadin/ui/Window.java
index 61664fc95d..61ba5826b8 100644
--- a/server/src/com/vaadin/ui/Window.java
+++ b/server/src/com/vaadin/ui/Window.java
@@ -268,6 +268,21 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
}
/**
+ * Sets the position of the window on the screen using
+ * {@link #setPositionX(int)} and {@link #setPositionY(int)}
+ *
+ * @since 7.5
+ * @param x
+ * The new x coordinate for the window
+ * @param y
+ * The new y coordinate for the window
+ */
+ public void setPosition(int x, int y) {
+ setPositionX(x);
+ setPositionY(y);
+ }
+
+ /**
* Sets the distance of Window left border in pixels from left border of the
* containing (main window). Has effect only if in {@link WindowMode#NORMAL}
* mode.
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java
index e193b79df3..bbf083c158 100644
--- a/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java
@@ -23,6 +23,7 @@ import com.vaadin.data.util.sqlcontainer.SQLContainer;
import com.vaadin.data.util.sqlcontainer.SQLTestsConstants;
import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB;
import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
public class FreeformQueryTest {
@@ -892,6 +893,83 @@ public class FreeformQueryTest {
EasyMock.verify(delegate);
}
+ public static class NonMatchingDelegateWithGroupBy implements
+ FreeformQueryDelegate {
+
+ private String fromWhere = "FROM people p1 LEFT JOIN people p2 ON p2.id = p1.id WHERE p1.\"NAME\" LIKE 'notfound' GROUP BY p1.ID";
+
+ @Override
+ public int storeRow(Connection conn, RowItem row)
+ throws UnsupportedOperationException, SQLException {
+ // Not used in this test
+ return 0;
+ }
+
+ @Override
+ public void setOrderBy(List<OrderBy> orderBys)
+ throws UnsupportedOperationException {
+ // Not used in this test
+ }
+
+ @Override
+ public void setFilters(List<Filter> filters)
+ throws UnsupportedOperationException {
+ // Not used in this test
+ }
+
+ @Override
+ public boolean removeRow(Connection conn, RowItem row)
+ throws UnsupportedOperationException, SQLException {
+ // Not used in this test
+ return false;
+ }
+
+ @Override
+ public String getQueryString(int offset, int limit)
+ throws UnsupportedOperationException {
+ return "SELECT * " + fromWhere;
+ }
+
+ @Override
+ public String getCountQuery() throws UnsupportedOperationException {
+ return "SELECT COUNT(*) " + fromWhere;
+ }
+
+ @Override
+ public String getContainsRowQueryString(Object... keys)
+ throws UnsupportedOperationException {
+ // Not used in this test
+ return null;
+ }
+ }
+
+ public static class NonMatchingStatementDelegateWithGroupBy extends
+ NonMatchingDelegateWithGroupBy implements FreeformStatementDelegate {
+
+ @Override
+ public StatementHelper getQueryStatement(int offset, int limit)
+ throws UnsupportedOperationException {
+ StatementHelper sh = new StatementHelper();
+ sh.setQueryString(getQueryString(offset, limit));
+ return sh;
+ }
+
+ @Override
+ public StatementHelper getCountStatement()
+ throws UnsupportedOperationException {
+ StatementHelper sh = new StatementHelper();
+ sh.setQueryString(getCountQuery());
+ return sh;
+ }
+
+ @Override
+ public StatementHelper getContainsRowQueryStatement(Object... keys)
+ throws UnsupportedOperationException {
+ // Not used in this test
+ return null;
+ }
+ }
+
@Test
public void containsRowWithKeys_delegateRegisteredGetContainsRowQueryStringNotImplemented_shouldBuildQueryString()
throws SQLException {
@@ -909,4 +987,24 @@ public class FreeformQueryTest {
EasyMock.verify(delegate);
}
+
+ @Test
+ public void delegateStatementCountWithGroupBy() throws SQLException {
+ String dummyNotUsed = "foo";
+ FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool,
+ "p1.ID");
+ query.setDelegate(new NonMatchingStatementDelegateWithGroupBy());
+
+ Assert.assertEquals(0, query.getCount());
+ }
+
+ @Test
+ public void delegateCountWithGroupBy() throws SQLException {
+ String dummyNotUsed = "foo";
+ FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool,
+ "p1.ID");
+ query.setDelegate(new NonMatchingDelegateWithGroupBy());
+
+ Assert.assertEquals(0, query.getCount());
+ }
}
diff --git a/server/tests/src/com/vaadin/server/DownloadStreamTest.java b/server/tests/src/com/vaadin/server/DownloadStreamTest.java
new file mode 100644
index 0000000000..180b2e348b
--- /dev/null
+++ b/server/tests/src/com/vaadin/server/DownloadStreamTest.java
@@ -0,0 +1,39 @@
+package com.vaadin.server;
+
+import static org.mockito.Matchers.contains;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class DownloadStreamTest {
+ private String filename = "日本語.png";
+ private DownloadStream stream;
+
+ @Before
+ public void setup() {
+ stream = new DownloadStream(mock(InputStream.class), "", filename);
+ }
+
+ @Test
+ public void contentDispositionFilenameIsUtf8Encoded() throws IOException {
+ VaadinResponse response = mock(VaadinResponse.class);
+
+ stream.writeResponse(mock(VaadinRequest.class), response);
+
+ String encodedFileName = URLEncoder.encode(filename, "utf-8");
+ verify(response).setHeader(eq(DownloadStream.CONTENT_DISPOSITION),
+ contains(String.format("filename=\"%s\";", encodedFileName)));
+ verify(response)
+ .setHeader(
+ eq(DownloadStream.CONTENT_DISPOSITION),
+ contains(String.format("filename*=utf-8''%s",
+ encodedFileName)));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java b/server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java
deleted file mode 100644
index 70855f67dc..0000000000
--- a/server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2000-2014 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.vaadin.tests.server.component;
-
-import org.junit.Test;
-
-import com.vaadin.shared.ui.MarginInfo;
-import com.vaadin.tests.design.DeclarativeTestBase;
-import com.vaadin.ui.AbstractLayout;
-import com.vaadin.ui.VerticalLayout;
-
-public class AbstractLayoutDeclarativeMarginTest extends
- DeclarativeTestBase<AbstractLayout> {
-
- @Test
- public void testMarginInfo() {
- VerticalLayout vl = new VerticalLayout();
-
- String left = getMarginTag(true, false, false, false);
- MarginInfo leftInfo = getMarginInfo(true, false, false, false);
-
- String right = getMarginTag(false, true, false, false);
- MarginInfo rightInfo = getMarginInfo(false, true, false, false);
-
- String top = getMarginTag(false, false, true, false);
- MarginInfo topInfo = getMarginInfo(false, false, true, false);
-
- String bottom = getMarginTag(false, false, false, true);
- MarginInfo bottomInfo = getMarginInfo(false, false, false, true);
-
- String topLeft = getMarginTag(true, false, true, false);
- MarginInfo topLeftInfo = getMarginInfo(true, false, true, false);
-
- String topRight = getMarginTag(false, true, true, false);
- MarginInfo topRightInfo = getMarginInfo(false, true, true, false);
-
- String bottomLeft = getMarginTag(true, false, false, true);
- MarginInfo bottomLeftInfo = getMarginInfo(true, false, false, true);
-
- String bottomRight = getMarginTag(false, true, false, true);
- MarginInfo bottomRightInfo = getMarginInfo(false, true, false, true);
-
- testRW(vl, left, leftInfo);
- testRW(vl, right, rightInfo);
- testRW(vl, top, topInfo);
- testRW(vl, bottom, bottomInfo);
-
- testRW(vl, topLeft, topLeftInfo);
- testRW(vl, topRight, topRightInfo);
- testRW(vl, bottomLeft, bottomLeftInfo);
- testRW(vl, bottomRight, bottomRightInfo);
-
- // Test special case of all edges margin'ed
- testRW(vl, getMarginTag(true, true, true, true), new MarginInfo(true));
- }
-
- private void testRW(VerticalLayout vl, String design, MarginInfo margin) {
- vl.setMargin(margin);
- testWrite(design, vl);
- testRead(design, vl);
- }
-
- private String getMarginTag(boolean left, boolean right, boolean top,
- boolean bottom) {
- String s = "<v-vertical-layout ";
-
- if (left && right && top && bottom) {
- s += "margin='true'";
- } else {
- if (left) {
- s += "margin-left='true' ";
- }
- if (right) {
- s += "margin-right='true' ";
- }
- if (top) {
- s += "margin-top='true' ";
- }
- if (bottom) {
- s += "margin-bottom='true' ";
- }
- }
- return s + " />";
- }
-
- private MarginInfo getMarginInfo(boolean left, boolean right, boolean top,
- boolean bottom) {
- return new MarginInfo(top, right, bottom, left);
- }
-
-}
diff --git a/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java b/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java
new file mode 100644
index 0000000000..9fcb64acca
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server.component;
+
+import org.junit.Assert;
+
+import com.vaadin.shared.ui.MarginInfo;
+import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.Layout.MarginHandler;
+
+public abstract class DeclarativeMarginTestBase<L extends Layout & MarginHandler>
+ extends DeclarativeTestBase<L> {
+
+ protected void testMargins(String componentTag) {
+
+ for (int i = 0; i < 16; ++i) {
+ boolean top = (i & 1) == 1;
+ boolean right = (i & 2) == 2;
+ boolean bottom = (i & 4) == 4;
+ boolean left = (i & 8) == 8;
+
+ MarginInfo m = new MarginInfo(top, right, bottom, left);
+
+ String design = getMarginTag(componentTag, top, right, bottom, left);
+
+ // The assertEquals machinery in DeclarativeTestBase uses bean
+ // introspection and MarginInfo is not a proper bean. It ends up
+ // considering *all* MarginInfo objects equal... (#18229)
+ L layout = read(design);
+ Assert.assertEquals(m, layout.getMargin());
+
+ testWrite(design, layout);
+ }
+ }
+
+ private String getMarginTag(String componentTag, boolean top,
+ boolean right, boolean bottom, boolean left) {
+ String s = "<" + componentTag + " ";
+
+ if (left && right && top && bottom) {
+ s += "margin='true'";
+ } else {
+ if (left) {
+ s += "margin-left='true' ";
+ }
+ if (right) {
+ s += "margin-right='true' ";
+ }
+ if (top) {
+ s += "margin-top='true' ";
+ }
+ if (bottom) {
+ s += "margin-bottom='true' ";
+ }
+ }
+ return s + " />";
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java
index 8ccd41f797..28ccfa407c 100644
--- a/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java
@@ -21,7 +21,7 @@ import java.util.List;
import org.junit.Test;
import com.vaadin.shared.ui.label.ContentMode;
-import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.tests.server.component.DeclarativeMarginTestBase;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
@@ -35,58 +35,47 @@ import com.vaadin.ui.VerticalLayout;
* @author Vaadin Ltd
*/
public class AbstractOrderedLayoutDeclarativeTest extends
- DeclarativeTestBase<AbstractOrderedLayout> {
+ DeclarativeMarginTestBase<AbstractOrderedLayout> {
private List<String> defaultAlignments = Arrays.asList(new String[] {
":top", ":left" });
@Test
- public void testMargin() {
- String design = getDesign(0, true);
- AbstractOrderedLayout layout = getLayout(0, true, null);
- testRead(design, layout);
- testWrite(design, layout);
- design = getDesign(0, false);
- layout = getLayout(0, false, null);
- testRead(design, layout);
- testWrite(design, layout);
+ public void testMargins() {
+ testMargins("v-vertical-layout");
}
@Test
public void testExpandRatio() {
- String design = getDesign(1, false);
- AbstractOrderedLayout layout = getLayout(1, false, null);
+ String design = getDesign(1);
+ AbstractOrderedLayout layout = getLayout(1, null);
testRead(design, layout);
testWrite(design, layout);
- design = getDesign(0.25f, false);
- layout = getLayout(0.25f, false, null);
+ design = getDesign(0.25f);
+ layout = getLayout(0.25f, null);
testRead(design, layout);
testWrite(design, layout);
}
@Test
public void testAlignment() {
- String design = getDesign(0, false, ":top", ":left");
- AbstractOrderedLayout layout = getLayout(0, false, Alignment.TOP_LEFT);
+ String design = getDesign(0, ":top", ":left");
+ AbstractOrderedLayout layout = getLayout(0, Alignment.TOP_LEFT);
testRead(design, layout);
testWrite(design, layout);
- design = getDesign(0, false, ":middle", ":center");
- layout = getLayout(0, false, Alignment.MIDDLE_CENTER);
+ design = getDesign(0, ":middle", ":center");
+ layout = getLayout(0, Alignment.MIDDLE_CENTER);
testRead(design, layout);
testWrite(design, layout);
- design = getDesign(0, false, ":bottom", ":right");
- layout = getLayout(0, false, Alignment.BOTTOM_RIGHT);
+ design = getDesign(0, ":bottom", ":right");
+ layout = getLayout(0, Alignment.BOTTOM_RIGHT);
testRead(design, layout);
testWrite(design, layout);
}
- private String getDesign(float expandRatio, boolean margin,
- String... alignments) {
- String result = "<v-vertical-layout caption=test-layout";
- if (margin) {
- result += " margin=true";
- }
- result += "><v-label caption=test-label ";
+ private String getDesign(float expandRatio, String... alignments) {
+ String result = "<v-vertical-layout caption=test-layout>";
+ result += "<v-label caption=test-label ";
String ratioString = expandRatio == 1.0f ? "\"\"" : String
.valueOf(expandRatio);
if (expandRatio != 0) {
@@ -110,10 +99,9 @@ public class AbstractOrderedLayoutDeclarativeTest extends
return result;
}
- private AbstractOrderedLayout getLayout(float expandRatio, boolean margin,
+ private AbstractOrderedLayout getLayout(float expandRatio,
Alignment alignment) {
VerticalLayout layout = new VerticalLayout();
- layout.setMargin(margin);
layout.setCaption("test-layout");
Label l = new Label();
l.setCaption("test-label");
diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java
index 35553bb406..2b960d26a0 100644
--- a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java
+++ b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java
@@ -338,4 +338,20 @@ public class GridColumns {
public void testAddingColumnsWithSetColumnsNonDefaultContainer() {
grid.setColumns("column1", "column2", "column50");
}
+
+ @Test
+ public void testDefaultColumnHidingToggleCaption() {
+ Column firstColumn = grid.getColumns().get(0);
+ firstColumn.setHeaderCaption("headerCaption");
+ assertEquals(null, firstColumn.getHidingToggleCaption());
+ }
+
+ @Test
+ public void testOverriddenColumnHidingToggleCaption() {
+ Column firstColumn = grid.getColumns().get(0);
+ firstColumn.setHidingToggleCaption("hidingToggleCaption");
+ firstColumn.setHeaderCaption("headerCaption");
+ assertEquals("hidingToggleCaption",
+ firstColumn.getHidingToggleCaption());
+ }
}
diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/GridContainerTest.java b/server/tests/src/com/vaadin/tests/server/component/grid/GridContainerTest.java
index cbd448618b..527568eac8 100644
--- a/server/tests/src/com/vaadin/tests/server/component/grid/GridContainerTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/grid/GridContainerTest.java
@@ -15,9 +15,11 @@
*/
package com.vaadin.tests.server.component.grid;
+import org.junit.Assert;
import org.junit.Test;
import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.ui.Grid;
public class GridContainerTest {
@@ -43,4 +45,56 @@ public class GridContainerTest {
container.addItem(0).getItemProperty("x").setValue("y");
return container;
}
+
+ @Test
+ public void setColumnsOrder() {
+ Grid grid = new Grid();
+ IndexedContainer ic = new IndexedContainer();
+ ic.addContainerProperty("foo", String.class, "");
+ ic.addContainerProperty("baz", String.class, "");
+ ic.addContainerProperty("bar", String.class, "");
+ grid.setContainerDataSource(ic);
+ grid.setColumns("foo", "baz", "bar");
+
+ Assert.assertEquals("foo", grid.getColumns().get(0).getPropertyId());
+ Assert.assertEquals("baz", grid.getColumns().get(1).getPropertyId());
+ Assert.assertEquals("bar", grid.getColumns().get(2).getPropertyId());
+ }
+
+ @Test
+ public void addColumnNotInContainer() {
+ Grid grid = new Grid();
+ grid.setContainerDataSource(new IndexedContainer());
+ try {
+ grid.addColumn("notInContainer");
+ Assert.fail("Adding a property id not in the container should throw an exception");
+ } catch (IllegalStateException e) {
+ Assert.assertTrue(e.getMessage().contains("notInContainer"));
+ Assert.assertTrue(e.getMessage().contains(
+ "does not exist in the container"));
+ }
+ }
+
+ @Test
+ public void setColumnsForPropertyIdNotInContainer() {
+ Grid grid = new Grid();
+ grid.setContainerDataSource(new IndexedContainer());
+ try {
+ grid.setColumns("notInContainer", "notThereEither");
+ Assert.fail("Setting columns for property ids not in the container should throw an exception");
+ } catch (IllegalStateException e) {
+ // addColumn is run in random order..
+ Assert.assertTrue(e.getMessage().contains("notInContainer")
+ || e.getMessage().contains("notThereEither"));
+ Assert.assertTrue(e.getMessage().contains(
+ "does not exist in the container"));
+ }
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void multipleAddColumnsForDefaultContainer() {
+ Grid grid = new Grid();
+ grid.addColumn("foo");
+ grid.addColumn("foo");
+ }
}
diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/GridEditorTest.java b/server/tests/src/com/vaadin/tests/server/component/grid/GridEditorTest.java
index 135d7d398c..b70f17779a 100644
--- a/server/tests/src/com/vaadin/tests/server/component/grid/GridEditorTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/grid/GridEditorTest.java
@@ -184,12 +184,16 @@ public class GridEditorTest {
.getEditorField();
field.setValue("New Name");
+ Property<?> datasource = field.getPropertyDataSource();
+
grid.cancelEditor();
assertFalse(grid.isEditorActive());
assertNull(grid.getEditedItemId());
assertFalse(field.isModified());
- assertEquals(DEFAULT_NAME, field.getValue());
- assertEquals(DEFAULT_NAME, field.getPropertyDataSource().getValue());
+ assertEquals("", field.getValue());
+ assertEquals(DEFAULT_NAME, datasource.getValue());
+ assertNull(field.getPropertyDataSource());
+ assertNull(grid.getEditorFieldGroup().getItemDataSource());
}
@Test(expected = IllegalArgumentException.class)
diff --git a/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java
index 7c9c126707..9d3b5001da 100644
--- a/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java
@@ -18,13 +18,19 @@ package com.vaadin.tests.server.component.gridlayout;
import org.junit.Assert;
import org.junit.Test;
-import com.vaadin.tests.design.DeclarativeTestBase;
+import com.vaadin.tests.server.component.DeclarativeMarginTestBase;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.declarative.DesignContext;
-public class GridLayoutDeclarativeTest extends DeclarativeTestBase<GridLayout> {
+public class GridLayoutDeclarativeTest extends
+ DeclarativeMarginTestBase<GridLayout> {
+
+ @Test
+ public void testMargins() {
+ testMargins("v-grid-layout");
+ }
@Test
public void testSimpleGridLayout() {
diff --git a/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java b/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java
index b74896b7a1..e9e73c1e0f 100644
--- a/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java
@@ -50,4 +50,11 @@ public class WindowTest {
Assert.assertEquals(b2, window.getAssistiveDescription()[1]);
}
+
+ @Test
+ public void testSetPosition() {
+ window.setPosition(100, 200);
+ Assert.assertEquals(100, window.getPositionX());
+ Assert.assertEquals(200, window.getPositionY());
+ }
}
diff --git a/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java b/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java
index ff6028648e..2c045d53fa 100644
--- a/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java
+++ b/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java
@@ -712,4 +712,21 @@ public class NavigatorTest extends TestCase {
navigator.addView("view", view);
navigator.navigateTo("view");
}
+
+ public void testNullViewProvider() {
+ IMocksControl control = EasyMock.createControl();
+ NavigationStateManager manager = control
+ .createMock(NavigationStateManager.class);
+ ViewDisplay display = control.createMock(ViewDisplay.class);
+
+ // create navigator to test
+ Navigator navigator = createNavigator(manager, display);
+
+ try {
+ navigator.addProvider(null);
+ fail("Should not be allowed to add a null view provider");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
}
diff --git a/server/tests/src/com/vaadin/tests/util/MockUI.java b/server/tests/src/com/vaadin/tests/util/MockUI.java
new file mode 100644
index 0000000000..17dc24e9e8
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/util/MockUI.java
@@ -0,0 +1,46 @@
+/*
+ * 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.util;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.UI;
+
+public class MockUI extends UI {
+
+ public MockUI() {
+ this(findOrcreateSession());
+ }
+
+ public MockUI(VaadinSession session) {
+ setSession(session);
+ setCurrent(this);
+ }
+
+ @Override
+ protected void init(VaadinRequest request) {
+ // Do nothing
+ }
+
+ private static VaadinSession findOrcreateSession() {
+ VaadinSession session = VaadinSession.getCurrent();
+ if (session == null) {
+ session = new AlwaysLockedVaadinSession(null);
+ VaadinSession.setCurrent(session);
+ }
+ return session;
+ }
+}
diff --git a/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java b/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java
new file mode 100644
index 0000000000..617c7f54ed
--- /dev/null
+++ b/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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 static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.server.Sizeable.Unit;
+
+public class GridLayoutExpandRatioTest {
+
+ private GridLayout gridLayout;
+
+ @Test
+ public void testColExpandRatioIsForgotten() {
+ gridLayout = new GridLayout(4, 1);
+ gridLayout.setWidth(100, Unit.PERCENTAGE);
+ gridLayout.setSizeFull();
+ gridLayout.setSpacing(true);
+
+ addComponents(true);
+
+ gridLayout.setColumnExpandRatio(1, 1);
+ gridLayout.setColumnExpandRatio(3, 1);
+
+ assertTrue(gridLayout.getColumnExpandRatio(0) == 0);
+ assertTrue(gridLayout.getColumnExpandRatio(1) == 1);
+ assertTrue(gridLayout.getColumnExpandRatio(2) == 0);
+ assertTrue(gridLayout.getColumnExpandRatio(3) == 1);
+ assertFalse(gridLayout.getState().explicitColRatios.contains(0));
+ assertTrue(gridLayout.getState().explicitColRatios.contains(1));
+ assertFalse(gridLayout.getState().explicitColRatios.contains(2));
+ assertTrue(gridLayout.getState().explicitColRatios.contains(3));
+
+ gridLayout.removeAllComponents();
+ gridLayout.setColumns(3);
+ addComponents(false);
+
+ assertTrue(gridLayout.getColumnExpandRatio(0) == 0);
+ assertTrue(gridLayout.getColumnExpandRatio(1) == 1);
+ assertTrue(gridLayout.getColumnExpandRatio(2) == 0);
+ assertTrue(gridLayout.getColumnExpandRatio(3) == 0);
+ assertFalse(gridLayout.getState().explicitColRatios.contains(0));
+ assertTrue(gridLayout.getState().explicitColRatios.contains(1));
+ assertFalse(gridLayout.getState().explicitColRatios.contains(2));
+ assertFalse(gridLayout.getState().explicitColRatios.contains(3));
+ }
+
+ @Test
+ public void testRowExpandRatioIsForgotten() {
+ gridLayout = new GridLayout(1, 4);
+ gridLayout.setWidth(100, Unit.PERCENTAGE);
+ gridLayout.setSizeFull();
+ gridLayout.setSpacing(true);
+
+ addComponents(true);
+
+ gridLayout.setRowExpandRatio(1, 1);
+ gridLayout.setRowExpandRatio(3, 1);
+
+ assertTrue(gridLayout.getRowExpandRatio(0) == 0);
+ assertTrue(gridLayout.getRowExpandRatio(1) == 1);
+ assertTrue(gridLayout.getRowExpandRatio(2) == 0);
+ assertTrue(gridLayout.getRowExpandRatio(3) == 1);
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(0));
+ assertTrue(gridLayout.getState().explicitRowRatios.contains(1));
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(2));
+ assertTrue(gridLayout.getState().explicitRowRatios.contains(3));
+
+ gridLayout.removeAllComponents();
+ gridLayout.setRows(3);
+ addComponents(false);
+
+ assertTrue(gridLayout.getRowExpandRatio(0) == 0);
+ assertTrue(gridLayout.getRowExpandRatio(1) == 1);
+ assertTrue(gridLayout.getRowExpandRatio(2) == 0);
+ assertTrue(gridLayout.getRowExpandRatio(3) == 0);
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(0));
+ assertTrue(gridLayout.getState().explicitRowRatios.contains(1));
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(2));
+ assertFalse(gridLayout.getState().explicitRowRatios.contains(3));
+ }
+
+ private void addComponents(boolean includeLastOne) {
+ gridLayout.addComponent(label("{1}"));
+ gridLayout.addComponent(label("{2}"));
+ gridLayout.addComponent(label("{3}"));
+ if (includeLastOne) {
+ gridLayout.addComponent(label("{4}"));
+ }
+ }
+
+ private Label label(String content) {
+ Label label = new Label(content);
+ label.setSizeUndefined();
+ return label;
+ }
+}
diff --git a/server/tests/src/com/vaadin/ui/LabelDataSourceTest.java b/server/tests/src/com/vaadin/ui/LabelDataSourceTest.java
index 8ec3ca1245..030504cf2b 100644
--- a/server/tests/src/com/vaadin/ui/LabelDataSourceTest.java
+++ b/server/tests/src/com/vaadin/ui/LabelDataSourceTest.java
@@ -22,9 +22,9 @@ import org.junit.Before;
import org.junit.Test;
import com.vaadin.data.util.ObjectProperty;
-import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinSession;
import com.vaadin.tests.util.AlwaysLockedVaadinSession;
+import com.vaadin.tests.util.MockUI;
public class LabelDataSourceTest {
@@ -104,18 +104,6 @@ public class LabelDataSourceTest {
Assert.assertEquals("after", label.getValue());
}
- public class MockUI extends UI {
-
- public MockUI() {
- setSession(vaadinSession);
- }
-
- @Override
- protected void init(VaadinRequest request) {
- }
-
- }
-
@Test
public void attachToSessionWithDifferentLocale() {
label.setValue("before");