From 61010412547bfb9727d29da617aa684c6510c72f Mon Sep 17 00:00:00 2001 From: scottkurz Date: Tue, 22 Jul 2008 17:52:12 +0000 Subject: Propose some fault matching refactoring git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@678833 13f79535-47bb-0310-9956-ffa450edef68 --- .../wire/DataTransformationInterceptor.java | 153 ++----------------- .../databinding/wire/FaultTransformHelper.java | 166 +++++++++++++++++++++ 2 files changed, 177 insertions(+), 142 deletions(-) create mode 100755 branches/sca-java-1.3/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/FaultTransformHelper.java (limited to 'branches/sca-java-1.3/modules/core-databinding') diff --git a/branches/sca-java-1.3/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java b/branches/sca-java-1.3/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java index 5814f3d215..89ce15e796 100644 --- a/branches/sca-java-1.3/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java +++ b/branches/sca-java-1.3/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java @@ -54,6 +54,7 @@ public class DataTransformationInterceptor implements Interceptor, DataExchangeS private RuntimeWire wire; private Mediator mediator; private FaultExceptionMapper faultExceptionMapper; + private FaultTransformHelper faultTransformHelper; public DataTransformationInterceptor(RuntimeWire wire, Operation sourceOperation, @@ -66,6 +67,7 @@ public class DataTransformationInterceptor implements Interceptor, DataExchangeS this.mediator = mediator; this.wire = wire; this.faultExceptionMapper = faultExceptionMapper; + this.faultTransformHelper = new FaultTransformHelper(mediator); } public Invoker getNext() { @@ -91,86 +93,20 @@ public class DataTransformationInterceptor implements Interceptor, DataExchangeS new DataTypeImpl(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); - + Object transformedFault = null; 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); - } + transformedFault = faultTransformHelper.transformFault(result, sourceOperation, targetOperation, wire); + } + // Otherwise, we leave it to another layer to actually throw the RuntimeException which constitutes + // the message body. We don't throw it here. + if (transformedFault != result) { + resultMsg.setFaultBody(transformedFault); } - } 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); - } - } + resultMsg.setBody(newResult); + } return resultMsg; } @@ -186,73 +122,6 @@ public class DataTransformationInterceptor implements Interceptor, DataExchangeS return mediator.mediate(source, sourceType, targetType, metadata); } - private DataType getFaultType(DataType exceptionType) { - return exceptionType == null ? null : (DataType)exceptionType.getLogical(); - } - - private boolean typesMatch(Object first, Object second) { - if (first.equals(second)) { - return true; - } - if (first instanceof XMLType && second instanceof XMLType) { - XMLType t1 = (XMLType)first; - XMLType t2 = (XMLType)second; - // TUSCANY-2113, we should compare element names only - return matches(t1.getElementName(), t2.getElementName()); - } - return false; - } - - /** - * @param qn1 - * @param qn2 - */ - private boolean matches(QName qn1, QName qn2) { - if (qn1 == qn2) { - return true; - } - if (qn1 == null || qn2 == null) { - return false; - } - String ns1 = qn1.getNamespaceURI(); - String ns2 = qn2.getNamespaceURI(); - String e1 = qn1.getLocalPart(); - String e2 = qn2.getLocalPart(); - if (e1.equals(e2) && (ns1.equals(ns2) || ns1.equals(ns2 + "/") || ns2.equals(ns1 + "/"))) { - // Tolerating the trailing / which is required by JAX-WS java package --> xml ns mapping - return true; - } - return false; - } - - /** - * @param source The source exception - * @param sourceExType The data type for the source exception - * @param targetExType The data type for the target exception - * @param sourceType The fault type for the source - * @param targetType The fault type for the target - * @return - */ - private Object transformException(Object source, - DataType sourceExType, - DataType targetExType, - DataType sourceType, - DataType targetType) { - if (sourceType == targetType || (sourceType != null && sourceType.equals(targetType))) { - return source; - } - Map metadata = new HashMap(); - metadata.put("source.operation", targetOperation); - metadata.put("target.operation", sourceOperation); - metadata.put("wire", wire); - DataType eSourceDataType = - new DataTypeImpl("idl:fault", sourceExType.getPhysical(), sourceType); - DataType eTargetDataType = - new DataTypeImpl("idl:fault", targetExType.getPhysical(), targetType); - - return mediator.mediate(source, eSourceDataType, eTargetDataType, metadata); - } - public void setNext(Invoker next) { this.next = next; } diff --git a/branches/sca-java-1.3/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/FaultTransformHelper.java b/branches/sca-java-1.3/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/FaultTransformHelper.java new file mode 100755 index 0000000000..9c1a054d90 --- /dev/null +++ b/branches/sca-java-1.3/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/FaultTransformHelper.java @@ -0,0 +1,166 @@ +package org.apache.tuscany.sca.core.databinding.wire; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.databinding.Mediator; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl; +import org.apache.tuscany.sca.interfacedef.util.FaultException; +import org.apache.tuscany.sca.interfacedef.util.XMLType; +import org.apache.tuscany.sca.runtime.RuntimeWire; +import org.osoa.sca.ServiceRuntimeException; + +public class FaultTransformHelper { + + private Mediator mediator; + + public FaultTransformHelper(Mediator mediator) { + this.mediator = mediator; + } + + public Object transformFault(Object result, Operation sourceOperation, Operation targetOperation, RuntimeWire wire) { + + // 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); + } + + Map metadata = new HashMap(); + metadata.put("source.operation", targetOperation); + metadata.put("target.operation", sourceOperation); + // When is the 'wire' used? + if (wire != null) { + metadata.put("wire", wire); + } + + Object newResult = + transformException(result, targetDataType, sourceDataType, targetFaultType, sourceFaultType, metadata); + + return newResult; + + } + + /** + * @param source The source exception + * @param sourceExType The data type for the source exception + * @param targetExType The data type for the target exception + * @param sourceType The fault type for the source + * @param targetType The fault type for the target + * @return + */ + private Object transformException(Object source, + DataType sourceExType, + DataType targetExType, + DataType sourceType, + DataType targetType, + Map metadata) { + + if (sourceType == targetType || (sourceType != null && sourceType.equals(targetType))) { + return source; + } + + DataType eSourceDataType = + new DataTypeImpl("idl:fault", sourceExType.getPhysical(), sourceType); + DataType eTargetDataType = + new DataTypeImpl("idl:fault", targetExType.getPhysical(), targetType); + + return mediator.mediate(source, eSourceDataType, eTargetDataType, metadata); + } + + private DataType getFaultType(DataType exceptionType) { + return exceptionType == null ? null : (DataType)exceptionType.getLogical(); + } + + private boolean typesMatch(Object first, Object second) { + if (first.equals(second)) { + return true; + } + if (first instanceof XMLType && second instanceof XMLType) { + XMLType t1 = (XMLType)first; + XMLType t2 = (XMLType)second; + // TUSCANY-2113, we should compare element names only + return matches(t1.getElementName(), t2.getElementName()); + } + return false; + } + + /** + * @param qn1 + * @param qn2 + */ + private boolean matches(QName qn1, QName qn2) { + if (qn1 == qn2) { + return true; + } + if (qn1 == null || qn2 == null) { + return false; + } + String ns1 = qn1.getNamespaceURI(); + String ns2 = qn2.getNamespaceURI(); + String e1 = qn1.getLocalPart(); + String e2 = qn2.getLocalPart(); + if (e1.equals(e2) && (ns1.equals(ns2) || ns1.equals(ns2 + "/") || ns2.equals(ns1 + "/"))) { + // Tolerating the trailing / which is required by JAX-WS java package --> xml ns mapping + return true; + } + return false; + } +} -- cgit v1.2.3