diff options
author | Henri Sara <hesara@vaadin.com> | 2015-08-19 11:54:59 +0300 |
---|---|---|
committer | Henri Sara <hesara@vaadin.com> | 2015-08-19 11:54:59 +0300 |
commit | 123c9fbc74d52c66f59bb825414ad3260aaea975 (patch) | |
tree | 8deda9347560f9324d36a5513d4a6fc555d0f13d /server | |
parent | 7a3e03b5acd416141e1a95eae32c3808a8e5addd (diff) | |
parent | e7fda93b300b11d9507f25917306e1f3d57cb27c (diff) | |
download | vaadin-framework-123c9fbc74d52c66f59bb825414ad3260aaea975.tar.gz vaadin-framework-123c9fbc74d52c66f59bb825414ad3260aaea975.zip |
Merge branch 'master-before-18503' into grid-unbuffered-editor
Conflicts:
server/src/com/vaadin/data/RpcDataProviderExtension.java
uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridEditorTest.java
Change-Id: I9e7907c9caf839fd043444db0505f9853f020a6a
Diffstat (limited to 'server')
-rw-r--r-- | server/ivy.xml | 2 | ||||
-rw-r--r-- | server/src/com/vaadin/server/VaadinServlet.java | 20 | ||||
-rw-r--r-- | server/src/com/vaadin/server/WebBrowser.java | 14 | ||||
-rw-r--r-- | server/src/com/vaadin/server/communication/AtmospherePushConnection.java | 7 | ||||
-rw-r--r-- | server/src/com/vaadin/server/communication/FileUploadHandler.java | 2 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/Grid.java | 30 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/HorizontalLayout.java | 7 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/VerticalLayout.java | 7 | ||||
-rw-r--r-- | server/src/com/vaadin/ui/renderers/ImageRenderer.java | 2 | ||||
-rw-r--r-- | server/tests/src/com/vaadin/server/communication/FileUploadHandlerTest.java | 120 |
10 files changed, 182 insertions, 29 deletions
diff --git a/server/ivy.xml b/server/ivy.xml index e9bc8b818d..0711b4b2ea 100644 --- a/server/ivy.xml +++ b/server/ivy.xml @@ -36,7 +36,7 @@ <!-- Google App Engine --> <dependency org="com.google.appengine" name="appengine-api-1.0-sdk" - rev="1.2.1" conf="build-provided,ide,test -> default" /> + rev="1.7.7" conf="build-provided,ide,test -> default" /> <!-- Bean Validation API --> <dependency org="javax.validation" name="validation-api" diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java index 7aada2402d..61df02feaa 100644 --- a/server/src/com/vaadin/server/VaadinServlet.java +++ b/server/src/com/vaadin/server/VaadinServlet.java @@ -28,6 +28,7 @@ import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -694,17 +695,20 @@ public class VaadinServlet extends HttpServlet implements Constants { return false; } + String decodedRequestURI = URLDecoder.decode(request.getRequestURI(), + "UTF-8"); if ((request.getContextPath() != null) - && (request.getRequestURI().startsWith("/VAADIN/"))) { - serveStaticResourcesInVAADIN(request.getRequestURI(), request, - response); + && (decodedRequestURI.startsWith("/VAADIN/"))) { + serveStaticResourcesInVAADIN(decodedRequestURI, request, response); return true; - } else if (request.getRequestURI().startsWith( - request.getContextPath() + "/VAADIN/")) { + } + + String decodedContextPath = URLDecoder.decode(request.getContextPath(), + "UTF-8"); + if (decodedRequestURI.startsWith(decodedContextPath + "/VAADIN/")) { serveStaticResourcesInVAADIN( - request.getRequestURI().substring( - request.getContextPath().length()), request, - response); + decodedRequestURI.substring(decodedContextPath.length()), + request, response); return true; } diff --git a/server/src/com/vaadin/server/WebBrowser.java b/server/src/com/vaadin/server/WebBrowser.java index 66018b02f2..9bf30cb3db 100644 --- a/server/src/com/vaadin/server/WebBrowser.java +++ b/server/src/com/vaadin/server/WebBrowser.java @@ -126,6 +126,20 @@ public class WebBrowser implements Serializable { } /** + * Tests whether the user is using Edge. + * + * @return true if the user is using Edge, false if the user is not using + * Edge or if no information on the browser is present + */ + public boolean isEdge() { + if (browserDetails == null) { + return false; + } + + return browserDetails.isEdge(); + } + + /** * Tests whether the user is using Safari. * * @return true if the user is using Safari, false if the user is not using diff --git a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java index 357278f411..a45d9aa059 100644 --- a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java +++ b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java @@ -274,6 +274,13 @@ public class AtmospherePushConnection implements PushConnection { public void disconnect() { assert isConnected(); + if (resource == null) { + // Already disconnected. Should not happen but if it does, we don't + // want to cause NPEs + getLogger() + .fine("AtmospherePushConnection.disconnect() called twice, this should not happen"); + return; + } if (resource.isResumed()) { // This can happen for long polling because of // http://dev.vaadin.com/ticket/16919 diff --git a/server/src/com/vaadin/server/communication/FileUploadHandler.java b/server/src/com/vaadin/server/communication/FileUploadHandler.java index 576cbd8411..532c7fe95b 100644 --- a/server/src/com/vaadin/server/communication/FileUploadHandler.java +++ b/server/src/com/vaadin/server/communication/FileUploadHandler.java @@ -269,7 +269,7 @@ public class FileUploadHandler implements RequestHandler { streamVariable = uI.getConnectorTracker().getStreamVariable( connectorId, variableName); String secKey = uI.getConnectorTracker().getSeckey(streamVariable); - if (!secKey.equals(parts[3])) { + if (secKey == null || !secKey.equals(parts[3])) { // TODO Should rethink error handling return true; } diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java index bee424e98f..c7ad9632fa 100644 --- a/server/src/com/vaadin/ui/Grid.java +++ b/server/src/com/vaadin/ui/Grid.java @@ -1167,6 +1167,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, private int selectionLimit = DEFAULT_MAX_SELECTIONS; + private boolean allSelected; + @Override public boolean select(final Object... itemIds) throws IllegalArgumentException { @@ -1212,6 +1214,9 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, } fireSelectionEvent(oldSelection, selection); } + + updateAllSelectedState(); + return selectionWillChange; } @@ -1277,6 +1282,9 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, selection.removeAll(itemIds); fireSelectionEvent(oldSelection, selection); } + + updateAllSelectedState(); + return hasCommonElements; } @@ -1357,6 +1365,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, fireSelectionEvent(oldSelection, selection); } + updateAllSelectedState(); + return changed; } @@ -1370,6 +1380,13 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, "Vararg array of itemIds may not be null"); } } + + private void updateAllSelectedState() { + if (allSelected != selection.size() >= selectionLimit) { + allSelected = selection.size() >= selectionLimit; + grid.getRpcProxy(GridClientRpc.class).setSelectAll(allSelected); + } + } } /** @@ -3648,10 +3665,21 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, safeConverter.getPresentationType(), locale); } - JsonValue encodedValue = renderer.encode(presentationValue); + JsonValue encodedValue; + try { + encodedValue = renderer.encode(presentationValue); + } catch (Exception e) { + getLogger().log(Level.SEVERE, "Unable to encode data", e); + encodedValue = renderer.encode(null); + } return encodedValue; } + + private static Logger getLogger() { + return Logger.getLogger(AbstractRenderer.class.getName()); + } + } /** diff --git a/server/src/com/vaadin/ui/HorizontalLayout.java b/server/src/com/vaadin/ui/HorizontalLayout.java index 54569570b9..616fa09225 100644 --- a/server/src/com/vaadin/ui/HorizontalLayout.java +++ b/server/src/com/vaadin/ui/HorizontalLayout.java @@ -15,6 +15,8 @@ */ package com.vaadin.ui; +import com.vaadin.shared.ui.orderedlayout.HorizontalLayoutState; + /** * Horizontal layout * @@ -48,4 +50,9 @@ public class HorizontalLayout extends AbstractOrderedLayout { addComponents(children); } + @Override + protected HorizontalLayoutState getState() { + return (HorizontalLayoutState) super.getState(); + } + } diff --git a/server/src/com/vaadin/ui/VerticalLayout.java b/server/src/com/vaadin/ui/VerticalLayout.java index 12819e50bc..7002fbc7e6 100644 --- a/server/src/com/vaadin/ui/VerticalLayout.java +++ b/server/src/com/vaadin/ui/VerticalLayout.java @@ -15,6 +15,8 @@ */ package com.vaadin.ui; +import com.vaadin.shared.ui.orderedlayout.VerticalLayoutState; + /** * Vertical layout * @@ -48,4 +50,9 @@ public class VerticalLayout extends AbstractOrderedLayout { this(); addComponents(children); } + + @Override + protected VerticalLayoutState getState() { + return (VerticalLayoutState) super.getState(); + } } diff --git a/server/src/com/vaadin/ui/renderers/ImageRenderer.java b/server/src/com/vaadin/ui/renderers/ImageRenderer.java index 2fb872583e..ad7d5cae2b 100644 --- a/server/src/com/vaadin/ui/renderers/ImageRenderer.java +++ b/server/src/com/vaadin/ui/renderers/ImageRenderer.java @@ -58,7 +58,7 @@ public class ImageRenderer extends ClickableRenderer<Resource> { if (!(resource == null || resource instanceof ExternalResource || resource instanceof ThemeResource)) { throw new IllegalArgumentException( "ImageRenderer only supports ExternalResource and ThemeResource (" - + resource.getClass().getSimpleName() + "given )"); + + resource.getClass().getSimpleName() + " given)"); } return encode(ResourceReference.create(resource, this, null), diff --git a/server/tests/src/com/vaadin/server/communication/FileUploadHandlerTest.java b/server/tests/src/com/vaadin/server/communication/FileUploadHandlerTest.java index 2cb4c3bf4d..286163541e 100644 --- a/server/tests/src/com/vaadin/server/communication/FileUploadHandlerTest.java +++ b/server/tests/src/com/vaadin/server/communication/FileUploadHandlerTest.java @@ -15,50 +15,136 @@ */ package com.vaadin.server.communication; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import org.junit.Before; import org.junit.Test; -import org.mockito.Mockito; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import com.vaadin.server.ClientConnector; +import com.vaadin.server.ServletPortletHelper; +import com.vaadin.server.StreamVariable; import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinResponse; +import com.vaadin.server.VaadinSession; +import com.vaadin.ui.ConnectorTracker; +import com.vaadin.ui.UI; -/** - * Tests whether we get infinite loop if InputStream is already read (#10096) - */ public class FileUploadHandlerTest { private FileUploadHandler handler; - private VaadinRequest request; + @Mock private VaadinResponse response; + @Mock private StreamVariable streamVariable; + @Mock private ClientConnector clientConnector; + @Mock private VaadinRequest request; + @Mock private UI ui; + @Mock private ConnectorTracker connectorTracker; + @Mock private VaadinSession session; + @Mock private OutputStream responseOutput; + + private int uiId = 123; + private final String connectorId = "connectorId"; + private final String variableName = "name"; + private final String expectedSecurityKey = "key"; @Before public void setup() throws Exception { + MockitoAnnotations.initMocks(this); + handler = new FileUploadHandler(); - InputStream inputStream = new InputStream() { - private int counter = 0; + + mockRequest(); + mockConnectorTracker(); + mockUi(); + + when(clientConnector.isConnectorEnabled()).thenReturn(true); + when(streamVariable.getOutputStream()).thenReturn(mock(OutputStream.class)); + when(response.getOutputStream()).thenReturn(responseOutput); + } + + private void mockConnectorTracker() { + when(connectorTracker.getSeckey(streamVariable)).thenReturn(expectedSecurityKey); + when(connectorTracker.getStreamVariable(connectorId, variableName)).thenReturn(streamVariable); + when(connectorTracker.getConnector(connectorId)).thenReturn(clientConnector); + } + + private void mockRequest() throws IOException { + when(request.getPathInfo()).thenReturn("/" + ServletPortletHelper.UPLOAD_URL_PREFIX + uiId + "/"+ connectorId + "/" + variableName + "/" + expectedSecurityKey); + when(request.getInputStream()).thenReturn(createInputStream("foobar")); + when(request.getHeader("Content-Length")).thenReturn("6"); + when(request.getContentType()).thenReturn("foobar"); + } + + private InputStream createInputStream(final String content) { + return new InputStream() { + int counter = 0; + byte[] msg = content.getBytes(); @Override public int read() throws IOException { - counter++; - if (counter > 6) { - throw new RuntimeException( - "-1 is ignored by FileUploadHandler"); + if(counter > msg.length + 1) { + throw new AssertionError("-1 was ignored by FileUploadHandler."); + } + + if(counter >= msg.length) { + counter++; + return -1; } - return -1; - } + return msg[counter++]; + } }; - request = Mockito.mock(VaadinRequest.class); - Mockito.when(request.getInputStream()).thenReturn(inputStream); - Mockito.when(request.getHeader("Content-Length")).thenReturn("211"); } + private void mockUi() { + when(ui.getConnectorTracker()).thenReturn(connectorTracker); + when(session.getUIById(uiId)).thenReturn(ui); + } + + /** + * Tests whether we get infinite loop if InputStream is already read (#10096) + */ @Test(expected = IOException.class) - public void testStreamEnded() throws IOException { + public void exceptionIsThrownOnUnexpectedEnd() throws IOException { + when(request.getInputStream()).thenReturn(createInputStream("")); + when(request.getHeader("Content-Length")).thenReturn("1"); + handler.doHandleSimpleMultipartFileUpload(null, request, null, null, null, null, null); + } + + @Test + public void responseIsSentOnCorrectSecurityKey() throws IOException { + when(connectorTracker.getSeckey(streamVariable)).thenReturn(expectedSecurityKey); + + handler.handleRequest(session, request, response); + verify(responseOutput).close(); } + @Test + public void responseIsNotSentOnIncorrectSecurityKey() throws IOException { + when(connectorTracker.getSeckey(streamVariable)).thenReturn("another key expected"); + + handler.handleRequest(session, request, response); + + verifyZeroInteractions(responseOutput); + } + + @Test + public void responseIsNotSentOnMissingSecurityKey() throws IOException { + when(connectorTracker.getSeckey(streamVariable)).thenReturn(null); + + handler.handleRequest(session, request, response); + + verifyZeroInteractions(responseOutput); + } } |