]> source.dussan.org Git - vaadin-framework.git/commitdiff
More refactorings, application resource downloads should now work on both servlets...
authorPetter Holmström <petter.holmstrom@itmill.com>
Wed, 4 Nov 2009 11:57:10 +0000 (11:57 +0000)
committerPetter Holmström <petter.holmstrom@itmill.com>
Wed, 4 Nov 2009 11:57:10 +0000 (11:57 +0000)
svn changeset:9617/svn branch:portlet_2.0

src/com/vaadin/Application.java
src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java

index bea366307dd69e5a4b5e77a055370d91f8dc764b..dfdf4e32301f3072ad6f8c4333b15dab2446672f 100644 (file)
@@ -107,7 +107,7 @@ public abstract class Application implements URIHandler,
     /**
      * Mapping from window name to window instance.
      */
-    private final Hashtable windows = new Hashtable();
+    private final Hashtable<String, Window> windows = new Hashtable<String, Window>();
 
     /**
      * Main window of the application.
@@ -123,7 +123,7 @@ public abstract class Application implements URIHandler,
      * The ID of the portlet window that this application runs in.
      */
     private String portletWindowId;
-    
+
     /**
      * Name of the theme currently used by the application.
      */
@@ -147,24 +147,24 @@ public abstract class Application implements URIHandler,
     /**
      * List of listeners listening user changes.
      */
-    private LinkedList userChangeListeners = null;
+    private LinkedList<UserChangeListener> userChangeListeners = null;
 
     /**
      * Window attach listeners.
      */
-    private LinkedList windowAttachListeners = null;
+    private LinkedList<WindowAttachListener> windowAttachListeners = null;
 
     /**
      * Window detach listeners.
      */
-    private LinkedList windowDetachListeners = null;
+    private LinkedList<WindowDetachListener> windowDetachListeners = null;
 
     /**
      * Application resource mapping: key <-> resource.
      */
-    private final Hashtable resourceKeyMap = new Hashtable();
+    private final Hashtable<ApplicationResource, String> resourceKeyMap = new Hashtable<ApplicationResource, String>();
 
-    private final Hashtable keyResourceMap = new Hashtable();
+    private final Hashtable<String, ApplicationResource> keyResourceMap = new Hashtable<String, ApplicationResource>();
 
     private long lastResourceKeyNumber = 0;
 
@@ -190,12 +190,82 @@ public abstract class Application implements URIHandler,
     public String getPortletWindowId() {
         return portletWindowId;
     }
-    
+
     // TODO Document me!
     public void setPortletWindowId(String portletWindowId) {
         this.portletWindowId = portletWindowId;
     }
-    
+
+    // TODO Document me!
+    public static interface ResourceURLGenerator {
+
+        public String generateResourceURL(ApplicationResource resource,
+                String mapKey);
+
+        public boolean isResourceURL(URL context, String relativeUri);
+
+        public String getMapKey(URL context, String relativeUri);
+
+    }
+
+    /*
+     * Default resource URL generator for servlets
+     */
+    private static ResourceURLGenerator defaultResourceURLGenerator = new ResourceURLGenerator() {
+        public String generateResourceURL(ApplicationResource resource,
+                String mapKey) {
+
+            final String filename = resource.getFilename();
+            if (filename == null) {
+                return "APP/" + mapKey + "/";
+            } else {
+                return "APP/" + mapKey + "/" + filename;
+            }
+
+        }
+
+        public boolean isResourceURL(URL context, String relativeUri) {
+            // If the relative uri is null, we are ready
+            if (relativeUri == null) {
+                return false;
+            }
+
+            // Resolves the prefix
+            String prefix = relativeUri;
+            final int index = relativeUri.indexOf('/');
+            if (index >= 0) {
+                prefix = relativeUri.substring(0, index);
+            }
+
+            // Handles the resource requests
+            return (prefix.equals("APP"));
+        }
+
+        public String getMapKey(URL context, String relativeUri) {
+            final int index = relativeUri.indexOf('/');
+            final int next = relativeUri.indexOf('/', index + 1);
+            if (next < 0) {
+                return null;
+            }
+            return relativeUri.substring(index + 1, next);
+        };
+
+    };
+
+    private ResourceURLGenerator resourceURLGenerator = defaultResourceURLGenerator;
+
+    public ResourceURLGenerator getResourceURLGenerator() {
+        return resourceURLGenerator;
+    }
+
+    public void setResourceURLGenerator(
+            ResourceURLGenerator resourceURLGenerator) {
+        if (resourceURLGenerator == null)
+            this.resourceURLGenerator = defaultResourceURLGenerator;
+        else
+            this.resourceURLGenerator = resourceURLGenerator;
+    }
+
     /**
      * <p>
      * Gets a window by name. Returns <code>null</code> if the application is
@@ -516,7 +586,7 @@ public abstract class Application implements URIHandler,
      * 
      * @return the Unmodifiable collection of windows.
      */
-    public Collection getWindows() {
+    public Collection<Window> getWindows() {
         return Collections.unmodifiableCollection(windows.values());
     }
 
@@ -554,10 +624,10 @@ public abstract class Application implements URIHandler,
      */
     public void setTheme(String theme) {
         // Collect list of windows not having the current or future theme
-        final LinkedList toBeUpdated = new LinkedList();
+        final LinkedList<Window> toBeUpdated = new LinkedList<Window>();
         final String oldAppTheme = getTheme();
-        for (final Iterator i = getWindows().iterator(); i.hasNext();) {
-            final Window w = (Window) i.next();
+        for (final Iterator<Window> i = getWindows().iterator(); i.hasNext();) {
+            final Window w = i.next();
             final String windowTheme = w.getTheme();
             if ((windowTheme == null)
                     || (!windowTheme.equals(theme) && windowTheme
@@ -570,8 +640,8 @@ public abstract class Application implements URIHandler,
         this.theme = theme;
 
         // Ask windows to update themselves
-        for (final Iterator i = toBeUpdated.iterator(); i.hasNext();) {
-            ((Window) i.next()).requestRepaint();
+        for (final Iterator<Window> i = toBeUpdated.iterator(); i.hasNext();) {
+            i.next().requestRepaint();
         }
     }
 
@@ -610,7 +680,7 @@ public abstract class Application implements URIHandler,
      *         the keys in the default property list.
      * 
      */
-    public Enumeration getPropertyNames() {
+    public Enumeration<?> getPropertyNames() {
         return properties.propertyNames();
     }
 
@@ -682,12 +752,7 @@ public abstract class Application implements URIHandler,
             return null;
         }
 
-        final String filename = resource.getFilename();
-        if (filename == null) {
-            return "APP/" + key + "/";
-        } else {
-            return "APP/" + key + "/" + filename;
-        }
+        return resourceURLGenerator.generateResourceURL(resource, key);
     }
 
     /**
@@ -701,27 +766,11 @@ public abstract class Application implements URIHandler,
      */
     public DownloadStream handleURI(URL context, String relativeUri) {
 
-        // If the relative uri is null, we are ready
-        if (relativeUri == null) {
-            return null;
-        }
-
-        // Resolves the prefix
-        String prefix = relativeUri;
-        final int index = relativeUri.indexOf('/');
-        if (index >= 0) {
-            prefix = relativeUri.substring(0, index);
-        }
-
-        // Handles the resource requests
-        if (prefix.equals("APP")) {
+        if (resourceURLGenerator.isResourceURL(context, relativeUri)) {
 
             // Handles the resource request
-            final int next = relativeUri.indexOf('/', index + 1);
-            if (next < 0) {
-                return null;
-            }
-            final String key = relativeUri.substring(index + 1, next);
+            final String key = resourceURLGenerator.getMapKey(context,
+                    relativeUri);
             final ApplicationResource resource = (ApplicationResource) keyResourceMap
                     .get(key);
             if (resource != null) {
@@ -861,7 +910,7 @@ public abstract class Application implements URIHandler,
      */
     public void addListener(UserChangeListener listener) {
         if (userChangeListeners == null) {
-            userChangeListeners = new LinkedList();
+            userChangeListeners = new LinkedList<UserChangeListener>();
         }
         userChangeListeners.add(listener);
     }
@@ -992,7 +1041,7 @@ public abstract class Application implements URIHandler,
      */
     public void addListener(WindowAttachListener listener) {
         if (windowAttachListeners == null) {
-            windowAttachListeners = new LinkedList();
+            windowAttachListeners = new LinkedList<WindowAttachListener>();
         }
         windowAttachListeners.add(listener);
     }
@@ -1005,7 +1054,7 @@ public abstract class Application implements URIHandler,
      */
     public void addListener(WindowDetachListener listener) {
         if (windowDetachListeners == null) {
-            windowDetachListeners = new LinkedList();
+            windowDetachListeners = new LinkedList<WindowDetachListener>();
         }
         windowDetachListeners.add(listener);
     }
index 398b4d8414070eefff3f00851ed72647ca6879a8..c8ae4d108b0430de4a478d0280c54ef452616b2f 100644 (file)
@@ -10,6 +10,7 @@ import java.io.Serializable;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.MalformedURLException;
+import java.net.URL;
 import java.security.GeneralSecurityException;
 import java.util.Collection;
 import java.util.Date;
@@ -40,8 +41,9 @@ import javax.servlet.http.HttpServletResponse;
 import com.vaadin.Application;
 import com.vaadin.Application.SystemMessages;
 import com.vaadin.external.org.apache.commons.fileupload.portlet.PortletFileUpload;
+import com.vaadin.terminal.ApplicationResource;
+import com.vaadin.terminal.DownloadStream;
 import com.vaadin.terminal.Terminal;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.ui.Window;
 
 /**
@@ -58,14 +60,64 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
      * to try to integrate the common parts into a shared super class.
      */
 
-    // TODO Close application when portlet window is closed
+    // TODO Can we close the application when the portlet is removed? Do we know
+    // when the portlet is removed?
 
-    // TODO What happens when the portlet window is resized?
+    // TODO What happens when the portlet window is resized? Do we know when the
+    // window is resized?
 
     private Properties applicationProperties;
 
     private boolean productionMode = false;
 
+    private static class PortletResourceURLGenerator implements
+            Application.ResourceURLGenerator {
+
+        private final MimeResponse response;
+
+        public PortletResourceURLGenerator(MimeResponse response) {
+            this.response = response;
+        }
+
+        public boolean isResourceURL(URL context, String relativeUri) {
+            // If the relative uri is null, we are ready
+            if (relativeUri == null) {
+                return false;
+            }
+
+            // Resolves the prefix
+            String prefix = relativeUri;
+            final int index = relativeUri.indexOf('/');
+            if (index >= 0) {
+                prefix = relativeUri.substring(0, index);
+            }
+
+            // Handles the resource requests
+            return (prefix.equals("APP"));
+        }
+
+        public String getMapKey(URL context, String relativeUri) {
+            final int index = relativeUri.indexOf('/');
+            final int next = relativeUri.indexOf('/', index + 1);
+            if (next < 0) {
+                return null;
+            }
+            return relativeUri.substring(index + 1, next);
+        }
+
+        public String generateResourceURL(ApplicationResource resource,
+                String mapKey) {
+            ResourceURL resourceURL = response.createResourceURL();
+            final String filename = resource.getFilename();
+            if (filename == null) {
+                resourceURL.setResourceID("APP/" + mapKey + "/");
+            } else {
+                resourceURL.setResourceID("APP/" + mapKey + "/" + filename);
+            }
+            return resourceURL.toString();
+        }
+    };
+
     @SuppressWarnings("unchecked")
     @Override
     public void init(PortletConfig config) throws PortletException {
@@ -203,7 +255,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
     }
 
     enum RequestType {
-        FILE_UPLOAD, UIDL, RENDER, STATIC_FILE, UNKNOWN;
+        FILE_UPLOAD, UIDL, RENDER, STATIC_FILE, APPLICATION_RESOURCE, UNKNOWN;
     }
 
     protected RequestType getRequestType(PortletRequest request) {
@@ -212,7 +264,9 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         } else if (request instanceof ResourceRequest) {
             if (isUIDLRequest((ResourceRequest) request)) {
                 return RequestType.UIDL;
-            } else if (isStaticResourceRequest((ResourceRequest) request)) {
+            } else if (isApplicationResourceRequest((ResourceRequest) request)) {
+                return RequestType.APPLICATION_RESOURCE;
+            } else {
                 return RequestType.STATIC_FILE;
             }
         } else if (request instanceof ActionRequest) {
@@ -223,12 +277,9 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         return RequestType.UNKNOWN;
     }
 
-    private boolean isStaticResourceRequest(ResourceRequest request) {
-        String resourceID = request.getResourceID();
-        if (resourceID != null && !resourceID.startsWith("/VAADIN/")) {
-            return true;
-        }
-        return false;
+    private boolean isApplicationResourceRequest(ResourceRequest request) {
+        return request.getResourceID() != null
+                && request.getResourceID().startsWith("APP");
     }
 
     private boolean isUIDLRequest(ResourceRequest request) {
@@ -277,6 +328,11 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
             if (application == null) {
                 return;
             }
+            if (response instanceof MimeResponse) {
+                application
+                        .setResourceURLGenerator(new PortletResourceURLGenerator(
+                                (MimeResponse) response));
+            }
 
             /*
              * Get or create an application context and an application manager
@@ -309,39 +365,43 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
                 applicationManager.handleUidlRequest((ResourceRequest) request,
                         (ResourceResponse) response, this);
                 return;
-            } else if (requestType == RequestType.RENDER) {
-                /*
-                 * Removes the application if it has stopped
-                 */
-                if (!application.isRunning()) {
-                    endApplication(request, response, application);
-                    return;
-                }
+            }
 
-                /*
-                 * Always use the main window when running inside a portlet.
-                 */
-                Window window = application.getMainWindow();
-                if (window == null) {
-                    throw new PortletException(ERROR_NO_WINDOW_FOUND);
-                }
+            /*
+             * Removes the application if it has stopped
+             */
+            if (!application.isRunning()) {
+                endApplication(request, response, application);
+                return;
+            }
 
-                /*
-                 * Sets terminal type for the window, if not already set
-                 */
-                if (window.getTerminal() == null) {
-                    window.setTerminal(applicationContext.getBrowser());
-                }
+            /*
+             * Always use the main window when running inside a portlet.
+             */
+            Window window = application.getMainWindow();
+            if (window == null) {
+                throw new PortletException(ERROR_NO_WINDOW_FOUND);
+            }
 
-                /*
-                 * Handle parameters
-                 */
-                final Map<String, String[]> parameters = request
-                        .getParameterMap();
-                if (window != null && parameters != null) {
-                    window.handleParameters(parameters);
-                }
+            /*
+             * Sets terminal type for the window, if not already set
+             */
+            if (window.getTerminal() == null) {
+                window.setTerminal(applicationContext.getBrowser());
+            }
+
+            /*
+             * Handle parameters
+             */
+            final Map<String, String[]> parameters = request.getParameterMap();
+            if (window != null && parameters != null) {
+                window.handleParameters(parameters);
+            }
 
+            if (requestType == RequestType.APPLICATION_RESOURCE) {
+                handleURI(applicationManager, window,
+                        (ResourceRequest) request, (ResourceResponse) response);
+            } else if (requestType == RequestType.RENDER) {
                 /*
                  * Send initial AJAX page that kickstarts the Vaadin application
                  */
@@ -349,10 +409,16 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
                         (RenderResponse) response, window, application);
             }
         } catch (final SessionExpired e) {
-            // Session has expired, notify user
-            handleServiceSessionExpired(request, response);
+            // TODO Figure out a better way to deal with SessionExpired
+            // -exceptions
+            System.err.println("Session has expired");
+            e.printStackTrace(System.err);
         } catch (final GeneralSecurityException e) {
-            handleServiceSecurityException(request, response);
+            // TODO Figure out a better way to deal with
+            // GeneralSecurityExceptions
+            System.err
+                    .println("General security exception, should never happen");
+            e.printStackTrace(System.err);
         } catch (final Throwable e) {
             handleServiceException(request, response, application, e);
         } finally {
@@ -364,6 +430,95 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         }
     }
 
+    private boolean handleURI(PortletCommunicationManager applicationManager,
+            Window window, ResourceRequest request, ResourceResponse response)
+            throws IOException {
+        // Handles the URI
+        DownloadStream download = applicationManager.handleURI(window, request,
+                response, this);
+
+        // A download request
+        if (download != null) {
+            // Client downloads an resource
+            handleDownload(download, request, response);
+            return true;
+        }
+
+        return false;
+    }
+
+    @SuppressWarnings("unchecked")
+    private void handleDownload(DownloadStream stream, ResourceRequest request,
+            ResourceResponse response) throws IOException {
+
+        if (stream.getParameter("Location") != null) {
+            response.setProperty(ResourceResponse.HTTP_STATUS_CODE, Integer
+                    .toString(HttpServletResponse.SC_MOVED_TEMPORARILY));
+            response.setProperty("Location", stream.getParameter("Location"));
+            return;
+        }
+
+        // Download from given stream
+        final InputStream data = stream.getStream();
+        if (data != null) {
+
+            // Sets content type
+            response.setContentType(stream.getContentType());
+
+            // Sets cache headers
+            final long cacheTime = stream.getCacheTime();
+            if (cacheTime <= 0) {
+                response.setProperty("Cache-Control", "no-cache");
+                response.setProperty("Pragma", "no-cache");
+                response.setProperty("Expires", "0");
+            } else {
+                response.setProperty("Cache-Control", "max-age=" + cacheTime
+                        / 1000);
+                response.setProperty("Expires", "" + System.currentTimeMillis()
+                        + cacheTime);
+                response.setProperty("Pragma", "cache"); // Required to apply
+                // caching in some
+                // Tomcats
+            }
+
+            // Copy download stream parameters directly
+            // to HTTP headers.
+            final Iterator i = stream.getParameterNames();
+            if (i != null) {
+                while (i.hasNext()) {
+                    final String param = (String) i.next();
+                    response.setProperty(param, stream.getParameter(param));
+                }
+            }
+
+            // suggest local filename from DownloadStream if Content-Disposition
+            // not explicitly set
+            String contentDispositionValue = stream
+                    .getParameter("Content-Disposition");
+            if (contentDispositionValue == null) {
+                contentDispositionValue = "filename=\"" + stream.getFileName()
+                        + "\"";
+                response.setProperty("Content-Disposition",
+                        contentDispositionValue);
+            }
+
+            int bufferSize = stream.getBufferSize();
+            if (bufferSize <= 0 || bufferSize > MAX_BUFFER_SIZE) {
+                bufferSize = DEFAULT_BUFFER_SIZE;
+            }
+            final byte[] buffer = new byte[bufferSize];
+            int bytesRead = 0;
+
+            final OutputStream out = response.getPortletOutputStream();
+
+            while ((bytesRead = data.read(buffer)) > 0) {
+                out.write(buffer, 0, bytesRead);
+                out.flush();
+            }
+            out.close();
+        }
+    }
+
     private void serveStaticResources(ResourceRequest request,
             ResourceResponse response) throws IOException, PortletException {
         final String resourceID = request.getResourceID();
@@ -582,9 +737,10 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         } else {
             widgetset = sharedWidgetset;
         }
-        
-        // TODO Currently, we can only load widgetsets and themes from the portal
-        
+
+        // TODO Currently, we can only load widgetsets and themes from the
+        // portal
+
         String themeName = getThemeForWindow(request, window);
 
         String widgetsetURL = getWidgetsetURL(widgetset);
@@ -652,7 +808,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         page.write("};\n</script>\n");
 
         page.write("<script type=\"text/javascript\">\n");
-        page.write("//<![CDATA[\n");
+        // page.write("//<![CDATA[\n");
         page.write("if(!vaadin.themesLoaded['" + themeName + "']) {\n");
         page.write("var stylesheet = document.createElement('link');\n");
         page.write("stylesheet.setAttribute('rel', 'stylesheet');\n");
@@ -662,7 +818,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         page
                 .write("document.getElementsByTagName('head')[0].appendChild(stylesheet);\n");
         page.write("vaadin.themesLoaded['" + themeName + "'] = true;\n}\n");
-        page.write("//]]>\n</script>\n");
+        page.write("</script>\n");
 
         // TODO Warn if widgetset has not been loaded after 15 seconds
 
@@ -746,10 +902,6 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         return getClass().getClassLoader();
     }
 
-    private boolean isOnUnloadRequest(PortletRequest request) {
-        return request.getParameter(ApplicationConnection.PARAM_UNLOADBURST) != null;
-    }
-
     /**
      * Get system messages from the current application class
      * 
@@ -781,89 +933,12 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
         return Application.getSystemMessages();
     }
 
-    void handleServiceSessionExpired(PortletRequest request,
-            PortletResponse response) throws IOException, PortletException {
-
-        if (isOnUnloadRequest(request)) {
-            /*
-             * Request was an unload request (e.g. window close event) and the
-             * client expects no response if it fails.
-             */
-            return;
-        }
-
-        try {
-            Application.SystemMessages ci = getSystemMessages();
-            if (getRequestType(request) != RequestType.UIDL) {
-                // 'plain' http req - e.g. browser reload;
-                // just go ahead redirect the browser
-                if (response instanceof ActionResponse) {
-                    ((ActionResponse) response).sendRedirect(ci
-                            .getSessionExpiredURL());
-                } else {
-                    // TODO What to do if we are e.g. rendering?
-                }
-            } else {
-                /*
-                 * Session must be invalidated before criticalNotification as it
-                 * commits the response.
-                 */
-                request.getPortletSession().invalidate();
-
-                // send uidl redirect
-                criticalNotification(request, (ResourceResponse) response, ci
-                        .getSessionExpiredCaption(), ci
-                        .getSessionExpiredMessage(), null, ci
-                        .getSessionExpiredURL());
-
-            }
-        } catch (SystemMessageException ee) {
-            throw new PortletException(ee);
-        }
-
-    }
-
-    private void handleServiceSecurityException(PortletRequest request,
-            PortletResponse response) throws IOException, PortletException {
-        if (isOnUnloadRequest(request)) {
-            /*
-             * Request was an unload request (e.g. window close event) and the
-             * client expects no response if it fails.
-             */
-            return;
-        }
-
-        try {
-            Application.SystemMessages ci = getSystemMessages();
-            if (getRequestType(request) != RequestType.UIDL) {
-                // 'plain' http req - e.g. browser reload;
-                // just go ahead redirect the browser
-                if (response instanceof ActionResponse) {
-                    ((ActionResponse) response).sendRedirect(ci
-                            .getCommunicationErrorURL());
-                } else {
-                    // TODO What to do if we are e.g. rendering?
-                }
-            } else {
-                // send uidl redirect
-                criticalNotification(request, (ResourceResponse) response, ci
-                        .getCommunicationErrorCaption(), ci
-                        .getCommunicationErrorMessage(),
-                        INVALID_SECURITY_KEY_MSG, ci.getCommunicationErrorURL());
-                /*
-                 * Invalidate session. Portal integration will fail otherwise
-                 * since the session is not created by the portal.
-                 */
-                request.getPortletSession().invalidate();
-            }
-        } catch (SystemMessageException ee) {
-            throw new PortletException(ee);
-        }
-    }
-
     private void handleServiceException(PortletRequest request,
             PortletResponse response, Application application, Throwable e)
             throws IOException, PortletException {
+        // TODO Check that this error handler is working when running inside a
+        // portlet
+
         // if this was an UIDL request, response UIDL back to client
         if (getRequestType(request) == RequestType.UIDL) {
             Application.SystemMessages ci = getSystemMessages();
index 71fa1eff2e3bffe62dce758301e50e5466738e66..756ea8fc8ec6ad2f29a9f64953d62bd560d4ebe0 100644 (file)
@@ -1616,9 +1616,6 @@ public abstract class AbstractCommunicationManager implements
     protected DownloadStream handleURI(Window window, Request request,
             Response response, Callback callback) {
 
-        // FIXME Check what to do when running as a portlet that does not have
-        // URIs
-
         String uri = callback.getRequestPathInfo(request);
 
         // If no URI is available
index f4e0853fe2b3629fa7c1ad1cc70edb5d9f6b6110..c5a09dc4e6ae3c12f5b7340a486b0a77e1ceb7d2 100644 (file)
@@ -19,6 +19,8 @@ import com.vaadin.external.org.apache.commons.fileupload.FileItemIterator;
 import com.vaadin.external.org.apache.commons.fileupload.FileUpload;
 import com.vaadin.external.org.apache.commons.fileupload.FileUploadException;
 import com.vaadin.external.org.apache.commons.fileupload.portlet.PortletFileUpload;
+import com.vaadin.terminal.DownloadStream;
+import com.vaadin.ui.Window;
 
 /**
  * TODO document me!
@@ -144,9 +146,14 @@ public class PortletCommunicationManager extends AbstractCommunicationManager {
         }
 
         public String getRequestPathInfo(Request request) {
-            // We do not use paths in portlet mode
-            throw new UnsupportedOperationException(
-                    "PathInfo not available when running in Portlet mode");
+            if (request.getWrappedRequest() instanceof ResourceRequest) {
+                return ((ResourceRequest) request.getWrappedRequest())
+                        .getResourceID();
+            } else {
+                // We do not use paths in portlet mode
+                throw new UnsupportedOperationException(
+                        "PathInfo only available when using ResourceRequests");
+            }
         }
 
         public InputStream getThemeResourceAsStream(String themeName,
@@ -189,4 +196,12 @@ public class PortletCommunicationManager extends AbstractCommunicationManager {
                 new AbstractApplicationPortletWrapper(applicationPortlet));
     }
 
+    DownloadStream handleURI(Window window, ResourceRequest request,
+            ResourceResponse response,
+            AbstractApplicationPortlet applicationPortlet) {
+        return handleURI(window, new PortletRequestWrapper(request),
+                new PortletResponseWrapper(response),
+                new AbstractApplicationPortletWrapper(applicationPortlet));
+    }
+
 }