/**
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.webservice.handler;

// $Id: ServerHandlerChain.java,v 1.6.2.4 2005/04/22 11:28:31 tdiesler Exp $

import org.jboss.axis.providers.java.RPCInvocation;
import org.jboss.axis.providers.java.RPCProvider;
import org.jboss.logging.Logger;

import javax.xml.rpc.handler.MessageContext;
import java.util.List;
import java.util.Set;

/**
 * Represents a list of handlers. All elements in the
 * HandlerChain are of the type javax.xml.rpc.handler.Handler.
 * <p/>
 * Abstracts the policy and mechanism for the invocation of the registered handlers.
 *
 * @author Thomas.Diesler@jboss.org
 * @since 06-May-2004
 */
public class ServerHandlerChain extends HandlerChainBaseImpl
{
   private static Logger log = Logger.getLogger(ServerHandlerChain.class);

   public ServerHandlerChain(List infos, Set roles)
   {
      super(infos, roles);
   }

   /**
    * Gets the RPCInvocation before the the server handler chain is invoked, gets it again
    * after handler processing and replaces it in the message contaxt in case the handlers
    * modified the request SOAPEnvelope.
    */
   public boolean handleRequest(MessageContext msgContext)
   {
      RPCInvocation invBefore = (RPCInvocation)msgContext.getProperty(RPCProvider.RPC_INVOCATION);
      if (invBefore == null)
         throw new IllegalStateException("Cannot obtain RPCInvocation from message context");

      String xmlBefore = invBefore.getRequestEnvelope().getAsStringFromInternal();
      if (log.isTraceEnabled())
         log.trace("RequestEnvelope before request handlers: " + xmlBefore);

      boolean doNext = super.handleRequest(msgContext);

      checkMustUnderstand(msgContext);

      RPCInvocation invAfter = new RPCInvocation(invBefore);
      invAfter.prepareFromRequestEnvelope();

      String xmlAfter = invAfter.getRequestEnvelope().getAsStringFromInternal();
      if (xmlBefore.equals(xmlAfter) == false)
      {
         if (log.isTraceEnabled())
            log.trace("RequestEnvelope after request handlers: " + xmlAfter);

         msgContext.setProperty(RPCProvider.RPC_INVOCATION, invAfter);
      }

      return doNext;
   }

   /**
    * Initiates the response processing for this handler chain.
    * <p/>
    * In this implementation, the response handler chain starts processing from the same Handler
    * instance (that returned false) and goes backward in the execution sequence.
    *
    * @return Returns true if all handlers in chain have been processed.
    *         Returns false if a handler in the chain returned false from its handleResponse method.
    * @throws javax.xml.rpc.JAXRPCException if any processing error happens
    */
   public boolean handleResponse(MessageContext msgContext)
   {
      boolean status = super.handleResponse(msgContext);

      checkMustUnderstand(msgContext);

      return status;
   }
}
