From: Petter Holmström Date: Fri, 30 Oct 2009 08:54:51 +0000 (+0000) Subject: WIP X-Git-Tag: 6.7.0.beta1~2266^2~27 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f8cbe291c67207981d3b8ea4506edf8f4502af62;p=vaadin-framework.git WIP svn changeset:9488/svn branch:portlet_2.0 --- diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index ab880b0c5d..10278e6537 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -1,6 +1,10 @@ package com.vaadin.terminal.gwt.server; +import java.io.BufferedWriter; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.net.MalformedURLException; +import java.util.Map; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; @@ -8,54 +12,292 @@ import javax.portlet.Portlet; import javax.portlet.PortletConfig; import javax.portlet.PortletException; import javax.portlet.PortletRequest; +import javax.portlet.PortletResponse; 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 com.vaadin.Application; +import com.vaadin.external.org.apache.commons.fileupload.portlet.PortletFileUpload; +import com.vaadin.ui.Window; -public abstract class AbstractApplicationPortlet implements Portlet { +public abstract class AbstractApplicationPortlet implements Portlet, + ResourceServingPortlet { - public void destroy() { - // TODO Auto-generated method stub + public void destroy() { + // TODO Auto-generated method stub + } - } + public void init(PortletConfig config) throws PortletException { + // TODO Auto-generated method stub + } - public void init(PortletConfig config) throws PortletException { - // TODO Auto-generated method stub + enum RequestType { + FILE_UPLOAD, UIDL, RENDER, STATIC_FILE, UNKNOWN; + } - } + protected RequestType getRequestType(PortletRequest request) { + if (request instanceof RenderRequest) { + return RequestType.RENDER; + } else if (request instanceof ResourceRequest) { + 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)) { + return RequestType.FILE_UPLOAD; + } + } + return RequestType.UNKNOWN; + } - public void processAction(ActionRequest request, ActionResponse response) - throws PortletException, IOException { - // TODO Auto-generated method stub + private boolean isStaticResourceRequest(ResourceRequest request) { + String resourceID = request.getResourceID(); + if (resourceID != null && resourceID.startsWith("/VAADIN/")) { + return true; + } + return false; + } - } + private boolean isUIDLRequest(ActionRequest request) { + return request.getParameter("UIDL") != null; + } - public void render(RenderRequest request, RenderResponse response) - throws PortletException, IOException { - // TODO Auto-generated method stub + private boolean isFileUploadRequest(ActionRequest request) { + return PortletFileUpload.isMultipartContent(request); + } - } + protected void handleRequest(PortletRequest request, + PortletResponse response) throws PortletException, IOException { + System.out.println("AbstractApplicationPortlet.handleRequest()"); - protected abstract Class getApplicationClass() - throws ClassNotFoundException; + RequestType requestType = getRequestType(request); - protected Application getNewApplication(PortletRequest request) - throws PortletException { - try { - final Application application = getApplicationClass().newInstance(); - return application; - } catch (final IllegalAccessException e) { - throw new PortletException("getNewApplication failed", e); - } catch (final InstantiationException e) { - throw new PortletException("getNewApplication failed", e); - } catch (final ClassNotFoundException e) { - throw new PortletException("getNewApplication failed", e); - } - } + if (requestType == RequestType.UNKNOWN) { + System.out.println("Unknown request type"); + return; + } else if (requestType == RequestType.STATIC_FILE) { + serveStaticResources((ResourceRequest) request, + (ResourceResponse) response); + return; + } - protected ClassLoader getClassLoader() throws PortletException { - // TODO Add support for custom class loader - return getClass().getClassLoader(); - } + Application application = null; + + try { + /* Find out which application this request is related to */ + application = findApplicationInstance(request); + if (application == null) { + return; + } + + /* + * Get or create an application context and an application manager + * for the session + */ + PortletApplicationContext2 applicationContext = PortletApplicationContext2 + .getApplicationContext(request.getPortletSession()); + PortletCommunicationManager applicationManager = applicationContext + .getApplicationManager(application); + + /* Update browser information from request */ + applicationContext.getBrowser().updateBrowserProperties(request); + + /* Start the newly created application */ + startApplication(request, application, applicationManager); + + /* + * Transaction starts. Call transaction listeners. Transaction end + * is called in the finally block below. + */ + applicationContext.startTransaction(application, request); + + /* Handle the request */ + if (requestType == RequestType.FILE_UPLOAD) { + applicationManager.handleFileUpload((ActionRequest) request, (ActionResponse) response); + return; + } else if (requestType == RequestType.UIDL) { + // Handles AJAX UIDL requests + applicationManager.handleUIDLRequest((ActionRequest) request, (ActionResponse) response); + return; + } else if (requestType == RequestType.RENDER) { + /* + * Removes the application if it has stopped + */ + if (!application.isRunning()) { + endApplication(request, response, application); + return; + } + + /* + * Finds the window within the application + */ + Window window = getApplicationWindow(request, + applicationManager, application); + if (window == null) { + throw new PortletException(Constants.ERROR_NO_WINDOW_FOUND); + } + + /* + * Sets terminal type for the window, if not already set + */ + if (window.getTerminal() == null) { + window.setTerminal(applicationContext.getBrowser()); + } + + /* + * Handle parameters + */ + final Map parameters = request + .getParameterMap(); + if (window != null && parameters != null) { + window.handleParameters(parameters); + } + + /* + * Send initial AJAX page that kickstarts the Vaadin application + */ + writeAjaxPage((RenderRequest) request, + (RenderResponse) response, window, application); + } + } catch (final Throwable e) { + // TODO Handle exceptions + } finally { + // Notifies transaction end + if (application != null) { + ((PortletApplicationContext2) application.getContext()) + .endTransaction(application, request); + } + } + } + + private void serveStaticResources(ResourceRequest request, + ResourceResponse response) { + // TODO Auto-generated method stub + + } + + 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) + 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 Auto-generated method stub + return null; + } + + private void startApplication(PortletRequest request, + Application application, + PortletCommunicationManager applicationManager) + throws PortletException, MalformedURLException { + // TODO Auto-generated method stub + } + + private void endApplication(PortletRequest request, + PortletResponse response, Application application) + throws IOException { + // TODO Auto-generated method stub + } + + private Application findApplicationInstance(PortletRequest request) + throws PortletException, SessionExpired, MalformedURLException { + return null; + } + + protected void writeAjaxPage(RenderRequest request, + RenderResponse response, Window window, Application application) + throws IOException, MalformedURLException, PortletException { + final BufferedWriter page = new BufferedWriter(new OutputStreamWriter( + response.getPortletOutputStream(), "UTF-8")); + + response.setContentType("text/html"); + + // TODO Figure out the format of resource URLs + ResourceURL widgetsetURL = response.createResourceURL(); + // TODO Add support for custom widgetsets. + widgetsetURL.setResourceID(Constants.DEFAULT_WIDGETSET); + + page.write("\n"); + // TODO Add custom theme + // TODO Warn if widgetset has not been loaded after 15 seconds + page.close(); + } + + protected abstract Class getApplicationClass() + throws ClassNotFoundException; + + protected Application getNewApplication(PortletRequest request) + throws PortletException { + try { + final Application application = getApplicationClass().newInstance(); + return application; + } catch (final IllegalAccessException e) { + throw new PortletException("getNewApplication failed", e); + } catch (final InstantiationException e) { + throw new PortletException("getNewApplication failed", e); + } catch (final ClassNotFoundException e) { + throw new PortletException("getNewApplication failed", e); + } + } + + protected ClassLoader getClassLoader() throws PortletException { + // TODO Add support for custom class loader + return getClass().getClassLoader(); + } } diff --git a/src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java b/src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java index 1f28282287..ec373908f7 100644 --- a/src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java +++ b/src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java @@ -16,31 +16,31 @@ import com.vaadin.Application; */ public class ApplicationPortlet2 extends AbstractApplicationPortlet { - private Class applicationClass; - - @SuppressWarnings("unchecked") - @Override - public void init(PortletConfig config) throws PortletException { - super.init(config); - final String applicationClassName = config - .getInitParameter("application"); - if (applicationClassName == null) { - throw new PortletException( - "Application not specified in portlet parameters"); - } - - try { - applicationClass = (Class) getClassLoader() - .loadClass(applicationClassName); - } catch (final ClassNotFoundException e) { - throw new PortletException("Failed to load application class: " - + applicationClassName); - } - } - - @Override - protected Class getApplicationClass() { - return applicationClass; - } + private Class applicationClass; + + @SuppressWarnings("unchecked") + @Override + public void init(PortletConfig config) throws PortletException { + super.init(config); + final String applicationClassName = config + .getInitParameter("application"); + if (applicationClassName == null) { + throw new PortletException( + "Application not specified in portlet parameters"); + } + + try { + applicationClass = (Class) getClassLoader() + .loadClass(applicationClassName); + } catch (final ClassNotFoundException e) { + throw new PortletException("Failed to load application class: " + + applicationClassName); + } + } + + @Override + protected Class getApplicationClass() { + return applicationClass; + } } diff --git a/src/com/vaadin/terminal/gwt/server/Constants.java b/src/com/vaadin/terminal/gwt/server/Constants.java new file mode 100644 index 0000000000..0cf6bc5dbe --- /dev/null +++ b/src/com/vaadin/terminal/gwt/server/Constants.java @@ -0,0 +1,20 @@ +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"; + +} diff --git a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java index 08546c4366..cb69836f9f 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java +++ b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java @@ -13,6 +13,8 @@ import java.util.LinkedList; import javax.portlet.PortletRequest; import javax.portlet.PortletSession; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; import com.vaadin.Application; import com.vaadin.service.ApplicationContext; @@ -24,7 +26,7 @@ import com.vaadin.service.ApplicationContext; */ @SuppressWarnings("serial") public class PortletApplicationContext2 implements ApplicationContext, - Serializable { + HttpSessionBindingListener, Serializable { protected LinkedList listeners; @@ -155,4 +157,37 @@ public class PortletApplicationContext2 implements ApplicationContext, } } + protected void removeApplication(Application application) { + applications.remove(application); + } + + protected void addApplication(Application application) { + applications.add(application); + } + + public PortletSession getPortletSession() { + return session; + } + + @Override + public void valueBound(HttpSessionBindingEvent event) { + // We are not interested in bindings + } + + public void valueUnbound(HttpSessionBindingEvent event) { + // If we are going to be unbound from the session, the session must be + // closing + try { + while (!applications.isEmpty()) { + final Application app = applications.iterator().next(); + app.close(); + applicationToAjaxAppMgrMap.remove(app); + removeApplication(app); + } + } catch (Exception e) { + // FIXME: Handle exception + System.err.println("Could not remove application, leaking memory."); + e.printStackTrace(); + } + } } diff --git a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java new file mode 100644 index 0000000000..3fb7febe81 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java @@ -0,0 +1,24 @@ +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 new file mode 100644 index 0000000000..302546c3c5 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManagerImpl.java @@ -0,0 +1,38 @@ +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 { + + @Override + public void repaintRequested(RepaintRequestEvent event) { + // TODO Auto-generated method stub + + } + + @Override + public void handleFileUpload(ActionRequest request, ActionResponse response) + throws FileUploadException, IOException { + // TODO Auto-generated method stub + + } + + @Override + public void handleUIDLRequest(ActionRequest request, ActionResponse response) + throws IOException, PortletException { + // TODO Auto-generated method stub + + } + +}