Author: ate
Date: Thu Feb 22 17:28:50 2007
New Revision: 510753
URL: http://svn.apache.org/viewvc?view=rev&rev=510753
Log:
Fixing PB-38: Switching between View and Edit modes, portlet remembers only the
last action (and not the last action in that mode) and goes to that regardless
of the mode.
and PB-49: Multiple instances of a struts portlet should be able to coexist
on a single page
Added:
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/PortletWindowUtils.java
(with props)
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/ServletPortletSessionProxy.java
(with props)
Modified:
portals/bridges/trunk/struts/pom.xml
portals/bridges/trunk/struts/project.xml
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServlet.java
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestDispatcher.java
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestWrapper.java
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortlet.java
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortletURL.java
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/config/RenderContextAttributes.java
portals/bridges/trunk/struts/xdocs/features.xml
Added:
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/PortletWindowUtils.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/PortletWindowUtils.java?view=auto&rev=510753
==============================================================================
---
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/PortletWindowUtils.java
(added)
+++
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/PortletWindowUtils.java
Thu Feb 22 17:28:50 2007
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2000-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.portals.bridges.util;
+
+import java.util.Enumeration;
+
+import javax.portlet.PortletSession;
+import javax.portlet.PortletSessionUtil;
+
+/**
+ * PortletWindowUtils
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Ate Douma</a>
+ * @version $Id$
+ */
+public class PortletWindowUtils
+{
+ public static String PORTLET_WINDOW_ID =
"org.apache.portals.bridges.util.portlet_window_id";
+
+ /**
+ * Return the unique identification for the portlet window as assigned by
the portal/portlet-container.
+ * <br/>
+ * This method makes use of the PortletSession to determine the window id
as specified by the Portlet Specification 1.0, PLT.15.3,
+ * as well as stores the determined value under the [EMAIL PROTECTED]
#PORTLET_WINDOW_ID} in the portlet scope session.
+ *
+ * @param session the current PortletSession
+ * @return the unique identification of the portlet window
+ */
+ public static String getPortletWindowId(PortletSession session)
+ {
+ String portletWindowId =
(String)session.getAttribute(PORTLET_WINDOW_ID);
+ if ( portletWindowId == null )
+ {
+ synchronized (session)
+ {
+ Double value = new Double(Math.random());
+ session.setAttribute(PORTLET_WINDOW_ID, value);
+ Enumeration names =
session.getAttributeNames(PortletSession.APPLICATION_SCOPE);
+ while (names.hasMoreElements())
+ {
+ String name = (String)names.nextElement();
+ if
(PortletSessionUtil.decodeAttributeName(name).equals(PORTLET_WINDOW_ID) &&
value.equals(session.getAttribute(name,PortletSession.APPLICATION_SCOPE)) )
+ {
+ portletWindowId =
name.substring("javax.portlet.p.".length(),name.indexOf('?'));
+ session.setAttribute(PORTLET_WINDOW_ID,
portletWindowId);
+ break;
+ }
+ }
+ }
+ }
+ return portletWindowId;
+ }
+
+ /**
+ * Returns the name an attribute is (or will be) encoded in the
PortletSession APPLICATION_SCOPE.
+ * @param session PortletSession
+ * @param attributeName the attribute name to encode
+ */
+ public static String
getApplicationScopeSessionAttributeName(PortletSession session, String
attributeName)
+ {
+ return
getApplicationScopeSessionAttributeName(getPortletWindowId(session),attributeName);
+ }
+
+ /**
+ * Returns the name an attribute is (or will be) encoded in the
PortletSession APPLICATION_SCOPE.
+ *
+ * @param portletWindowId the unique portlet window identification
retrieved from [EMAIL PROTECTED] #getPortletWindowId(PortletSession)}.
+ * @param attributeName the attribute name to encode
+ */
+ public static String getApplicationScopeSessionAttributeName(String
portletWindowId, String attributeName)
+ {
+ return "javax.portlet.p."+portletWindowId+"?"+attributeName;
+ }
+}
Propchange:
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/PortletWindowUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/PortletWindowUtils.java
------------------------------------------------------------------------------
svn:keywords = Id
Added:
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/ServletPortletSessionProxy.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/ServletPortletSessionProxy.java?view=auto&rev=510753
==============================================================================
---
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/ServletPortletSessionProxy.java
(added)
+++
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/ServletPortletSessionProxy.java
Thu Feb 22 17:28:50 2007
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2000-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS"
+ * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.portals.bridges.util;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletSession;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Proxy for a Servlet HttpSession to wrap a PortletSession, providing only
access to PORTLET_SCOPE session attributes
+ * and hiding the APPLICATION_SCOPE attributes from the Servlet.
+ * <br/>
+ * This Proxy can be used to isolate two instances of the same Portlet
dispatching to Servlets so they don't overwrite or read
+ * each others session attributes.
+ * <br/>
+ * Caveat: APPLICATION_SCOPE sessions attributes cannot be used anymore
(directly) for inter-portlet communication,
+ * or when using Servlets directly which also need to "attach" to the
PORTLET_SCOPE session attributes.<br/>
+ * The [EMAIL PROTECTED] PortletWindowUtils} class can help out with that
though.
+
+ * @see PortletWindowUtils
+ * @author <a href="mailto:[EMAIL PROTECTED]">Ate Douma</a>
+ * @version $Id$
+ *
+ */
+public class ServletPortletSessionProxy implements InvocationHandler
+{
+ HttpSession servletSession;
+ PortletSession portletSession;
+
+ public static HttpSession createProxy(HttpServletRequest request)
+ {
+ HttpSession servletSession = request.getSession();
+ PortletRequest portletRequest = (PortletRequest)
request.getAttribute("javax.portlet.request");
+ if (portletRequest != null)
+ {
+ PortletSession portletSession = portletRequest.getPortletSession();
+ servletSession = (HttpSession)
Proxy.newProxyInstance(servletSession.getClass().getClassLoader(),
+ servletSession.getClass().getInterfaces(), new
ServletPortletSessionProxy(servletSession,
+ portletSession));
+ }
+ return servletSession;
+ }
+
+ private ServletPortletSessionProxy(HttpSession servletSession,
PortletSession portletSession)
+ {
+ this.servletSession = servletSession;
+ this.portletSession = portletSession;
+ }
+
+ /**
+ * (non-Javadoc)
+ *
+ * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
+ * java.lang.reflect.Method, java.lang.Object[])
+ */
+ public Object invoke(Object proxy, Method m, Object[] args) throws
Throwable
+ {
+ Object retval = null;
+ if (("getAttribute".equals(m.getName()) ||
"getValue".equals(m.getName())) && args.length == 1 && args[0] instanceof
String)
+ {
+ retval = portletSession.getAttribute((String)args[0]);
+ }
+ else if (("setAttribute".equals(m.getName()) ||
"putValue".equals(m.getName())) && args.length == 2 && args[0] instanceof
String)
+ {
+ portletSession.setAttribute((String)args[0], args[1]);
+ }
+ else if (("removeAttribute".equals(m.getName()) ||
"removeValue".equals(m.getName())) && args.length == 1 && args[0] instanceof
String)
+ {
+ portletSession.removeAttribute((String)args[0]);
+ }
+ else if (("getAttributeNames".equals(m.getName()) ||
"getValueNames".equals(m.getName())) && args.length == 0)
+ {
+
+ retval = portletSession.getAttributeNames();
+ }
+ else
+ {
+ retval = m.invoke(servletSession, args);
+ }
+ return retval;
+ }
+}
Propchange:
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/ServletPortletSessionProxy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
portals/bridges/trunk/common/src/java/org/apache/portals/bridges/util/ServletPortletSessionProxy.java
------------------------------------------------------------------------------
svn:keywords = Id
Modified: portals/bridges/trunk/struts/pom.xml
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/struts/pom.xml?view=diff&rev=510753&r1=510752&r2=510753
==============================================================================
--- portals/bridges/trunk/struts/pom.xml (original)
+++ portals/bridges/trunk/struts/pom.xml Thu Feb 22 17:28:50 2007
@@ -58,6 +58,10 @@
<artifactId>commons-digester</artifactId>
</dependency>
<dependency>
+ <groupId>commons-beanutils</groupId>
+ <artifactId>commons-beanutils</artifactId>
+ </dependency>
+ <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
Modified: portals/bridges/trunk/struts/project.xml
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/struts/project.xml?view=diff&rev=510753&r1=510752&r2=510753
==============================================================================
--- portals/bridges/trunk/struts/project.xml (original)
+++ portals/bridges/trunk/struts/project.xml Thu Feb 22 17:28:50 2007
@@ -49,9 +49,10 @@
<id>commons-digester</id>
<version>1.5</version>
<url>http://jakarta.apache.org/commons/digester.html</url>
- <properties>
- <war.bundle>true</war.bundle>
- </properties>
+ </dependency>
+ <dependency>
+ <id>commons-beanutils</id>
+ <version>1.7.0</version>
</dependency>
<dependency>
<id>struts</id>
Modified:
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServlet.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServlet.java?view=diff&rev=510753&r1=510752&r2=510753
==============================================================================
---
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServlet.java
(original)
+++
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServlet.java
Thu Feb 22 17:28:50 2007
@@ -128,21 +128,14 @@
if (!request.getAttribute(StrutsPortlet.REQUEST_TYPE).equals(
StrutsPortlet.ACTION_REQUEST))
{
- StrutsPortletRenderContext context = null;
+ StrutsPortletRenderContext context =
(StrutsPortletRenderContext)request.getAttribute(StrutsPortlet.RENDER_CONTEXT);
- String portletName = (String)
request.getAttribute(StrutsPortlet.PORTLET_NAME);
-
- String contextKey = StrutsPortlet.RENDER_CONTEXT + "_"
+ portletName;
- context = (StrutsPortletRenderContext) request
- .getSession(true)
- .getAttribute(contextKey);
if (context != null)
{
if (log.isDebugEnabled())
{
log.debug("render context path: " + context.getPath());
}
- request.getSession().removeAttribute(contextKey);
if (context.getActionForm() != null) {
String attribute = mapping.getAttribute();
if (attribute != null) {
Modified:
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestDispatcher.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestDispatcher.java?view=diff&rev=510753&r1=510752&r2=510753
==============================================================================
---
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestDispatcher.java
(original)
+++
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestDispatcher.java
Thu Feb 22 17:28:50 2007
@@ -22,7 +22,6 @@
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -101,20 +100,8 @@
originURL);
}
}
- String portletName = (String)
req.getAttribute(StrutsPortlet.PORTLET_NAME);
- try
- {
- req.getSession(true).setAttribute(StrutsPortlet.RENDER_CONTEXT
+ "_" + portletName, context);
- }
- catch (IllegalStateException ise)
- {
- // catch Session already invalidated Exception
- if (log.isDebugEnabled())
- {
- log.debug("Session invalidated: redirecting to: "+path+"
instead.");
- }
- ((HttpServletResponse)response).sendRedirect(path);
- }
+ // save context in the request, StrutsPortlet will store it in the
Portlet Session later on
+ req.setAttribute(StrutsPortlet.RENDER_CONTEXT, context);
}
else
{
Modified:
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestWrapper.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestWrapper.java?view=diff&rev=510753&r1=510752&r2=510753
==============================================================================
---
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestWrapper.java
(original)
+++
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/PortletServletRequestWrapper.java
Thu Feb 22 17:28:50 2007
@@ -19,6 +19,7 @@
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -33,10 +34,17 @@
{
private static final Log log =
LogFactory.getLog(PortletServletRequestWrapper.class);
private ServletContext context;
- public PortletServletRequestWrapper(ServletContext context,
HttpServletRequest request)
+ private HttpSession session;
+
+ public PortletServletRequestWrapper(ServletContext context,
HttpServletRequest request, HttpSession proxiedSession)
{
super(request);
this.context = context;
+ session = proxiedSession;
+ if ( proxiedSession == null )
+ {
+ session = request.getSession();
+ }
}
public String getPathInfo()
@@ -95,5 +103,10 @@
return new PortletServletRequestDispatcher(dispatcher, path,
false);
else
return null;
+ }
+
+ public HttpSession getSession()
+ {
+ return session;
}
}
Modified:
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortlet.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortlet.java?view=diff&rev=510753&r1=510752&r2=510753
==============================================================================
---
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortlet.java
(original)
+++
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortlet.java
Thu Feb 22 17:28:50 2007
@@ -25,6 +25,7 @@
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
+import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.servlet.RequestDispatcher;
@@ -39,6 +40,7 @@
import org.apache.portals.bridges.common.ServletContextProvider;
import org.apache.portals.bridges.struts.config.StrutsPortletConfig;
import org.apache.portals.bridges.struts.util.EmptyHttpServletResponseWrapper;
+import org.apache.portals.bridges.util.ServletPortletSessionProxy;
/**
* StrutsPortlet
@@ -56,6 +58,8 @@
* Name of portlet preference for Struts Portlet Config Location
*/
public static final String STRUTS_PORTLET_CONFIG_LOCATION =
"StrutsPortletConfigLocation";
+
+ public static final String PORTLET_SCOPE_STRUTS_SESSION =
"PortletScopeStrutsSession";
/**
* Name of portlet preference for Action page
*/
@@ -97,6 +101,7 @@
*/
private String defaultViewPage = null;
private ServletContextProvider servletContextProvider;
+ private boolean portletScopeStrutsSession = false;
private static final Log log = LogFactory.getLog(StrutsPortlet.class);
public static final String REQUEST_TYPE =
"org.apache.portals.bridges.struts.request_type";
public static final String PAGE_URL =
"org.apache.portals.bridges.struts.page_url";
@@ -108,6 +113,8 @@
public static final String PORTLET_NAME =
"org.apache.portals.bridges.struts.portlet_name";
public static final String STRUTS_PORTLET_CONFIG =
"org.apache.portals.bridges.struts.portlet_config";
public static final String DEFAULT_STRUTS_PORTLET_CONFIG_LOCATION =
"WEB-INF/struts-portlet-config.xml";
+ public static final String SERVLET_PORTLET_SESSION_PROXY =
"org.apache.portals.bridges.util.servlet_portlet_session_proxy";
+ public static final String SERVLET_PORTLET_APPLICATION_SESSION =
"org.apache.portals.bridges.util.servlet_portlet_application_session";
public static final String ACTION_REQUEST = "ACTION";
public static final String VIEW_REQUEST = "VIEW";
public static final String CUSTOM_REQUEST = "CUSTOM";
@@ -152,6 +159,7 @@
+ " is incorrectly configured. Invalid init parameter "
+ PARAM_SERVLET_CONTEXT_PROVIDER + " value "
+ contextProviderClassName);
+ this.portletScopeStrutsSession =
getPortletScopeStrutsSessionParameter(config).booleanValue();
this.defaultActionPage = getActionPageParameter(config);
this.defaultCustomPage = getCustomPageParameter(config);
this.defaultEditPage = getEditPageParameter(config);
@@ -214,12 +222,25 @@
protected String getStrutsPageURL(PortletRequest request)
{
- return request.getParameter(StrutsPortletURL.PAGE);
+ if ( ACTION_REQUEST.equals(request.getAttribute(REQUEST_TYPE)))
+ {
+ return request.getParameter(StrutsPortletURL.PAGE);
+ }
+ return
request.getParameter(StrutsPortletURL.PAGE+request.getPortletMode().toString());
}
protected String getStrutsOriginURL(PortletRequest request)
{
- return request.getParameter(StrutsPortletURL.ORIGIN);
+ if ( ACTION_REQUEST.equals(request.getAttribute(REQUEST_TYPE)))
+ {
+ return request.getParameter(StrutsPortletURL.ORIGIN);
+ }
+ return
request.getParameter(StrutsPortletURL.ORIGIN+request.getPortletMode().toString());
+ }
+
+ protected String getKeepRenderAttributes(PortletRequest request)
+ {
+ return
request.getParameter(StrutsPortletURL.KEEP_RENDER_ATTRIBUTES+request.getPortletMode().toString());
}
protected String getActionPageParameter(PortletConfig config)
@@ -252,6 +273,11 @@
return config.getInitParameter(STRUTS_PORTLET_CONFIG_LOCATION);
}
+ protected Boolean getPortletScopeStrutsSessionParameter(PortletConfig
config)
+ {
+ return
Boolean.valueOf(config.getInitParameter(PORTLET_SCOPE_STRUTS_SESSION));
+ }
+
public void doEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
@@ -286,21 +312,23 @@
ServletContext servletContext = getServletContext(this, request,
response);
HttpServletRequest req = getHttpServletRequest(this, request,
response);
HttpServletResponse res = getHttpServletResponse(this, request,
response);
- HttpSession session = req.getSession();
String portletName = this.getPortletConfig().getPortletName();
req.setAttribute(PORTLET_NAME, portletName);
boolean actionRequest = ACTION_REQUEST.equals(requestType);
+ // save requestType early so getStrutsPageURL and getStrutsOrigURL can
determine the type
+ req.setAttribute(StrutsPortlet.REQUEST_TYPE, requestType);
+
+ PortletSession portletSession = request.getPortletSession();
+
try
{
- StrutsPortletErrorContext errorContext =
(StrutsPortletErrorContext) req
- .getSession().getAttribute(StrutsPortlet.ERROR_CONTEXT +
"_" + portletName);
+ StrutsPortletErrorContext errorContext =
(StrutsPortletErrorContext)
portletSession.getAttribute(StrutsPortlet.ERROR_CONTEXT);
if (errorContext != null)
{
if (!actionRequest)
{
- req.getSession().removeAttribute(
- StrutsPortlet.ERROR_CONTEXT + "_" + portletName);
+
portletSession.removeAttribute(StrutsPortlet.ERROR_CONTEXT);
renderError(res, errorContext);
}
return;
@@ -310,24 +338,35 @@
if ( !actionRequest )
{
- keepRenderAttributes =
request.getParameter(StrutsPortletURL.KEEP_RENDER_ATTRIBUTES);
+ keepRenderAttributes = getKeepRenderAttributes(request);
}
if ( keepRenderAttributes == null )
{
-
strutsPortletConfig.getRenderContextAttributes().clearAttributes(session);
+
strutsPortletConfig.getRenderContextAttributes().clearAttributes(portletSession);
}
else
{
-
strutsPortletConfig.getRenderContextAttributes().restoreAttributes(req);
+
strutsPortletConfig.getRenderContextAttributes().restoreAttributes(request);
}
String path = null;
String pageURL = getStrutsPageURL(request);
+
if (pageURL == null)
path = defaultPage;
else
{
path = pageURL;
+ if ( !actionRequest )
+ {
+ // restore possible render context from the session and
store it as request attribute for the StrutsServlet to be able to find it
+ StrutsPortletRenderContext renderContext =
(StrutsPortletRenderContext)portletSession.getAttribute(RENDER_CONTEXT);
+ if ( renderContext != null )
+ {
+ portletSession.removeAttribute(RENDER_CONTEXT);
+ req.setAttribute(RENDER_CONTEXT, renderContext);
+ }
+ }
}
if (log.isDebugEnabled())
@@ -369,10 +408,20 @@
req.setAttribute(StrutsPortlet.PAGE_URL, path);
}
- req.setAttribute(StrutsPortlet.REQUEST_TYPE, requestType);
+ HttpSession proxiedSession = null;
+ if ( portletScopeStrutsSession )
+ {
+ proxiedSession =
(HttpSession)portletSession.getAttribute(SERVLET_PORTLET_SESSION_PROXY);
+ if (proxiedSession == null)
+ {
+ proxiedSession =
ServletPortletSessionProxy.createProxy(req);
+
portletSession.setAttribute(SERVLET_PORTLET_SESSION_PROXY, proxiedSession);
+ }
+ }
+ req.setAttribute(SERVLET_PORTLET_APPLICATION_SESSION,
req.getSession());
try
{
- rd.include(new
PortletServletRequestWrapper(servletContext, req), res);
+ rd.include(new
PortletServletRequestWrapper(servletContext, req, proxiedSession), res);
}
catch (ServletException e)
{
@@ -392,15 +441,13 @@
pageURL = StrutsPortletURL.getOriginURL(req);
if ( pageURL != null )
{
- ((ActionResponse)
response).setRenderParameter(StrutsPortletURL.PAGE, pageURL);
+ ((ActionResponse)
response).setRenderParameter(StrutsPortletURL.PAGE+request.getPortletMode().toString(),
pageURL);
}
if (log.isDebugEnabled())
log.debug("action render error context");
try
{
- req.getSession(true).setAttribute(
- StrutsPortlet.ERROR_CONTEXT + "_" +
portletName,
-
req.getAttribute(StrutsPortlet.ERROR_CONTEXT));
+
portletSession.setAttribute(StrutsPortlet.ERROR_CONTEXT,req.getAttribute(StrutsPortlet.ERROR_CONTEXT));
}
catch (IllegalStateException ise)
{
@@ -420,9 +467,24 @@
}
else
{
-
strutsPortletConfig.getRenderContextAttributes().saveAttributes(req);
+ try
+ {
+
strutsPortletConfig.getRenderContextAttributes().saveAttributes(request);
+ }
+ catch (IllegalStateException ise)
+ {
+ // catch Session already invalidated exception
+ // There isn't much we can do here other than
+ // redirecting the user to the start page
+ return;
+ }
+ StrutsPortletRenderContext renderContext =
(StrutsPortletRenderContext)req.getAttribute(RENDER_CONTEXT);
+ if ( renderContext != null )
+ {
+ portletSession.setAttribute(RENDER_CONTEXT,
renderContext);
+ }
((ActionResponse) response).setRenderParameter(
- StrutsPortletURL.KEEP_RENDER_ATTRIBUTES,
"1");
+
StrutsPortletURL.KEEP_RENDER_ATTRIBUTES+request.getPortletMode().toString(),
"1");
if ((renderURL = (String) req
.getAttribute(StrutsPortlet.REDIRECT_PAGE_URL)) != null)
@@ -437,7 +499,7 @@
if (renderURL == null && log.isWarnEnabled())
log.warn("Warning: Using the original
action URL for render URL: " +pageURL+".\nA redirect should have been issued.");
((ActionResponse) response).setRenderParameter(
- StrutsPortletURL.PAGE, pageURL);
+
StrutsPortletURL.PAGE+request.getPortletMode().toString(), pageURL);
}
}
}
@@ -481,5 +543,15 @@
writer.println("</td></tr>");
}
writer.println("</table>");
+ }
+
+ public HttpSession getApplicationSession(HttpServletRequest request)
+ {
+ HttpSession appSession =
(HttpSession)request.getAttribute(SERVLET_PORTLET_APPLICATION_SESSION);
+ if ( appSession == null )
+ {
+ appSession = request.getSession();
+ }
+ return appSession;
}
}
Modified:
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortletURL.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortletURL.java?view=diff&rev=510753&r1=510752&r2=510753
==============================================================================
---
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortletURL.java
(original)
+++
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/StrutsPortletURL.java
Thu Feb 22 17:28:50 2007
@@ -16,6 +16,7 @@
package org.apache.portals.bridges.struts;
import javax.portlet.PortletURL;
+import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
@@ -34,7 +35,7 @@
public static String getPageURL(ServletRequest request)
{
- return request.getParameter(PAGE);
+ return (String)request.getAttribute(StrutsPortlet.PAGE_URL);
}
public static String getOriginURL(ServletRequest request)
{
@@ -57,12 +58,17 @@
if (pageURL.startsWith(contextPath))
pageURL = pageURL.substring(contextPath.length());
}
- portletURL.setParameter(PAGE, pageURL.replaceAll("&","&"));
if (actionURL)
{
+ portletURL.setParameter(PAGE, pageURL.replaceAll("&","&"));
String originURL = request.getParameter(PAGE);
if (originURL != null)
portletURL.setParameter(ORIGIN, originURL);
+ }
+ else
+ {
+ RenderRequest renderRequest =
(RenderRequest)request.getAttribute("javax.portlet.request");
+
portletURL.setParameter(PAGE+renderRequest.getPortletMode().toString(),
pageURL.replaceAll("&","&"));
}
return portletURL;
}
Modified:
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/config/RenderContextAttributes.java
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/config/RenderContextAttributes.java?view=diff&rev=510753&r1=510752&r2=510753
==============================================================================
---
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/config/RenderContextAttributes.java
(original)
+++
portals/bridges/trunk/struts/src/java/org/apache/portals/bridges/struts/config/RenderContextAttributes.java
Thu Feb 22 17:28:50 2007
@@ -5,8 +5,8 @@
import java.util.Enumeration;
import java.util.List;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletSession;
import org.apache.commons.digester.Digester;
@@ -90,6 +90,11 @@
prefixAttributesList = new ArrayList();
}
+ private static boolean isNotEmpty(String str)
+ {
+ return str != null && str.length() > 0;
+ }
+
private Attribute[] createArray(List attributes)
{
Attribute[] array = null;
@@ -146,7 +151,12 @@
prefixAttributesList = null;
}
- public void saveAttributes(HttpServletRequest request)
+ /**
+ * Save attributes in the PortletSession. This will ensure
+ * that each portlet instance will have its own render attributes.
+ * @param request The PortletRequest
+ */
+ public void saveAttributes(PortletRequest request)
{
ArrayList keepAttributes = new ArrayList();
ArrayList tempAttributes = new ArrayList();
@@ -202,23 +212,32 @@
keepAttributes.add(null); // indicating subsequent
attributeValues are temporarily
keepAttributes.addAll(tempAttributes);
}
- request.getSession().setAttribute(name,keepAttributes);
+ request.getPortletSession().setAttribute(name,keepAttributes);
}
else if (tempAttributes.size() > 0)
{
tempAttributes.add(0,null); // indicating subsequent
attributeValues are temporarily
- request.getSession().setAttribute(name,tempAttributes);
+ request.getPortletSession().setAttribute(name,tempAttributes);
}
}
- public void clearAttributes(HttpSession session)
+ /**
+ * Remove attributes from the PortletSession
+ * @param session The PortletSession
+ */
+ public void clearAttributes(PortletSession session)
{
session.removeAttribute(name);
}
- public void restoreAttributes(HttpServletRequest request)
+ /**
+ * Restore attributes from the PortletSession.
+ * @param request The portletRequest
+ */
+ public void restoreAttributes(PortletRequest request)
{
- ArrayList attributes =
(ArrayList)request.getSession().getAttribute(name);
+ PortletSession portletSession = request.getPortletSession();
+ ArrayList attributes = (ArrayList)portletSession.getAttribute(name);
if ( attributes != null )
{
for ( int size = attributes.size(), i = size - 1 ; i > -1; i-- )
@@ -228,7 +247,7 @@
{
if ( i == 0 )
{
- request.getSession().removeAttribute(name);
+ portletSession.removeAttribute(name);
}
else
{
Modified: portals/bridges/trunk/struts/xdocs/features.xml
URL:
http://svn.apache.org/viewvc/portals/bridges/trunk/struts/xdocs/features.xml?view=diff&rev=510753&r1=510752&r2=510753
==============================================================================
--- portals/bridges/trunk/struts/xdocs/features.xml (original)
+++ portals/bridges/trunk/struts/xdocs/features.xml Thu Feb 22 17:28:50 2007
@@ -68,6 +68,13 @@
</a>
</li>
<li>
+ <a href="#1.0.1: Multiple StrutsPortlet instances PORTLET_SCOPE
isolated StrutsServlet sessions">
+ 1.0.1: Multiple StrutsPortlet instances with the StrutsServlet
session isolated to PORTLET_SCOPE
+ </a>
+ </li>
+
+
+ <li>
Supports Struts releases 1.2.4 and 1.2.7
</li>
</ul>
@@ -431,6 +438,28 @@
<p>
Another benefit of such a "dual" mode Struts Application is that it
can be tested as Web Application
which <em>is</em> somewhat easier than testing it as a Portlet.
+ </p>
+ </subsection>
+ <subsection name="1.0.1: Multiple StrutsPortlet instances PORTLET_SCOPE
isolated StrutsServlet sessions">
+ <p>
+ The Struts framework itself, as well as many Struts applications
make have use of the (Servlet) Session for storing user state.
+ When you want to use multiple StrutsPortlets from the same web
application this can cause conflicts and session state corruption.
+ With Struts Bridge release 1.0.1, this now has been solved by
(optionally, and not by default) isolating the Session scope
+ seen by the StrutsServlet to PortletSession.PORTLET_SCOPE.
+ </p>
+ <p>
+ If the optional StrutsPortlet init parameter
<code>PortletScopeStrutsSession</code> is set to true, the Session object
provided to the
+ StrutsServlet will be a Proxy for the PortletSession and will
provide only access to the PortletSession.PORTLET_SCOPE attributes.
+ </p>
+ <p>
+ One caveat though: If you also need to use direct Servlet access to
the Struts application (meaning: the browser is invoking the
+ Servlet directly, not through the Portlet), this Servlet won't "see"
the previously APPLICATION_SCOPE Session attributes anymore.<br/>
+ This can be an issue for features like binary file (pdf) rendering
through a servlet which needs to use the Session to access its data.
+ To solve this, the utility
+ <a
href="../portals-bridges-common/apidocs/org/apache/portals/bridges/util/PortletWindowUtils.html">PortletWindowUtils</a>
class can
+ be used which provides methods to access a specific Portlet instance
its PORTLET_SCOPE session attributes based on its PortletWindowId.<br/>
+ That PortletWindowId (which a Portlet can retrieve itself using the
PortletWindowUtils) needs to be passed on to the Servlet first
+ (for example as query-string parameter on a link send to the
browser) for it to be able to make use of it.
</p>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]