You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-scm@portals.apache.org by ms...@apache.org on 2016/04/08 15:40:42 UTC
[30/34] portals-pluto git commit: Completed contextual support for
listeners and threads run by AsyncContext#start(). Expanded async demo
portlet to show information from filters and listeners when possible. Fixed
several bugs to allow resources to be cl
Completed contextual support for listeners and threads run by
AsyncContext#start(). Expanded async demo portlet to show information from
filters and listeners when possible. Fixed several bugs to allow resources
to be cleanly released when a timeout occurs.
Project: http://git-wip-us.apache.org/repos/asf/portals-pluto/repo
Commit: http://git-wip-us.apache.org/repos/asf/portals-pluto/commit/9fa76dbe
Tree: http://git-wip-us.apache.org/repos/asf/portals-pluto/tree/9fa76dbe
Diff: http://git-wip-us.apache.org/repos/asf/portals-pluto/diff/9fa76dbe
Branch: refs/heads/V3Prototype
Commit: 9fa76dbe99b6bf5fe169befdbbf520befca68b7f
Parents: 74d5f10
Author: Scott Nicklous <ms...@apache.org>
Authored: Tue Apr 5 16:10:12 2016 +0200
Committer: Scott Nicklous <ms...@apache.org>
Committed: Tue Apr 5 16:10:12 2016 +0200
----------------------------------------------------------------------
.../apache/portals/samples/AsyncDialogBean.java | 69 +++++++---
.../portals/samples/AsyncPortletFilter.java | 3 +-
.../portals/samples/AsyncPortletListener.java | 83 +++++++++---
.../portals/samples/AsyncPortletResource.java | 28 +++-
.../src/main/webapp/WEB-INF/jsp/asyncDialog.jsp | 4 +-
.../src/main/webapp/resources/css/infobox.css | 10 ++
.../pluto/container/PortletAsyncContext.java | 10 +-
.../PortletResourceRequestContext.java | 3 +
.../pluto/container/driver/PortletServlet3.java | 11 +-
.../container/PortletAsyncContextImpl.java | 125 +++++++++++++-----
.../container/PortletAsyncContextualRunner.java | 4 +-
.../container/PortletAsyncListener.java | 129 +++++++++++++++++--
.../PortletResourceRequestContextImpl.java | 25 +++-
13 files changed, 407 insertions(+), 97 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncDialogBean.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncDialogBean.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncDialogBean.java
index c5717bc..d90af02 100644
--- a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncDialogBean.java
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncDialogBean.java
@@ -56,6 +56,7 @@ public class AsyncDialogBean implements PortletSerializable {
public static final String PARAM_REPS = "reps";
public static final String PARAM_AUTO = "auto";
public static final String PARAM_FILTER = "filter";
+ public static final String PARAM_LISTENER = "listener";
public static final String PARAM_TYPE = "type";
public static final String PARAM_TYPE_TXT = OutputType.TEXT.toString();
public static final String PARAM_TYPE_INC = OutputType.INC.toString();
@@ -71,8 +72,9 @@ public class AsyncDialogBean implements PortletSerializable {
private OutputType type;
private String msg;
private boolean autoDispatch;
- private boolean useFilter;
+ private boolean showFilter;
private TimeoutType handleTimeout;
+ private boolean showListener;
/**
* This method is called by the portlet container to initialize the bean at
@@ -87,16 +89,18 @@ public class AsyncDialogBean implements PortletSerializable {
type = OutputType.TEXT;
msg = null;
autoDispatch = true;
- useFilter = false;
+ showFilter = false;
handleTimeout = TimeoutType.CPL;
+ showListener = false;
} else {
delay = Integer.parseInt(state[0]);
reps = Integer.parseInt(state[1]);
type = OutputType.valueOf(state[2]);
msg = state[3];
autoDispatch = Boolean.parseBoolean(state[4]);
- useFilter = Boolean.parseBoolean(state[5]);
+ showFilter = Boolean.parseBoolean(state[5]);
handleTimeout = TimeoutType.valueOf(state[6]);
+ showListener = Boolean.parseBoolean(state[7]);
}
LOGGER.fine("deserialized: " + Arrays.asList(state).toString());
}
@@ -108,7 +112,7 @@ public class AsyncDialogBean implements PortletSerializable {
@Override
public String[] serialize() {
String[] state = { "" + delay, "" + reps, type.toString(), msg,
- ""+autoDispatch, ""+useFilter, handleTimeout.toString() };
+ ""+autoDispatch, ""+showFilter, handleTimeout.toString(), ""+showListener };
LOGGER.fine("serialized: " + Arrays.asList(state).toString());
return state;
}
@@ -189,31 +193,45 @@ public class AsyncDialogBean implements PortletSerializable {
}
/**
- * @return the useFilter
+ * @return the handleTimeout
*/
- public boolean isUseFilter() {
- return useFilter;
+ public TimeoutType getHandleTimeout() {
+ return handleTimeout;
}
/**
- * @param useFilter the useFilter to set
+ * @param handleTimeout the handleTimeout to set
*/
- public void setUseFilter(boolean useFilter) {
- this.useFilter = useFilter;
+ public void setHandleTimeout(TimeoutType handleTimeout) {
+ this.handleTimeout = handleTimeout;
}
/**
- * @return the handleTimeout
+ * @return the showFilter
*/
- public TimeoutType getHandleTimeout() {
- return handleTimeout;
+ public boolean isShowFilter() {
+ return showFilter;
}
/**
- * @param handleTimeout the handleTimeout to set
+ * @param showFilter the showFilter to set
*/
- public void setHandleTimeout(TimeoutType handleTimeout) {
- this.handleTimeout = handleTimeout;
+ public void setShowFilter(boolean showFilter) {
+ this.showFilter = showFilter;
+ }
+
+ /**
+ * @return the showListener
+ */
+ public boolean isShowListener() {
+ return showListener;
+ }
+
+ /**
+ * @param showListener the showListener to set
+ */
+ public void setShowListener(boolean showListener) {
+ this.showListener = showListener;
}
/**
@@ -283,13 +301,13 @@ public class AsyncDialogBean implements PortletSerializable {
String filter = req.getActionParameters().getValue(PARAM_FILTER);
if (filter != null) {
- useFilter = true;
+ showFilter = true;
if ((type == OutputType.FWD)) {
msg = "Filter can't generate output with forward processing.";
- useFilter = false;
+ showFilter = false;
}
} else {
- useFilter = false;
+ showFilter = false;
}
String strto = req.getActionParameters().getValue(PARAM_TO);
@@ -301,8 +319,19 @@ public class AsyncDialogBean implements PortletSerializable {
}
}
+ String lstnr = req.getActionParameters().getValue(PARAM_LISTENER);
+ if (lstnr != null) {
+ showListener = true;
+ if ((type == OutputType.FWD)) {
+ msg = "Listener can't generate output with forward processing.";
+ showListener = false;
+ }
+ } else {
+ showListener = false;
+ }
+
String[] state = { "" + delay, "" + reps, type.toString(), msg,
- ""+autoDispatch, ""+useFilter, handleTimeout.toString() };
+ ""+autoDispatch, ""+showFilter, handleTimeout.toString() };
LOGGER.fine("Resulting params: " + Arrays.asList(state).toString());
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletFilter.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletFilter.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletFilter.java
index f7c430e..09eff20 100644
--- a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletFilter.java
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletFilter.java
@@ -19,7 +19,6 @@
package org.apache.portals.samples;
import java.io.IOException;
-import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
@@ -65,7 +64,7 @@ public class AsyncPortletFilter implements ResourceFilter {
txt.append(", request #: ").append(reqnum.getRandomNumber());
LOGGER.fine(txt.toString());
- if (adb.isUseFilter()) {
+ if (adb.isShowFilter()) {
txt.setLength(0);
txt.append("<div class='msgbox'>");
txt.append("Filter: Request number: ").append(reqnum.getRandomNumber());
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletListener.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletListener.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletListener.java
index ce2086c..d8fd5fb 100644
--- a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletListener.java
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletListener.java
@@ -20,21 +20,32 @@ package org.apache.portals.samples;
import java.io.IOException;
import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.logging.Logger;
+import javax.inject.Inject;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
-import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import static org.apache.portals.samples.AsyncDialogBean.TimeoutType;
+import static org.apache.portals.samples.AsyncPortletResource.*;
/**
* @author Scott Nicklous
- *
+ *
*/
public class AsyncPortletListener implements AsyncListener {
- private static final Logger LOGGER = Logger.getLogger(AsyncPortletListener.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(AsyncPortletListener.class.getName());
+
+ private long start = System.currentTimeMillis();
- private long start = System.currentTimeMillis();
+ @Inject
+ private PortletRequestRandomNumberBean reqnum;
+ @Inject
+ private AsyncDialogBean adb;
/*
* (non-Javadoc)
@@ -88,7 +99,33 @@ public class AsyncPortletListener implements AsyncListener {
// complete.
AsyncContext ctx = evt.getAsyncContext();
- ctx.addListener(this);
+ // ctx.addListener(this);
+
+ // Try to write some output.
+
+ try {
+ if (adb.isShowListener()) {
+ HttpServletRequest req = (HttpServletRequest) ctx.getRequest();
+ HttpServletResponse resp = (HttpServletResponse) ctx.getResponse();
+ txt.setLength(0);
+ txt.append("<div class='orangebox'>");
+ txt.append("Listener: restarting async.");
+ txt.append("<span style='margin-left: 2em;'>");
+ txt.append("Request number: ").append(reqnum.getRandomNumber());
+ txt.append("</span>");
+ txt.append("<span style='margin-left: 2em;'>");
+ txt.append("Dispatcher type: ").append(req.getDispatcherType());
+ txt.append("</span>");
+ txt.append("</div>");
+ resp.getWriter().write(txt.toString());
+ }
+ } catch (Exception e) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ pw.flush();
+ LOGGER.fine("Exception producing output: \n" + sw.toString());
+ }
}
/*
@@ -100,19 +137,35 @@ public class AsyncPortletListener implements AsyncListener {
public void onTimeout(AsyncEvent evt) throws IOException {
long delta = System.currentTimeMillis() - start;
- StringBuilder txt = new StringBuilder(128);
- txt.append("Listener: Timeout after ").append(delta).append(" milliseconds.");
-
try {
- PrintWriter writer = evt.getAsyncContext().getResponse().getWriter();
- writer.println("<p>");
- writer.println(txt.toString());
- writer.println("</p>");
- evt.getAsyncContext().complete();
+ HttpServletRequest req = (HttpServletRequest) evt.getAsyncContext().getRequest();
+ if (adb.isShowListener()) {
+ StringBuilder txt = new StringBuilder(128);
+ txt.append("<div class='orangebox'>");
+ txt.append("AsyncPortletListener: Timeout after ").append(delta).append(" milliseconds.");
+ txt.append("<span style='margin-left: 2em;'>");
+ txt.append("Action: ").append(adb.getHandleTimeout().toString());
+ txt.append("</span>");
+ txt.append("<span style='margin-left: 2em;'>");
+ txt.append("Request number: ").append(reqnum.getRandomNumber());
+ txt.append("</span>");
+ txt.append("<span style='margin-left: 2em;'>");
+ txt.append("Dispatcher type: ").append(req.getDispatcherType());
+ txt.append("</span>");
+ txt.append("</div>");
+ PrintWriter writer = evt.getAsyncContext().getResponse().getWriter();
+ writer.println(txt.toString());
+ }
+
+ if (adb.getHandleTimeout() == TimeoutType.CPL) {
+ evt.getAsyncContext().complete();
+ } else if (adb.getHandleTimeout() == TimeoutType.DIS) {
+ req.setAttribute(ATTRIB_TIMEOUT, ATTRIB_TIMEOUT);
+ evt.getAsyncContext().dispatch();
+ }
} catch (Exception e) {
- txt.append(" Couldn't get response and complete. Exception: " + e.toString());
+ LOGGER.warning(" Couldn't get response to generate output. Exception: " + e.toString());
}
- LOGGER.fine(txt.toString());
}
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletResource.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletResource.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletResource.java
index 6cbaebc..1c25e61 100644
--- a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletResource.java
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/AsyncPortletResource.java
@@ -19,6 +19,8 @@
package org.apache.portals.samples;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
@@ -33,6 +35,7 @@ import javax.portlet.ResourceResponse;
import javax.portlet.annotations.ServeResourceMethod;
import javax.servlet.AsyncContext;
import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -52,6 +55,7 @@ public class AsyncPortletResource {
private final static String ATTRIB_REPS = "reps";
private final static String ATTRIB_AUTO = "auto";
public final static String ATTRIB_TITLE = "title";
+ public final static String ATTRIB_TIMEOUT = "timeout";
public static class AsyncRunnable implements Runnable {
@@ -150,6 +154,19 @@ public class AsyncPortletResource {
@ServeResourceMethod(portletNames = "AsyncPortlet", asyncSupported = true)
public void getResource(ResourceRequest req, ResourceResponse resp) throws IOException, PortletException {
+
+ if (req.getAttribute(ATTRIB_TIMEOUT) != null) {
+ StringBuilder txt = new StringBuilder(128);
+ txt.append("<p>Resource method: listener reports timout.");
+ txt.append("<span style='margin-left: 2em;'>Request #: ");
+ txt.append("dispatcher type: ").append(req.getDispatcherType().toString());
+ txt.append("</span>");
+ txt.append("<span style='margin-left: 2em;'>Request #: ");
+ txt.append(reqnum.getRandomNumber());
+ txt.append("</span></p><hr>");
+ resp.getWriter().write(txt.toString());
+ return;
+ }
Boolean auto = (Boolean) req.getAttribute(ATTRIB_AUTO);
if (auto == null) {
@@ -179,8 +196,15 @@ public class AsyncPortletResource {
AsyncContext ctx = req.startAsync();
ctx.setTimeout(4000);
- AsyncPortletListener apl = new AsyncPortletListener();
- ctx.addListener(apl);
+ try {
+ ctx.addListener(ctx.createListener(AsyncPortletListener.class));
+ } catch (ServletException e) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ pw.flush();
+ LOGGER.fine("Exception adding listener: \n" + sw.toString());
+ }
if (auto || (adb.getDelay() <= 0)) {
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/asyncDialog.jsp
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/asyncDialog.jsp b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/asyncDialog.jsp
index 355ce90..9d5616b 100644
--- a/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/asyncDialog.jsp
+++ b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/asyncDialog.jsp
@@ -61,7 +61,9 @@ limitations under the License.
</td></tr><tr><td>
<INPUT id ='<portlet:namespace/>-send' VALUE='execute' TYPE='submit'>
</td><td>
- <input name='<%=PARAM_FILTER%>' value='<%=PARAM_FILTER%>' type='checkbox' ${adb.isUseFilter() ? "checked" : "" } > show filter
+ <input name='<%=PARAM_FILTER%>' value='<%=PARAM_FILTER%>' type='checkbox' ${adb.isShowFilter() ? "checked" : "" } > show filter
+ </td><td>
+ <input name='<%=PARAM_LISTENER%>' value='<%=PARAM_LISTENER%>' type='checkbox' ${adb.isShowListener() ? "checked" : "" } > show listener
</td></tr></table>
</FORM>
<p>
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
index 3cafd6c..1486349 100644
--- a/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
+++ b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
@@ -18,6 +18,16 @@
background:#ddaadd;
}
+.orangebox {
+ border-style:solid;
+ border-width:2px;
+ padding:4px;
+ margin-bottom:4px;
+ overflow:auto;
+ border-color:#e68a00;
+ background:#ffdd99;
+}
+
.parmbox {
border-style:solid;
border-width:2px;
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/pluto-container-api/src/main/java/org/apache/pluto/container/PortletAsyncContext.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletAsyncContext.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletAsyncContext.java
index c4c9966..0892139 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletAsyncContext.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletAsyncContext.java
@@ -1,15 +1,15 @@
package org.apache.pluto.container;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.portlet.ResourceRequest;
import javax.servlet.AsyncContext;
public interface PortletAsyncContext extends AsyncContext {
- void init(PortletResourceRequestContext prctx, ResourceRequest resreq, BeanManager beanmgr);
void setWrapped(AsyncContext actx);
- void registerContext();
- void deregisterContext();
+ void registerContext(boolean isListener);
+ void deregisterContext(boolean isListener);
void removeContext();
+ void launchRunner();
+ boolean isComplete();
+ void setComplete(boolean complete);
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java
index 20adad4..b999eee 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java
@@ -18,6 +18,7 @@ package org.apache.pluto.container;
import java.util.Map;
+import javax.enterprise.inject.spi.BeanManager;
import javax.portlet.ResourceParameters;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
@@ -75,4 +76,6 @@ public interface PortletResourceRequestContext extends PortletRequestContext
AsyncContext startAsync();
AsyncContext startAsync(ServletRequest request, ServletResponse response);
PortletAsyncContext getPortletAsyncContext();
+ BeanManager getBeanManager();
+ void setBeanManager(BeanManager beanmgr);
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
index 820ab14..3aef3e4 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
@@ -341,7 +341,7 @@ public class PortletServlet3 extends HttpServlet {
}
// enable contextual support for async
- ((PortletResourceRequestContext)requestContext).getPortletAsyncContext().registerContext();
+ ((PortletResourceRequestContext)requestContext).getPortletAsyncContext().registerContext(false);
} else {
@@ -394,6 +394,8 @@ public class PortletServlet3 extends HttpServlet {
if (ps != null) {
resourceRequest.setAttribute(ResourceRequest.PAGE_STATE, ps);
}
+
+ rc.setBeanManager(beanmgr);
ResourceResponse resourceResponse = (ResourceResponse) portletResponse;
filterManager.processFilter(resourceRequest, resourceResponse, invoker, portletContext);
@@ -477,11 +479,8 @@ public class PortletServlet3 extends HttpServlet {
PortletResourceRequestContext resctx = (PortletResourceRequestContext)requestContext;
PortletAsyncContext pac = resctx.getPortletAsyncContext();
if (pac != null) {
- if (request.getDispatcherType() != DispatcherType.ASYNC) {
- // initialize only on the first time thru
- pac.init(resctx, (ResourceRequest) portletRequest, beanmgr);
- }
- pac.deregisterContext();
+ pac.deregisterContext(false);
+ pac.launchRunner();
} else {
LOG.warn("Couldn't get portlet async context.");
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextImpl.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextImpl.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextImpl.java
index 2df6a2f..ce8e044 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextImpl.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextImpl.java
@@ -51,58 +51,81 @@ import org.slf4j.LoggerFactory;
public class PortletAsyncContextImpl implements PortletAsyncContext {
private static final Logger LOG = LoggerFactory.getLogger(PortletAsyncContextImpl.class);
private static final boolean isDebug = LOG.isDebugEnabled();
+ @SuppressWarnings("unused")
private static final boolean isTrace = LOG.isTraceEnabled();
-
-
private AsyncContext actx;
+
private final HttpServletRequest hreq;
+ private final PortletAsyncListener pal;
+ private final PortletResourceRequestContext prctx;
- private PortletResourceRequestContext prctx;
private ResourceRequest resreq;
private PortletSessionBeanHolder sessbh;
private PortletStateScopedBeanHolder statebh;
private PortletRequestScopedBeanHolder reqbh;
private BeanManager beanmgr;
-
private Runnable pendingRunner;
+ private boolean doDeregister = true;
+ private boolean complete = false;
- public PortletAsyncContextImpl(AsyncContext actx, HttpServletRequest hreq) {
+ public PortletAsyncContextImpl(AsyncContext actx, PortletResourceRequestContext prctx, ResourceRequest resreq) {
this.actx = actx;
- this.hreq = hreq;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.pluto.driver.services.container.PortletAsyncContext#requestComplete(org.apache.pluto.container.
- * PortletResourceRequestContext)
- */
- @Override
- public void init(PortletResourceRequestContext prctx, ResourceRequest resreq, BeanManager beanmgr) {
this.prctx = prctx;
this.resreq = resreq;
- this.beanmgr = beanmgr;
+ this.hreq = (HttpServletRequest) actx.getRequest();
+ this.beanmgr = prctx.getBeanManager();
// get the original container req & resp to pass to listener for resource releasing
HttpServletRequest creq = prctx.getContainerRequest();
HttpServletResponse cresp = prctx.getContainerResponse();
- PortletAsyncListener pal = new PortletAsyncListener(this);
+ pal = new PortletAsyncListener(this);
actx.addListener(pal, creq, cresp);
+ }
+ /**
+ * @return the complete
+ */
+ @Override
+ public boolean isComplete() {
+ return complete;
+ }
+
+ /**
+ * @param complete the complete to set
+ */
+ @Override
+ public void setComplete(boolean complete) {
+ this.complete = complete;
}
/**
* Called when a new thread begins running in order to set up contextual support
*/
@Override
- public void registerContext() {
- PortletSessionBeanHolder.register(sessbh);
- PortletStateScopedBeanHolder.register(statebh);
- PortletRequestScopedBeanHolder.register(reqbh);
- PortletArtifactProducer.setPrecursors(resreq, prctx.getResponse(), prctx.getPortletConfig());
+ public void registerContext(boolean isListener) {
+
+ // if the context is already active, then ignore register / deregister calls.
+ if (complete || (isListener && PortletRequestScopedBeanHolder.getBeanHolder() != null)) {
+ doDeregister = false;
+ } else {
+ doDeregister = true;
+ PortletSessionBeanHolder.register(sessbh);
+ PortletStateScopedBeanHolder.register(statebh);
+ PortletRequestScopedBeanHolder.register(reqbh);
+ PortletArtifactProducer.setPrecursors(resreq, prctx.getResponse(), prctx.getPortletConfig());
+ }
+
+ if (isDebug) {
+ StringBuilder txt = new StringBuilder();
+ txt.append("Registered context.");
+ txt.append(" complete: ").append(complete);
+ txt.append(", isListener: ").append(isListener);
+ txt.append(", doRegister: ").append(doDeregister);
+ LOG.debug(txt.toString());
+ }
}
/**
@@ -110,11 +133,30 @@ public class PortletAsyncContextImpl implements PortletAsyncContext {
* saved rather than destroyed.
*/
@Override
- public void deregisterContext() {
- this.sessbh = PortletSessionBeanHolder.deregister();
- this.statebh = PortletStateScopedBeanHolder.deregister();
- this.reqbh = PortletRequestScopedBeanHolder.deregister();
- PortletArtifactProducer.remove();
+ public void deregisterContext(boolean isListener) {
+ if (!complete && (!isListener || doDeregister)) {
+ this.sessbh = PortletSessionBeanHolder.deregister();
+ this.statebh = PortletStateScopedBeanHolder.deregister();
+ this.reqbh = PortletRequestScopedBeanHolder.deregister();
+ PortletArtifactProducer.remove();
+ }
+
+ if (isDebug) {
+ StringBuilder txt = new StringBuilder();
+ txt.append("Deregistered context.");
+ txt.append(" complete: ").append(complete);
+ txt.append(", isListener: ").append(isListener);
+ txt.append(", doRegister: ").append(doDeregister);
+ LOG.debug(txt.toString());
+ }
+ }
+
+ /**
+ * Launches any runner that was registered for execution. To be called when
+ * leaving the portlet servlet.
+ */
+ @Override
+ public void launchRunner() {
// now if a runner is pending, initialize the contextual runnable and start it
@@ -163,7 +205,7 @@ public class PortletAsyncContextImpl implements PortletAsyncContext {
*/
@Override
public void addListener(AsyncListener l) {
- actx.addListener(l);
+ pal.addListener(l);
}
/*
@@ -174,7 +216,7 @@ public class PortletAsyncContextImpl implements PortletAsyncContext {
*/
@Override
public void addListener(AsyncListener l, ServletRequest req, ServletResponse resp) {
- actx.addListener(l, req, resp);
+ pal.addListener(l, req, resp);
}
/*
@@ -192,9 +234,30 @@ public class PortletAsyncContextImpl implements PortletAsyncContext {
*
* @see javax.servlet.AsyncContext#createListener(java.lang.Class)
*/
+ @SuppressWarnings("unchecked")
@Override
public <T extends AsyncListener> T createListener(Class<T> cls) throws ServletException {
- return actx.createListener(cls);
+ if (isDebug) {
+ StringBuilder txt = new StringBuilder();
+ txt.append("Creating listener.");
+ txt.append(" Bean manager: ").append(beanmgr);
+ txt.append(", listener class: ").append(cls.getCanonicalName());
+ LOG.debug(txt.toString());
+ }
+ T lis = null;
+ if (beanmgr != null) {
+ Set<Bean<?>> beans = beanmgr.getBeans(cls);
+ Bean<?> bean = beanmgr.resolve(beans);
+ if (bean != null) {
+ lis = (T) beanmgr.getReference(bean, bean.getBeanClass(), beanmgr.createCreationalContext(bean));
+ } else {
+ LOG.warn("Could not get bean reference for: " + cls.getCanonicalName());
+ lis = actx.createListener(cls);
+ }
+ } else {
+ lis = actx.createListener(cls);
+ }
+ return lis;
}
/*
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextualRunner.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextualRunner.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextualRunner.java
index 8535a7e..bfbfd34 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextualRunner.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncContextualRunner.java
@@ -55,7 +55,7 @@ public class PortletAsyncContextualRunner implements Runnable {
}
try {
- pactx.registerContext();
+ pactx.registerContext(false);
targetRunner.run();
} catch (Exception e) {
StringBuilder txt = new StringBuilder(128);
@@ -64,7 +64,7 @@ public class PortletAsyncContextualRunner implements Runnable {
if (isDebug) {
LOG.debug("Shutting down contextual environment for thread: " + Thread.currentThread().getId());
}
- pactx.deregisterContext();
+ pactx.deregisterContext(false);
}
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncListener.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncListener.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncListener.java
index d546986..11069ac 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncListener.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletAsyncListener.java
@@ -19,32 +19,68 @@
package org.apache.pluto.driver.services.container;
import java.io.IOException;
-import java.util.logging.Logger;
+import java.util.ArrayList;
+import java.util.List;
import javax.portlet.ResourceRequest;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.pluto.container.PortletAsyncContext;
import org.apache.pluto.container.PortletInvokerService;
import org.apache.pluto.container.PortletResourceResponseContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * Releases portal resources when the async request completes.
+ * Manages the listeners registered by the application. Releases portal resources when
+ * the async request completes and provides contextual services for the listeners.
*
* @author Scott Nicklous
*/
public class PortletAsyncListener implements AsyncListener {
- private static final Logger LOGGER = Logger.getLogger(PortletAsyncListener.class.getName());
-
+
+ /** Logger. */
+ private static final Logger LOG = LoggerFactory.getLogger(PortletAsyncListener.class);
+ private static final boolean isDebug = LOG.isDebugEnabled();
+ @SuppressWarnings("unused")
+ private static final boolean isTrace = LOG.isTraceEnabled();
+
+
+ // Data for one listener
+ private class Entry {
+ public Entry(AsyncListener lis, ServletRequest req, ServletResponse resp) {
+ this.lis = lis;
+ this.req = req;
+ this.resp = resp;
+ }
+ public AsyncListener lis;
+ public ServletRequest req;
+ public ServletResponse resp;
+ }
+
+ // The registered listeners
+ List<Entry> listeners = new ArrayList<Entry>();
+
private long start = System.currentTimeMillis();
private final PortletAsyncContext pactx;
+
public PortletAsyncListener(PortletAsyncContext pactx) {
this.pactx = pactx;
}
+
+ public void addListener(AsyncListener l) {
+ listeners.add(new Entry(l, null, null));
+ }
+
+ public void addListener(AsyncListener l, ServletRequest req, ServletResponse resp) {
+ listeners.add(new Entry(l, req, resp));
+ }
/*
* (non-Javadoc)
@@ -53,6 +89,22 @@ public class PortletAsyncListener implements AsyncListener {
*/
@Override
public void onComplete(AsyncEvent evt) throws IOException {
+
+ if (isDebug) {
+ StringBuilder txt = new StringBuilder();
+ txt.append("Firing onComplete event for ");
+ txt.append(listeners.size()).append(" listeners.");
+ LOG.debug(txt.toString());
+ }
+
+ pactx.registerContext(true);
+ for (Entry listener : listeners) {
+ AsyncEvent lisevt = new AsyncEvent(pactx, listener.req, listener.resp);
+ listener.lis.onComplete(lisevt);
+ }
+ pactx.deregisterContext(true);
+ pactx.setComplete(true);
+
long delta = System.currentTimeMillis() - start;
StringBuilder txt = new StringBuilder(128);
txt.append("Completed. Execution time: ").append(delta).append(" milliseconds.");
@@ -97,7 +149,9 @@ public class PortletAsyncListener implements AsyncListener {
txt.append(" Removing contextual info.");
pactx.removeContext();
- LOGGER.fine(txt.toString());
+ if (isDebug) {
+ LOG.debug(txt.toString());
+ }
}
@@ -108,6 +162,21 @@ public class PortletAsyncListener implements AsyncListener {
*/
@Override
public void onError(AsyncEvent evt) throws IOException {
+
+ if (isDebug) {
+ StringBuilder txt = new StringBuilder();
+ txt.append("Firing onError event for ");
+ txt.append(listeners.size()).append(" listeners.");
+ LOG.debug(txt.toString());
+ }
+
+ pactx.registerContext(true);
+ for (Entry listener : listeners) {
+ AsyncEvent lisevt = new AsyncEvent(pactx, listener.req, listener.resp, evt.getThrowable());
+ listener.lis.onError(lisevt);
+ }
+ pactx.deregisterContext(true);
+
long delta = System.currentTimeMillis() - start;
StringBuilder txt = new StringBuilder(128);
txt.append("Error after ").append(delta).append(" milliseconds.");
@@ -124,7 +193,9 @@ public class PortletAsyncListener implements AsyncListener {
}
txt.append(", Exception: ").append(evt.getThrowable().getMessage());
- LOGGER.fine(txt.toString());
+ if (isDebug) {
+ LOG.debug(txt.toString());
+ }
}
/*
@@ -134,10 +205,33 @@ public class PortletAsyncListener implements AsyncListener {
*/
@Override
public void onStartAsync(AsyncEvent evt) throws IOException {
+
+ if (isDebug) {
+ StringBuilder txt = new StringBuilder();
+ txt.append("Firing onStartAsync event for ");
+ txt.append(listeners.size()).append(" listeners.");
+ LOG.debug(txt.toString());
+ }
+
+ // copy & clear the original listener list. If a listener wants to be notified
+ // again, it will add itself again.
+
+ ArrayList<Entry> entries = new ArrayList<Entry>(listeners);
+ listeners.clear();
+
+ pactx.registerContext(true);
+ for (Entry listener : entries) {
+ AsyncEvent lisevt = new AsyncEvent(pactx, listener.req, listener.resp);
+ listener.lis.onStartAsync(lisevt);
+ }
+ pactx.deregisterContext(true);
+
long delta = System.currentTimeMillis() - start;
StringBuilder txt = new StringBuilder(128);
txt.append("Async started again after ").append(delta).append(" milliseconds.");
- LOGGER.fine(txt.toString());
+ if (isDebug) {
+ LOG.debug(txt.toString());
+ }
// need to add this listener again so it gets called when finally complete.
@@ -152,6 +246,21 @@ public class PortletAsyncListener implements AsyncListener {
*/
@Override
public void onTimeout(AsyncEvent evt) throws IOException {
+
+ if (isDebug) {
+ StringBuilder txt = new StringBuilder();
+ txt.append("Firing onTimeout event for ");
+ txt.append(listeners.size()).append(" listeners.");
+ LOG.debug(txt.toString());
+ }
+
+ pactx.registerContext(true);
+ for (Entry listener : listeners) {
+ AsyncEvent lisevt = new AsyncEvent(pactx, listener.req, listener.resp);
+ listener.lis.onTimeout(lisevt);
+ }
+ pactx.deregisterContext(true);
+
long delta = System.currentTimeMillis() - start;
StringBuilder txt = new StringBuilder(128);
txt.append("Timeout after ").append(delta).append(" milliseconds.");
@@ -179,9 +288,11 @@ public class PortletAsyncListener implements AsyncListener {
}
if (warn) {
- LOGGER.warning(txt.toString());
+ LOG.warn(txt.toString());
} else {
- LOGGER.fine(txt.toString());
+ if (isDebug) {
+ LOG.debug(txt.toString());
+ }
}
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9fa76dbe/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java
index 6906a57..c1e8332 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java
@@ -20,12 +20,12 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
+import javax.enterprise.inject.spi.BeanManager;
import javax.portlet.PortletConfig;
import javax.portlet.ResourceParameters;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.servlet.AsyncContext;
-import javax.servlet.DispatcherType;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
@@ -57,9 +57,10 @@ public class PortletResourceRequestContextImpl extends PortletRequestContextImpl
private static final boolean isDebug = LOG.isDebugEnabled();
private static final boolean isTrace = LOG.isTraceEnabled();
- private String pageState;
- private ResourceResponse response;
+ private String pageState;
+ private ResourceResponse response;
private PortletAsyncContextImpl actx;
+ private BeanManager beanmgr;
public PortletResourceRequestContextImpl(PortletContainer container, HttpServletRequest containerRequest,
HttpServletResponse containerResponse, PortletWindow window, String pageState) {
@@ -122,6 +123,22 @@ public class PortletResourceRequestContextImpl extends PortletRequestContextImpl
this.response = response;
}
+ /**
+ * @return the beanmgr
+ */
+ @Override
+ public BeanManager getBeanManager() {
+ return beanmgr;
+ }
+
+ /**
+ * @param beanmgr the beanmgr to set
+ */
+ @Override
+ public void setBeanManager(BeanManager beanmgr) {
+ this.beanmgr = beanmgr;
+ }
+
@Override
public AsyncContext startAsync(ResourceRequest request) throws IllegalStateException {
return startAsync(request, response);
@@ -189,7 +206,7 @@ public class PortletResourceRequestContextImpl extends PortletRequestContextImpl
if (actx != null) {
actx.setWrapped(hreq.startAsync(wreq, wresp));
} else {
- actx = new PortletAsyncContextImpl(hreq.startAsync(wreq, wresp), wreq);
+ actx = new PortletAsyncContextImpl(hreq.startAsync(wreq, wresp), this, request);
}
if (isTrace) {