scheu       2002/09/24 16:27:36

  Modified:    java/src/org/apache/axis/encoding/ser BeanDeserializer.java
                        BeanPropertyTarget.java
               java/test/encoding TestDeser.java
  Added:       java/test/encoding IndexPropBean.java
  Log:
  Fix for "Must Fix" Bugzilla Defect 12867.
  
  Summary of problem:  Axis Service expected a series of elements in
  the maxOccurs="unbounded" form.  A .Net client sent an array containing
  the elements instead.  This falls under the "be flexible in what you accept" rule.
  
  Solution: The BeanPropertyDescriptor.set() method can recognize this situation
  and set the indexed properties from the items in the deserialized array.
  
  I also added Tests to TestDeser for both situations.
  The test exposed a minor flaw in the BeanDeserializer associated with
  getting the child deserializers.
  
  All is well.
  
  Revision  Changes    Path
  1.55      +7 -4      
xml-axis/java/src/org/apache/axis/encoding/ser/BeanDeserializer.java
  
  Index: BeanDeserializer.java
  ===================================================================
  RCS file: 
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BeanDeserializer.java,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- BeanDeserializer.java     19 Sep 2002 20:25:12 -0000      1.54
  +++ BeanDeserializer.java     24 Sep 2002 23:27:35 -0000      1.55
  @@ -258,15 +258,17 @@
           QName childXMLType = context.getTypeFromXSITypeAttr(namespace, 
                                                               localName,
                                                               attributes);
  -        
  -        // If no xsi:type, check the meta-data for the field
  -        if (childXMLType == null && fieldDesc != null) {
  +
  +        String href = attributes.getValue("href");
  +
  +        // If no xsi:type or href, check the meta-data for the field
  +        if (childXMLType == null && fieldDesc != null && href == null) {
               childXMLType = fieldDesc.getXmlType();
           }
           
           // Get Deserializer for child, default to using DeserializerImpl
           Deserializer dSer = getDeserializer(childXMLType, propDesc.getType(), 
  -                                            attributes.getValue("href"),
  +                                            href,
                                               context);
           // It is an error if the dSer is not found, the base
           // deserializer impl is returned so that it can generate the correct 
message.
  @@ -415,6 +417,7 @@
           // See if we have a cached deserializer
           if (cacheStringDSer != null) {
               if (String.class.equals(javaType) &&
  +                href == null &&
                   (cacheXMLType == null && xmlType == null ||
                    cacheXMLType != null && cacheXMLType.equals(xmlType))) {
                   cacheStringDSer.reset();
  
  
  
  1.18      +45 -8     
xml-axis/java/src/org/apache/axis/encoding/ser/BeanPropertyTarget.java
  
  Index: BeanPropertyTarget.java
  ===================================================================
  RCS file: 
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BeanPropertyTarget.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- BeanPropertyTarget.java   18 Sep 2002 16:10:35 -0000      1.17
  +++ BeanPropertyTarget.java   24 Sep 2002 23:27:35 -0000      1.18
  @@ -65,6 +65,7 @@
   
   import org.xml.sax.SAXException;
   import java.lang.reflect.InvocationTargetException;
  +import java.lang.reflect.Array;
   
   /**
    * Class which knows how to update a bean property
  @@ -100,21 +101,57 @@
           this.index  = i;
       }
       
  +    /**
  +     * set the bean property with specified value
  +     * @param value is the value.
  +     */
       public void set(Object value) throws SAXException {
  +
           try {
  -            if (index < 0)
  +            // Set the value on the bean property. 
  +            // Use the indexed property method if the 
  +            // index is set.
  +            if (index < 0) {
                   pd.set(object, value);
  -            else
  +            } else {
                   pd.set(object, index, value);
  +            }
           } catch (Exception e) {
  -            Class type = pd.getType();
  -            value = JavaUtils.convert(value, type);
  +
               try {
  -                if (index < 0)
  -                    pd.set(object, value);
  -                else
  -                    pd.set(object, index, value);
  +                // If an exception occurred, 
  +                // see it the value can be converted into
  +                // the expected type.
  +                Class type = pd.getType();
  +                if (JavaUtils.isConvertable(value, type)) {
  +                    value = JavaUtils.convert(value, type);
  +                    if (index < 0)
  +                        pd.set(object, value);
  +                    else
  +                        pd.set(object, index, value);
  +                } else {
  +                    // It is possible that an indexed
  +                    // format was expected, but the
  +                    // entire array was sent.  In such 
  +                    // cases traverse the array and 
  +                    // call the setter for each item.
  +                    if (index == 0 &&
  +                        value.getClass().isArray() &&
  +                        !type.getClass().isArray()) {
  +                        for (int i=0; i<Array.getLength(value); i++) {
  +                            Object item = 
  +                                JavaUtils.convert(Array.get(value, i), type);
  +                            pd.set(object, i, item); 
  +                        }
  +                    } else {
  +                        // Can't proceed.  Throw an exception that
  +                        // will be caught in the catch block below.
  +                        throw e;
  +                    }
  +                }
               } catch (Exception ex) {
  +                // Throw a SAX exception with an informative
  +                // message.
                   String field= pd.getName();
                   if (index >=0) {
                       field += "[" + index + "]";
  
  
  
  1.41      +34 -1     xml-axis/java/test/encoding/TestDeser.java
  
  Index: TestDeser.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/test/encoding/TestDeser.java,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -r1.40 -r1.41
  --- TestDeser.java    19 Sep 2002 20:25:12 -0000      1.40
  +++ TestDeser.java    24 Sep 2002 23:27:36 -0000      1.41
  @@ -51,6 +51,7 @@
                 "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"; " +
                 "xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"; " +
                 "xmlns:me=\"http://soapinterop.org/xsd\"; " +
  +              "xmlns:this=\"http://encoding.test\"; " + 
                 "xmlns:xsi=\"" + NS_XSI + "\" " +
                 "xmlns:xsd=\"" + NS_XSD + "\">\n" +
                 "<soap:Body>\n" +
  @@ -93,6 +94,14 @@
                       new org.apache.axis.encoding.ser.BeanDeserializerFactory(
                             samples.echo.SOAPStructStruct.class,
                             new QName("http://soapinterop.org/xsd";, 
"SOAPStructStruct")));
  +        tm.register(test.encoding.IndexPropBean.class, 
  +                    new QName("http://encoding.test";, "IndexPropBean"),
  +                    new org.apache.axis.encoding.ser.BeanSerializerFactory(
  +                          test.encoding.IndexPropBean.class,
  +                          new QName("http://encoding.test";, "IndexPropBean")),
  +                    new org.apache.axis.encoding.ser.BeanDeserializerFactory(
  +                          test.encoding.IndexPropBean.class,
  +                          new QName("http://encoding.test";, "IndexPropBean")));
       }
   
       /**
  @@ -533,7 +542,31 @@
                       "</soapenc:Array>",
                       s, true);
       }
  -
  +    // Deserialize Bean with discreet names
  +    public void testBeanWithIndexedPropA() throws Exception {
  +        IndexPropBean s = new IndexPropBean();
  +        s.setName(new String[] {"hello", "goodbye"});
  +        deserialize("<result xsi:type=\"this:IndexPropBean\" " + "> " +
  +                    "<name href=\"#ref-1\"/>" +
  +                    "<name href=\"#ref-2\"/>" +
  +                    "</result>" +
  +                    "<item id=\"ref-1\" xsi:type=\"xsd:string\">hello</item>" +
  +                    "<item id=\"ref-2\" xsi:type=\"xsd:string\">goodbye</item>",
  +                    s, true);
  +    }
  +    // Deserialize Bean with names in an array
  +    public void testBeanWithIndexedPropB() throws Exception {
  +        IndexPropBean s = new IndexPropBean();
  +        s.setName(new String[] {"hello", "goodbye"});
  +        deserialize("<result xsi:type=\"this:IndexPropBean\" " + "> " +
  +                    "<name href=\"#ref-0\" /> " +
  +                    "</result>" +
  +                    "<soapenc:Array id=\"ref-0\" 
soapenc:arrayType=\"xsd:string[2]\"> " +
  +                    "<item xsi:type=\"xsd:string\">hello</item>" +
  +                    "<item xsi:type=\"xsd:string\">goodbye</item>" +
  +                    "</soapenc:Array>",
  +                    s, true);
  +    }
       // Struct within Struct
       public void testStructStruct() throws Exception {
   
  
  
  
  1.1                  xml-axis/java/test/encoding/IndexPropBean.java
  
  Index: IndexPropBean.java
  ===================================================================
  /*
  * The Apache Software License, Version 1.1
  *
  *
  * Copyright (c) 2001 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
  *    the documentation and/or other materials provided with the
  *    distribution.
  *
  * 3. The end-user documentation included with the redistribution,
  *    if any, must include the following acknowledgment:
  *       "This product includes software developed by the
  *        Apache Software Foundation (http://www.apache.org/)."
  *    Alternately, this acknowledgment may appear in the software itself,
  *    if and wherever such third-party acknowledgments normally appear.
  *
  * 4. The names "Axis" and "Apache Software Foundation" must
  *    not be used to endorse or promote products derived from this
  *    software without prior written permission. For written
  *    permission, please contact [EMAIL PROTECTED]
  *
  * 5. Products derived from this software may not be called "Apache",
  *    nor may "Apache" appear in their name, without prior written
  *    permission of the Apache Software Foundation.
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * ====================================================================
  *
  * This software consists of voluntary contributions made by many
  * individuals on behalf of the Apache Software Foundation.  For more
  * information on the Apache Software Foundation, please see
  * <http://www.apache.org/>.
  */
  
  package test.encoding;
  
  import org.apache.axis.description.AttributeDesc;
  import org.apache.axis.description.ElementDesc;
  import org.apache.axis.description.FieldDesc;
  import org.apache.axis.description.TypeDesc;
  
  import javax.xml.namespace.QName;
  
  /**
   * Bean with an indexed property
   */ 
  public class IndexPropBean  {
      private java.lang.String[] name;
      
      public IndexPropBean() {}
      
      public java.lang.String getName(int i) {
          return name[i];
      }
      
      public void setName(int i, java.lang.String name){
          this.name[i] = name;
      }
      
      public java.lang.String[] getName() {
          return name;
      }
      
      public void setName(java.lang.String name[]){
          this.name = name;
      }
  
      public boolean equals(Object obj)
      {
          if (obj == null || !(obj instanceof IndexPropBean))
              return false;
          IndexPropBean other = (IndexPropBean)obj;
          if (other.name == null && this.name == null) 
              return true;
          if (other.name != null &&
              java.util.Arrays.equals(other.name, name)) 
              return true;
          return false;
      }
  
      public int hashCode() {
          int _hashCode = 0;
          if (name != null) {
              for (int i=0;
                   i<java.lang.reflect.Array.getLength(name);
                   i++) {
                  java.lang.Object obj = java.lang.reflect.Array.get(name, i);
                  if (obj != null) {
                      _hashCode += obj.hashCode();
                  }
              }
          }
          return _hashCode;
      }
      // Type metadata
      private static TypeDesc typeDesc;
      
      static {
          typeDesc = new TypeDesc(IndexPropBean.class);
          FieldDesc field;
  
          field = new ElementDesc();
          field.setFieldName("name");
          field.setXmlName(new QName("", "name"));
          typeDesc.addFieldDesc(field);
      }
      
      public static TypeDesc getTypeDesc()
      {
          return typeDesc;
      }
  
      /**
       * Get Custom Serializer
       */
      public static org.apache.axis.encoding.Serializer getSerializer(
             java.lang.String mechType, 
             java.lang.Class _javaType,  
             javax.xml.namespace.QName _xmlType) {
          return 
            new  org.apache.axis.encoding.ser.BeanSerializer(
              _javaType, _xmlType, typeDesc);
      }
  
      /**
       * Get Custom Deserializer
       */
      public static org.apache.axis.encoding.Deserializer getDeserializer(
             java.lang.String mechType, 
             java.lang.Class _javaType,  
             javax.xml.namespace.QName _xmlType) {
          return 
            new  org.apache.axis.encoding.ser.BeanDeserializer(
              _javaType, _xmlType, typeDesc);
      }
  }
  
  
  


Reply via email to