/*
 * JBoss, the OpenSource WebOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package org.jboss.web.tomcat.security;

import java.security.Principal;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.servlet.http.HttpServletRequest;

import org.jboss.security.auth.callback.SecurityAssociationHandler;

/**
 * An implementation of CallbackHandler that extends the default
 * SecurityAssociationHandler to add Callbacks that only have sense in a Web
 * environment.
 * 
 * In order to use it you need to override the default CallbackHandler used by
 * the JaasSecurityManager.
 * 
 * @see javax.security.auth.callback.CallbackHandler
 * @see #handle(Callback[])
 * 
 * @author Ricardo Arguello (ricardoarguello@users.sourceforge.net)
 * @version $Revision: 1.1.2.1 $
 */
public class WebCallbackHandler extends SecurityAssociationHandler implements
      CallbackHandler
{
   public WebCallbackHandler()
   {
      super();
   }

   /**
    * Initialize the HttpServletRequestCallbackHandler with the principal and
    * credentials to use.
    */
   public WebCallbackHandler(Principal principal, Object credential)
   {
      super(principal, credential);
   }

   /**
    * @see org.jboss.security.auth.callback.SecurityAssociationHandler#setSecurityInfo(java.security.Principal,
    *      java.lang.Object)
    */
   public void setSecurityInfo(Principal principal, Object credential)
   {
      super.setSecurityInfo(principal, credential);
   }

   /**
    * @see javax.security.auth.callback.CallbackHandler#handle(javax.security.auth.callback.Callback[])
    */
   public void handle(Callback[] callbacks) throws UnsupportedCallbackException
   {
      try
      {
         super.handle(callbacks);
      }
      catch (UnsupportedCallbackException uce)
      {
         Callback c = uce.getCallback();

         if (c instanceof HttpServletRequestCallback)
         {
            // Get the HttpServletRequest from the Valve
            HttpServletRequest request = getHttpServletRequestFromValve();

            // Set it in the Callback
            HttpServletRequestCallback hsrc = (HttpServletRequestCallback) c;
            hsrc.setHttpServletRequest(request);
         }
         else
         {
            throw new UnsupportedCallbackException(c, "Unrecognized Callback");
         }
      }
   }

   /**
    * Obtains the HttpServletRequest saved inside the HttpServletRequestValve.
    * 
    * @return an HttpServletRequest.
    */
   protected HttpServletRequest getHttpServletRequestFromValve()
   {
      return (HttpServletRequest) HttpServletRequestValve.httpRequest.get();
   }
}