| ServiceEndpointInterceptor.java |
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.webservice.server;
// $Id: ServiceEndpointInterceptor.java,v 1.4.4.2 2005/03/02 14:32:32 tdiesler Exp $
import org.jboss.axis.providers.java.RPCInvocation;
import org.jboss.axis.providers.java.RPCProvider;
import org.jboss.ejb.plugins.AbstractInterceptor;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.InvocationKey;
import org.jboss.webservice.Constants;
import javax.xml.rpc.handler.HandlerChain;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
/**
* This Interceptor does the ws4ee handler processing.
* <p/>
* According to the ws4ee spec the handler logic must be invoked after the container
* applied method level security to the invocation. I don't think we can use Axis handlers
* for ws4ee handler processing.
*
* @author Thomas.Diesler@jboss.org
* @version $Revision: 1.4.4.2 $
*/
public class ServiceEndpointInterceptor
extends AbstractInterceptor
{
// Interceptor implementation --------------------------------------
/**
* Before and after we call the service endpoint bean, we process the handler chains.
* <p/>
* The handler chain implemantation may replace the RPCInvocation object in the message context
* if it finds the the handlers have modyfied the SOAPEnvelope.
* <p/>
* When you change the implementation here, make sure you do the same in the InvokerProviderJSE
*/
public Object invoke(final Invocation mi) throws Exception
{
// It's not for us
SOAPMessageContext msgContext = (SOAPMessageContext)mi.getPayloadValue(InvocationKey.SOAP_MESSAGE_CONTEXT);
if (msgContext == null)
{
return getNext().invoke(mi);
}
// Handlers need to be Tx. Therefore we must invoke the handler chain after the TransactionInterceptor.
// Invoking the ws4ee handlers from an axis handler would be far too early in the invocation path.
HandlerChain handlerChain = (HandlerChain)msgContext.getProperty(Constants.HANDLER_CHAIN);
if (handlerChain == null)
throw new IllegalStateException("Cannot obtain handler chain from msg context");
// Get the invocation object from the message context
RPCInvocation invocation = (RPCInvocation)msgContext.getProperty(RPCProvider.RPC_INVOCATION);
if (invocation == null)
throw new IllegalStateException("Cannot obtain RPCInvocation from message context");
try
{
// Call the request handler chain
if (handlerChain.handleRequest(msgContext) == false)
{
log.warn("FIXME: handlerChain.handleRequest() returned false");
return null;
}
// The handler chain might have replaced the invocation object
RPCInvocation invAfterRequestHandler = (RPCInvocation)msgContext.getProperty(RPCProvider.RPC_INVOCATION);
// Replace the arguments in the method invocation
if (invocation.equals(invAfterRequestHandler) == false)
{
Object[] args = invAfterRequestHandler.getArgValues();
if (args.length != mi.getArguments().length)
throw new IllegalArgumentException("Invalid argument list in RPCInvocation");
for (int i = 0; i < args.length; i++)
{
Class miClass = mi.getArguments()[i].getClass();
Class rpcClass = args[i].getClass();
if (miClass.isAssignableFrom(rpcClass) == false)
throw new IllegalArgumentException("RPCInvocation argument cannot be assigned: " + miClass.getName() + " != " + rpcClass.getName());
mi.getArguments()[i] = args[i];
}
}
}
catch (Exception e)
{
log.error("Error processing request handler chain", e);
throw e;
}
Object resObj = null;
try
{
// Call the next interceptor in the chain
resObj = getNext().invoke(mi);
}
catch (Exception e)
{
msgContext.setProperty(Constants.LAST_FAULT, e);
log.error("Error from service endpoint, processing fault handler chain", e);
// Call the response handler chain
if (handlerChain.handleFault(msgContext) == false)
{
log.warn("FIXME: handlerChain.handleFault() returned false");
return null;
}
// Throw the exception from the service endpoint to axis
throw e;
}
try
{
// Prepare the response envelope for the response handlers
invocation.prepareResponseEnvelope(resObj);
// Call the response handler chain
if (handlerChain.handleResponse(msgContext) == false)
{
log.warn("FIXME: handlerChain.handleResponse() returned false");
return null;
}
// There is no way we can get a new resObj from the response SOAPEnvelope.
// Sucker is the response handler that modifies the response value.
// The RPCInvocation will ignore another call to prepareResponseEnvelope
// because this could potentially overwrite what the handlers did.
}
catch (Exception e)
{
log.error("Error processing response handler chain", e);
throw e;
}
return resObj;
}
}
| ServiceEndpointInterceptor.java |