From ae89a704f20c11fbfdab8eea0457dfa6ea98ae7d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Petter=20Holmstr=C3=B6m?= Date: Tue, 3 Nov 2009 07:39:24 +0000 Subject: [PATCH] The current implementation is able to run the Hello World example inside a portlet. Still lots of issues to iron out, though. svn changeset:9591/svn branch:portlet_2.0 --- .../server/AbstractApplicationPortlet.java | 316 ++++++++++++----- .../gwt/server/CommunicationManager.java | 320 +++++++++++++++--- .../vaadin/terminal/gwt/server/Constants.java | 26 -- .../server/PortletApplicationContext2.java | 9 +- .../server/PortletCommunicationManager.java | 24 -- .../PortletCommunicationManagerImpl.java | 35 -- 6 files changed, 511 insertions(+), 219 deletions(-) delete mode 100644 src/com/vaadin/terminal/gwt/server/Constants.java delete mode 100644 src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java delete mode 100644 src/com/vaadin/terminal/gwt/server/PortletCommunicationManagerImpl.java diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index ac04468975..5fbd45a9f9 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -2,38 +2,89 @@ package com.vaadin.terminal.gwt.server; import java.io.BufferedWriter; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.MalformedURLException; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Locale; import java.util.Map; +import java.util.Properties; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; -import javax.portlet.Portlet; +import javax.portlet.GenericPortlet; import javax.portlet.PortletConfig; +import javax.portlet.PortletContext; import javax.portlet.PortletException; import javax.portlet.PortletRequest; import javax.portlet.PortletResponse; import javax.portlet.PortletSession; +import javax.portlet.RenderMode; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import javax.portlet.ResourceRequest; import javax.portlet.ResourceResponse; -import javax.portlet.ResourceServingPortlet; import javax.portlet.ResourceURL; +import javax.servlet.http.HttpServletResponse; import com.vaadin.Application; import com.vaadin.external.org.apache.commons.fileupload.portlet.PortletFileUpload; import com.vaadin.ui.Window; -public abstract class AbstractApplicationPortlet implements Portlet, - ResourceServingPortlet { +public abstract class AbstractApplicationPortlet extends GenericPortlet { + public static final String ERROR_NO_WINDOW_FOUND = "No window found. Did you remember to setMainWindow()?"; + + public static final String THEME_DIRECTORY_PATH = "VAADIN/themes/"; + + public static final String WIDGETSET_DIRECTORY_PATH = "VAADIN/widgetsets/"; + + public static final String DEFAULT_WIDGETSET = "com.vaadin.terminal.gwt.DefaultWidgetSet"; + + public static final String URL_PARAMETER_REPAINT_ALL = "repaintAll"; + + public static final String URL_PARAMETER_RESTART_APPLICATION = "restartApplication"; + + public static final String URL_PARAMETER_CLOSE_APPLICATION = "closeApplication"; + + public static final int DEFAULT_BUFFER_SIZE = 32 * 1024; + + // TODO Close application when portlet window is closed + + private Properties applicationProperties; + + @Override public void destroy() { // TODO Auto-generated method stub } + @SuppressWarnings("unchecked") + @Override public void init(PortletConfig config) throws PortletException { - // TODO Auto-generated method stub + super.init(config); + // Stores the application parameters into Properties object + applicationProperties = new Properties(); + for (final Enumeration e = config.getInitParameterNames(); e + .hasMoreElements();) { + final String name = (String) e.nextElement(); + applicationProperties.setProperty(name, config + .getInitParameter(name)); + } + + // Overrides with server.xml parameters + final PortletContext context = config.getPortletContext(); + for (final Enumeration e = context.getInitParameterNames(); e + .hasMoreElements();) { + final String name = (String) e.nextElement(); + applicationProperties.setProperty(name, context + .getInitParameter(name)); + } + // TODO Check production mode + // TODO Check cross site protection } enum RequestType { @@ -44,13 +95,13 @@ public abstract class AbstractApplicationPortlet implements Portlet, if (request instanceof RenderRequest) { return RequestType.RENDER; } else if (request instanceof ResourceRequest) { - if (isStaticResourceRequest((ResourceRequest) request)) { + if (isUIDLRequest((ResourceRequest) request)) { + return RequestType.UIDL; + } else if (isStaticResourceRequest((ResourceRequest) request)) { return RequestType.STATIC_FILE; } } else if (request instanceof ActionRequest) { - if (isUIDLRequest((ActionRequest) request)) { - return RequestType.UIDL; - } else if (isFileUploadRequest((ActionRequest) request)) { + if (isFileUploadRequest((ActionRequest) request)) { return RequestType.FILE_UPLOAD; } } @@ -65,8 +116,8 @@ public abstract class AbstractApplicationPortlet implements Portlet, return false; } - private boolean isUIDLRequest(ActionRequest request) { - return request.getParameter("UIDL") != null; + private boolean isUIDLRequest(ResourceRequest request) { + return request.getResourceID().equals("UIDL"); } private boolean isFileUploadRequest(ActionRequest request) { @@ -79,6 +130,9 @@ public abstract class AbstractApplicationPortlet implements Portlet, RequestType requestType = getRequestType(request); + System.out.println(" RequestType: " + requestType); + System.out.println(" WindowID: " + request.getWindowID()); + if (requestType == RequestType.UNKNOWN) { System.out.println("Unknown request type"); return; @@ -103,14 +157,14 @@ public abstract class AbstractApplicationPortlet implements Portlet, */ PortletApplicationContext2 applicationContext = PortletApplicationContext2 .getApplicationContext(request.getPortletSession()); - PortletCommunicationManager applicationManager = applicationContext + CommunicationManager applicationManager = applicationContext .getApplicationManager(application); /* Update browser information from request */ applicationContext.getBrowser().updateBrowserProperties(request); /* Start the newly created application */ - startApplication(request, application, applicationManager); + startApplication(request, application, applicationContext); /* * Transaction starts. Call transaction listeners. Transaction end @@ -120,11 +174,13 @@ public abstract class AbstractApplicationPortlet implements Portlet, /* Handle the request */ if (requestType == RequestType.FILE_UPLOAD) { - applicationManager.handleFileUpload((ActionRequest) request, (ActionResponse) response); + applicationManager.handleFileUpload((ActionRequest) request, + (ActionResponse) response); return; } else if (requestType == RequestType.UIDL) { // Handles AJAX UIDL requests - applicationManager.handleUIDLRequest((ActionRequest) request, (ActionResponse) response); + applicationManager.handleUidlRequest((ResourceRequest) request, + (ResourceResponse) response); return; } else if (requestType == RequestType.RENDER) { /* @@ -136,12 +192,11 @@ public abstract class AbstractApplicationPortlet implements Portlet, } /* - * Finds the window within the application + * Always use the main window when running inside a portlet. */ - Window window = getApplicationWindow(request, - applicationManager, application); + Window window = application.getMainWindow(); if (window == null) { - throw new PortletException(Constants.ERROR_NO_WINDOW_FOUND); + throw new PortletException(ERROR_NO_WINDOW_FOUND); } /* @@ -178,38 +233,64 @@ public abstract class AbstractApplicationPortlet implements Portlet, } } + // TODO Vaadin resources cannot be loaded, try to load other resources using the portlet context + @Deprecated private void serveStaticResources(ResourceRequest request, - ResourceResponse response) { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); + ResourceResponse response) throws IOException, PortletException { + // Currently, we can only provide VAADIN content + final String resourceID = request.getResourceID(); + if (resourceID.startsWith("/VAADIN/")) { + // Strip leading "/" + // final String filename = resourceID.substri + final PortletContext pc = getPortletContext(); + + System.out.println("Trying to load resource [" + resourceID + "]"); + + InputStream is = pc.getResourceAsStream(resourceID); + if (is != null) { + final String mimetype = pc.getMimeType(resourceID); + if (mimetype != null) { + response.setContentType(mimetype); + } + final OutputStream os = response.getPortletOutputStream(); + final byte buffer[] = new byte[DEFAULT_BUFFER_SIZE]; + int bytes; + while ((bytes = is.read(buffer)) >= 0) { + os.write(buffer, 0, bytes); + } + return; + } + } + + System.err.println("Requested resource [" + resourceID + + "] could not be found"); + response.setProperty(ResourceResponse.HTTP_STATUS_CODE, Integer + .toString(HttpServletResponse.SC_NOT_FOUND)); } + @Override public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException { System.out.println("AbstractApplicationPortlet.processAction()"); handleRequest(request, response); } - public void render(RenderRequest request, RenderResponse response) + @RenderMode(name = "VIEW") + public void doRender(RenderRequest request, RenderResponse response) throws PortletException, IOException { System.out.println("AbstractApplicationPortlet.render()"); handleRequest(request, response); } + @Override public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException { System.out.println("AbstractApplicationPortlet.serveResource()"); handleRequest(request, response); } - private Window getApplicationWindow(PortletRequest request, - PortletCommunicationManager applicationManager, - Application application) throws PortletException { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); - } - - boolean requestCanCreateApplication(PortletRequest request, RequestType requestType) { + boolean requestCanCreateApplication(PortletRequest request, + RequestType requestType) { if (requestType == RequestType.UIDL && isRepaintAll(request)) { return true; } else if (requestType == RequestType.RENDER) { @@ -217,46 +298,56 @@ public abstract class AbstractApplicationPortlet implements Portlet, } return false; } - + private boolean isRepaintAll(PortletRequest request) { - return (request.getParameter(Constants.URL_PARAMETER_REPAINT_ALL) != null) - && (request.getParameter(Constants.URL_PARAMETER_REPAINT_ALL).equals("1")); + return (request.getParameter(URL_PARAMETER_REPAINT_ALL) != null) + && (request.getParameter(URL_PARAMETER_REPAINT_ALL).equals("1")); } private void startApplication(PortletRequest request, - Application application, - PortletCommunicationManager applicationManager) + Application application, PortletApplicationContext2 context) throws PortletException, MalformedURLException { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); + if (!application.isRunning()) { + Locale locale = request.getLocale(); + application.setLocale(locale); + // No application URL when running inside a portlet + application.start(null, applicationProperties, context); + } } private void endApplication(PortletRequest request, PortletResponse response, Application application) throws IOException { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); + final PortletSession session = request.getPortletSession(); + if (session != null) { + PortletApplicationContext2.getApplicationContext(session) + .removeApplication(application); + } + // Do not send any redirects when running inside a portlet. } - private Application findApplicationInstance(PortletRequest request, RequestType requestType) - throws PortletException, SessionExpired, MalformedURLException { - - boolean requestCanCreateApplication = requestCanCreateApplication(request, requestType); - + private Application findApplicationInstance(PortletRequest request, + RequestType requestType) throws PortletException, SessionExpired, + MalformedURLException { + + boolean requestCanCreateApplication = requestCanCreateApplication( + request, requestType); + /* Find an existing application for this request. */ - Application application = getExistingApplication(request, requestCanCreateApplication); - + Application application = getExistingApplication(request, + requestCanCreateApplication); + if (application != null) { /* * There is an existing application. We can use this as long as the * user not specifically requested to close or restart it. */ - + final boolean restartApplication = (request - .getParameter(Constants.URL_PARAMETER_RESTART_APPLICATION) != null); + .getParameter(URL_PARAMETER_RESTART_APPLICATION) != null); final boolean closeApplication = (request - .getParameter(Constants.URL_PARAMETER_CLOSE_APPLICATION) != null); - + .getParameter(URL_PARAMETER_CLOSE_APPLICATION) != null); + if (restartApplication) { closeApplication(application, request.getPortletSession(false)); return createApplication(request); @@ -267,48 +358,88 @@ public abstract class AbstractApplicationPortlet implements Portlet, return application; } } - + // No existing application was found - + if (requestCanCreateApplication) { return createApplication(request); } else { throw new SessionExpired(); } } - - private void closeApplication(Application application, PortletSession session) { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); + + private void closeApplication(Application application, + PortletSession session) { + if (application == null) { + return; + } + + application.close(); + if (session != null) { + PortletApplicationContext2 context = PortletApplicationContext2 + .getApplicationContext(session); + context.applicationToAjaxAppMgrMap.remove(application); + context.removeApplication(application); + } } - + private Application createApplication(PortletRequest request) - throws PortletException, MalformedURLException { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); + throws PortletException, MalformedURLException { + Application newApplication = getNewApplication(request); + newApplication.setPortletWindowId(request.getWindowID()); + final PortletApplicationContext2 context = PortletApplicationContext2 + .getApplicationContext(request.getPortletSession()); + context.addApplication(newApplication); + return newApplication; } private Application getExistingApplication(PortletRequest request, boolean allowSessionCreation) throws MalformedURLException, SessionExpired { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); + + final PortletSession session = request + .getPortletSession(allowSessionCreation); + if (session == null) { + throw new SessionExpired(); + } + + PortletApplicationContext2 context = PortletApplicationContext2 + .getApplicationContext(session); + + final Collection applications = context.getApplications(); + for (final Iterator i = applications.iterator(); i + .hasNext();) { + final Application sessionApplication = i.next(); + if (request.getWindowID().equals( + sessionApplication.getPortletWindowId())) { + if (sessionApplication.isRunning()) { + return sessionApplication; + } + PortletApplicationContext2.getApplicationContext(session) + .removeApplication(sessionApplication); + break; + } + } + + return null; } - + protected void writeAjaxPage(RenderRequest request, RenderResponse response, Window window, Application application) throws IOException, MalformedURLException, PortletException { - + System.out.println("AbstractApplicationPortlet.writeAjaxPage()"); - + response.setContentType("text/html"); final BufferedWriter page = new BufferedWriter(new OutputStreamWriter( response.getPortletOutputStream(), "UTF-8")); + ; - // TODO Figure out the format of resource URLs - ResourceURL widgetsetURL = response.createResourceURL(); - // TODO Add support for custom widgetsets. - widgetsetURL.setResourceID(Constants.DEFAULT_WIDGETSET); + // TODO Make the widgetset URL creation more configurable + + String widgetsetURL = "/html/VAADIN/widgetsets/" + DEFAULT_WIDGETSET + + "/" + DEFAULT_WIDGETSET + ".nocache.js?" + + new Date().getTime(); page.write("\n"); // TODO Add custom theme // TODO Warn if widgetset has not been loaded after 15 seconds + + /*- Add classnames; + * .v-app + * .v-app-loading + * .v-app- + * .v-theme- + */ + + String appClass = "v-app-"; + try { + appClass += getApplicationClass().getSimpleName(); + } catch (ClassNotFoundException e) { + appClass += "unknown"; + e.printStackTrace(); + } + // TODO Add support for flexible theme names + String themeClass = "v-theme-" + + "reindeer".replaceAll("[^a-zA-Z0-9]", ""); + + String classNames = "v-app v-app-loading " + themeClass + " " + + appClass; + + page.write("
\n"); + page.close(); } diff --git a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java index 4238aab019..07bbac7922 100644 --- a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java @@ -35,9 +35,12 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import javax.portlet.ActionRequest; +import javax.portlet.ActionResponse; +import javax.portlet.PortletException; +import javax.portlet.ResourceRequest; +import javax.portlet.ResourceResponse; import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -123,12 +126,42 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, private int timeoutInterval = -1; + /** + * @deprecated use {@link #CommunicationManager(Application)} instead + * @param application + * @param applicationServlet + */ + @Deprecated public CommunicationManager(Application application, AbstractApplicationServlet applicationServlet) { this.application = application; requireLocale(application.getLocale().toString()); } + /** + * TODO New constructor - document me! + * + * @param application + */ + public CommunicationManager(Application application) { + this.application = application; + requireLocale(application.getLocale().toString()); + } + + /** + * TODO New method - document me! + * + * @param reuqest + * @param response + * @throws IOException + * @throws FileUploadException + */ + public void handleFileUpload(ActionRequest reuqest, ActionResponse response) + throws IOException, FileUploadException { + // FIXME Implement me! + throw new UnsupportedOperationException("Not implemented!"); + } + /** * Handles file upload request submitted via Upload component. * @@ -232,6 +265,25 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, out.close(); } + /** + * TODO New method - document me! + * + * @param request + * @param response + * @throws IOException + * @throws PortletException + * @throws InvalidUIDLSecurityKeyException + */ + public void handleUidlRequest(ResourceRequest request, + ResourceResponse response) throws IOException, PortletException, + InvalidUIDLSecurityKeyException { + try { + doHandleUidlRequest(request, response, null); + } catch (ServletException e) { + throw new PortletException(e.getMessage(), e.getCause()); + } + } + /** * Handles UIDL request * @@ -244,17 +296,42 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, HttpServletResponse response, AbstractApplicationServlet applicationServlet) throws IOException, ServletException, InvalidUIDLSecurityKeyException { + doHandleUidlRequest(request, response, applicationServlet); + } + + private void doHandleUidlRequest(Object request, Object response, + AbstractApplicationServlet applicationServlet) throws IOException, + ServletException, InvalidUIDLSecurityKeyException { // repaint requested or session has timed out and new one is created - boolean repaintAll = (request.getParameter(GET_PARAM_REPAINT_ALL) != null) - || request.getSession().isNew(); + boolean repaintAll; + final OutputStream out; + + if (request instanceof ResourceRequest) { + repaintAll = (((ResourceRequest) request) + .getParameter(GET_PARAM_REPAINT_ALL) != null) + || ((ResourceRequest) request).getPortletSession().isNew(); + // Assume the response is a ResourceResponse + out = ((ResourceResponse) response).getPortletOutputStream(); + } else { + repaintAll = (((HttpServletRequest) request) + .getParameter(GET_PARAM_REPAINT_ALL) != null) + || ((HttpServletRequest) request).getSession().isNew(); + // Assume the response is a HttpServletResponse + out = ((HttpServletResponse) response).getOutputStream(); + } boolean analyzeLayouts = false; if (repaintAll) { // analyzing can be done only with repaintAll - analyzeLayouts = (request.getParameter(GET_PARAM_ANALYZE_LAYOUTS) != null); + if (request instanceof ResourceRequest) { + analyzeLayouts = (((ResourceRequest) request) + .getParameter(GET_PARAM_ANALYZE_LAYOUTS) != null); + } else { + analyzeLayouts = (((HttpServletRequest) request) + .getParameter(GET_PARAM_ANALYZE_LAYOUTS) != null); + } } - final OutputStream out = response.getOutputStream(); final PrintWriter outWriter = new PrintWriter(new BufferedWriter( new OutputStreamWriter(out, "UTF-8"))); @@ -266,15 +343,23 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, // Finds the window within the application Window window = null; if (application.isRunning()) { - window = getApplicationWindow(request, applicationServlet, + window = doGetApplicationWindow(request, applicationServlet, application, null); // Returns if no window found if (window == null) { // This should not happen, no windows exists but // application is still open. - System.err - .println("Warning, could not get window for application with request URI " - + request.getRequestURI()); + if (request instanceof ResourceRequest) { + System.err + .println("Warning, could not get window for application with resource ID " + + ((ResourceRequest) request) + .getResourceID()); + } else { + System.err + .println("Warning, could not get window for application with request URI " + + ((HttpServletRequest) request) + .getRequestURI()); + } return; } } else { @@ -304,8 +389,13 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, String msg = ci.getOutOfSyncMessage(); String cap = ci.getOutOfSyncCaption(); if (msg != null || cap != null) { - applicationServlet.criticalNotification(request, - response, cap, msg, null, ci.getOutOfSyncURL()); + if (request instanceof HttpServletRequest) { + applicationServlet.criticalNotification( + (HttpServletRequest) request, + (HttpServletResponse) response, cap, msg, + null, ci.getOutOfSyncURL()); + } + // FIXME What about Portlets? // will reload page after this return; } @@ -328,8 +418,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, out.close(); } - private void paintAfterVariablechanges(HttpServletRequest request, - HttpServletResponse response, + private void paintAfterVariablechanges(Object request, Object response, AbstractApplicationServlet applicationServlet, boolean repaintAll, final PrintWriter outWriter, Window window, boolean analyzeLayouts) throws IOException, ServletException, PaintException { @@ -359,18 +448,50 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, } // Sets the response type - response.setContentType("application/json; charset=UTF-8"); + if (response instanceof ResourceResponse) { + ((ResourceResponse) response) + .setContentType("application/json; charset=UTF-8"); + } else { + ((HttpServletResponse) response) + .setContentType("application/json; charset=UTF-8"); + } // some dirt to prevent cross site scripting outWriter.print("for(;;);[{"); // security key - if (request.getAttribute(WRITE_SECURITY_TOKEN_FLAG) != null) { - String seckey = (String) request.getSession().getAttribute( - ApplicationConnection.UIDL_SECURITY_TOKEN_ID); + Object writeSecurityTokenFlag; + if (request instanceof ResourceRequest) { + writeSecurityTokenFlag = ((ResourceRequest) request) + .getAttribute(WRITE_SECURITY_TOKEN_FLAG); + } else { + writeSecurityTokenFlag = ((HttpServletRequest) request) + .getAttribute(WRITE_SECURITY_TOKEN_FLAG); + } + + if (writeSecurityTokenFlag != null) { + String seckey; + if (request instanceof ResourceRequest) { + seckey = (String) ((ResourceRequest) request) + .getPortletSession().getAttribute( + ApplicationConnection.UIDL_SECURITY_TOKEN_ID); + } else { + seckey = (String) ((HttpServletRequest) request).getSession() + .getAttribute( + ApplicationConnection.UIDL_SECURITY_TOKEN_ID); + } if (seckey == null) { seckey = "" + (int) (Math.random() * 1000000); - request.getSession().setAttribute( - ApplicationConnection.UIDL_SECURITY_TOKEN_ID, seckey); + if (request instanceof ResourceRequest) { + ((ResourceRequest) request) + .getPortletSession() + .setAttribute( + ApplicationConnection.UIDL_SECURITY_TOKEN_ID, + seckey); + } else { + ((HttpServletRequest) request).getSession().setAttribute( + ApplicationConnection.UIDL_SECURITY_TOKEN_ID, + seckey); + } } outWriter.print("\"" + ApplicationConnection.UIDL_SECURITY_TOKEN_ID + "\":\""); @@ -389,7 +510,7 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, List invalidComponentRelativeSizes = null; // re-get window - may have been changed - Window newWindow = getApplicationWindow(request, + Window newWindow = doGetApplicationWindow(request, applicationServlet, application, window); if (newWindow != window) { window = newWindow; @@ -561,8 +682,14 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, if (ci != null && ci.getSessionExpiredMessage() == null && ci.getSessionExpiredCaption() == null && ci.isSessionExpiredNotificationEnabled()) { - int newTimeoutInterval = request.getSession() - .getMaxInactiveInterval(); + int newTimeoutInterval; + if (request instanceof ResourceRequest) { + newTimeoutInterval = ((ResourceRequest) request) + .getPortletSession().getMaxInactiveInterval(); + } else { + newTimeoutInterval = ((HttpServletRequest) request) + .getSession().getMaxInactiveInterval(); + } if (repaintAll || (timeoutInterval != newTimeoutInterval)) { String escapedURL = ci.getSessionExpiredURL() == null ? "" : ci.getSessionExpiredURL().replace("/", "\\/"); @@ -581,8 +708,16 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, // Precache custom layouts String themeName = window.getTheme(); - if (request.getParameter("theme") != null) { - themeName = request.getParameter("theme"); + String requestThemeName; + if (request instanceof ResourceRequest) { + requestThemeName = ((ResourceRequest) request) + .getParameter("theme"); + } else { + requestThemeName = ((HttpServletRequest) request) + .getParameter("theme"); + } + if (requestThemeName != null) { + themeName = requestThemeName; } if (themeName == null) { themeName = AbstractApplicationServlet.getDefaultTheme(); @@ -623,9 +758,17 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, r.close(); } catch (final java.io.IOException e) { // FIXME: Handle exception - System.err.println("Resource transfer failed: " - + request.getRequestURI() + ". (" - + e.getMessage() + ")"); + if (request instanceof ResourceRequest) { + System.err.println("Resource transfer failed: " + + ((ResourceRequest) request) + .getResourceID() + ". (" + + e.getMessage() + ")"); + } else { + System.err.println("Resource transfer failed: " + + ((HttpServletRequest) request) + .getRequestURI() + ". (" + + e.getMessage() + ")"); + } } outWriter.print("\"" + JsonPaintTarget.escapeJSON(layout.toString()) @@ -682,14 +825,19 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, * @return true if successful, false if there was an inconsistency * @throws IOException */ - private boolean handleVariables(HttpServletRequest request, - HttpServletResponse response, + private boolean handleVariables(Object request, Object response, AbstractApplicationServlet applicationServlet, Application application2, Window window) throws IOException, InvalidUIDLSecurityKeyException { boolean success = true; + int contentLength; + if (request instanceof ResourceRequest) { + contentLength = ((ResourceRequest) request).getContentLength(); + } else { + contentLength = ((HttpServletRequest) request).getContentLength(); + } - if (request.getContentLength() > 0) { + if (contentLength > 0) { String changes = readRequest(request); // Manage bursts one by one @@ -703,13 +851,29 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, if (bursts.length == 1 && "init".equals(bursts[0])) { // init request; don't handle any variables, key sent in // response. - request.setAttribute(WRITE_SECURITY_TOKEN_FLAG, true); + if (request instanceof ResourceRequest) { + ((ResourceRequest) request).setAttribute( + WRITE_SECURITY_TOKEN_FLAG, true); + } else { + ((HttpServletRequest) request).setAttribute( + WRITE_SECURITY_TOKEN_FLAG, true); + } return true; } else { // ApplicationServlet has stored the security token in the // session; check that it matched the one sent in the UIDL - String sessId = (String) request.getSession().getAttribute( - ApplicationConnection.UIDL_SECURITY_TOKEN_ID); + String sessId; + if (request instanceof ResourceRequest) { + sessId = (String) ((ResourceRequest) request) + .getPortletSession() + .getAttribute( + ApplicationConnection.UIDL_SECURITY_TOKEN_ID); + } else { + sessId = (String) ((HttpServletRequest) request) + .getSession() + .getAttribute( + ApplicationConnection.UIDL_SECURITY_TOKEN_ID); + } if (sessId == null || !sessId.equals(bursts[0])) { throw new InvalidUIDLSecurityKeyException( "Security key mismatch"); @@ -841,20 +1005,30 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, } /** - * Reads the request data from the HttpServletRequest and returns it - * converted to an UTF-8 string. + * Reads the request data from the HttpServletRequest or ResourceRequest and + * returns it converted to an UTF-8 string. * * @param request * @return * @throws IOException */ - private static String readRequest(HttpServletRequest request) - throws IOException { + private static String readRequest(Object request) throws IOException { - int requestLength = request.getContentLength(); + int requestLength; + if (request instanceof ResourceRequest) { + requestLength = ((ResourceRequest) request).getContentLength(); + } else { // Will throw ClassCastException if invalid request type + requestLength = ((HttpServletRequest) request).getContentLength(); + } byte[] buffer = new byte[requestLength]; - ServletInputStream inputStream = request.getInputStream(); + InputStream inputStream; + + if (request instanceof ResourceRequest) { + inputStream = ((ResourceRequest) request).getPortletInputStream(); + } else { + inputStream = ((HttpServletRequest) request).getInputStream(); + } int bytesRemaining = requestLength; while (bytesRemaining > 0) { @@ -1095,11 +1269,47 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, AbstractApplicationServlet applicationServlet, Application application, Window assumedWindow) throws ServletException { + return doGetApplicationWindow((Object) request, applicationServlet, + application, assumedWindow); + } + + /** + * TODO New method - document me! + * + * @param request + * @param application + * @param assumedWindow + * @return + * @throws PortletException + */ + Window getApplicationWindow(ResourceRequest request, + Application application, Window assumedWindow) + throws PortletException { + try { + return doGetApplicationWindow((Object) request, null, application, + assumedWindow); + } catch (ServletException e) { + throw new PortletException(e.getMessage(), e.getCause()); + } + } + + private Window doGetApplicationWindow(Object request, + AbstractApplicationServlet applicationServlet, + Application application, Window assumedWindow) + throws ServletException { Window window = null; // If the client knows which window to use, use it if possible - String windowClientRequestedName = request.getParameter("windowName"); + String windowClientRequestedName; + if (request instanceof ResourceRequest) { + windowClientRequestedName = ((ResourceRequest) request) + .getParameter("windowName"); + } else { + windowClientRequestedName = ((HttpServletRequest) request) + .getParameter("windowName"); + } + if (assumedWindow != null && application.getWindows().contains(assumedWindow)) { windowClientRequestedName = assumedWindow.getName(); @@ -1112,10 +1322,13 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, } // If client does not know what window it wants - if (window == null) { + if (window == null && request instanceof HttpServletRequest) { + // This is only supported if the application is running inside a + // servlet // Get the path from URL - String path = applicationServlet.getRequestPathInfo(request); + String path = applicationServlet + .getRequestPathInfo((HttpServletRequest) request); if (path != null && path.startsWith("/UIDL")) { path = path.substring("/UIDL".length()); } @@ -1172,17 +1385,16 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, * Ends the Application. * * @param request - * the HTTP request instance. + * the HTTP/Resource request instance. * @param response - * the HTTP response to write to. + * the HTTP/Resource response to write to. * @param application * the Application to end. * @throws IOException * if the writing failed due to input/output error. */ - private void endApplication(HttpServletRequest request, - HttpServletResponse response, Application application) - throws IOException { + private void endApplication(Object request, Object response, + Application application) throws IOException { String logoutUrl = application.getLogoutURL(); if (logoutUrl == null) { @@ -1191,8 +1403,16 @@ public class CommunicationManager implements Paintable.RepaintRequestListener, // clients JS app is still running, send a special json file to tell // client that application has quit and where to point browser now // Set the response type - response.setContentType("application/json; charset=UTF-8"); - final ServletOutputStream out = response.getOutputStream(); + final OutputStream out; + if (response instanceof ResourceResponse) { + ((ResourceResponse) response) + .setContentType("application/json; charset=UTF-8"); + out = ((ResourceResponse) response).getPortletOutputStream(); + } else { // Will throw ClassCastException if invalid response + ((HttpServletResponse) response) + .setContentType("application/json; charset=UTF-8"); + out = ((HttpServletResponse) response).getOutputStream(); + } final PrintWriter outWriter = new PrintWriter(new BufferedWriter( new OutputStreamWriter(out, "UTF-8"))); outWriter.print("for(;;);[{"); diff --git a/src/com/vaadin/terminal/gwt/server/Constants.java b/src/com/vaadin/terminal/gwt/server/Constants.java deleted file mode 100644 index defc0a10c5..0000000000 --- a/src/com/vaadin/terminal/gwt/server/Constants.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.vaadin.terminal.gwt.server; - -/** - * TODO Write documentation, fix JavaDoc tags. - * - * @author peholmst - */ -public interface Constants { - - public static final String ERROR_NO_WINDOW_FOUND = "No window found. Did you remember to setMainWindow()?"; - -// public static final String THEME_DIRECTORY_PATH = "VAADIN/themes/"; - -// public static final String WIDGETSET_DIRECTORY_PATH = "VAADIN/widgetsets/"; - - public static final String DEFAULT_WIDGETSET = "com.vaadin.terminal.gwt.DefaultWidgetSet"; - -// public static final String AJAX_UIDL_URI = "/UIDL"; - - public static final String URL_PARAMETER_REPAINT_ALL = "repaintAll"; - - public static final String URL_PARAMETER_RESTART_APPLICATION = "restartApplication"; - - public static final String URL_PARAMETER_CLOSE_APPLICATION = "closeApplication"; - -} diff --git a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java index 48357eb75f..765cccd2b6 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java +++ b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java @@ -36,7 +36,7 @@ public class PortletApplicationContext2 implements ApplicationContext, protected WebBrowser browser = new WebBrowser(); - protected HashMap applicationToAjaxAppMgrMap = new HashMap(); + protected HashMap applicationToAjaxAppMgrMap = new HashMap(); public void addTransactionListener(TransactionListener listener) { if (listeners == null) { @@ -71,15 +71,14 @@ public class PortletApplicationContext2 implements ApplicationContext, } } - protected PortletCommunicationManager getApplicationManager( + protected CommunicationManager getApplicationManager( Application application) { - PortletCommunicationManager mgr = applicationToAjaxAppMgrMap + CommunicationManager mgr = applicationToAjaxAppMgrMap .get(application); if (mgr == null) { // Creates a new manager - // TODO Use a factory instead - mgr = new PortletCommunicationManagerImpl(); + mgr = new CommunicationManager(application); applicationToAjaxAppMgrMap.put(application, mgr); } return mgr; diff --git a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java deleted file mode 100644 index 3fb7febe81..0000000000 --- a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.vaadin.terminal.gwt.server; - -import java.io.IOException; - -import javax.portlet.ActionRequest; -import javax.portlet.ActionResponse; -import javax.portlet.PortletException; - -import com.vaadin.external.org.apache.commons.fileupload.FileUploadException; - -/** - * TODO Write documentation, fix JavaDoc tags. - * - * @author peholmst - */ -public interface PortletCommunicationManager { - - public void handleFileUpload(ActionRequest request, ActionResponse response) - throws FileUploadException, IOException; - - public void handleUIDLRequest(ActionRequest request, ActionResponse response) - throws IOException, PortletException; - -} diff --git a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManagerImpl.java b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManagerImpl.java deleted file mode 100644 index c8960bce3d..0000000000 --- a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManagerImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.vaadin.terminal.gwt.server; - -import java.io.IOException; -import java.io.Serializable; - -import javax.portlet.ActionRequest; -import javax.portlet.ActionResponse; -import javax.portlet.PortletException; - -import com.vaadin.external.org.apache.commons.fileupload.FileUploadException; -import com.vaadin.terminal.Paintable; -import com.vaadin.terminal.Paintable.RepaintRequestEvent; - -@SuppressWarnings("serial") -public class PortletCommunicationManagerImpl implements - PortletCommunicationManager, Paintable.RepaintRequestListener, Serializable { - - public void repaintRequested(RepaintRequestEvent event) { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); - } - - public void handleFileUpload(ActionRequest request, ActionResponse response) - throws FileUploadException, IOException { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); - } - - public void handleUIDLRequest(ActionRequest request, ActionResponse response) - throws IOException, PortletException { - // TODO Implement me! - throw new UnsupportedOperationException("Not implemented yet"); - } - -} -- 2.39.5