I posted this and it probably got lost in the midst of  releasing 1.0 ...
let me resend now.

Thanks,
Scott


On 9/15/07, Scott Kurz <[EMAIL PROTECTED]> wrote:
>
> In doing some work trying to leverage the Tuscany databinding framework to
> transform business exceptions across a binding, I noticed a couple issues
> relating to the need to handle both exception and fault DataType(s) .
>
> Basically, I'd like to discuss:
>
> * getting rid of the exception DataType and replacing it with simply a
> fault DataType.
> * decoupling the fault databinding from the way that the exception maps to
> a fault.
>
> Let me explain:
>
> Today, for Java interfaces, we build exception DataTypes during 
> theintrospection phase
> and we set a databinding upon it.  This DB identifies an exceptionHandler
> which can (via getFaultType())  construct a fault DataType from the exc
> DataType.
>
> Different exception patterns result in different mappings between
> exception and fault data types.   For example, we have the pattern defined
> by JAX-WS Sec 2.5 in which the Java exception class wrappers a "fault
> bean" returned by the exception's getFaultInfo().   I'm thinking we also
> want to support POJO exceptions as well in certain contexts.
>
> Today we would support the JAX-WS Sec. 2.5 pattern by constructing an
> DataType wrappering the exception, introspecting the exception to find 
> thefault
> and its databinding.   This databinding's exception handler would, at
> transform time, be used to construct a fault DataType representing thefault 
> bean, distinct from
> the exception DataType.     This more or less works the same for JAXB andSDO, 
> except that for SDO we have
> the Tuscany-ism of looking at FAULT_ELEMENT instead of @WebFault ( which I
> mention below I'd like to change).
>
> For the POJO exception pattern, on the other hand, the fault DataType 
> andexception DataType collapse into one as we see in
> the logic of JavaBeansExceptionHandler.
>
> I don't think we need the complexity of the two DataTypes;  I think all we
> really need from the exception DataType is its "physical', i.e. the Java
> Class of the exception type.   We use this to match the exception we have
> in-hand from the Java runtime with the DataType on the operation.   It is
> only the fault that gets transformed by the Tuscany databinding framework.
>
>
> Perhaps what would be better, instead of an exception DataType and fault
> DataType, would be to simply have the fault DataType with an additional
> "exceptionPhysical" member.    (We still need ExceptionHandler 
> withgetFaultInfo()
> and createFaultException() as well).
>
> This would let us get the exception handlers out of the introspection
> business.
>
> If we look at DataBindingJavaInterfaceProcessor.processInterface() today,
> and see how the various databindings' exception handlers' getFaultType()s
> are called in order to find the right databinding to set on the exception
> DataType, it does seem messy to have to rely on this same getFaultType()
> method to work in a certain way and introspection time and transform
> time.
>
> The best reason, I think is elegance:  if it is the actual fault DataType
> which is interesting at transform time, and if we have an introspect step,
> let's have the introspect step set up this interesting fault
> DataType.      As an example, in  working on some binding impl code in 
> thepast, I found myself calling this same getFaultType() method to get
> the fault from the exc...   making for at least three times this same
> getFaultType() method was called (Java introspect, my binding construction,
> and transform time).
>
> Then there is also performance to consider...
>
> ---------
>
> In addition, (and to some degree this is a separate point),  I think we
> should recognize certain patterns in which a Java exception relates to both
> the Java type of the "fault bean" and to a logical type and decouple these
> patterns from association with one of the various databinding impls we
> support.
>
> So, as an example, if you take the pattern in JAX-WS Sec. 2.5, you can
> have an exception with @WebFault(<fault elem>)  with a getFaultInfo()
> method returning a fault bean of any of the simple, SDO, or JAXB
> databindings.     I don't see the rationale for using FAULT_ELEMENT to
> denote the logical type when the fault bean is an SDO vs. using [EMAIL 
> PROTECTED] for a JAXB;  I think this pattern should be decoupled from
> the choice of databinding, and we don't want the same  algorithm (looking
> for @WebFault and using reflection to find the type returned by
> getFaultInfo(), etc.) to be re-coded for each databinding.
>
> (Though I don't think Tuscany has it presently, I coded a Simple DB
> ExceptionHandler which is largely just a copy of the SDOExceptionHandler,
> wihch illustrates my point.   Someone please correct me if Tuscany can
> already handle simple-typed fault beans in the JAX-WS Sec 2.5 pattern).
>
>
> In addition we'd have other patterns like POJO exception and maybe theAxis2 
> exception which Simon Nash recently did some work regarding.
>
>
> At this point I'd like to show some sample code, which is part of some
> changes I've run with successfully (some of my own tests in my own sandbox
> - not Tuscany tests yet).
>
>
>     public DataType<?> getFaultFromExceptionDataType(DataType<?>
> excDataType) {
>
>         //
>         // 1. Find the Java type of the fault bean, construct fault DT andset 
> exc physical
>         //
>         Object excPhysical = excDataType.getPhysical();
>         if (!(excPhysical instanceof Class)) {
>             return null;    // Should we be throwing exc instead?
>         }
>         Class excClass = (Class)excPhysical;
>         Class faultBeanClass = null;
>         try {
>             Method method = excClass.getMethod("getFaultInfo",
> EMPTY_CLASS_ARRAY);
>             faultBeanClass = method.getReturnType();
>         } catch (NoSuchMethodException e) {
>             faultBeanClass = null;
>         }
>         if (faultBeanClass == null) {
>             return null;
>         }
>
>         // Only the physical is set here.
>         DataType faultDataType = new DataTypeImpl(null, faultBeanClass,
> null);
>         faultDataType.setExceptionPhysical(excClass);
>
>         //
>         // 2. Send through already-existing introspection routine
>         //
>
>         // Don't try to propagate annotations yet.  Note the DB on 
> thefaultDataType
>         // is set by the databinding according to the implied contract we
> have going.
>         dataBindingRegistry.introspectType(faultDataType, null);
>
>         //
>         // 3) instantiate an exception handler for this fault from 
> theappropriate DB
> and
>         //    set in the fault DT
>         //
>
>         DataBinding faultDataBinding = dataBindingRegistry.getDataBinding(
> faultDataType.getDataBinding());
>         ExceptionHandler excHandler = faultDataBinding.getExceptionHandler();
>         faultDataType.setExceptionHandler(excHandler);
>
>         //
>         // 4) set the logical from the @WebFault (FAULT_ELEMENT for now)
>         //
>         QName faultElement = null;
>         try {
>             Field field = excClass.getField("FAULT_ELEMENT");
>             faultElement = (QName)field.get(null);
>         } catch (NoSuchFieldException e) {
>             // Ignore
>         } catch (Throwable e) {
>             // Ignore
>         }
>         if (faultElement == null) {
>             // Should we be responsible for calculating a default
> fault_elem
>             // or leave this to someone else???
>             return null;
>         }
>
>         // Having set the physical and DB already, we now set the logical
> of the fault
>         faultDataType.setLogical(new XMLType(faultElement, null));
>
>         return faultDataType;
>
>     }
>
>
> The above is code that would be called in some form from
> DataBindingJavaInterfaceProcessor.processInterface(), passing in the
> exception DataType.
>
> In this code, I'm finding the fault bean class through a databinding-neutral
> look at the getFaultInfo() return type.  I'm then setting the DB on this
> based on the normal DB.introspect() routine (i.e. the same introspection
> of input and output types to find the databinding).
> Step 4 is to set the logical, again in a databinding-neutral way.
>
> I also have a step 3 where the ExceptionHandler is now stored in theDataType. 
>   This is a non-trivial change which could probably
> really use some improvement (it brings up build and intra-project
> dependency issues).     I wanted to have a working prototype before
> posting this, however, and this is how I did it.    The ExceptionHandler
> still has the job of implementing createException() and getFaultInfo() but
>
> not getFaultType() any more
>
> I also have a simple routine to do something similar for "POJO exceptions"
> which do not have a fault bean and which have a Java, not an XML
> logical type.
>
>     public DataType<?> getFaultFromExceptionDataType(DataType<?>
> excDataType) {
>
>         //
>         // 1. Fault physical and Exception physical are one and the same
>         //
>         Object excPhysical = excDataType.getPhysical();
>         if (!(excPhysical instanceof Class)) {
>             return null;    // Should we be throwing exc instead?
>         }
>         Class excClass = (Class)excPhysical;
>
>         // Only the physical is set here.
>         DataType faultDataType = new DataTypeImpl(null, excClass, null);
>         faultDataType.setExceptionPhysical(excClass);
>
>         //
>         // 2. Send through already-existing introspection routine
>         //
>
>         // Don't try to propagate annotations yet.  Note the DB on 
> thefaultDataType
>         // is set by the databinding according to the implied contract we
> have going.
>         dataBindingRegistry.introspectType(faultDataType, null);
>
>         //
>         // 3) instantiate an exception handler for this fault from 
> theappropriate DB
> and
>         //    set in the fault DT
>         //
>
>         DataBinding faultDataBinding = dataBindingRegistry.getDataBinding(
> faultDataType.getDataBinding());
>         ExceptionHandler excHandler = faultDataBinding.getExceptionHandler();
>         faultDataType.setExceptionHandler(excHandler);
>
>         //
>         // 4) set the logical to be the exc class as well
>         //
>
>         // Having set the physical and DB already, we now set the logical
> of the fault
>         faultDataType.setLogical(excClass);
>
>         return faultDataType;
>
>     }
>
> Assuming it gets that far, I'm not sure whether it would be better to have
> these pieces of code in classes which are added to some registry
> (like the databinding registry), or whether it would be better to have
> one, master, order in which the exception to fault
> mapping is assumed to take place in Tuscany.
>
> I coded up a parallel modification in WSDL introspection in the class:
> org.apache.tuscany.sca.interfacedef.wsdl.introspect.WSDLOperation.
> Basically I just need to set "FaultException" as the exceptionPhysical on
> top of what had been done, as the "logical" was being set just fine
> already.
>
>
> ------------------------------------------------------------------------------
>
> So, this is getting long........
>
> Where I see this going from here is.. if this sounds interesting to
> people, it would be interesting to try incorporating
> the Axis2 exc->fault mapping pattern with the example from the recent JIRA
> Simon worked on into this new view I'm working on.
>
> Another pattern I could imagine would be the one mentioned in JAX-WS Sec.
> 3.7 in cases in which the exceptions don't conform to the Sec 2.5 pattern.
>
> And it might be that my point about "decoupling" is only partially
> right.   Maybe the POJO exception case will always be associated 
> withJavaBeans DB
> and maybe the JAX-WS Sec 3.7 case will always be associated withJAXB.
>
> However, I wanted to get this posted before thinking through all those
> permutations.
>
> Thanks,
> Scott
>
>
>
>
>
>

Reply via email to