From e49e13eeb53719f42f7f58ce202c57ea65a56181 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 29 Jun 2012 09:54:51 +0300 Subject: [PATCH] Added rootId to stream variables URLs (#9034) --- src/com/vaadin/Application.java | 14 ++++++++ .../terminal/AbstractClientConnector.java | 2 +- .../server/AbstractApplicationPortlet.java | 6 ++-- .../server/AbstractApplicationServlet.java | 8 ++--- .../server/AbstractCommunicationManager.java | 27 ++++++++------- .../terminal/gwt/server/ClientConnector.java | 9 +++++ .../gwt/server/CommunicationManager.java | 33 +++++++++++-------- .../gwt/server/DragAndDropService.java | 5 +++ .../terminal/gwt/server/JsonPaintTarget.java | 5 ++- .../server/PortletCommunicationManager.java | 19 ++++++++--- 10 files changed, 86 insertions(+), 42 deletions(-) diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java index 84a8df5053..468a7ee8be 100644 --- a/src/com/vaadin/Application.java +++ b/src/com/vaadin/Application.java @@ -2373,4 +2373,18 @@ public class Application implements Terminal.ErrorListener, Serializable { private static final Logger getLogger() { return Logger.getLogger(Application.class.getName()); } + + /** + * Returns a Root with the given id. + *

+ * This is meant for framework internal use. + *

+ * + * @param rootId + * The root id + * @return The root with the given id or null if not found + */ + public Root getRootById(int rootId) { + return roots.get(rootId); + } } diff --git a/src/com/vaadin/terminal/AbstractClientConnector.java b/src/com/vaadin/terminal/AbstractClientConnector.java index 9de444d70e..752b5326fc 100644 --- a/src/com/vaadin/terminal/AbstractClientConnector.java +++ b/src/com/vaadin/terminal/AbstractClientConnector.java @@ -322,7 +322,7 @@ public abstract class AbstractClientConnector implements ClientConnector { * @return the Root ancestor of this connector, or null if none * is found. */ - protected Root getRoot() { + public Root getRoot() { ClientConnector connector = this; while (connector != null) { if (connector instanceof Root) { diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index c2f887674a..acfc926d68 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -638,8 +638,10 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet /* Handle the request */ if (requestType == RequestType.FILE_UPLOAD) { - applicationManager.handleFileUpload(root, wrappedRequest, - wrappedResponse); + // Root is resolved in handleFileUpload by + // PortletCommunicationManager + applicationManager.handleFileUpload(application, + wrappedRequest, wrappedResponse); return; } else if (requestType == RequestType.BROWSER_DETAILS) { applicationManager.handleBrowserDetailsRequest( diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index 7d88b432f4..f61f40dccc 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -436,11 +436,9 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /* Handle the request */ if (requestType == RequestType.FILE_UPLOAD) { - Root root = application.getRootForRequest(request); - if (root == null) { - throw new ServletException(ERROR_NO_ROOT_FOUND); - } - applicationManager.handleFileUpload(root, request, response); + // Root is resolved in communication manager + applicationManager.handleFileUpload(application, request, + response); return; } else if (requestType == RequestType.UIDL) { Root root = application.getRootForRequest(request); diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index ba17822813..d71ab7f892 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -212,7 +212,7 @@ public abstract class AbstractCommunicationManager implements Serializable { */ protected void doHandleSimpleMultipartFileUpload(WrappedRequest request, WrappedResponse response, StreamVariable streamVariable, - String variableName, Connector owner, String boundary) + String variableName, ClientConnector owner, String boundary) throws IOException { // multipart parsing, supports only one file for request, but that is // fine for our current terminal @@ -275,14 +275,16 @@ public abstract class AbstractCommunicationManager implements Serializable { final String mimeType = rawMimeType; try { - /* - * safe cast as in GWT terminal all variable owners are expected to - * be components. - */ - Component component = (Component) owner; - if (component.isReadOnly()) { + // TODO Shouldn't this check connectorEnabled? + if (owner == null) { throw new UploadException( - "Warning: file upload ignored because the componente was read-only"); + "File upload ignored because the connector for the stream variable was not found"); + } + if (owner instanceof Component) { + if (((Component) owner).isReadOnly()) { + throw new UploadException( + "Warning: file upload ignored because the componente was read-only"); + } } boolean forgetVariable = streamToReceiver(simpleMultiPartReader, streamVariable, filename, mimeType, contentLength); @@ -311,7 +313,7 @@ public abstract class AbstractCommunicationManager implements Serializable { */ protected void doHandleXhrFilePost(WrappedRequest request, WrappedResponse response, StreamVariable streamVariable, - String variableName, Connector owner, int contentLength) + String variableName, ClientConnector owner, int contentLength) throws IOException { // These are unknown in filexhr ATM, maybe add to Accept header that @@ -2273,10 +2275,11 @@ public abstract class AbstractCommunicationManager implements Serializable { } - abstract String getStreamVariableTargetUrl(Connector owner, String name, - StreamVariable value); + abstract String getStreamVariableTargetUrl(ClientConnector owner, + String name, StreamVariable value); - abstract protected void cleanStreamVariable(Connector owner, String name); + abstract protected void cleanStreamVariable(ClientConnector owner, + String name); /** * Gets the bootstrap handler that should be used for generating the pages diff --git a/src/com/vaadin/terminal/gwt/server/ClientConnector.java b/src/com/vaadin/terminal/gwt/server/ClientConnector.java index dfdd58879d..ca1ad349c1 100644 --- a/src/com/vaadin/terminal/gwt/server/ClientConnector.java +++ b/src/com/vaadin/terminal/gwt/server/ClientConnector.java @@ -12,6 +12,7 @@ import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.terminal.gwt.client.communication.SharedState; import com.vaadin.ui.Component; import com.vaadin.ui.ComponentContainer; +import com.vaadin.ui.Root; /** * Interface implemented by all connectors that are capable of communicating @@ -136,4 +137,12 @@ public interface ClientConnector extends Connector, RpcTarget { * the extension to remove. */ public void removeExtension(Extension extension); + + /** + * Returns the root this connector is attached to + * + * @return The Root this connector is attached to or null if it is not + * attached to any Root + */ + public Root getRoot(); } diff --git a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java index 2d2888e034..2cf3b23446 100644 --- a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java @@ -20,7 +20,6 @@ import com.vaadin.terminal.PaintException; import com.vaadin.terminal.StreamVariable; import com.vaadin.terminal.WrappedRequest; import com.vaadin.terminal.WrappedResponse; -import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.ui.Root; /** @@ -72,12 +71,13 @@ public class CommunicationManager extends AbstractCommunicationManager { * @throws IOException * @throws InvalidUIDLSecurityKeyException */ - public void handleFileUpload(Root root, WrappedRequest request, - WrappedResponse response) throws IOException, - InvalidUIDLSecurityKeyException { + public void handleFileUpload(Application application, + WrappedRequest request, WrappedResponse response) + throws IOException, InvalidUIDLSecurityKeyException { /* - * URI pattern: APP/UPLOAD/[PID]/[NAME]/[SECKEY] See #createReceiverUrl + * URI pattern: APP/UPLOAD/[ROOTID]/[PID]/[NAME]/[SECKEY] See + * #createReceiverUrl */ String pathInfo = request.getRequestPathInfo(); @@ -86,16 +86,20 @@ public class CommunicationManager extends AbstractCommunicationManager { .indexOf(AbstractApplicationServlet.UPLOAD_URL_PREFIX) + AbstractApplicationServlet.UPLOAD_URL_PREFIX.length(); String uppUri = pathInfo.substring(startOfData); - String[] parts = uppUri.split("/", 3); // 0 = pid, 1= name, 2 = sec key - String variableName = parts[1]; - String connectorId = parts[0]; + String[] parts = uppUri.split("/", 4); // 0= rootid, 1 = cid, 2= name, 3 + // = sec key + String rootId = parts[0]; + String connectorId = parts[1]; + String variableName = parts[2]; + Root root = application.getRootById(Integer.parseInt(rootId)); + Root.setCurrent(root); StreamVariable streamVariable = pidToNameToStreamVariable.get( connectorId).get(variableName); String secKey = streamVariableToSeckey.get(streamVariable); - if (secKey.equals(parts[2])) { + if (secKey.equals(parts[3])) { - Connector source = getConnector(root, connectorId); + ClientConnector source = getConnector(root, connectorId); String contentType = request.getContentType(); if (contentType.contains("boundary")) { // Multipart requests contain boundary string @@ -143,13 +147,13 @@ public class CommunicationManager extends AbstractCommunicationManager { private Map streamVariableToSeckey; @Override - String getStreamVariableTargetUrl(Connector owner, String name, + String getStreamVariableTargetUrl(ClientConnector owner, String name, StreamVariable value) { /* * We will use the same APP/* URI space as ApplicationResources but * prefix url with UPLOAD * - * eg. APP/UPLOAD/[PID]/[NAME]/[SECKEY] + * eg. APP/UPLOAD/[ROOTID]/[PID]/[NAME]/[SECKEY] * * SECKEY is created on each paint to make URL's unpredictable (to * prevent CSRF attacks). @@ -158,7 +162,8 @@ public class CommunicationManager extends AbstractCommunicationManager { * handling post */ String paintableId = owner.getConnectorId(); - String key = paintableId + "/" + name; + int rootId = owner.getRoot().getRootId(); + String key = rootId + "/" + paintableId + "/" + name; if (pidToNameToStreamVariable == null) { pidToNameToStreamVariable = new HashMap>(); @@ -186,7 +191,7 @@ public class CommunicationManager extends AbstractCommunicationManager { } @Override - protected void cleanStreamVariable(Connector owner, String name) { + protected void cleanStreamVariable(ClientConnector owner, String name) { Map nameToStreamVar = pidToNameToStreamVariable .get(owner.getConnectorId()); nameToStreamVar.remove("name"); diff --git a/src/com/vaadin/terminal/gwt/server/DragAndDropService.java b/src/com/vaadin/terminal/gwt/server/DragAndDropService.java index 0e8d1c0152..8e0346f6af 100644 --- a/src/com/vaadin/terminal/gwt/server/DragAndDropService.java +++ b/src/com/vaadin/terminal/gwt/server/DragAndDropService.java @@ -26,6 +26,7 @@ import com.vaadin.terminal.gwt.client.communication.SharedState; import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager; import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager.DragEventType; import com.vaadin.ui.Component; +import com.vaadin.ui.Root; public class DragAndDropService implements VariableOwner, ClientConnector { @@ -287,4 +288,8 @@ public class DragAndDropService implements VariableOwner, ClientConnector { private Logger getLogger() { return Logger.getLogger(DragAndDropService.class.getName()); } + + public Root getRoot() { + return null; + } } diff --git a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java index 70ab452e4e..15b5ced703 100644 --- a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java +++ b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java @@ -24,7 +24,6 @@ import com.vaadin.terminal.Resource; import com.vaadin.terminal.StreamVariable; import com.vaadin.terminal.ThemeResource; import com.vaadin.terminal.VariableOwner; -import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.ui.Alignment; import com.vaadin.ui.Component; import com.vaadin.ui.CustomLayout; @@ -992,8 +991,8 @@ public class JsonPaintTarget implements PaintTarget { public void addVariable(VariableOwner owner, String name, StreamVariable value) throws PaintException { - String url = manager.getStreamVariableTargetUrl((Connector) owner, - name, value); + String url = manager.getStreamVariableTargetUrl( + (ClientConnector) owner, name, value); if (url != null) { addVariable(owner, name, url); } // else { //NOP this was just a cleanup by component } diff --git a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java index 7398315ee2..d45e652110 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java @@ -43,12 +43,19 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { super(application); } - public void handleFileUpload(Root root, WrappedRequest request, - WrappedResponse response) throws IOException { + public void handleFileUpload(Application application, + WrappedRequest request, WrappedResponse response) + throws IOException { String contentType = request.getContentType(); String name = request.getParameter("name"); String ownerId = request.getParameter("rec-owner"); - Connector owner = getConnector(root, ownerId); + String rootId = request.getParameter("rootId"); + + Root root = application.getRootById(Integer.parseInt(rootId)); + Root.setCurrent(root); + + ClientConnector owner = getConnector(root, ownerId); + StreamVariable streamVariable = ownerToNameToStreamVariable.get(owner) .get(name); @@ -123,7 +130,7 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { private Map> ownerToNameToStreamVariable; @Override - String getStreamVariableTargetUrl(Connector owner, String name, + String getStreamVariableTargetUrl(ClientConnector owner, String name, StreamVariable value) { if (ownerToNameToStreamVariable == null) { ownerToNameToStreamVariable = new HashMap>(); @@ -139,8 +146,10 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { resurl.setResourceID("UPLOAD"); resurl.setParameter("name", name); resurl.setParameter("rec-owner", owner.getConnectorId()); + resurl.setParameter("rootId", "" + owner.getRoot().getRootId()); resurl.setProperty("name", name); resurl.setProperty("rec-owner", owner.getConnectorId()); + resurl.setProperty("rootId", "" + owner.getRoot().getRootId()); return resurl.toString(); } @@ -153,7 +162,7 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { } @Override - protected void cleanStreamVariable(Connector owner, String name) { + protected void cleanStreamVariable(ClientConnector owner, String name) { Map map = ownerToNameToStreamVariable .get(owner); map.remove(name); -- 2.39.5