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 wo...@apache.org on 2009/03/24 16:48:48 UTC

svn commit: r757857 - in /portals/pluto/trunk/pluto-container/src/main: java/org/apache/pluto/container/impl/ java/org/apache/pluto/container/util/ resources/org/apache/pluto/container/driver/impl/

Author: woonsan
Date: Tue Mar 24 15:48:44 2009
New Revision: 757857

URL: http://svn.apache.org/viewvc?rev=757857&view=rev
Log:
PLUTO-542: ContainerRuntimeOption - servletDefaultSessionScope support by default.
- Adds the functionality by default in the pluto side.

This functionality can be tested:
  - portlet.xml should have container-runtime-option like the following:
  
   <container-runtime-option>
    <name>javax.portlet.servletDefaultSessionScope</name>
    <value>PORTLET_SCOPE</value>
  </container-runtime-option>
  
 - A test jsp can have the following test code fragment:

// set app scope attribute 
renderRequest.getPortletSession().setAttribute("testvarapp", "testvalueapp",
                                               javax.portlet.PortletSession.APPLICATION_SCOPE);
// set portlet scope attribute
renderRequest.getPortletSession().setAttribute("testvarplt", "testvalueplt",
                                               javax.portlet.PortletSession.PORTLET_SCOPE);
// see if the app scope session variable is visible
out.println("testvarapp: " + session.getAttribute("testvarapp"));
// see if the portlet scope session variable is visible
out.println("testvarplt: " + session.getAttribute("testvarplt"));

With the configuration in portlet.xml as mentioned above, the second only will be printed.
Otherwise, the former only will be visible.

Added:
    portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java   (with props)
    portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/util/NamespacedNamesEnumeration.java   (with props)
Modified:
    portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestDispatcherImpl.java
    portals/pluto/trunk/pluto-container/src/main/resources/org/apache/pluto/container/driver/impl/pluto-configuration.properties

Modified: portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestDispatcherImpl.java
URL: http://svn.apache.org/viewvc/portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestDispatcherImpl.java?rev=757857&r1=757856&r2=757857&view=diff
==============================================================================
--- portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestDispatcherImpl.java (original)
+++ portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestDispatcherImpl.java Tue Mar 24 15:48:44 2009
@@ -17,8 +17,10 @@
 package org.apache.pluto.container.impl;
 
 import java.io.IOException;
+import java.util.Map;
 
 import javax.portlet.MimeResponse;
+import javax.portlet.PortletConfig;
 import javax.portlet.PortletException;
 import javax.portlet.PortletRequest;
 import javax.portlet.PortletRequestDispatcher;
@@ -31,6 +33,7 @@
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpServletResponseWrapper;
+import javax.servlet.http.HttpSession;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -46,7 +49,7 @@
  */
 public class PortletRequestDispatcherImpl implements PortletRequestDispatcher, RequestDispatcher
 {	
-	/** Logger. */
+    /** Logger. */
     private static final Log LOG = LogFactory.getLog(PortletRequestDispatcherImpl.class);
     
     // Private Member Variables ------------------------------------------------
@@ -136,9 +139,18 @@
         }
         
         PortletRequestContext requestContext = (PortletRequestContext)request.getAttribute(PortletInvokerService.REQUEST_CONTEXT);
+        HttpSession session = null;
+        
+        // PLT.10.4.3. Proxied session is created and passed if javax.portlet.servletDefaultSessionScope == PORTLET_SCOPE
+        if (isPortletScopeSessionConfigured(requestContext))
+        {
+            String portletWindowId = requestContext.getPortletWindow().getId().getStringId();
+            session = ServletPortletSessionProxy.createProxy(requestContext.getServletRequest(), portletWindowId);
+        }
+        
         HttpServletPortletRequestWrapper req = new HttpServletPortletRequestWrapper(requestContext.getServletRequest(), 
                                                                                     requestContext.getServletContext(),
-                                                                                    null, // TODO: ProxySession if javax.portlet.servletDefaultSessionScope == PORTLET_SCOPE
+                                                                                    session,
                                                                                     request,
                                                                                     pathInfo,
                                                                                     included);
@@ -183,6 +195,22 @@
             req.removeAttribute(PortletInvokerService.PORTLET_RESPONSE);
         }
     }
+    
+    private boolean isPortletScopeSessionConfigured(PortletRequestContext requestContext)
+    {
+        boolean portletScopeSessionConfigured = false;
+        
+        PortletConfig portletConfig = requestContext.getPortletConfig();
+        Map<String, String []> containerRuntimeOptions = portletConfig.getContainerRuntimeOptions();
+        String [] values = containerRuntimeOptions.get("javax.portlet.servletDefaultSessionScope");
+        
+        if (values != null && values.length > 0)
+        {
+            portletScopeSessionConfigured = "PORTLET_SCOPE".equals(values[0]);
+        }
+        
+        return portletScopeSessionConfigured;
+    }
 
     private void doDispatch(ServletRequest request, ServletResponse response, HttpServletPortletRequestWrapper req,
                             HttpServletPortletResponseWrapper res, boolean included) throws ServletException, IOException

Added: portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java
URL: http://svn.apache.org/viewvc/portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java?rev=757857&view=auto
==============================================================================
--- portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java (added)
+++ portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java Tue Mar 24 15:48:44 2009
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pluto.container.impl;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.pluto.container.util.NamespacedNamesEnumeration;
+
+/**
+ * Proxy for a Servlet HttpSession to attach to 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.
+ * 
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class ServletPortletSessionProxy implements InvocationHandler
+{
+    HttpSession servletSession;
+    String portletWindowId;
+    String portletScopeAttrNamePrefix;
+
+    public static HttpSession createProxy(HttpServletRequest request, String portletWindowId)
+    {
+        HttpSession servletSession = request.getSession();
+        HashSet interfaces = new HashSet();
+        interfaces.add(HttpSession.class);
+        Class current = servletSession.getClass();
+        while (current != null)
+        {
+            try
+            {
+                Class[] currentInterfaces = current.getInterfaces();
+                for (int i = 0; i < currentInterfaces.length; i++)
+                {
+                    interfaces.add(currentInterfaces[i]);
+                }
+                current = current.getSuperclass();
+            }
+            catch (Exception e)
+            {
+                current = null;
+            }
+        }
+        Object proxy = Proxy.newProxyInstance(servletSession.getClass().getClassLoader(), 
+                (Class[])interfaces.toArray(new Class[interfaces.size()]), 
+                new ServletPortletSessionProxy(request.getSession(), portletWindowId));
+        return (HttpSession)proxy;
+    }
+
+    private ServletPortletSessionProxy(HttpSession servletSession, String portletWindowId)
+    {
+        this.servletSession = servletSession;
+        this.portletWindowId = portletWindowId;
+        this.portletScopeAttrNamePrefix = PortletSessionImpl.PORTLET_SCOPE_NAMESPACE + this.portletWindowId + PortletSessionImpl.ID_NAME_SEPARATOR;
+    }
+
+    /**
+     * (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 = servletSession.getAttribute(this.portletScopeAttrNamePrefix + (String) args[0]);
+        }
+        else if (("setAttribute".equals(m.getName()) || "putValue".equals(m.getName())) && args.length == 2 && args[0] instanceof String)
+        {
+            servletSession.setAttribute(this.portletScopeAttrNamePrefix + (String) args[0], args[1]);
+        }
+        else if (("removeAttribute".equals(m.getName()) || "removeValue".equals(m.getName())) && args.length == 1 && args[0] instanceof String)
+        {
+            servletSession.removeAttribute(this.portletScopeAttrNamePrefix + (String) args[0]);
+        }
+        else if ("getAttributeNames".equals(m.getName()) && args == null)
+        {
+            retval = new NamespacedNamesEnumeration(servletSession.getAttributeNames(), this.portletScopeAttrNamePrefix);
+        }
+        else if ("getValueNames".equals(m.getName()) && args == null)
+        {
+            ArrayList list = new ArrayList();
+            Enumeration e = new NamespacedNamesEnumeration(servletSession.getAttributeNames(), this.portletScopeAttrNamePrefix);
+            while (e.hasMoreElements())
+            {
+                list.add(e.nextElement());
+            }
+            retval = list.toArray(new String[list.size()]);
+        }
+        else
+        {
+            retval = m.invoke(servletSession, args);
+        }
+        return retval;
+    }
+}

Propchange: portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/util/NamespacedNamesEnumeration.java
URL: http://svn.apache.org/viewvc/portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/util/NamespacedNamesEnumeration.java?rev=757857&view=auto
==============================================================================
--- portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/util/NamespacedNamesEnumeration.java (added)
+++ portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/util/NamespacedNamesEnumeration.java Tue Mar 24 15:48:44 2009
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.pluto.container.util;
+
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class NamespacedNamesEnumeration implements Enumeration
+{
+    private Enumeration namesEnumeration;
+    private String      namespace;
+    
+    private String nextName;
+    private boolean done;
+    
+    public NamespacedNamesEnumeration(Enumeration namesEnumeration, String namespace)
+    {
+        this.namesEnumeration = namesEnumeration;
+        this.namespace = namespace;
+        hasMoreElements();
+    }
+    
+    public boolean hasMoreElements()
+    {
+        if (!done)
+        {
+            if (nextName == null)
+            {
+                while (namesEnumeration.hasMoreElements())
+                {
+                    String name = (String)namesEnumeration.nextElement();
+                    if ( name.startsWith(namespace))
+                    {
+                        nextName = name.substring(namespace.length());
+                        break;
+                    }
+                }
+                done = nextName == null;
+            }
+        }
+        return !done;
+    }
+
+    public Object nextElement()
+    {
+        if (done)
+        {
+            throw new NoSuchElementException();
+        }
+        String name = nextName;
+        nextName = null;
+        return name;
+    }
+}

Propchange: portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/util/NamespacedNamesEnumeration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/util/NamespacedNamesEnumeration.java
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: portals/pluto/trunk/pluto-container/src/main/java/org/apache/pluto/container/util/NamespacedNamesEnumeration.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: portals/pluto/trunk/pluto-container/src/main/resources/org/apache/pluto/container/driver/impl/pluto-configuration.properties
URL: http://svn.apache.org/viewvc/portals/pluto/trunk/pluto-container/src/main/resources/org/apache/pluto/container/driver/impl/pluto-configuration.properties?rev=757857&r1=757856&r2=757857&view=diff
==============================================================================
--- portals/pluto/trunk/pluto-container/src/main/resources/org/apache/pluto/container/driver/impl/pluto-configuration.properties (original)
+++ portals/pluto/trunk/pluto-container/src/main/resources/org/apache/pluto/container/driver/impl/pluto-configuration.properties Tue Mar 24 15:48:44 2009
@@ -25,4 +25,4 @@
 javax.portlet.version.minor=${javax.portlet.version.minor}
 
 org.apache.pluto.descriptors.services.PortletAppDescriptorService=org.apache.pluto.container.impl.PortletAppDescriptorServiceImpl
-org.apache.pluto.container.supportedContainerRuntimeOptions=test,escapeXML,value
+org.apache.pluto.container.supportedContainerRuntimeOptions=test,escapeXML,value,javax.portlet.servletDefaultSessionScope