Package org.gatein.wsrp.handler

Source Code of org.gatein.wsrp.handler.RequestHeaderClientHandler$CurrentInfo

/*
* JBoss, a division of Red Hat
* Copyright 2010, Red Hat Middleware, LLC, and individual
* contributors as indicated by the @authors tag. See the
* copyright.txt in the distribution for a full listing of
* individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.gatein.wsrp.handler;

import org.gatein.wsrp.consumer.handlers.ProducerSessionInformation;

import javax.xml.namespace.QName;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* A WS-level handler to intercept cookies returned from the remote producer responses and provide them back again to the producer when invoking WS operations.
*
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @author <a href="mailto:chris.laprun@jboss.com">Chris Laprun</a>
*/
public class RequestHeaderClientHandler implements SOAPHandler<SOAPMessageContext>
{
   private static final ThreadLocal<CurrentInfo> local = new ThreadLocal<CurrentInfo>();

   public Set<QName> getHeaders()
   {
      return null;
   }

   public boolean handleMessage(SOAPMessageContext soapMessageContext)
   {
      // outbound message means request
      if (Boolean.TRUE.equals(soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)))
      {
         return handleRequest(soapMessageContext);
      }
      else
      {
         return handleResponse(soapMessageContext);
      }
   }

   public boolean handleFault(SOAPMessageContext soapMessageContext)
   {
      return true;
   }

   public void close(MessageContext messageContext)
   {
      // nothing to do
   }

   /**
    * Retrieves cookie information from currently held information and adds them to outbound (producer-bound) messages.
    *
    * @param msgContext the SOAP message context to add cookies to
    * @return <code>true</code> to continue processing, <code>false</code> otherwise (defined by {@link javax.xml.ws.handler.Handler#handleMessage(javax.xml.ws.handler.MessageContext)})
    */
   public boolean handleRequest(SOAPMessageContext msgContext)
   {
      final List<String> cookies = getCookiesFromCurrentInfo();
      if (cookies.isEmpty())
      {
         return true;
      }
      else
      {
         SOAPMessage message = msgContext.getMessage();

         // Legacy JBossWS native approach
         final MimeHeaders mimeHeaders = message.getMimeHeaders();
         // proper approach through MessageContext.HTTP_REQUEST_HEADERS
         List<String> cookieHeaders = getCookieHeaders(msgContext);

         for (String cookie : cookies)
         {
            mimeHeaders.addHeader(CookieUtil.COOKIE, cookie);
            cookieHeaders.add(cookie);
         }

         return true;
      }
   }

   private List<String> getCookieHeaders(SOAPMessageContext msgContext)
   {
      Map<String, List<String>> httpHeaders = (Map<String, List<String>>)msgContext.get(MessageContext.HTTP_REQUEST_HEADERS);
      if (httpHeaders == null)
      {
         httpHeaders = new HashMap<String, List<String>>();
         msgContext.put(MessageContext.HTTP_REQUEST_HEADERS, httpHeaders);
      }
      List<String> cookieHeaders = httpHeaders.get(CookieUtil.COOKIE);
      if (cookieHeaders == null)
      {
         cookieHeaders = new LinkedList<String>();
         httpHeaders.put(CookieUtil.COOKIE, cookieHeaders);
      }
      return cookieHeaders;
   }


   public static String createCoalescedCookieFromCurrentInfo()
   {
      return CookieUtil.coalesceCookies(getCookiesFromCurrentInfo());
   }

   private static List<String> getCookiesFromCurrentInfo()
   {
      CurrentInfo info = getCurrentInfo(false);
      if (info != null)
      {

         final ProducerSessionInformation sessionInfo = info.sessionInfo;
         if (sessionInfo == null)
         {
            return Collections.emptyList();
         }

         final List<String> cookies = new ArrayList<String>(7);
         if (sessionInfo.isPerGroupCookies())
         {
            if (info.groupId == null)
            {
               throw new IllegalStateException("Was expecting a current group Id...");
            }

            cookies.addAll(sessionInfo.getGroupCookiesFor(info.groupId));
         }

         cookies.addAll(sessionInfo.getUserCookies());

         return cookies;
      }

      return Collections.emptyList();
   }

   /**
    * Extracts any cookie from the inbound (provider-issued) message and make this information available to other WSRP components via {@link ProducerSessionInformation}.
    *
    * @param msgContext the inbound (provider-issued) message from which cookie information is extracted
    * @return <code>true</code> to continue processing, <code>false</code> otherwise (defined by {@link javax.xml.ws.handler.Handler#handleMessage(javax.xml.ws.handler.MessageContext)})
    */
   public boolean handleResponse(MessageContext msgContext)
   {
      SOAPMessageContext smc = (SOAPMessageContext)msgContext;
      SOAPMessage message = smc.getMessage();

      // get cookies
      // proper approach through MessageContext.HTTP_RESPONSE_HEADERS
      @SuppressWarnings("unchecked")
      Map<String, List<String>> httpHeaders = (Map<String, List<String>>)smc.get(MessageContext.HTTP_RESPONSE_HEADERS);
      List<String> cookieValues = httpHeaders.get(CookieUtil.SET_COOKIE);
      if (cookieValues == null)
      {
         // try the legacy JBossWS native approach
         MimeHeaders mimeHeaders = message.getMimeHeaders();
         final String[] cookieHeaders = mimeHeaders.getHeader(CookieUtil.SET_COOKIE);
         if (cookieHeaders != null)
         {
            cookieValues = Arrays.asList(cookieHeaders);
         }
      }

      // if we have cookies...
      if (cookieValues != null)
      {
         String endpointAddress = (String)msgContext.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
         if (endpointAddress == null)
         {
            throw new NullPointerException("Was expecting an endpoint address but none was provided in the MessageContext");
         }

         URL hostURL;
         try
         {
            hostURL = new URL(endpointAddress);
         }
         catch (MalformedURLException e)
         {
            // should not happen
            throw new IllegalArgumentException("'" + endpointAddress + "' is not a valid URL for the endpoint address.");
         }

         // extract their metadata and check that they are valid for the given domain
         final List<CookieUtil.Cookie> cookies = CookieUtil.extractCookiesFrom(hostURL, cookieValues);

         // retrieve the session information associated with this interaction
         CurrentInfo info = getCurrentInfo(true);
         ProducerSessionInformation sessionInfo = info.sessionInfo;

         // update the current information with the new information
         if (sessionInfo.isPerGroupCookies())
         {
            if (info.groupId == null)
            {
               throw new IllegalStateException("Was expecting a current group Id...");
            }

            sessionInfo.setGroupCookiesFor(info.groupId, cookies);
         }
         else
         {
            sessionInfo.setUserCookies(cookies);
         }
      }

      // allow other handlers in the chain to process the message
      return true;
   }

   /**
    * Updates the information associated with the current interactions with the specified information.
    *
    * @param groupId            the portlet group identifier (if any) associated with the portlet(s) being interacted with
    * @param sessionInformation the session metadata to associate with the current interaction
    */
   public static void setCurrentInfo(String groupId, ProducerSessionInformation sessionInformation)
   {
      local.set(new CurrentInfo(groupId, sessionInformation));
   }

   /** Removes any data associated with the current interaction. */
   public static void resetCurrentInfo()
   {
      local.set(null);
   }

   /**
    * Retrieves the session metadata associated with the current interaction.
    *
    * @return the session metadata associated with the current interaction or <code>null</code> if none currently exists
    */
   public static ProducerSessionInformation getCurrentProducerSessionInformation()
   {
      CurrentInfo info = getCurrentInfo(false);

      if (info != null)
      {
         return info.sessionInfo;
      }

      return null;
   }

   /**
    * Retrieves the portlet group identifier, if any, associated with the portlets being interacted with.
    *
    * @return the portlet group identifier associated with the portlets being interacted with or <code>null</code> if the portlets are not part of a group
    */
   public static String getCurrentGroupId()
   {
      CurrentInfo info = getCurrentInfo(false);
      if (info != null)
      {
         return info.groupId;
      }
      return null;
   }

   /**
    * Specifies that the portlets being interacted with are part of the portlet group identified by the specified group identifier
    *
    * @param groupId the group identifier for the group the portlets being interacted with are part of
    */
   public static void setCurrentGroupId(String groupId)
   {
      CurrentInfo currentInfo = local.get();
      if (currentInfo == null)
      {
         throw new IllegalStateException("Cannot set current group id when the current info hasn't been initialized.");
      }
      currentInfo.groupId = groupId;
   }

   private static CurrentInfo getCurrentInfo(boolean createIfNeeded)
   {
      CurrentInfo info = local.get();
      if (info == null && createIfNeeded)
      {
         info = new CurrentInfo(null, new ProducerSessionInformation());
         local.set(info);
      }
      return info;
   }

   /** Holder for the current (thread-specific) cookie and session information particular to this consumer-producer exchange. */
   static class CurrentInfo
   {
      public CurrentInfo(String groupId, ProducerSessionInformation sessionInfo)
      {
         this.groupId = groupId;
         this.sessionInfo = sessionInfo;
      }

      /** The WSRP groupId for the portlet being invoked */
      String groupId;
      /** Session information */
      ProducerSessionInformation sessionInfo;
   }
}
TOP

Related Classes of org.gatein.wsrp.handler.RequestHeaderClientHandler$CurrentInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.