]> source.dussan.org Git - vaadin-framework.git/commitdiff
WIP
authorPetter Holmström <petter.holmstrom@itmill.com>
Fri, 30 Oct 2009 08:54:51 +0000 (08:54 +0000)
committerPetter Holmström <petter.holmstrom@itmill.com>
Fri, 30 Oct 2009 08:54:51 +0000 (08:54 +0000)
svn changeset:9488/svn branch:portlet_2.0

src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java
src/com/vaadin/terminal/gwt/server/Constants.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java
src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/server/PortletCommunicationManagerImpl.java [new file with mode: 0644]

index ab880b0c5d332761853305979c3b5abdffc58db5..10278e6537dfeaad58f02e57c9c23a8f2efbb483 100644 (file)
@@ -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<? extends Application> 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<String, String[]> 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("<script type=\"text/javascript\">\n");
+        page.write("if(!vaadin || !vaadin.vaadinConfigurations) {\n "
+                + "if(!vaadin) { var vaadin = {}} \n"
+                + "vaadin.vaadinConfigurations = {};\n"
+                + "if (!vaadin.themesLoaded) { vaadin.themesLoaded = {}; }\n");
+        // TODO Add support for production mode
+        page.write("vaadin.debug = true;\n");
+        page
+                .write("document.write('<iframe tabIndex=\"-1\" id=\"__gwt_historyFrame\" "
+                        + "style=\"width:0;height:0;border:0;overflow:"
+                        + "hidden\" src=\"javascript:false\"></iframe>');\n");
+        page.write("document.write(\"<script language='javascript' src='"
+                + widgetsetURL.toString() + "'><\\/script>\");\n}\n");
+
+        page.write("vaadin.vaadinConfigurations[\"" + request.getWindowID() + "\"] = {");
+        page.write("portletMode: true, ");
+        
+        String pathInfo = response.createActionURL().toString();
+
+        page.write("pathInfo: '" + pathInfo + "', ");
+        // TODO Custom window
+        if (window != application.getMainWindow()) {
+            page.write("windowName: '" + window.getName() + "', ");
+        }
+        page.write("themeUri:");
+        // page.write(themeUri != null ? "'" + themeUri + "'" : "null");
+        page.write("null"); // TODO Fix this
+        page.write(", versionInfo : {vaadinVersion:\"");
+        // page.write(VERSION);
+        page.write("UNVERSIONED"); // TODO Fix this
+        page.write("\",applicationVersion:\"");
+        page.write(application.getVersion());
+        page.write("\"},");
+        // TODO Add system messages
+        page.write("};\n</script>\n");
+        // TODO Add custom theme
+        // TODO Warn if widgetset has not been loaded after 15 seconds
+        page.close();
+    }
+
+    protected abstract Class<? extends Application> 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();
+    }
 }
index 1f2828228790e672d0bf7d311500237d3937321d..ec373908f7538f3e2f37df1e0914f4fb85f8edac 100644 (file)
@@ -16,31 +16,31 @@ import com.vaadin.Application;
  */
 public class ApplicationPortlet2 extends AbstractApplicationPortlet {
 
-       private Class<? extends Application> 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<? extends Application>) getClassLoader()
-                                       .loadClass(applicationClassName);
-               } catch (final ClassNotFoundException e) {
-                       throw new PortletException("Failed to load application class: "
-                                       + applicationClassName);
-               }
-       }
-
-       @Override
-       protected Class<? extends Application> getApplicationClass() {
-               return applicationClass;
-       }
+    private Class<? extends Application> 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<? extends Application>) getClassLoader()
+                    .loadClass(applicationClassName);
+        } catch (final ClassNotFoundException e) {
+            throw new PortletException("Failed to load application class: "
+                    + applicationClassName);
+        }
+    }
+
+    @Override
+    protected Class<? extends Application> 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 (file)
index 0000000..0cf6bc5
--- /dev/null
@@ -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";
+
+}
index 08546c43660ff9dc30d0e5cecc079cd77ece9195..cb69836f9ff4eec94ac90450c3e510ba28df1882 100644 (file)
@@ -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<TransactionListener> 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 (file)
index 0000000..3fb7feb
--- /dev/null
@@ -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 (file)
index 0000000..302546c
--- /dev/null
@@ -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
+        
+    }
+
+}