You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sc...@apache.org on 2006/11/17 05:01:50 UTC

svn commit: r476045 [2/2] - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/ src/org/apache/axis2/jaxws/client/proxy/ src/org/apache/axis2/jaxws/description/impl/ src/org/apache/axis2/jaxws/i18n/ src/org/apache/axis2/jaxws/ma...

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/MethodMarshallerUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/MethodMarshallerUtils.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/MethodMarshallerUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/MethodMarshallerUtils.java Thu Nov 16 20:01:48 2006
@@ -17,19 +17,52 @@
  * under the License.
  */
 package org.apache.axis2.jaxws.marshaller.impl.alt;
+ 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
 
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
 import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Holder;
+import javax.xml.ws.Response;
 import javax.xml.ws.WebServiceException;
 
+import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.description.EndpointDescription;
+import org.apache.axis2.jaxws.description.FaultDescription;
 import org.apache.axis2.jaxws.description.OperationDescription;
+import org.apache.axis2.jaxws.description.ParameterDescription;
 import org.apache.axis2.jaxws.description.ServiceDescription;
+import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.marshaller.MethodMarshaller;
 import org.apache.axis2.jaxws.marshaller.impl.MethodMarshallerImpl;
+import org.apache.axis2.jaxws.message.Block;
 import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.message.MessageException;
 import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.message.XMLFault;
+import org.apache.axis2.jaxws.message.XMLFaultReason;
+import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
+import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
+import org.apache.axis2.jaxws.message.util.MessageUtils;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.apache.axis2.jaxws.util.ClassUtils;
+import org.apache.axis2.jaxws.util.XMLRootElementUtil;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import javax.jws.WebParam.Mode;
+import javax.jws.soap.SOAPBinding.Style;
 
 
 /**
@@ -38,6 +71,9 @@
 class MethodMarshallerUtils  {
 
     private static Log log = LogFactory.getLog(MethodMarshallerUtils.class);
+    
+    private static JAXBBlockFactory factory = 
+        (JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
 
     /**
      * Intentionally Private.  This is a static utility class
@@ -45,6 +81,571 @@
     private MethodMarshallerUtils() {
     }
    
+    /**
+     * Returns the list of PDElements that need to be marshalled onto the wire
+     * 
+     * @param params ParameterDescription for this operation
+     * @param sigArguments arguments 
+     * @param isInput indicates if input or output  params(input args on client, output args on server)
+     * @param usePartName indicates whether to use the partName or name for the name of the xml element
+     *        partName is used for RPC and doc/lit wrapped, name is used for doc/lit bare
+     * @param forceXSIType if upgrading a type to an element
+     * @return PDElements
+     */
+    static List<PDElement> getPDElements(ParameterDescription[] params, Object[] sigArguments, boolean isInput, boolean usePartName, boolean forceXSIType) {
+        List<PDElement> pvList = new ArrayList<PDElement>();
+        
+        int index = 0;
+        for (int i=0; i<params.length; i++) {
+            ParameterDescription pd = params[i];
+         
+            if (pd.getMode() == Mode.IN && isInput ||
+                pd.getMode() == Mode.INOUT ||
+                pd.getMode() == Mode.OUT && !isInput) {
+                
+                // Get the matching signature argument
+                Object value = sigArguments[i];
+                
+                // Don't consider async handlers, they are are not represented on the wire,
+                // thus they don't have a PDElement
+                if (isAsyncHandler(value)) {
+                    continue;
+                }
+                
+                // Convert from Holder into value
+                if (isHolder(value)) {
+                    value =((Holder)value).value;
+                }
+                
+                // Get the formal type representing the value
+                Class formalType = pd.getParameterActualType();
+                
+                // If this value is element enabled, then we are okay
+                // Otherwise make an element enabled value
+                if (!XMLRootElementUtil.isElementEnabled(formalType)) {
+                    String localName = (usePartName) ? pd.getPartName() : pd.getParameterName();
+                    value = XMLRootElementUtil.getElementEnabledObject(pd.getTargetNamespace(), localName, formalType, value, forceXSIType);
+                }
+                
+                // The object is now ready for marshalling
+                PDElement pv = new PDElement(pd, value);
+                pvList.add(pv);
+            }
+        }
+        
+        return pvList;
+    }
+    
+    /**
+     * Return the list of PDElements that is unmarshalled from the wire
+     * 
+     * @param params ParameterDescription for this operation
+     * @param message Message
+     * @param packages set of packages needed to unmarshal objects for this operation
+     * @param isInput indicates if input or output  params (input on server, output on client)
+     * @param usePartName indicates whether to use the partName or name for the name of the xml element
+     * @return ParamValues
+     */
+    static List<PDElement> getPDElements(ParameterDescription[] params, 
+            Message message, 
+            Set<Package> packages, 
+            boolean isInput, 
+            boolean usePartName) throws MessageException, XMLStreamException {
+        
+        List<PDElement> pvList = new ArrayList<PDElement>();
+            
+        int index = 0; 
+        for (int i=0; i<params.length; i++) {
+            ParameterDescription pd = params[i];
+         
+            if (pd.getMode() == Mode.IN && isInput ||
+                pd.getMode() == Mode.INOUT ||
+                pd.getMode() == Mode.OUT && !isInput) {
+                
+                // Don't consider async handlers, they are are not represented on the wire,
+                // thus they don't have a PDElement
+                // TODO
+                //if (isAsyncHandler(param)) {
+                //    continue;
+                //}
+                
+                // Unmarshal the object into a JAXB object or JAXBElement
+                Block block = null;
+                if (pd.isHeader()) {
+
+                    // Get the Block from the header
+                    if (message.getStyle() == Style.RPC) {
+                        // TODO add xsi type
+                    }
+                    String localName = (usePartName) ? pd.getPartName() : pd.getParameterName();
+                    block = message.getHeaderBlock(pd.getTargetNamespace(), localName, new JAXBBlockContext(packages), factory);
+                } else {
+                    if (message.getStyle() == Style.RPC) {
+                        // TODO add xsi type
+                    }
+                    block = message.getBodyBlock(index, new JAXBBlockContext(packages), factory);
+                }
+                
+                // The object is now ready for marshalling
+                PDElement pv = new PDElement(pd, block.getBusinessObject(true));
+                pvList.add(pv);
+            }
+        }
+        
+        return pvList;
+    }
+    
+    /**
+     * Creates the request signature arguments (server) from a list
+     * of element eabled object (PDEements)
+     * @param pds ParameterDescriptions for this Operation
+     * @param pvList Element enabled object
+     * @return Signature Args
+     * @throws InstantiationException
+     * @throws IllegalAccessException
+     * @throws ClassNotFoundException
+     */
+    static Object[] createRequestSignatureArgs(ParameterDescription[] pds, List<PDElement> pvList) 
+        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        Object[] args = new Object[pds.length];
+        int pvIndex = 0;
+        for (int i=0; i< args.length; i++) {
+            // Get the paramValue
+            PDElement pv = (pvIndex < pvList.size()) ? pvList.get(pvIndex) : null;
+            ParameterDescription pd = pds[i];
+            if (pv == null ||
+                pv.getParam() != pd) {
+                // We have a ParameterDesc but there is not an equivalent PDElement. 
+                // Provide the default
+                if (pd.isHolderType()) {
+                    args[i] = createHolder(pd.getParameterType(), null);
+                } else {
+                    args[i] = null;
+                }
+            } else {
+          
+                // We have a matching paramValue
+                Object value = pv.getElementValue();
+                pvIndex++;
+                
+                // The signature wants the object that is rendered as the type
+                value = XMLRootElementUtil.getTypeEnabledObject(value);
+                
+                // The signature may want a holder representation
+                if (pd.isHolderType()) {
+                    args[i] = createHolder(pd.getParameterType(), value);
+                } else {
+                    args[i] = value;
+                }
+            }
+         
+        }
+        return args;
+    }
+    
+    /**
+     * Update the signature arguments on the client with the unmarshalled element enabled objects (pvList)
+     * @param pds ParameterDescriptions
+     * @param pvList Element Enabled objects
+     * @param signatureArgs Signature Arguments (the out/inout holders are updated)
+     * @throws InstantiationException
+     * @throws IllegalAccessException
+     * @throws ClassNotFoundException
+     */
+    static void updateResponseSignatureArgs(ParameterDescription[] pds, List<PDElement> pvList, Object[] signatureArgs) 
+            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        int pvIndex = 0;
+        
+        // Each ParameterDescriptor has a correspondinging signatureArg from the 
+        // the initial client call.  The pvList contains the response values from the message.
+        // Walk the ParameterDescriptor/SignatureArg list and populate the holders with 
+        // the match PDElement
+        for (int i=0; i< pds.length; i++) {
+            // Get the paramValue
+            PDElement pv = (pvIndex < pvList.size()) ? pvList.get(pvIndex) : null;
+            ParameterDescription pd = pds[i];
+            if (pv != null && pv.getParam() == pd) {   
+                // We have a matching paramValue
+                Object value = pv.getElementValue();
+                pvIndex++;
+                
+                // The signature wants the object that is rendered as the type
+                value = XMLRootElementUtil.getTypeEnabledObject(value);
+                
+                // TODO Assert that this ParameterDescriptor must represent
+                // an OUT or INOUT and must have a non-null holder object to 
+                // store the value
+                if (isHolder(signatureArgs[i])) {
+                    ((Holder) signatureArgs[i]).value = value;
+                }
+            }    
+        }
+    }
+    
+    /**
+     * Marshal the element enabled objects (pvList) to the Message
+     * @param pvList element enabled objects
+     * @param message Message
+     * @param packages Packages needed to do a JAXB Marshal
+     * @throws MessageException
+     */
+    static void toMessage(List<PDElement> pvList, Message message, Set<Package> packages) throws MessageException {
+        
+        int index = message.getNumBodyBlocks();
+        for (int i=0; i<pvList.size(); i++) {
+            PDElement pv = pvList.get(i);
+            
+            // Create a JAXBBlock out of the value.
+            // (Note that the PDElement.getValue always returns an object
+            // that has an element rendering...ie. it is either a JAXBElement o
+            // has @XmlRootElement defined
+            Block block = factory.createFrom(pv.getElementValue(), 
+                    new JAXBBlockContext(packages), 
+                    null);  // The factory will get the qname from the value
+            
+            if (pv.getParam().isHeader()) {
+                // Header block
+                QName qname = block.getQName();
+                message.setHeaderBlock(qname.getNamespaceURI(), 
+                        qname.getLocalPart(),
+                        block);
+            } else {
+                // Body block
+                message.setBodyBlock(index, block);
+                index++;
+            }
+        }
+    }
+    
+    /**
+     * Marshals the return object to the message (used on server to marshal return object)
+     * @param returnValue
+     * @param returnType
+     * @param returnNS
+     * @param returnLocalPart
+     * @param packages
+     * @param message
+     * @param forceXSIType if upgrading type to an element
+     * @throws MessageException
+     */
+    static void toMessage(Object returnValue, 
+            Class returnType, 
+            String returnNS, 
+            String returnLocalPart, 
+            Set<Package> packages, 
+            Message message, 
+            boolean forceXSIType) 
+            throws MessageException {
+        // If this type is an element rendering, then we are okay
+        // If it is a type rendering then make a JAXBElement 
+        if (!XMLRootElementUtil.isElementEnabled(returnType)) {
+            returnValue = XMLRootElementUtil.getElementEnabledObject(returnNS, returnLocalPart,returnType, returnValue, forceXSIType);
+        }
+        
+        //  Create a JAXBBlock out of the value.
+        Block block = factory.createFrom(returnValue, 
+                new JAXBBlockContext(packages), 
+                null);  // The factory will get the qname from the value
+        message.setBodyBlock(0, block);
+    }
+    
+    /**
+     * Unmarshal the return object from the message
+     * @param packages
+     * @param message
+     * @return type enabled object
+     * @throws MessageException
+     * @throws XMLStreamException
+     */
+    static Object getReturnValue(Set<Package> packages, Message message) 
+        throws MessageException, XMLStreamException {
+        
+        
+        // The return object is the first block in the body
+        if (message.getStyle() == Style.RPC) {
+            // TODO add xsi type
+        }
+        Block block = message.getBodyBlock(0, new JAXBBlockContext(packages), factory);
+        
+        // Get the business object.  We want to return the object that represents the type.
+        Object returnValue = block.getBusinessObject(true);
+        //  The signature wants the object that is rendered as the type
+        returnValue = XMLRootElementUtil.getTypeEnabledObject(returnValue);
+        return returnValue;
+    }
+    
+    /**
+     * Utility method to get the Class representing the actual return type
+     * 
+     * @param operationDesc
+     * @return actual return type
+     */
+    static Class getActualReturnType(OperationDescription operationDesc){
+        Method seiMethod = operationDesc.getSEIMethod();
+        Class returnType = seiMethod.getReturnType();
+        if(isAsync(operationDesc)){
+            //pooling implementation
+            if(Response.class == returnType){
+                Type type = seiMethod.getGenericReturnType();
+                ParameterizedType pType = (ParameterizedType) type;
+                return (Class)pType.getActualTypeArguments()[0];    
+            }
+            //Callback Implementation
+            else{
+                Type[] type = seiMethod.getGenericParameterTypes();
+                Class parameters[]= seiMethod.getParameterTypes();
+                int i=0;
+                for(Class param:parameters){
+                    if(AsyncHandler.class.isAssignableFrom(param)){
+                        ParameterizedType pType = (ParameterizedType)type[i];
+                        return (Class)pType.getActualTypeArguments()[0];
+                    }
+                    i++;
+                }
+            }
+            
+        }
+        
+        return returnType;  
+    }
+    
+    /**
+     * Marshaling a fault is essentially the same for rpc/lit and doc/lit.
+     * This method is used by all of the MethodMarshallers
+     * @param throwable Throwable to marshal
+     * @param operationDesc OperationDescription
+     * @param packages Packages needed to marshal the object
+     * @param message Message
+     * @param forceXSIType if the faultbean 
+     * @throws MessageException
+     * @throws NoSuchMethodException
+     * @throws InvocationTargetException
+     * @throws IllegalAccessException
+     */
+    static void marshalFaultResponse(Throwable throwable, OperationDescription operationDesc,  Set<Package> packages, Message message, 
+            boolean forceXSIType)
+     throws MessageException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        
+        // Get the root cause of the throwable object
+        if (log.isDebugEnabled()) {
+            log.debug("Marshal Throwable =" + throwable.getClass().getName());
+            log.debug("  message=" + throwable.getMessage());
+            log.debug("  stack=" + MessageUtils.stackToString(throwable));
+        }
+        Throwable t = ClassUtils.getRootCause(throwable);
+
+        XMLFault xmlfault = null;
+      
+        // Get the FaultDescriptor matching this Exception.
+        // If FaultDescriptor is found, this is a JAX-B Service Exception.
+        // If not found, this is a System Exception
+        FaultDescription fd = operationDesc.resolveFaultByExceptionName(t.getClass().getName());
+
+        String text = null;
+        if (fd != null) {
+            // Service Exception.  
+            
+            // Get the fault bean object.  Make sure it can be rendered as an element
+            Method getFaultInfo = t.getClass().getMethod("getFaultInfo", null);
+            Object faultBeanObject = getFaultInfo.invoke(t, null);
+            if (!XMLRootElementUtil.isElementEnabled(faultBeanObject.getClass())) {
+                faultBeanObject = XMLRootElementUtil.getElementEnabledObject(fd.getTargetNamespace(), fd.getName(), 
+                        faultBeanObject.getClass(), faultBeanObject, forceXSIType);
+            }
+            
+            // Create a detailblock representing the faultBeanObject
+            JAXBBlockContext context = new JAXBBlockContext(packages);
+            Block[] detailBlocks = new Block[1];
+            detailBlocks[0] = factory.createFrom(faultBeanObject,context,null);
+            
+            // Now make a XMLFault containing the detailblock
+            text = t.getMessage();
+            xmlfault = new XMLFault(null, new XMLFaultReason(text), detailBlocks);
+        } else {
+            // System Exception
+            xmlfault = new XMLFault(null,       // Use the default XMLFaultCode
+                    new XMLFaultReason(text));  // Assumes text is the language supported by the current Locale
+        }
+        // Add the fault to the message
+        message.setXMLFault(xmlfault);
+    }
+    
+    /**
+     * Unmarshal the service/system exception from a Message.
+     * This is used by all of the marshallers
+     * @param operationDesc
+     * @param packages
+     * @param message
+     * @param isRPC
+     * @return Throwable
+     * @throws MessageException
+     * @throws ClassNotFoundException
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     * @throws XMLStreamException
+     * @throws InvocationTargetException
+     * @throws NoSuchMethodException
+     */
+    static Throwable demarshalFaultResponse(OperationDescription operationDesc, Set<Package> packages,Message message, boolean isRPC) 
+        throws MessageException, ClassNotFoundException, IllegalAccessException,
+               InstantiationException, XMLStreamException, InvocationTargetException, NoSuchMethodException {
+        
+        Throwable exception = null;
+        // Get the fault from the message and get the detail blocks (probably one)
+        XMLFault xmlfault = message.getXMLFault();
+        Block[] detailBlocks = xmlfault.getDetailBlocks();
+        
+        
+        if ((operationDesc.getFaultDescriptions().length == 0) || (detailBlocks == null))  {
+            // This is a system exception if the method does not throw a checked exception or if 
+            // there is nothing in the detail element.
+            // Shouldn't this create 
+            
+            // Create SystemException
+            // TODO shouldn't the exception capture the contents of the detail blocks
+            exception = createSystemException(xmlfault.getReason().getText());
+        } else {
+            
+            // TODO what if there are multiple blocks in the detail ?
+            // We should create a generic fault with the appropriate detail
+            
+            // Get the JAXB object from the block
+            JAXBBlockContext blockContext = new JAXBBlockContext(packages);        
+            
+            if (isRPC) {
+                //TODO add xsi:type
+            }
+            Block jaxbBlock = factory.createFrom(detailBlocks[0], blockContext);
+            Object faultBeanObject = jaxbBlock.getBusinessObject(true); 
+            
+            // At this point, faultBeanObject is an object that can be rendered as an
+            // element.  We want the object that represents the type.  Also get the 
+            // name of the element.
+            QName faultBeanQName = null;
+            if (faultBeanObject instanceof JAXBElement) {
+                faultBeanQName = ((JAXBElement)faultBeanObject).getName();
+                faultBeanObject = ((JAXBElement)faultBeanObject).getValue();
+            } else {
+                faultBeanQName = XMLRootElementUtil.getXmlRootElementQName(faultBeanObject);
+            }
+            
+            // Using the faultBeanQName, find the matching faultDescription 
+            FaultDescription faultDesc = null;
+            for(int i=0; i<operationDesc.getFaultDescriptions().length && faultDesc == null; i++) {
+                FaultDescription fd = operationDesc.getFaultDescriptions()[i];
+                QName tryQName = new QName(fd.getTargetNamespace(), fd.getName());
+                                
+                if (faultBeanQName == null || faultBeanQName.equals(tryQName)) {
+                    faultDesc = fd;
+                    
+                }
+            }
+            if (faultDesc == null) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("MethodMarshallerErr1", faultBeanObject.getClass().toString()));
+            }
+            
+            // Construct the JAX-WS generated exception that holds the faultBeanObject
+            Class exceptionClass = loadClass(faultDesc.getExceptionClassName());
+            Class faultBeanFormalClass = loadClass(faultDesc.getFaultBean());            
+            exception =createServiceException(xmlfault.getReason().getText(), exceptionClass, faultBeanObject, faultBeanFormalClass);
+        }
+        return exception;
+    }
+    
+    /**
+     * @param operationDesc
+     * @return if asyc operation
+     */
+    static boolean isAsync(OperationDescription operationDesc){
+        Method method = operationDesc.getSEIMethod();
+        if(method == null){
+            return false;
+        }
+        String methodName = method.getName();
+        Class returnType = method.getReturnType();
+        return methodName.endsWith("Async") && (returnType.isAssignableFrom(Response.class) || returnType.isAssignableFrom(Future.class));
+    }
+   
     
+    /**
+     * @param value
+     * @return if async handler
+     */
+    static boolean isAsyncHandler(Object value){
+        return (value instanceof AsyncHandler);
+    }
+    
+    /**
+     * @param value
+     * @return true if value is holder
+     */
+    static boolean isHolder(Object value){
+        return value!=null && Holder.class.isAssignableFrom(value.getClass());
+    }
+  
+    /** Crate a Holder 
+     * @param <T>
+     * @param paramType
+     * @param value
+     * @return
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     * @throws ClassNotFoundException
+     */
+    static <T> Holder<T> createHolder(Class paramType, T value) throws IllegalAccessException, InstantiationException, ClassNotFoundException{
+        if(Holder.class.isAssignableFrom(paramType)){
+            Class holderClazz = loadClass(paramType.getName());
+            Holder<T> holder = (Holder<T>) holderClazz.newInstance();
+            holder.value = value;
+            return holder;
+        }
+        return null;
+    }
+    
+    /** 
+     * Load the class
+     * @param className
+     * @return loaded class
+     * @throws ClassNotFoundException
+     */
+    static Class loadClass(String className)throws ClassNotFoundException{
+        // TODO J2W AccessController Needed
+        // Don't make this public, its a security exposure
+        return Class.forName(className, true, Thread.currentThread().getContextClassLoader());
+    }
+    
+    /** Create a JAX-WS Service Exception (Generated Exception)
+     * @param message
+     * @param exceptionclass
+     * @param bean
+     * @param beanFormalType
+     * @return
+     * @throws InvocationTargetException
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     * @throws NoSuchMethodException
+     */
+    private static Exception createServiceException(String message, Class exceptionclass, Object bean, Class beanFormalType) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException {
+        // All webservice exception classes are required to have a constructor that takes a (String, bean) argument
+        // TODO necessary to be more careful here with instantiating, cassting, etc?
+        if (log.isDebugEnabled()) {
+            log.debug("Constructing JAX-WS Exception:" + exceptionclass);
+        }
+        Constructor constructor = exceptionclass.getConstructor(new Class[] { String.class, beanFormalType });
+        Object exception = constructor.newInstance(new Object[] { message, bean });
 
+        return (Exception) exception;
+
+    }
+    
+    /**
+     * Create a system exception
+     * @param message
+     * @return
+     */
+    private static Exception createSystemException(String message) {
+        return ExceptionFactory.makeWebServiceException(message);
+    }
+    
+    
 }

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/PDElement.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/PDElement.java?view=auto&rev=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/PDElement.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/PDElement.java Thu Nov 16 20:01:48 2006
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *      
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws.marshaller.impl.alt;
+
+import org.apache.axis2.jaxws.description.ParameterDescription;
+
+
+/**
+ * A PDElement object holds a ParameterDescription (Param) and 
+ * the "Element" value.
+ * Characteristics of the "Element" value.
+ *    * The Element value is ready for marshalling or is the result of unmarshalling.
+ *    * The Element value represents the element rendering.  Thus it is either
+ *      a JAXBElement or has the @XmlRootElement annotation.  (i.e. it is never a 
+ *      java.lang.String)
+ *    * The Element value is not a JAX-WS object. (i.e. it is not a holder or exception)
+ */
+public class PDElement {
+    private ParameterDescription param;
+    private Object value;
+    
+    public PDElement(ParameterDescription param, Object value) {
+        super();
+        this.param = param;
+        this.value = value;
+    }
+
+    public ParameterDescription getParam() {
+        return param;
+    }
+
+    public Object getElementValue() {
+        return value;
+    }
+    
+}

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/RPCLitMethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/RPCLitMethodMarshaller.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/RPCLitMethodMarshaller.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/RPCLitMethodMarshaller.java Thu Nov 16 20:01:48 2006
@@ -18,17 +18,23 @@
  */
 package org.apache.axis2.jaxws.marshaller.impl.alt;
 
+import java.util.List;
+import java.util.Set;
+
+import javax.jws.soap.SOAPBinding.Style;
 import javax.xml.namespace.QName;
 import javax.xml.ws.WebServiceException;
 
 import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.description.EndpointDescription;
 import org.apache.axis2.jaxws.description.OperationDescription;
+import org.apache.axis2.jaxws.description.ParameterDescription;
 import org.apache.axis2.jaxws.description.ServiceDescription;
 import org.apache.axis2.jaxws.marshaller.MethodMarshaller;
-import org.apache.axis2.jaxws.marshaller.impl.MethodMarshallerImpl;
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.message.factory.MessageFactory;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -50,44 +56,222 @@
         this.protocol = protocol;
     }
 
-    public Object demarshalResponse(Message message, Object[] inputArgs)
-            throws WebServiceException {
+    public Message marshalRequest(Object[] signatureArguments) throws WebServiceException {
         // Note all exceptions are caught and rethrown with a WebServiceException
         try {
-            // TODO Add Real Code
-            throw new UnsupportedOperationException();
+            
+            // Sample RPC message
+            // ..
+            // <soapenv:body>
+            //    <m:op xmlns:m="urn://api">
+            //       <m:param xsi:type="data:foo" xmlns:data="urn://mydata" >...</m:param>
+            //    </m:op>
+            // </soapenv:body>
+            //
+            // Important points.
+            //   1) RPC has an operation element under the body.  This is the name of the
+            //      wsdl operation.
+            //   2) The data blocks are located underneath the operation element.  (In doc/lit
+            //      the data elements are underneath the body.
+            //   3) The name of the data blocks (m:param) are defined by the wsdl:part not the
+            //      schema.  
+            //   4) The type of the data block (data:foo) is defined by schema (thus there is 
+            //      JAXB type rendering.  Since we are using JAXB to marshal the data, 
+            //      we always generate an xsi:type attribute.  This is an implemenation detail
+            //      and is not defined by any spec.
+            
+            
+            // Get the operation information
+            ParameterDescription[] pds =operationDesc.getParameterDescriptions();
+            Set<Package> packages = endpointDesc.getPackages();
+            
+            // Create the message 
+            MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
+            Message m = mf.create(protocol);
+            
+            // Indicate the style and operation element name.  This triggers the message to
+            // put the data blocks underneath the operation element
+            m.setStyle(Style.RPC);
+            m.setOperationElement(operationDesc.getName());
+            
+            // The input object represent the signature arguments.
+            // Signature arguments are both holders and non-holders
+            // Convert the signature into a list of JAXB objects for marshalling
+            List<PDElement> pvList = 
+                MethodMarshallerUtils.getPDElements(pds, 
+                        signatureArguments,
+                        true,  // input
+                        true, // use partName since this is rpc/lit
+                        true); // always force xsi:type since this is rpc/lit
+            
+            // Put values onto the message
+            MethodMarshallerUtils.toMessage(pvList, m, packages);
+            
+            return m;
         } catch(Exception e) {
             throw ExceptionFactory.makeWebServiceException(e);
         }
     }
-
+    
     public Object[] demarshalRequest(Message message)
-            throws WebServiceException {
+        throws WebServiceException {
         // Note all exceptions are caught and rethrown with a WebServiceException
         try {
-            // TODO Add Real Code
-            throw new UnsupportedOperationException();
+            // Sample RPC message
+            // ..
+            // <soapenv:body>
+            //    <m:op xmlns:m="urn://api">
+            //       <m:param xsi:type="data:foo" xmlns:data="urn://mydata" >...</m:param>
+            //    </m:op>
+            // </soapenv:body>
+            //
+            // Important points.
+            //   1) RPC has an operation element under the body.  This is the name of the
+            //      wsdl operation.
+            //   2) The data blocks are located underneath the operation element.  (In doc/lit
+            //      the data elements are underneath the body.
+            //   3) The name of the data blocks (m:param) are defined by the wsdl:part not the
+            //      schema.  
+            //   4) The type of the data block (data:foo) is defined by schema (thus there is 
+            //      JAXB type rendering.  
+            //   5) We always send an xsi:type, but other vendor's may not.
+            // Get the operation information
+            ParameterDescription[] pds =operationDesc.getParameterDescriptions();
+            Set<Package> packages = endpointDesc.getPackages();
+            
+            // Indicate that the style is RPC.  This is important so that the message understands
+            // that the data blocks are underneath the operation element
+            message.setStyle(Style.RPC);
+            
+            // Unmarshal the ParamValues from the Message
+            List<PDElement> pvList = MethodMarshallerUtils.getPDElements(pds, message, packages, true, true);
+            
+            // Build the signature arguments
+            Object[] sigArguments = MethodMarshallerUtils.createRequestSignatureArgs(pds, pvList);
+            
+            return sigArguments;
         } catch(Exception e) {
             throw ExceptionFactory.makeWebServiceException(e);
         }
     }
 
-    public Message marshalResponse(Object returnObject, Object[] holderObjects)
+   
+
+    public Message marshalResponse(Object returnObject, Object[] signatureArgs)
             throws WebServiceException {
         // Note all exceptions are caught and rethrown with a WebServiceException
         try {
-            // TODO Add Real Code
-            throw new UnsupportedOperationException();
+            // Sample RPC message
+            // ..
+            // <soapenv:body>
+            //    <m:opResponse xmlns:m="urn://api">
+            //       <m:param xsi:type="data:foo" xmlns:data="urn://mydata" >...</m:param>
+            //    </m:op>
+            // </soapenv:body>
+            //
+            // Important points.
+            //   1) RPC has an operation element under the body.  This is the name of the
+            //      wsdl operation.
+            //   2) The data blocks are located underneath the operation element.  (In doc/lit
+            //      the data elements are underneath the body.
+            //   3) The name of the data blocks (m:param) are defined by the wsdl:part not the
+            //      schema.  
+            //   4) The type of the data block (data:foo) is defined by schema (thus there is 
+            //      JAXB type rendering.  Since we are using JAXB to marshal the data, 
+            //      we always generate an xsi:type attribute.  This is an implemenation detail
+            //      and is not defined by any spec.
+            
+            // Get the operation information
+            ParameterDescription[] pds =operationDesc.getParameterDescriptions();
+            Set<Package> packages = endpointDesc.getPackages();
+            
+            // Create the message 
+            MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
+            Message m = mf.create(protocol);
+            
+            // Indicate the style and operation element name.  This triggers the message to
+            // put the data blocks underneath the operation element
+            m.setStyle(Style.RPC);
+            
+            // TODO Is there an annotation for the operation element response ?
+            String localPart = operationDesc.getName().getLocalPart() + "Response";
+            QName responseOp = new QName(operationDesc.getName().getNamespaceURI(), localPart);
+            m.setOperationElement(responseOp);
+            
+            // Put the return object onto the message
+            Class returnType = MethodMarshallerUtils.getActualReturnType(operationDesc);
+            if (returnType != void.class) {
+                MethodMarshallerUtils.toMessage(returnObject, 
+                        returnType, 
+                        operationDesc.getResultTargetNamespace(),
+                        operationDesc.getResultPartName(), 
+                        packages, 
+                        m,
+                        true); // forceXSI since this is rpc/lit
+            }
+            
+            // Convert the holder objects into a list of JAXB objects for marshalling
+            List<PDElement> pvList = 
+                MethodMarshallerUtils.getPDElements(pds, 
+                        signatureArgs, 
+                        false,  // output
+                        true,   // use partName since this is rpc/lit
+                        true);  // forceXSI since this is rpc/lit
+
+            // Put values onto the message
+            MethodMarshallerUtils.toMessage(pvList, m, packages);
+            
+            return m;
         } catch(Exception e) {
             throw ExceptionFactory.makeWebServiceException(e);
         }
     }
 
-    public Message marshalRequest(Object[] object) throws WebServiceException {
+    
+    public Object demarshalResponse(Message message, Object[] signatureArgs)
+          throws WebServiceException {
         // Note all exceptions are caught and rethrown with a WebServiceException
         try {
-            // TODO Add Real Code
-            throw new UnsupportedOperationException();
+            // Sample RPC message
+            // ..
+            // <soapenv:body>
+            //    <m:opResponse xmlns:m="urn://api">
+            //       <m:param xsi:type="data:foo" xmlns:data="urn://mydata" >...</m:param>
+            //    </m:op>
+            // </soapenv:body>
+            //
+            // Important points.
+            //   1) RPC has an operation element under the body.  This is the name of the
+            //      wsdl operation.
+            //   2) The data blocks are located underneath the operation element.  (In doc/lit
+            //      the data elements are underneath the body.
+            //   3) The name of the data blocks (m:param) are defined by the wsdl:part not the
+            //      schema.  
+            //   4) The type of the data block (data:foo) is defined by schema (thus there is 
+            //      JAXB type rendering.  
+            //   5) We always send an xsi:type, but other vendor's may not.
+            // Get the operation information
+            ParameterDescription[] pds =operationDesc.getParameterDescriptions();
+            Set<Package> packages = endpointDesc.getPackages();
+            
+            // Indicate that the style is RPC.  This is important so that the message understands
+            // that the data blocks are underneath the operation element
+            message.setStyle(Style.RPC);
+            
+            // Get the return value.
+            Class returnType = MethodMarshallerUtils.getActualReturnType(operationDesc);
+            Object returnValue = null;
+            if (returnType != void.class) {
+                returnValue = MethodMarshallerUtils.getReturnValue(packages, message);
+            }
+            
+            // Unmarshall the ParamValues from the Message
+            List<PDElement> pvList = MethodMarshallerUtils.getPDElements(pds, message, packages, false, true);
+            
+            // Populate the response Holders
+            MethodMarshallerUtils.updateResponseSignatureArgs(pds, pvList, signatureArgs);
+            
+            return returnValue;
         } catch(Exception e) {
             throw ExceptionFactory.makeWebServiceException(e);
         }
@@ -96,18 +280,27 @@
     public Message marshalFaultResponse(Throwable throwable) throws WebServiceException {
         // Note all exceptions are caught and rethrown with a WebServiceException
         try {
-            // TODO Add Real Code
-            throw new UnsupportedOperationException();
+            // Create the message 
+            MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
+            Message m = mf.create(protocol);
+            
+            // Put the fault onto the message
+            MethodMarshallerUtils.marshalFaultResponse(throwable, 
+                    operationDesc, 
+                    endpointDesc.getPackages(), 
+                    m, 
+                    true);  // always marshal xsi:type if rpc/lit
+            return m;
         } catch(Exception e) {
             throw ExceptionFactory.makeWebServiceException(e);
         }
     }
 
-    public Object demarshalFaultResponse(Message message) throws WebServiceException {
+    public Throwable demarshalFaultResponse(Message message) throws WebServiceException {
         // Note all exceptions are caught and rethrown with a WebServiceException
         try {
-            // TODO Add Real Code
-            throw new UnsupportedOperationException();
+            Throwable t = MethodMarshallerUtils.demarshalFaultResponse(operationDesc, endpointDesc.getPackages(), message,  true); 
+            return t;
         } catch(Exception e) {
             throw ExceptionFactory.makeWebServiceException(e);
         }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockFactoryImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockFactoryImpl.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockFactoryImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockFactoryImpl.java Thu Nov 16 20:01:48 2006
@@ -29,7 +29,7 @@
 import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
 import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
 import org.apache.axis2.jaxws.message.impl.BlockFactoryImpl;
-import org.apache.axis2.jaxws.util.ClassUtils;
+import org.apache.axis2.jaxws.util.XMLRootElementUtil;
 
 /**
  * JAXBBlockFactoryImpl
@@ -77,7 +77,7 @@
         
         // The business object must be either a JAXBElement or a block with an @XmlRootElement qname.  The best way
         // to verify this is to get the QName from the business object.
-        QName bQName = ClassUtils.getXmlRootElementQName(businessObject);
+        QName bQName = XMLRootElementUtil.getXmlRootElementQName(businessObject);
         if (bQName == null) {
             throw ExceptionFactory.makeMessageException(Messages.getMessage("JAXBBlockFactoryErr2", businessObject.getClass().getName()), null);
         }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockImpl.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockImpl.java Thu Nov 16 20:01:48 2006
@@ -44,7 +44,7 @@
 import org.apache.axis2.jaxws.message.databinding.JAXBUtils;
 import org.apache.axis2.jaxws.message.factory.BlockFactory;
 import org.apache.axis2.jaxws.message.impl.BlockImpl;
-import org.apache.axis2.jaxws.util.ClassUtils;
+import org.apache.axis2.jaxws.util.XMLRootElementUtil;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -110,7 +110,7 @@
             jaxb = u.unmarshal(reader);
             
             // Set the qname 
-            QName qName = ClassUtils.getXmlRootElementQName(jaxb);
+            QName qName = XMLRootElementUtil.getXmlRootElementQName(jaxb);
             if (qName != null) {  // qname should always be non-null
                 setQName(qName); 
             }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java Thu Nov 16 20:01:48 2006
@@ -96,7 +96,7 @@
                     equals(e.getNamespace().getNamespaceURI())) {
                 return OMAbstractFactory.getSOAP11Factory();
             } else {
-                return OMAbstractFactory.getSOAP11Factory();
+                return OMAbstractFactory.getSOAP12Factory();
             }
         }
         return null;

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java Thu Nov 16 20:01:48 2006
@@ -124,7 +124,6 @@
             }
 
         } catch (Exception e) {
-        	// TODO NLS
             ThreadContextMigratorUtil.performThreadCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
             throw ExceptionFactory.makeWebServiceException(e);
         } 

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java Thu Nov 16 20:01:48 2006
@@ -80,6 +80,19 @@
         	response = target.invoke(serviceInstance, methodInputParams);
         } catch (Exception e) {
         	response = e;
+            if (log.isDebugEnabled()) {
+                log.debug("Exception invoking a method of " + 
+                        serviceImplClass.toString() + " of instance " +
+                        serviceInstance.toString());
+                        
+                log.debug("Method = " + target.toGenericString());
+              
+                for (int i=0; i<methodInputParams.length; i++) {
+                    String value = (methodInputParams[i] == null) ? "null" :
+                        methodInputParams[i].getClass().toString();
+                    log.debug(" Argument[" + i +"] is " + value);
+                }
+            }
         }
         
         Message message = null;
@@ -203,12 +216,12 @@
 			parameterStyle = javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED;
 		}
         return cf.createMethodMarshaller(Style.DOCUMENT, parameterStyle, 
-                serviceDesc, endpointDesc, operationDesc, protocol);
+                serviceDesc, endpointDesc, operationDesc, protocol, false);
 	}
 	
 	private MethodMarshaller createRPCLitMessageConvertor(MethodMarshallerFactory cf, Protocol protocol){
         return cf.createMethodMarshaller(Style.RPC, ParameterStyle.WRAPPED, 
-                serviceDesc, endpointDesc, operationDesc, protocol);
+                serviceDesc, endpointDesc, operationDesc, protocol, false);
 	}
 	
     

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/ClassUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/ClassUtils.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/ClassUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/ClassUtils.java Thu Nov 16 20:01:48 2006
@@ -29,10 +29,6 @@
 import java.util.List;
 
 import javax.jws.WebService;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlSchema;
-import javax.xml.namespace.QName;
 import javax.xml.ws.Holder;
 import javax.xml.ws.WebFault;
 import javax.xml.ws.WebServiceClient;
@@ -331,6 +327,10 @@
      * @return true if this is a JAX-WS or JAX-WS generated class
      */
     public static final boolean isJAXWSClass(Class cls) {
+        // TODO Processing all of these annotations is very expensive.  We need to cache the 
+        // result in a static WeakHashMap<Class, Boolean>
+        
+        
         // Kinds of generated classes: Service, Provider, Impl, Exception, Holder
         // Or the class is in the jaxws.xml.ws package
         
@@ -367,65 +367,6 @@
             return true;
         }
         return false;
-    }
-
-    
-    /**
-     * @param clazz
-     * @return namespace of root element qname or null if this is not object does not represent a root element
-     */
-    public static QName getXmlRootElementQName(Object obj){
-        
-        // A JAXBElement stores its name
-        if (obj instanceof JAXBElement) {
-            return ((JAXBElement) obj).getName();
-        }
-        
-        Class clazz = obj.getClass();
-        
-        // If the clazz is a primitive, then it does not have a corresponding root element.
-        if (clazz.isPrimitive() ||
-                getWrapperClass(clazz) != null) {
-            return null;
-        }
-        
-        // See if the object represents a root element
-        XmlRootElement root = (XmlRootElement) clazz.getAnnotation(XmlRootElement.class);
-        if (root == null) {
-            return null;
-        }
-        
-        String namespace = root.namespace();
-        String localPart = root.name();
-        
-        // The namespace may need to be defaulted
-        if (namespace == null || namespace.length() == 0 || namespace.equals("##default")) {
-            Package pkg = clazz.getPackage();
-            XmlSchema schema = (XmlSchema) pkg.getAnnotation(XmlSchema.class);
-            if (schema != null) {
-                namespace = schema.namespace();
-            } else {
-                return null;
-            }
-        }
-        return new QName(namespace, localPart);
-    }
-    
-    /**
-     * @param clazz
-     * @return true if this class has a corresponding xml root element
-     */
-    public static boolean isXmlRootElementDefined(Class clazz){
-        // If the clazz is a primitive, then it does not have a corresponding root element.
-        if (clazz.isPrimitive() ||
-                getWrapperClass(clazz) != null) {
-            return false;
-        }
-        // TODO We could also prune out other known classes that will not have root elements defined.
-        // java.util.Date, arrays, java.math.BigInteger.
-        
-        XmlRootElement root = (XmlRootElement) clazz.getAnnotation(XmlRootElement.class);
-        return root !=null;
     }
 }
 

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/XMLRootElementUtil.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/XMLRootElementUtil.java?view=auto&rev=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/XMLRootElementUtil.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/XMLRootElementUtil.java Thu Nov 16 20:01:48 2006
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ * Copyright 2006 International Business Machines Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.axis2.jaxws.util;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchema;
+import javax.xml.namespace.QName;
+
+/**
+ * This utility contains code to determine if an Object is 
+ * "element enabled" or "type enabled".
+ * 
+ * Here is an example for illustration:
+ *    <element name='e1'>
+ *      <complexType>...</complexType>
+ *    </element>
+ *    
+ *    <element name='e2' type='t2' />
+ *    <complexType name= 't2'>..
+ *
+ *    <element name='e3' type='e3' />  <!-- note element and type have same name -->
+ *    <complexType name= 'e3'>..
+ *
+ * JAXB will generate the following objects:  E1, T2, E3
+ *   E1 will have an @XMLRootElement annotation.  It is "element" and "type" enabled.
+ *   e2 does not have a generated object.  So it will be represented as a JAXBElement
+ *     that contains an object T2.  The JAXBElement is "element" enabled. 
+ *   T2 represents a complexType.  It is only "type" enabled.
+ *   E3 represents the e3 complexType (it does not represent the e3 element).  Thus E3
+ *     is "type enabled".  
+ *     
+ * When JAXB unmarshals an object, it will return an "element" enabled object (either
+ * a generatated object with @XMLRootElement or a JAXBElement).
+ * Conversely, you must always marshal "element" enabled objects. 
+ * @see org.apache.axis2.jaxws.marshaller.impl.alt.PDElement
+ * 
+ * At the signature level, the values passed as arguments in an SEI operation represent
+ * type enabled objects.  Each of the object must be converted to an element enabled object
+ * to marshal (or conversely converted to a type enabled object when unmarshalling)
+ *
+ * -----------------------------------------
+ * There are other simular utility methods in this class.  Including utilities to get 
+ * a xml name -> bean property map.
+ * 
+ * -----------------------------------------
+ * 
+ * @TODO A secondary reason usage of XMLRootElementUtil is to isolate all of the 
+ * @XMLRootElement and related annotation queries.  Annotation queries are expensive.
+ * A follow-on version of this class will cache the results so that we can improve performance.
+ * 
+ */
+public class XMLRootElementUtil {
+
+    /**
+     * Constructor is intentionally private.  This class only provides static utility methods
+     */
+    private XMLRootElementUtil() {
+        
+    }
+
+    /**
+     * Return true if this class is element enabled
+     * @param clazz
+     * @return true if this class has a corresponding xml root element
+     */
+    public static boolean isElementEnabled(Class clazz){
+        if (clazz.equals(JAXBElement.class)) {
+            return true;
+        }
+        
+        // If the clazz is a primitive, then it does not have a corresponding root element.
+        if (clazz.isPrimitive() || ClassUtils.getWrapperClass(clazz) != null) {
+            return false;
+        }
+        
+        // Presence of an annotation means that it can be rendered as a root element
+        XmlRootElement root = (XmlRootElement) clazz.getAnnotation(XmlRootElement.class);
+        return root !=null;
+    }
+    
+    /**
+     * Returns ture if this class is type enabled
+     * @param clazz
+     * @return
+     */
+    public static boolean isTypeEnabled(Class clazz) {
+        // Primitives, Primitive wrappers, BigDecimal, etc. are all type enabled
+        // So are all classes with @XmlRootElement or @XmlType.
+        // For now I am only going to assume that the class is type enabled unless it is JAXBElement
+        return (!clazz.equals(JAXBElement.class));
+    }
+    
+    /**
+     * Return type enabled object
+     * @param obj type or element enabled object
+     * @return type enabled object
+     */
+    public static Object getTypeEnabledObject(Object obj) {
+        if (obj == null) {
+            return null;
+        }
+        if (obj instanceof JAXBElement) {
+            return ((JAXBElement) obj).getValue();
+        }
+        return obj;
+    }
+    
+    /**
+     * Return an object that can be marshalled/unmarshalled as an element
+     * If the specified object is already element enabled, it is returned.
+     * @param namespace
+     * @param localPart
+     * @param cls either the class or super class of obj
+     * @param type element or type enabled object
+     * @return
+     */
+    public static Object getElementEnabledObject(String namespace, String localPart, Class cls, Object obj, boolean forceXSIType) {
+        if (obj != null && isElementEnabled(obj.getClass())) {
+            return obj;
+        }
+        
+        QName qName = new QName(namespace, localPart);
+        
+        // I think the way to force an xsi:type is to use Object as the class
+        if (forceXSIType) {
+            cls = Object.class;
+        }
+        JAXBElement element = new JAXBElement(qName, cls, obj);
+        return element;
+    }
+    
+    
+    
+    /**
+     * @param clazz
+     * @return namespace of root element qname or null if this is not object does not represent a root element
+     */
+    public static QName getXmlRootElementQName(Object obj){
+        
+        // A JAXBElement stores its name
+        if (obj instanceof JAXBElement) {
+            return ((JAXBElement) obj).getName();
+        }
+        
+        Class clazz = obj.getClass();
+        
+        // If the clazz is a primitive, then it does not have a corresponding root element.
+        if (clazz.isPrimitive() ||
+                ClassUtils.getWrapperClass(clazz) != null) {
+            return null;
+        }
+        
+        // See if the object represents a root element
+        XmlRootElement root = (XmlRootElement) clazz.getAnnotation(XmlRootElement.class);
+        if (root == null) {
+            return null;
+        }
+        
+        String namespace = root.namespace();
+        String localPart = root.name();
+        
+        // The namespace may need to be defaulted
+        if (namespace == null || namespace.length() == 0 || namespace.equals("##default")) {
+            Package pkg = clazz.getPackage();
+            XmlSchema schema = (XmlSchema) pkg.getAnnotation(XmlSchema.class);
+            if (schema != null) {
+                namespace = schema.namespace();
+            } else {
+                return null;
+            }
+        }
+        return new QName(namespace, localPart);
+    }
+
+    
+    /**
+     * The JAXBClass has a set of bean properties each represented by a PropertyDescriptor
+     * Each of the fields of the class has an associated xml name.
+     * The method returns a map where the key is the xml name and value is the PropertyDescriptor
+     * @param jaxbClass
+     * @return map
+     */
+    public static Map<String, PropertyDescriptor> createPropertyDescriptorMap(Class jaxbClass) throws NoSuchFieldException, IntrospectionException {
+        
+        // TODO This is a very performance intensive search we should cache the calculated map keyed by the jaxbClass
+        
+        PropertyDescriptor[] pds = Introspector.getBeanInfo(jaxbClass).getPropertyDescriptors();
+        // Make this a weak map in case we want to cache the resolts
+        Map<String, PropertyDescriptor> map = new WeakHashMap<String, PropertyDescriptor>();
+        
+        // Unfortunately the element names are stored on the fields.
+        // Therefore we need to to match up the field and property descriptor
+        Field[] fields = jaxbClass.getDeclaredFields();
+        for(PropertyDescriptor pd:pds){
+            for(Field field:fields){
+                String fieldName = field.getName();
+                
+                // Use the name of the field and property to find the match
+                if (fieldName.equalsIgnoreCase(pd.getDisplayName()) ||
+                    fieldName.equalsIgnoreCase(pd.getName())   ) {
+                    // Get the xmlElement name for this field
+                    String xmlName =getXmlElementName(jaxbClass, field);
+                    map.put(xmlName, pd);
+                    break;
+                }
+                
+                // Unfortunately, sometimes the field name is preceeded by an underscore
+                if (fieldName.startsWith("_")) {
+                    fieldName = fieldName.substring(1);
+                    if (fieldName.equalsIgnoreCase(pd.getDisplayName()) ||
+                            fieldName.equalsIgnoreCase(pd.getName())) {
+                        // Get the xmlElement name for this field
+                        String xmlName =getXmlElementName(jaxbClass, field);
+                        map.put(xmlName, pd);
+                        break;
+                    }
+                }
+            }
+        }
+        return map;
+    }
+    
+    /**
+     * Get the name of the field by looking at the XmlElement annotation.
+     * @param jaxbClass
+     * @param fieldName
+     * @return
+     * @throws NoSuchFieldException
+     */
+    private static String getXmlElementName(Class jaxbClass, Field field)throws NoSuchFieldException{ 
+        XmlElement xmlElement =field.getAnnotation(XmlElement.class);
+        
+        
+        // If XmlElement does not exist, default to using the field name
+        if (xmlElement == null || 
+            xmlElement.name().equals("##default")) {
+            return field.getName();
+        }
+        return xmlElement.name();
+        
+    }
+    
+    
+    
+}

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/JAXBWrapperTool.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/JAXBWrapperTool.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/JAXBWrapperTool.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/JAXBWrapperTool.java Thu Nov 16 20:01:48 2006
@@ -17,7 +17,7 @@
 
 package org.apache.axis2.jaxws.wrapper;
 
-import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.axis2.jaxws.wrapper.impl.JAXBWrapperException;
@@ -34,9 +34,9 @@
      * @param jaxbObject that is the wrapper element (JAXBElement or object with @XMLRootElement)
      * @param jaxbContext JAXBContext
      * @param childNames list of xml child names as String
-     * @return list of Objects in the same order as the element names.
+     * @return list of Objects in the same order as the element names.  
      */
-   public Object[] unWrap(Object jaxbObject, ArrayList<String> childNames) throws JAXBWrapperException;
+   public Object[] unWrap(Object jaxbObject, List<String> childNames) throws JAXBWrapperException;
 
 
     /**
@@ -46,11 +46,10 @@
      * Note that the jaxbClass must be the class the represents the complexType. (It should never be JAXBElement)
      * 
      * @param jaxbClass 
-     * @param childObjects, component objects
+     * @param childObjects, component type objects
      * @param childNames list of xml child names as String
-     * @return list of Objects in the same order as the element names.
      */ 
-    public Object wrap(Class jaxbClass, ArrayList<String> childNames, Map<String, Object> childObjects) throws JAXBWrapperException;
+    public Object wrap(Class jaxbClass, List<String> childNames, Map<String, Object> childObjects) throws JAXBWrapperException;
     
     
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/JAXBWrapperToolImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/JAXBWrapperToolImpl.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/JAXBWrapperToolImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/JAXBWrapperToolImpl.java Thu Nov 16 20:01:48 2006
@@ -23,6 +23,7 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.WeakHashMap;
 
@@ -30,6 +31,7 @@
 import javax.xml.bind.annotation.XmlElement;
 
 import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.util.XMLRootElementUtil;
 import org.apache.axis2.jaxws.wrapper.JAXBWrapperTool;
 
 
@@ -45,7 +47,7 @@
 	 */
 	
 	public Object[] unWrap(Object jaxbObject, 
-			ArrayList<String> childNames) throws JAXBWrapperException{
+			List<String> childNames) throws JAXBWrapperException{
 		try{
 			if(jaxbObject == null){
 				throw new JAXBWrapperException(Messages.getMessage("JAXBWrapperErr1"));
@@ -54,6 +56,7 @@
 				throw new JAXBWrapperException(Messages.getMessage("JAXBWrapperErr2"));
 			}
             
+            // Review: I think that we can remove the next statement.  This is an assertion of the tool
             // Get the object that will have the property descriptors (i.e. the object representing the complexType)
             Object jaxbComplexTypeObj = (jaxbObject instanceof JAXBElement) ?
                     ((JAXBElement)jaxbObject).getValue() : // Type object is the value of the JAXBElement
@@ -84,7 +87,7 @@
 	 * @see org.apache.axis2.jaxws.wrapped.JAXBWrapperTool#wrap(java.lang.Class, java.lang.String, java.util.ArrayList, java.util.ArrayList)
 	 */
 	public Object wrap(Class jaxbClass, 
-			ArrayList<String> childNames, Map<String, Object> childObjects)
+			List<String> childNames, Map<String, Object> childObjects)
 			throws JAXBWrapperException {
 		
 		try{
@@ -120,91 +123,40 @@
 	 * childName if not use xmlElement annotation name and create PropertyInfo add childName or xmlElement name there, set propertyDescriptor 
 	 * and return Map<ChileName, PropertyInfo>.
 	 * @param jaxbClass - Class jaxbClass name
-	 * @param childNames - ArrayList<String> of childNames 
+	 * @param childNames - ArrayList<String> of xml childNames 
 	 * @return Map<String, PropertyInfo> - map of ChildNames that map to PropertyInfo that hold the propertyName and PropertyDescriptor.
 	 * @throws IntrospectionException, NoSuchFieldException
 	 */
-	private Map<String, PropertyInfo> createPropertyDescriptors(Class jaxbClass, ArrayList<String> childNames) throws IntrospectionException, NoSuchFieldException, JAXBWrapperException{
+	private Map<String, PropertyInfo> createPropertyDescriptors(Class jaxbClass, List<String> childNames) throws IntrospectionException, NoSuchFieldException, JAXBWrapperException{
 		Map<String, PropertyInfo> map = new WeakHashMap<String, PropertyInfo>();
-		PropertyDescriptor[] pds = Introspector.getBeanInfo(jaxbClass).getPropertyDescriptors();
 		
-		Map<String, PropertyDescriptor>  jaxbClassPds = filterDescriptors(pds, jaxbClass);
+		
+		Map<String, PropertyDescriptor>  pdMap = XMLRootElementUtil.createPropertyDescriptorMap(jaxbClass);
 		Field field[] = jaxbClass.getDeclaredFields();
-		if(field.length != childNames.size()){
+        
+        // It is possible the that the number of fields is greater than the number of child elements due
+        // to customizations.
+		if(field.length < childNames.size()){
 			throw new JAXBWrapperException(Messages.getMessage("JAXBWrapperErr4", jaxbClass.getName()));
 		}
-		pds=null;
+        
+		
+        // Create property infos for each class name
+        for (int i=0; i<childNames.size(); i++) {
+            PropertyInfo propInfo= null;
+            String childName = childNames.get(i);
+            PropertyDescriptor pd = pdMap.get(childName);
+            if(pd == null){
+                throw new JAXBWrapperException(Messages.getMessage("JAXBWrapperErr6", jaxbClass.getName(), childName));
+            }
+            propInfo = new PropertyInfo(pd);
+            map.put(childName, propInfo);
+        }
+        
 		
-		for(int i=0; i<field.length ;i++){
-			PropertyInfo propInfo= null;
-			String fieldName = field[i].getName();
-			String childName = childNames.get(i);
-			PropertyDescriptor pd = jaxbClassPds.get(childName);
-			if(pd == null){
-				pd = jaxbClassPds.get(fieldName);
-				if(pd == null){
-					throw new JAXBWrapperException(Messages.getMessage("JAXBWrapperErr4", jaxbClass.getName(), childName));
-				}	
-			}
-			propInfo = new PropertyInfo(fieldName, pd);
-			map.put(childName, propInfo);
-		}
-		jaxbClassPds = null;
-		field = null;
 		return map;
 	}
 	
 	
-	/** Filter PropertyDescriptors that belong to super class, return only the ones that belong to JABXClass
-	 * create map of java fieldName and propertyDescriptor, if propertyName different than java fieldName then
-	 * check the xmlElementName ensure they are same if not do conver both xmlName and propertyName to lowercase and
-	 * ensure they are same if they match then add the corrosponding javaFieldName and PropertyDescriptor in map. If they dont 
-	 * match the propertyName belongs to super class and we ignore it.
-	 * @param allPds 
-	 * @param jaxbClass
-	 * @return
-	 */
-	private Map<String, PropertyDescriptor> filterDescriptors(PropertyDescriptor[] allPds, Class jaxbClass) throws NoSuchFieldException{
-		Map<String, PropertyDescriptor> filteredPds = new WeakHashMap<String, PropertyDescriptor>();
-		Field[] fields = jaxbClass.getDeclaredFields();
-		for(PropertyDescriptor pd:allPds){
-			for(Field field:fields){
-				if(field.getName().equals(pd.getDisplayName())){
-					filteredPds.put(pd.getDisplayName(), pd);
-					break;
-				}else{
-					String xmlName =getXmlElementName(jaxbClass, field.getName());
-					if(xmlName.equals(pd.getDisplayName())){
-						filteredPds.put(field.getName(), pd);
-						break;
-					}
-					if(xmlName.toLowerCase().equals(pd.getDisplayName().toLowerCase())){
-						filteredPds.put(field.getName(), pd);
-						break;
-					}
-				}
-			}
-		}
-		allPds=null;
-		return filteredPds;
-	}
 	
-	/**
-	 * Get the name of the xml element by looking at the XmlElement annotation.
-	 * @param jaxbClass
-	 * @param fieldName
-	 * @return
-	 * @throws NoSuchFieldException
-	 */
-	private String getXmlElementName(Class jaxbClass, String fieldName)throws NoSuchFieldException{
-		Field field = jaxbClass.getDeclaredField(fieldName);
-		XmlElement xmlElement =field.getAnnotation(XmlElement.class);
-		
-		// If XmlElement does not exist, default to using the field name
-		if (xmlElement == null) {
-			return fieldName;
-		}
-		return xmlElement.name();
-		
-	}
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/PropertyInfo.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/PropertyInfo.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/PropertyInfo.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/wrapper/impl/PropertyInfo.java Thu Nov 16 20:01:48 2006
@@ -25,30 +25,44 @@
 import org.apache.commons.logging.LogFactory;
 
 
+/**
+ * A PropertyInfo is constructed with a PropertyDescriptor and
+ * exposes get/set methods to access the object on a bean that matches the PropertyDescriptor
+ *
+ */
 public class PropertyInfo {
-	String propertyName;
 	PropertyDescriptor descriptor;
 	private static Log log = LogFactory.getLog(PropertyInfo.class);
 	/**
 	 * @param propertyName
 	 * @param descriptor
 	 */
-	public PropertyInfo(String propertyName, PropertyDescriptor descriptor) {
+	public PropertyInfo(PropertyDescriptor descriptor) {
 		super();
-		
-		this.propertyName = propertyName;
 		this.descriptor = descriptor;
 	}
 	
-	public String getPropertyName(){
-		return this.propertyName;
-	}
 	
+	/**
+     * Get the object 
+	 * @param targetBean
+	 * @return Object for this property or null
+	 * @throws InvocationTargetException
+	 * @throws IllegalAccessException
+	 */
 	public Object get(Object targetBean)throws InvocationTargetException, IllegalAccessException{
 		Method method = descriptor.getReadMethod();
 		return method.invoke(targetBean, null);
 	}
 	
+	/** 
+     * Set the object
+	 * @param targetBean
+	 * @param propValue
+	 * @throws InvocationTargetException
+	 * @throws IllegalAccessException
+	 * @throws JAXBWrapperException
+	 */
 	public void set(Object targetBean, Object propValue)throws InvocationTargetException, IllegalAccessException, JAXBWrapperException{
 		Method method = descriptor.getWriteMethod();
 		Object[] object = new Object[]{propValue};

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageRPCTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageRPCTests.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageRPCTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageRPCTests.java Thu Nov 16 20:01:48 2006
@@ -300,7 +300,11 @@
         
         // Check to make sure the right object was returned
         assertNotNull(bo);
+        if (bo instanceof JAXBElement) {
+            bo = ((JAXBElement) bo).getValue();
+        }
         assertTrue(bo instanceof StockPrice);
+        
         
         // Check to make sure the content of that object is correct
         StockPrice obj = (StockPrice) bo;

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/AddressBookTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/AddressBookTests.java?view=diff&rev=476045&r1=476044&r2=476045
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/AddressBookTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/sample/AddressBookTests.java Thu Nov 16 20:01:48 2006
@@ -49,6 +49,7 @@
      * Test the endpoint by invoking it with a JAX-WS Dispatch.  
      */
     public void testAddressBookWithDispatch() throws Exception {
+        try {
         System.out.println("----------------------------------");
         System.out.println("test: " + getName());
         
@@ -80,6 +81,10 @@
         assertTrue(response.isStatus());
         System.out.println("[pass]     - valid response received");
         System.out.println("[response] - " + response.isStatus());
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
     }
     
     /**



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org