axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sc...@apache.org
Subject svn commit: r476847 - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/marshaller/impl/ src/org/apache/axis2/jaxws/marshaller/impl/alt/ src/org/apache/axis2/jaxws/message/databinding/ src/org/apache/axis2/jaxws/message/databin...
Date Sun, 19 Nov 2006 16:40:29 GMT
Author: scheu
Date: Sun Nov 19 08:40:28 2006
New Revision: 476847

URL: http://svn.apache.org/viewvc?view=rev&rev=476847
Log:
AXIS2-1730
Contributor:Rich Scheuerle
Enabled and fixed another rpc/lit test (JAXWS)

Added:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/XSDListUtils.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMethodMarshaller.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/MethodMarshallerUtils.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/RPCLitMethodMarshaller.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/XMLRootElementUtil.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java?view=diff&rev=476847&r1=476846&r2=476847
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java
(original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/DocLitWrappedMethodMarshallerImpl.java
Sun Nov 19 08:40:28 2006
@@ -210,7 +210,7 @@
             // the appropriate JAXBElement
             if (!XMLRootElementUtil.isElementEnabled(wrapperClazz)) {
                 wrapper = XMLRootElementUtil.getElementEnabledObject(wrapperTNS, 
-                        wrapperLocalName, wrapperClazz, wrapper, false);
+                        wrapperLocalName, wrapperClazz, wrapper);
             }
 			Message message = createMessage(wrapper);
 
@@ -252,7 +252,7 @@
                     XMLRootElementUtil.getElementEnabledObject(wrapperTNS, 
                             wrapperLocalName,
                             wrapperClazz, 
-                            jaxbObject, false);
+                            jaxbObject);
             }
 			Message message = createMessage(jaxbObject);
 

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java?view=diff&rev=476847&r1=476846&r2=476847
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java
(original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/MethodMarshallerImpl.java
Sun Nov 19 08:40:28 2006
@@ -216,7 +216,7 @@
                 // the actual object may be a derived type of the formal declaration)
             	if (!XMLRootElementUtil.isElementEnabled(faultBean.getClass())) {
                     faultBean = XMLRootElementUtil.getElementEnabledObject(fd.getTargetNamespace(),
fd.getName(),
-                            faultBean.getClass(), faultBean, false);
+                            faultBean.getClass(), faultBean);
                 }
             	detailBlocks[0] = createJAXBBlock(faultBean, context);
                 xmlfault = new XMLFault(null, new XMLFaultReason(t.toString()), detailBlocks);

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMethodMarshaller.java?view=diff&rev=476847&r1=476846&r2=476847
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMethodMarshaller.java
(original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMethodMarshaller.java
Sun Nov 19 08:40:28 2006
@@ -169,11 +169,11 @@
             List<PDElement> pvList = MethodMarshallerUtils.getPDElements(pds, 
                     signatureArgs, 
                     false, // output
-                    false, // use name (element name) not wsd:part name
-                    false); // don't force xsi:type for doc/lit
+                    false); // use name (element name) not wsd:part name
+                   
 
             // Put values onto the message
-            MethodMarshallerUtils.toMessage(pvList, m, packages);
+            MethodMarshallerUtils.toMessage(pvList, m, packages, false);
             
             return m;
         } catch(Exception e) {
@@ -212,11 +212,11 @@
             List<PDElement> pvList = MethodMarshallerUtils.getPDElements(pds, 
                     signatureArguments, 
                     true,  // input
-                    false, // use name (element name) not wsd:part name
-                    false); // don't force xsi:type for doc/lit
+                    false);// use name (element name) not wsd:part name
+                    
             
             // Put values onto the message
-            MethodMarshallerUtils.toMessage(pvList, m, packages);
+            MethodMarshallerUtils.toMessage(pvList, m, packages, false);
             
             return m;
         } catch(Exception e) {

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java?view=diff&rev=476847&r1=476846&r2=476847
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java
(original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java
Sun Nov 19 08:40:28 2006
@@ -144,8 +144,7 @@
                     value = XMLRootElementUtil.getElementEnabledObject(pd.getTargetNamespace(),
                             pd.getPartName(), 
                             pd.getParameterActualType(), 
-                            value,
-                            false); // don't force xsi:type for doc/lit
+                            value); 
      
                 }
                 pvList.add(new PDElement(pd, value));
@@ -230,8 +229,7 @@
                     value = XMLRootElementUtil.getElementEnabledObject(pd.getTargetNamespace(),
                             pd.getPartName(), 
                             pd.getParameterActualType(), 
-                            value, 
-                            false);  // don't force xsi:type for doc/lit
+                            value);
      
                 }
                 pvList.add(new PDElement(pd, value));
@@ -281,8 +279,8 @@
                 MethodMarshallerUtils.getPDElements(pds,
                         signatureArgs, 
                         false,  // output
-                        true,   // use partNames (which are child names)
-                        false);  // don't force xis:type for doc/lit
+                        true);   // use partNames (which are child names)
+                        
 
             // Now we want to create a single JAXB element that contains the 
             // ParameterValues.  We will use the wrapper tool to do this.
@@ -321,8 +319,7 @@
                         operationDesc.getResponseWrapperTargetNamespace(), 
                         operationDesc.getResponseWrapperLocalName(), 
                         cls, 
-                        object, 
-                        false);  // don't force xsitype for doc/lit
+                        object);
             }
             
             
@@ -372,8 +369,7 @@
             List<PDElement> pvList = MethodMarshallerUtils.getPDElements(pds, 
                     signatureArguments, 
                     true,   // input
-                    true,   // use partName (which are the child element names)
-                    false); // we don't force xsi:type for doc/lit
+                    true);   // use partName (which are the child element names)
             
             // Now we want to create a single JAXB element that contains the 
             // ParameterValues.  We will use the wrapper tool to do this.
@@ -404,8 +400,7 @@
                         operationDesc.getRequestWrapperTargetNamespace(), 
                         operationDesc.getRequestWrapperLocalName(), 
                         cls, 
-                        object, 
-                        false);  // for doc/lit we don't want to force xsi:type
+                        object);
             }
             
             // Put the object into the message

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=476847&r1=476846&r2=476847
==============================================================================
--- 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
Sun Nov 19 08:40:28 2006
@@ -89,10 +89,9 @@
      * @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) {
+    static List<PDElement> getPDElements(ParameterDescription[] params, Object[] sigArguments,
boolean isInput, boolean usePartName) {
         List<PDElement> pvList = new ArrayList<PDElement>();
         
         int index = 0;
@@ -124,7 +123,7 @@
                 // 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);
+                    value = XMLRootElementUtil.getElementEnabledObject(pd.getTargetNamespace(),
localName, formalType, value);
                 }
                 
                 // The object is now ready for marshalling
@@ -289,20 +288,28 @@
      * @param pvList element enabled objects
      * @param message Message
      * @param packages Packages needed to do a JAXB Marshal
+     * @param isRPC 
      * @throws MessageException
      */
-    static void toMessage(List<PDElement> pvList, Message message, Set<Package>
packages) throws MessageException {
+    static void toMessage(List<PDElement> pvList, Message message, Set<Package>
packages, boolean isRPC) throws MessageException {
         
         int index = message.getNumBodyBlocks();
         for (int i=0; i<pvList.size(); i++) {
             PDElement pv = pvList.get(i);
             
+            // Create the JAXBBlockContext
+            // RPC uses type marshalling, so recored the rpcType
+            JAXBBlockContext context = new JAXBBlockContext(packages);
+            if (isRPC) {
+                context.setRPCType(pv.getParam().getParameterActualType());
+            }
+                
             // 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), 
+                    context, 
                     null);  // The factory will get the qname from the value
             
             if (pv.getParam().isHeader()) {
@@ -327,7 +334,7 @@
      * @param returnLocalPart
      * @param packages
      * @param message
-     * @param forceXSIType if upgrading type to an element
+     * @param isRPC
      * @throws MessageException
      */
     static void toMessage(Object returnValue, 
@@ -336,17 +343,25 @@
             String returnLocalPart, 
             Set<Package> packages, 
             Message message, 
-            boolean forceXSIType) 
+            boolean isRPC) 
             throws MessageException {
+        
+        // Create the JAXBBlockContext
+        // RPC uses type marshalling, so recored the rpcType
+        JAXBBlockContext context = new JAXBBlockContext(packages);
+        if (isRPC) {
+            context.setRPCType(returnType);
+        }
+        
         // 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);
+            returnValue = XMLRootElementUtil.getElementEnabledObject(returnNS, returnLocalPart,returnType,
returnValue);
         }
         
         //  Create a JAXBBlock out of the value.
         Block block = factory.createFrom(returnValue, 
-                new JAXBBlockContext(packages), 
+                context, 
                 null);  // The factory will get the qname from the value
         message.setBodyBlock(0, block);
     }
@@ -420,14 +435,13 @@
      * @param operationDesc OperationDescription
      * @param packages Packages needed to marshal the object
      * @param message Message
-     * @param forceXSIType if the faultbean 
+     * @param isRPC
      * @throws MessageException
      * @throws NoSuchMethodException
      * @throws InvocationTargetException
      * @throws IllegalAccessException
      */
-    static void marshalFaultResponse(Throwable throwable, OperationDescription operationDesc,
 Set<Package> packages, Message message, 
-            boolean forceXSIType)
+    static void marshalFaultResponse(Throwable throwable, OperationDescription operationDesc,
 Set<Package> packages, Message message, boolean isRPC)
      throws MessageException, NoSuchMethodException, InvocationTargetException, IllegalAccessException
{
         
         // Get the root cause of the throwable object
@@ -452,11 +466,18 @@
             Object faultBeanObject = getFaultInfo.invoke(t, null);
             if (!XMLRootElementUtil.isElementEnabled(faultBeanObject.getClass())) {
                 faultBeanObject = XMLRootElementUtil.getElementEnabledObject(fd.getTargetNamespace(),
fd.getName(), 
-                        faultBeanObject.getClass(), faultBeanObject, forceXSIType);
+                        faultBeanObject.getClass(), faultBeanObject);
             }
             
-            // Create a detailblock representing the faultBeanObject
+            
+            // Create the JAXBBlockContext
+            // RPC uses type marshalling, so recored the rpcType
             JAXBBlockContext context = new JAXBBlockContext(packages);
+            if (isRPC) {
+                context.setRPCType(faultBeanObject.getClass());
+            }
+            
+            // Create a detailblock representing the faultBeanObject
             Block[] detailBlocks = new Block[1];
             detailBlocks[0] = factory.createFrom(faultBeanObject,context,null);
             

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=476847&r1=476846&r2=476847
==============================================================================
--- 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
Sun Nov 19 08:40:28 2006
@@ -101,11 +101,11 @@
                 MethodMarshallerUtils.getPDElements(pds, 
                         signatureArguments,
                         true,  // input
-                        true, // use partName since this is rpc/lit
-                        true); // always force xsi:type since this is rpc/lit
+                        true); // use partName since this is rpc/lit
+                        
             
             // Put values onto the message
-            MethodMarshallerUtils.toMessage(pvList, m, packages);
+            MethodMarshallerUtils.toMessage(pvList, m, packages, true);
             
             return m;
         } catch(Exception e) {
@@ -215,11 +215,10 @@
                 MethodMarshallerUtils.getPDElements(pds, 
                         signatureArgs, 
                         false,  // output
-                        true,   // use partName since this is rpc/lit
-                        true);  // forceXSI since this is rpc/lit
+                        true);   // use partName since this is rpc/lit
 
             // Put values onto the message
-            MethodMarshallerUtils.toMessage(pvList, m, packages);
+            MethodMarshallerUtils.toMessage(pvList, m, packages, true);
             
             return m;
         } catch(Exception e) {
@@ -289,7 +288,7 @@
                     operationDesc, 
                     endpointDesc.getPackages(), 
                     m, 
-                    true);  // always marshal xsi:type if rpc/lit
+                    true);  // isRPC=true
             return m;
         } catch(Exception e) {
             throw ExceptionFactory.makeWebServiceException(e);

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/XSDListUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/XSDListUtils.java?view=auto&rev=476847
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/XSDListUtils.java
(added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/XSDListUtils.java
Sun Nov 19 08:40:28 2006
@@ -0,0 +1,149 @@
+/*
+ * 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.message.databinding;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+
+/**
+ * Utilities to convert to/from xsd:list String to Object[]/List values.
+ */
+public class XSDListUtils {
+    /**
+     * Constructor is intentionally private
+     */
+    private XSDListUtils() {}
+    
+    //  Example:
+    // <xsd:simpleType name="LongList">
+    //   <xsd:list>
+    //     <xsd:simpleType>
+    //       <xsd:restriction base="xsd:unsignedInt"/>
+    //     </xsd:simpleType>
+    //   </xsd:list>
+    // </xsd:simpleType>
+    // <element name="myLong" nillable="true" type="impl:LongList"/>
+    //
+    // LongList will be represented as an int[]
+    // On the wire myLong will be represented as a list of integers
+    // with intervening whitespace
+    //   <myLong>1 2 3</myLong>
+    //
+    // Unfortunately, sometimes we want to marshal by type.  Therefore
+    // we want to marshal an element (foo) that is unknown to schema.
+    // If we use the normal marshal code, the wire will look like
+    // this (which is incorrect):
+    //  <foo><item>1</item><item>2</item><item>3</item></foo>
+    //
+    // The solution is to detect this situation and marshal the 
+    // String instead.  Then we get the correct wire format:
+    // <foo>1 2 3</foo>
+    // 
+    // This utility contains code to convert from Array/List -> String
+    // and from String -> Array/List
+    
+    /**
+     * Convert to String that can be used as an xsd:list content
+     * @param container Object
+     * @return xsd:list String
+     */
+    public static String toXSDListString(Object container) {
+        // TODO only supports arrays right now.  Need to implement this for List
+        if (container.getClass().isArray()) {
+            String xsdString = "";
+            for (int i=0; i <Array.getLength(container); i++) {
+                Object component = Array.get(container, i);
+                if (xsdString.length() != 0) {
+                    xsdString += " ";
+                }
+                xsdString += getAsText(component);
+            }
+            return xsdString;
+        } else {
+            throw new IllegalArgumentException(container.getClass().toString());
+        }
+    }
+    
+    /**
+     * Convert from xsdListString to an array/list 
+     * @param xsdListString
+     * @param type Class of return
+     * @return Array or List
+     * @throws InvocationTargetException 
+     * @throws IllegalAccessException 
+     * @throws InstantiationException 
+     * @throws NoSuchMethodException 
+     * @throws IllegalArgumentException 
+     */
+    public static Object fromXSDListString(String xsdListString, Class type) throws IllegalArgumentException,
NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
{
+        // TODO only supports arrays right now.  Need to implement this for List
+        if (type.isArray()) {
+           Class componentType = type.getComponentType();
+           List list = new ArrayList();
+           
+           // Parse the tokens based on whitespace
+           StringTokenizer st = new StringTokenizer(xsdListString);
+           while (st.hasMoreTokens()) {
+              String text = st.nextToken();
+              Object componentObject = getFromText(text, componentType);
+              list.add(componentObject);
+           }
+           Object array = Array.newInstance(componentType, list.size());
+           return list.toArray((Object[]) array);
+        } else {
+            throw new IllegalArgumentException(type.toString());
+        }
+    }
+    
+    /**
+     * @param obj
+     * @return xml text for this object
+     */
+    private static String getAsText(Object obj) {
+        // TODO Need to upgrade to handle more complicated objects like calendar and qname
+        return obj.toString();
+    }
+    
+    /**
+     * @param value
+     * @param componentType
+     * @return Object constructed from the specified xml text (value)
+     * @throws NoSuchMethodException
+     * @throws IllegalArgumentException
+     * @throws InstantiationException
+     * @throws IllegalAccessException
+     * @throws InvocationTargetException
+     */
+    private static Object getFromText(String value, Class componentType) throws NoSuchMethodException,
IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException
{
+        // TODO This needs to be upgraded to handle more complicated objects (enum, calendar,
primitive, etc.)
+        if (componentType == String.class) {
+            return value;
+        }
+        
+        // If you get an exception here, consider adding the code to convert the String value
to the required component object
+        // Default: Call the constructor
+        Constructor constructor = componentType.getConstructor(new Class[] {String.class}
);
+        Object obj = constructor.newInstance(new Object[] {value} );
+        return obj;
+    }
+    
+}

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=476847&r1=476846&r2=476847
==============================================================================
--- 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
Sun Nov 19 08:40:28 2006
@@ -18,6 +18,7 @@
 
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.util.List;
 
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
@@ -42,6 +43,7 @@
 import org.apache.axis2.jaxws.message.databinding.JAXBBlock;
 import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
 import org.apache.axis2.jaxws.message.databinding.JAXBUtils;
+import org.apache.axis2.jaxws.message.databinding.XSDListUtils;
 import org.apache.axis2.jaxws.message.factory.BlockFactory;
 import org.apache.axis2.jaxws.message.impl.BlockImpl;
 import org.apache.axis2.jaxws.util.XMLRootElementUtil;
@@ -108,11 +110,9 @@
             
             // Unmarshal into the business object.
             if (ctx.getRPCType() == null) {
-                jaxb = u.unmarshal(reader); // preferred and always used for style=document
+                jaxb = unmarshalByElement(u, reader); // preferred and always used for style=document
             } else {
-                // Unfortunately RPC is type based.  Thus a
-                // declared type must be used to unmarshal the xml.
-                jaxb = u.unmarshal(reader, ctx.getRPCType());
+                jaxb = unmarshalByType(u, reader, ctx.getRPCType());
             }
             
             // Set the qname 
@@ -183,7 +183,12 @@
                 m.setAttachmentMarshaller(am);
             }   
             
-            m.marshal(busObject, writer);
+            // Marshal the object
+            if (ctx.getRPCType() == null) {
+                marshalByElement(busObject, m, writer);
+            } else {
+                marshalByType(busObject, m, writer, ctx.getRPCType());
+            }
             
             // Successfully marshalled the data
             // TODO remove attachment marshaller ?
@@ -221,5 +226,148 @@
         }
         
         return false;
+    }
+    
+    /**
+     * Preferred way to marshal objects.  
+     * @param b Object that can be rendered as an element and the element name is known by
the Marshaller
+     * @param m Marshaller
+     * @param writer XMLStreamWriter
+     */
+    private static void marshalByElement(Object b, Marshaller m, XMLStreamWriter writer)
throws MessageException {
+        // TODO Log and trace here would be helpful
+        try {
+            m.marshal(b, writer);
+        } catch (Exception e) {
+            throw ExceptionFactory.makeMessageException(e);
+        }
+    }
+    
+    /**
+     * Preferred way to unmarshal objects
+     * @param u Unmarshaller
+     * @param reader XMLStreamReader
+     * @return Object that represents an element 
+     * @throws MessageException
+     */
+    private static Object unmarshalByElement(Unmarshaller u, XMLStreamReader reader) throws
MessageException {
+        // TODO Log and trace here would be helpful
+        try {
+            return u.unmarshal(reader);
+        } catch (Exception e) {
+            throw ExceptionFactory.makeMessageException(e);
+        }
+    }
+    
+    /**
+     * Marshal objects by type  
+     * @param b Object that can be rendered as an element, but the element name is not known
to the schema (i.e. rpc)
+     * @param m Marshaller
+     * @param writer XMLStreamWriter
+     * @param type
+     */
+    private static void marshalByType(Object b, Marshaller m, XMLStreamWriter writer, Class
type) throws MessageException {
+        // TODO Log and trace here would be helpful
+        try {
+            
+            // NOTE
+            // Example:
+            // <xsd:simpleType name="LongList">
+            //   <xsd:list>
+            //     <xsd:simpleType>
+            //       <xsd:restriction base="xsd:unsignedInt"/>
+            //     </xsd:simpleType>
+            //   </xsd:list>
+            // </xsd:simpleType>
+            // <element name="myLong" nillable="true" type="impl:LongList"/>
+            //
+            // LongList will be represented as an int[]
+            // On the wire myLong will be represented as a list of integers
+            // with intervening whitespace
+            //   <myLong>1 2 3</myLong>
+            //
+            // Unfortunately, we are trying to marshal by type.  Therefore
+            // we want to marshal an element (foo) that is unknown to schema.
+            // If we use the normal marshal code, the wire will look like
+            // this (which is incorrect):
+            //  <foo><item>1</item><item>2</item><item>3</item></foo>
+            //
+            // The solution is to detect this situation and marshal the 
+            // String instead.  Then we get the correct wire format:
+            // <foo>1 2 3</foo>
+            if (isXSDList(type)) {
+                QName qName = XMLRootElementUtil.getXmlRootElementQName(b);
+                String text = XSDListUtils.toXSDListString(XMLRootElementUtil.getTypeEnabledObject(b));
+                b = XMLRootElementUtil.getElementEnabledObject(qName.getNamespaceURI(), qName.getLocalPart(),
String.class, text);
+            }
+            m.marshal(b, writer);
+        } catch (Exception e) {
+            throw ExceptionFactory.makeMessageException(e);
+        }
+    }
+    
+    /**
+     * The root element being read is defined by schema/JAXB; however its contents are known
by schema/JAXB.
+     * Therefore we use unmarshal by the declared type
+     * (This method is used to unmarshal rpc elements)
+     * @param u Unmarshaller
+     * @param reader XMLStreamReader
+     * @param type Class
+     * @return Object 
+     * @throws MessageException
+     */
+    private static Object unmarshalByType(Unmarshaller u, XMLStreamReader reader, Class type)
throws MessageException {
+        // TODO Log and trace here would be helpful
+        try {
+            // Unfortunately RPC is type based.  Thus a
+            // declared type must be used to unmarshal the xml.
+            Object jaxb;
+            
+            
+            
+            
+            if (!isXSDList(type) ) {
+                // Normal case: We are not unmarshalling an xsd:list
+                jaxb = u.unmarshal(reader, type);
+            } else {
+                // If this is an xsd:list, we need to return the appropriate list or array
(see NOTE above)
+                // First unmarshal as a String
+                jaxb = u.unmarshal(reader, String.class);
+                
+                // Second convert the String into a list or array
+                if (XMLRootElementUtil.getTypeEnabledObject(jaxb) instanceof String) {
+                    QName qName = XMLRootElementUtil.getXmlRootElementQName(jaxb);
+                    Object obj = XSDListUtils.fromXSDListString((String) XMLRootElementUtil.getTypeEnabledObject(jaxb),
type);
+                    jaxb = XMLRootElementUtil.getElementEnabledObject(qName.getNamespaceURI(),
qName.getLocalPart(), type, obj);
+                }
+            } 
+            return jaxb;
+        } catch (Exception e) {
+            throw ExceptionFactory.makeMessageException(e);
+        }
+    }
+    
+    /**
+     * Detect if t represents an xsd:list
+     * @param t
+     * @return 
+     */
+    private static boolean isXSDList(Class t) {
+        // TODO This code returns true if the 
+        // class is an array or List.  The correct solution
+        // is to probably pass this information into the
+        // JAXBBlockContext.  I noticed that JAX-WS marks
+        // each xsd:list param/return with an @XmlList annotation.
+        
+        // 
+        // Example:
+        // <xsd:simpleType name="LongList">
+        //   <xsd:list>
+        //     <xsd:simpleType>
+        //       <xsd:restriction base="xsd:unsignedInt"/>
+        //     </xsd:simpleType>
+        //   </xsd:list>
+        // </xsd:simpleType>
+        return (t.isArray() || List.class.isAssignableFrom(t));
     }
 }

Modified: 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=diff&rev=476847&r1=476846&r2=476847
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/XMLRootElementUtil.java
(original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/XMLRootElementUtil.java
Sun Nov 19 08:40:28 2006
@@ -137,17 +137,12 @@
      * @param type element or type enabled object
      * @return
      */
-    public static Object getElementEnabledObject(String namespace, String localPart, Class
cls, Object obj, boolean forceXSIType) {
+    public static Object getElementEnabledObject(String namespace, String localPart, Class
cls, Object obj) {
         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;
     }

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java?view=diff&rev=476847&r1=476846&r2=476847
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java
(original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java
Sun Nov 19 08:40:28 2006
@@ -18,10 +18,16 @@
  */
 package org.apache.axis2.jaxws.proxy;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
 import javax.xml.namespace.QName;
 import javax.xml.ws.BindingProvider;
 import javax.xml.ws.Dispatch;
@@ -29,6 +35,8 @@
 
 import org.apache.axis2.jaxws.dispatch.DispatchTestConstants;
 import org.apache.axis2.jaxws.proxy.rpclit.sei.RPCLit;
+import org.test.proxy.rpclit.ObjectFactory;
+import org.test.proxy.rpclit.Enum;
 
 import junit.framework.TestCase;
 
@@ -160,7 +168,7 @@
     // This test sends the message in the correct format, but currently fails.  
     // We need to investigate the @XmlList processing.
     //
-    public void _testStringList_Dispatch() throws Exception {
+    public void testStringList_Dispatch() throws Exception {
         // Send a payload that simulates
         // the rpc message
         String request = "<tns:testStringList2 xmlns:tns='http://org/apache/axis2/jaxws/proxy/rpclit'>"
+
@@ -183,6 +191,4 @@
         assertTrue(response.contains("testStringList2Response"));
         assertTrue(response.contains("Hello World"));
     }
-    
-    
 }



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


Mime
View raw message