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 }