}
/** Invoke the the service endpoint */
public void invoke(InvocationContext invContext) throws Exception
{
CommonMessageContext msgContext = MessageContextAssociation.peekMessageContext();
ServerEndpointMetaData sepMetaData = (ServerEndpointMetaData)msgContext.getEndpointMetaData();
MessageAbstraction reqMessage = msgContext.getMessageAbstraction();
// The direction of the message
DirectionHolder direction = new DirectionHolder(Direction.InBound);
// Get the order of pre/post handlerchains
HandlerType[] handlerType = delegate.getHandlerTypeOrder();
HandlerType[] faultType = delegate.getHandlerTypeOrder();
// Set the required inbound context properties
setInboundContextProperties();
try
{
boolean oneway = false;
EndpointInvocation sepInv = null;
OperationMetaData opMetaData = null;
CommonBinding binding = bindingProvider.getCommonBinding();
binding.setHeaderSource(delegate);
if (binding instanceof CommonSOAPBinding)
XOPContext.setMTOMEnabled(((CommonSOAPBinding)binding).isMTOMEnabled());
// call the request handler chain
boolean handlersPass = callRequestHandlerChain(sepMetaData, handlerType[0]);
// Unbind the request message
if (handlersPass)
{
// Get the operation meta data from the SOAP message
opMetaData = getDispatchDestination(sepMetaData, reqMessage);
msgContext.setOperationMetaData(opMetaData);
oneway = opMetaData.isOneWay();
/*
* From JAX-WS 10.2.1 - "7. If the node does not understand how to process
* the message, then neither handlers nor the endpoint
* are invoked and instead the binding generates a SOAP must
* understand exception"
*
* Therefore, this must precede the ENDPOINT chain; however, The PRE
* chain still must happen first since the message may be encrypted, in which
* case the operation is still not known. Without knowing the operation, it
* is not possible to determine what headers are understood by the endpoint.
*/
if (binding instanceof CommonSOAPBinding)
((CommonSOAPBinding)binding).checkMustUnderstand(opMetaData);
// Unbind the request message
sepInv = binding.unbindRequestMessage(opMetaData, reqMessage);
}
handlersPass = handlersPass && callRequestHandlerChain(sepMetaData, handlerType[1]);
handlersPass = handlersPass && callRequestHandlerChain(sepMetaData, handlerType[2]);
if (handlersPass)
{
msgContext.put(CommonMessageContext.ALLOW_EXPAND_TO_DOM, Boolean.TRUE);
try
{
// Check if protocol handlers modified the payload
if (msgContext.isModified())
{
log.debug("Handler modified payload, unbind message again");
reqMessage = msgContext.getMessageAbstraction();
sepInv = binding.unbindRequestMessage(opMetaData, reqMessage);
}
// Invoke an instance of the SEI implementation bean
Invocation inv = setupInvocation(endpoint, sepInv, invContext);
InvocationHandler invHandler = endpoint.getInvocationHandler();
try
{
invHandler.invoke(endpoint, inv);
}
catch (InvocationTargetException th)
{
//Unwrap the throwable raised by the service endpoint implementation
Throwable targetEx = th.getTargetException();
throw (targetEx instanceof Exception ? (Exception)targetEx : new UndeclaredThrowableException(targetEx));
}
finally
{
// JBWS-2486
if (endpoint.getAttachment(Object.class) == null)
{
endpoint.addAttachment(Object.class, inv.getInvocationContext().getTargetBean());
}
}
// Handler processing might have replaced the endpoint invocation
sepInv = inv.getInvocationContext().getAttachment(EndpointInvocation.class);
}
finally
{
msgContext.remove(CommonMessageContext.ALLOW_EXPAND_TO_DOM);
}
// Reverse the message direction
msgContext = processPivotInternal(msgContext, direction);
// Set the required outbound context properties
setOutboundContextProperties();
// Bind the response message
MessageAbstraction resMessage = binding.bindResponseMessage(opMetaData, sepInv);
msgContext.setMessageAbstraction(resMessage);
}
else
{
// Reverse the message direction without calling the endpoint
MessageAbstraction resMessage = msgContext.getMessageAbstraction();
msgContext = processPivotInternal(msgContext, direction);
msgContext.setMessageAbstraction(resMessage);
}
if (oneway == false)
{
// call the response handler chain, removing the fault type entry will not call handleFault for that chain