}
public Message invoke(Message msg) {
Object input = transform(msg.getBody(), sourceOperation.getInputType(), targetOperation.getInputType(), false);
msg.setBody(input);
Message resultMsg = next.invoke(msg);
Object result = resultMsg.getBody();
if (sourceOperation.isNonBlocking()) {
// Not to reset the message body
return resultMsg;
}
// FIXME: Should we fix the Operation model so that getOutputType
// returns DataType<DataType<T>>?
DataType<DataType> targetType =
new DataTypeImpl<DataType>(DataBinding.IDL_OUTPUT, Object.class, targetOperation.getOutputType());
DataType<DataType> sourceType =
new DataTypeImpl<DataType>(DataBinding.IDL_OUTPUT, Object.class, sourceOperation.getOutputType());
if (resultMsg.isFault()) {
// FIXME: We need to figure out what fault type it is and then
// transform it
// back the source fault type
// throw new InvocationRuntimeException((Throwable) result);
if ((result instanceof Exception) && !(result instanceof RuntimeException)) {
// FIXME: How to match fault data to a fault type for the
// operation?
// If the result is from an InvocationTargetException look at
// the actual cause.
if (result instanceof InvocationTargetException) {
result = ((InvocationTargetException)result).getCause();
}
DataType targetDataType = null;
for (DataType exType : targetOperation.getFaultTypes()) {
if (((Class)exType.getPhysical()).isInstance(result)) {
if (result instanceof FaultException) {
DataType faultType = (DataType)exType.getLogical();
if (((FaultException)result).isMatchingType(faultType.getLogical())) {
targetDataType = exType;
break;
}
} else {
targetDataType = exType;
break;
}
}
}
/*
if (targetDataType == null) {
// Not a business exception
return resultMsg;
}
*/
DataType targetFaultType = getFaultType(targetDataType);
if (targetFaultType == null) {
// No matching fault type, it's a system exception
Throwable cause = (Throwable) result;
throw new ServiceRuntimeException(cause);
}
// FIXME: How to match a source fault type to a target fault
// type?
DataType sourceDataType = null;
DataType sourceFaultType = null;
for (DataType exType : sourceOperation.getFaultTypes()) {
DataType faultType = getFaultType(exType);
// Match by the QName (XSD element) of the fault type
if (faultType != null && typesMatch(targetFaultType.getLogical(), faultType.getLogical())) {
sourceDataType = exType;
sourceFaultType = faultType;
break;
}
}
if (sourceFaultType == null) {
// No matching fault type, it's a system exception
Throwable cause = (Throwable) result;
throw new ServiceRuntimeException(cause);
}
Object newResult =
transformException(result, targetDataType, sourceDataType, targetFaultType, sourceFaultType);
if (newResult != result) {
resultMsg.setFaultBody(newResult);
}
}
} else {
assert !(result instanceof Throwable) : "Expected messages that are not throwable " + result;
Object newResult = transform(result, targetType, sourceType, true);
if (newResult != result) {
resultMsg.setBody(newResult);
}
}
return resultMsg;
}