View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" 
13   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
14   * See the License for the specific language governing permissions and 
15   * limitations under the License.
16   */
17  package org.apache.portals.bridges.util;
18  
19  import java.lang.reflect.InvocationHandler;
20  import java.lang.reflect.Method;
21  import java.lang.reflect.Proxy;
22  import java.util.ArrayList;
23  import java.util.Enumeration;
24  import java.util.HashSet;
25  
26  import javax.portlet.PortletRequest;
27  import javax.portlet.PortletSession;
28  import javax.servlet.http.HttpServletRequest;
29  import javax.servlet.http.HttpSession;
30  
31  /***
32   * Proxy for a Servlet HttpSession to attach to a PortletSession, providing only access to PORTLET_SCOPE session attributes
33   * and hiding the APPLICATION_SCOPE attributes from the Servlet.
34   * <br/>
35   * This Proxy can be used to isolate two instances of the same Portlet dispatching to Servlets so they don't overwrite or read
36   * each others session attributes.
37   * <br/>
38   * Caveat: APPLICATION_SCOPE sessions attributes cannot be used anymore (directly) for inter-portlet communication,
39   * or when using Servlets directly which also need to "attach" to the PORTLET_SCOPE session attributes.<br/>
40   * The  {@link PortletWindowUtils} class can help out with that though.
41  
42   * @see PortletWindowUtils
43   * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
44   * @version $Id: ServletPortletSessionProxy.java 549659 2007-06-22 01:21:29Z ate $
45   * 
46   */
47  public class ServletPortletSessionProxy implements InvocationHandler
48  {
49      HttpSession servletSession;
50      String portletWindowPrefix;
51  
52      public static HttpSession createProxy(HttpServletRequest request)
53      {
54          HttpSession servletSession = request.getSession();
55          PortletRequest portletRequest = (PortletRequest) request.getAttribute("javax.portlet.request");
56          if (portletRequest != null)
57          {
58              PortletSession portletSession = portletRequest.getPortletSession();
59              servletSession = (HttpSession)createProxy(request, "javax.portlet.p."+PortletWindowUtils.getPortletWindowId(portletSession));
60          }
61          return servletSession;
62      }
63  
64      public static HttpSession createProxy(HttpServletRequest request, String portletWindowNamespace)
65      {
66          HttpSession servletSession = request.getSession();
67          HashSet interfaces = new HashSet();
68          interfaces.add(HttpSession.class);
69          Class current = servletSession.getClass();
70          while (current != null)
71          {
72              try
73              {
74                  Class[] currentInterfaces = current.getInterfaces();
75                  for (int i = 0; i < currentInterfaces.length; i++)
76                  {
77                      interfaces.add(currentInterfaces[i]);
78                  }
79                  current = current.getSuperclass();
80              }
81              catch (Exception e)
82              {
83                  current = null;
84              }
85          }
86          Object proxy = Proxy.newProxyInstance(servletSession.getClass().getClassLoader(), 
87                  (Class[])interfaces.toArray(new Class[interfaces.size()]), new ServletPortletSessionProxy(request.getSession(),
88                          portletWindowNamespace));
89          return (HttpSession)proxy;
90      }
91  
92      private ServletPortletSessionProxy(HttpSession servletSession, String portletWindowPrefix)
93      {
94          this.servletSession = servletSession;
95          this.portletWindowPrefix = portletWindowPrefix;
96      }
97  
98      /***
99       * (non-Javadoc)
100      * 
101      * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
102      *      java.lang.reflect.Method, java.lang.Object[])
103      */
104     public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
105     {
106         Object retval = null;
107         if (("getAttribute".equals(m.getName()) || "getValue".equals(m.getName())) && args.length == 1 && args[0] instanceof String)
108         {
109             retval = servletSession.getAttribute(portletWindowPrefix+(String)args[0]);
110         }
111         else if (("setAttribute".equals(m.getName()) || "putValue".equals(m.getName())) && args.length == 2 && args[0] instanceof String)
112         {
113             servletSession.setAttribute(portletWindowPrefix+(String)args[0],args[1]);
114         }
115         else if (("removeAttribute".equals(m.getName()) || "removeValue".equals(m.getName())) && args.length == 1 && args[0] instanceof String)
116         {
117             servletSession.removeAttribute(portletWindowPrefix+(String)args[0]);
118         }
119         else if ("getAttributeNames".equals(m.getName()) && args == null)
120         {
121             retval = new NamespacedNamesEnumeration(servletSession.getAttributeNames(), portletWindowPrefix);
122         }
123         else if ("getValueNames".equals(m.getName()) && args == null)
124         {
125             ArrayList list = new ArrayList();
126             Enumeration e = new NamespacedNamesEnumeration(servletSession.getAttributeNames(), portletWindowPrefix);
127             while (e.hasMoreElements())
128             {
129                 list.add(e.nextElement());
130             }
131             retval = list.toArray(new String[list.size()]);
132         }
133         else
134         {
135             retval = m.invoke(servletSession, args);
136         }
137         return retval;
138     }
139 }