summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin
diff options
context:
space:
mode:
authorHenri Sara <henri.sara@itmill.com>2009-12-01 15:00:49 +0000
committerHenri Sara <henri.sara@itmill.com>2009-12-01 15:00:49 +0000
commitd2240c3ace8ebca936037c5fbac1a0cc18e8937b (patch)
tree62863021126a2ccffc55b63adb99cc32a1145692 /src/com/vaadin
parente14e35cc2cce369bee90445618354cf97af89ac5 (diff)
downloadvaadin-framework-d2240c3ace8ebca936037c5fbac1a0cc18e8937b.tar.gz
vaadin-framework-d2240c3ace8ebca936037c5fbac1a0cc18e8937b.zip
#3117 inter-portlet event support (JSR-286), some support for custom portlet actions
svn changeset:10119/svn branch:6.2
Diffstat (limited to 'src/com/vaadin')
-rw-r--r--src/com/vaadin/Application.java6
-rw-r--r--src/com/vaadin/service/ApplicationContext.java8
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java31
-rw-r--r--src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java115
4 files changed, 131 insertions, 29 deletions
diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java
index 2b132fee64..5d10b215e4 100644
--- a/src/com/vaadin/Application.java
+++ b/src/com/vaadin/Application.java
@@ -722,10 +722,14 @@ public abstract class Application implements URIHandler,
/**
* Gets the relative uri of the resource.
+ *
+ * This method can only be called from within the processing of a UIDL
+ * request, not from a background thread.
*
* @param resource
* the resource to get relative location.
- * @return the relative uri of the resource.
+ * @return the relative uri of the resource or null if called in a
+ * background thread
*/
@Deprecated
public String getRelativeLocation(ApplicationResource resource) {
diff --git a/src/com/vaadin/service/ApplicationContext.java b/src/com/vaadin/service/ApplicationContext.java
index ab201a4bd4..3d2c76c8d0 100644
--- a/src/com/vaadin/service/ApplicationContext.java
+++ b/src/com/vaadin/service/ApplicationContext.java
@@ -71,6 +71,10 @@ public interface ApplicationContext extends Serializable {
* Generate a URL that can be used as the relative location of e.g. an
* {@link ApplicationResource}.
*
+ * This method should only be called from the processing of a UIDL request,
+ * not from a background thread. The return value is null if used outside a
+ * suitable request.
+ *
* @deprecated this is subject to change/removal from the interface
*
* @param resource
@@ -84,7 +88,7 @@ public interface ApplicationContext extends Serializable {
/**
* Tests if a URL is for an application resource (APP/...).
- *
+ *
* @deprecated this is subject to change/removal from the interface
*
* @param context
@@ -99,7 +103,7 @@ public interface ApplicationContext extends Serializable {
* the one that was given to
* {@link #generateApplicationResourceURL(ApplicationResource, String)} when
* creating the URL.
- *
+ *
* @deprecated this is subject to change/removal from the interface
*
* @param context
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
index 5c1396b449..9a5f4f0fb0 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
@@ -49,7 +49,7 @@ import com.vaadin.ui.Window;
/**
* TODO Document me!
- *
+ *
* @author peholmst
*/
public abstract class AbstractApplicationPortlet extends GenericPortlet
@@ -128,7 +128,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
/**
* Gets an application property value.
- *
+ *
* @param parameterName
* the Name or the parameter.
* @return String value or null if not found
@@ -149,7 +149,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
/**
* Gets an system property value.
- *
+ *
* @param parameterName
* the Name or the parameter.
* @return String value or null if not found
@@ -178,7 +178,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
/**
* Gets an application or system property value.
- *
+ *
* @param parameterName
* the Name or the parameter.
* @param defaultValue
@@ -209,7 +209,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
* Return the URL from where static files, e.g. the widgetset and the theme,
* are served. In a standard configuration the VAADIN folder inside the
* returned folder is what is used for widgetsets and themes.
- *
+ *
* @param request
* @return The location of static resources (inside which there should be a
* VAADIN directory). Does not end with a slash (/).
@@ -233,7 +233,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
}
enum RequestType {
- FILE_UPLOAD, UIDL, RENDER, STATIC_FILE, APPLICATION_RESOURCE, DUMMY, EVENT, UNKNOWN;
+ FILE_UPLOAD, UIDL, RENDER, STATIC_FILE, APPLICATION_RESOURCE, DUMMY, EVENT, ACTION, UNKNOWN;
}
protected RequestType getRequestType(PortletRequest request) {
@@ -252,6 +252,9 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
} else if (request instanceof ActionRequest) {
if (isFileUploadRequest((ActionRequest) request)) {
return RequestType.FILE_UPLOAD;
+ } else {
+ // action other than upload
+ return RequestType.ACTION;
}
} else if (request instanceof EventRequest) {
return RequestType.EVENT;
@@ -281,7 +284,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
/**
* Returns true if the servlet is running in production mode. Production
* mode disables all debug facilities.
- *
+ *
* @return true if in production mode, false if in debug mode
*/
public boolean isProductionMode() {
@@ -331,9 +334,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
*/
PortletApplicationContext2 applicationContext = PortletApplicationContext2
.getApplicationContext(request.getPortletSession());
- if (response instanceof MimeResponse) {
- applicationContext.setMimeResponse((MimeResponse) response);
- }
+ applicationContext.setResponse(response);
PortletCommunicationManager applicationManager = applicationContext
.getApplicationManager(application);
@@ -445,6 +446,10 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
} else if (requestType == RequestType.RENDER) {
writeAjaxPage((RenderRequest) request,
(RenderResponse) response, window, application);
+ } else if (requestType == RequestType.EVENT) {
+ // nothing to do, listeners do all the work
+ } else if (requestType == RequestType.ACTION) {
+ // nothing to do, listeners do all the work
} else {
throw new IllegalStateException(
"handleRequest() without anything to do - should never happen!");
@@ -929,7 +934,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
/**
* Returns the theme for given request/window
- *
+ *
* @param request
* @param window
* @return
@@ -980,7 +985,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
/**
* Get system messages from the current application class
- *
+ *
* @return
*/
protected SystemMessages getSystemMessages() {
@@ -1053,7 +1058,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
* Send notification to client's application. Used to notify client of
* critical errors and session expiration due to long inactivity. Server has
* no knowledge of what application client refers to.
- *
+ *
* @param request
* the Portlet request instance.
* @param response
diff --git a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java
index 3af45acfaf..f6217774e2 100644
--- a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java
+++ b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java
@@ -13,16 +13,22 @@ import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.MimeResponse;
+import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
+import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.ResourceURL;
+import javax.portlet.StateAwareResponse;
import javax.servlet.http.HttpSessionBindingListener;
+import javax.xml.namespace.QName;
import com.vaadin.Application;
import com.vaadin.terminal.ApplicationResource;
+import com.vaadin.terminal.ExternalResource;
+import com.vaadin.ui.Window;
/**
* TODO Write documentation, fix JavaDoc tags.
@@ -41,7 +47,10 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext {
protected HashMap<String, Application> portletWindowIdToApplicationMap = new HashMap<String, Application>();
- private MimeResponse mimeResponse;
+ private PortletResponse response;
+
+ private Map<String, QName> eventActionDestinationMap = new HashMap<String, QName>();
+ private Map<String, Serializable> eventActionValueMap = new HashMap<String, Serializable>();
public File getBaseDirectory() {
String resultPath = session.getPortletContext().getRealPath("/");
@@ -137,10 +146,20 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext {
public void firePortletActionRequest(Application app,
ActionRequest request, ActionResponse response) {
- Set<PortletListener> listeners = portletListeners.get(app);
- if (listeners != null) {
- for (PortletListener l : listeners) {
- l.handleActionRequest(request, response);
+ String key = request.getParameter(ActionRequest.ACTION_NAME);
+ if (eventActionDestinationMap.containsKey(key)) {
+ // this action request is only to send queued portlet events
+ response.setEvent(eventActionDestinationMap.get(key), eventActionValueMap
+ .get(key));
+ // cleanup
+ eventActionDestinationMap.remove(key);
+ eventActionValueMap.remove(key);
+ } else {
+ Set<PortletListener> listeners = portletListeners.get(app);
+ if (listeners != null) {
+ for (PortletListener l : listeners) {
+ l.handleActionRequest(request, response);
+ }
}
}
}
@@ -187,22 +206,92 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext {
*
* @param mimeResponse
*/
- void setMimeResponse(MimeResponse mimeResponse) {
- this.mimeResponse = mimeResponse;
+ void setResponse(PortletResponse response) {
+ this.response = response;
}
@Override
public String generateApplicationResourceURL(
ApplicationResource resource,
String mapKey) {
- ResourceURL resourceURL = mimeResponse.createResourceURL();
- final String filename = resource.getFilename();
- if (filename == null) {
- resourceURL.setResourceID("APP/" + mapKey + "/");
+ if (response instanceof MimeResponse) {
+ ResourceURL resourceURL = ((MimeResponse) response)
+ .createResourceURL();
+ final String filename = resource.getFilename();
+ if (filename == null) {
+ resourceURL.setResourceID("APP/" + mapKey + "/");
+ } else {
+ resourceURL.setResourceID("APP/" + mapKey + "/" + filename);
+ }
+ return resourceURL.toString();
+ } else {
+ // in a background thread or otherwise outside a request
+ return null;
+ }
+ }
+
+ /**
+ * Creates a new action URL.
+ *
+ * @param action
+ * @return action URL or null if called outside a MimeRequest (outside a
+ * UIDL request or similar)
+ */
+ public PortletURL generateActionURL(String action) {
+ PortletURL url = null;
+ if (response instanceof MimeResponse) {
+ url = ((MimeResponse) response).createActionURL();
+ url.setParameter("javax.portlet.action", action);
} else {
- resourceURL.setResourceID("APP/" + mapKey + "/" + filename);
+ return null;
}
- return resourceURL.toString();
+ return url;
}
+ /**
+ * Sends a portlet event to the indicated destination.
+ *
+ * Internally, an action may be created and opened, as an event cannot be
+ * sent directly from all types of requests.
+ *
+ * The event destinations and values need to be kept in the context until
+ * sent. Any memory leaks if the action fails are limited to the session.
+ *
+ * Event names for events sent and received by a portlet need to be declared
+ * in portlet.xml .
+ *
+ * @param window
+ * a window in which a temporary action URL can be opened if
+ * necessary
+ * @param name
+ * event name
+ * @param value
+ * event value object that is Serializable and, if appropriate,
+ * has a valid JAXB annotation
+ */
+ public void sendPortletEvent(Window window, QName name, Serializable value)
+ throws IllegalStateException {
+ if (response instanceof MimeResponse) {
+ String actionKey = "" + System.currentTimeMillis();
+ while (eventActionDestinationMap.containsKey(actionKey)) {
+ actionKey = actionKey + ".";
+ }
+ PortletURL actionUrl = generateActionURL(actionKey);
+ if (actionUrl != null) {
+ eventActionDestinationMap.put(actionKey, name);
+ eventActionValueMap.put(actionKey, value);
+ window.open(new ExternalResource(actionUrl.toString()));
+ } else {
+ // this should never happen as we already know the response is a
+ // MimeResponse
+ throw new IllegalStateException(
+ "Portlet events can only be sent from a portlet request");
+ }
+ } else if (response instanceof StateAwareResponse) {
+ ((StateAwareResponse) response).setEvent(name, value);
+ } else {
+ throw new IllegalStateException(
+ "Portlet events can only be sent from a portlet request");
+ }
+ }
}