scheu       2002/09/25 11:27:03

  Modified:    java/src/org/apache/axis/encoding
                        DefaultTypeMappingImpl.java
                        SerializationContextImpl.java
               java/src/org/apache/axis/encoding/ser
                        BaseSerializerFactory.java
  Log:
  Follow-on fix for 12886. (xsi:type needs to be sent if the
  prefered xmlType does not match the actual type)
  
  Changes:
    * Changed the getSerializer(javaType, preferedXMLType) method
      to have an extra actualXMLType QNameHolder parameter.
      The getSerializer method returns the actual xmlType
      via this parameter.
  
    * If the actual xmlType is different than the
      prefered xmlType, the xsi:type attribute is set with
      the actual xmlType. (Same logic that Glen had in
      his fix.)
  
    * The getSerializer method determines the actual xmlType
      by querying the BaseSerializerFactory.  If this fails,
      a less performant solution is used (using the
      same strategy as Glen's fix).
  
    * getXMLType() and getJavaType() access methods are added to
      the BaseSerializerFactory.
  
    * Testing revealed a bug in DefaultTypeMappingImpl.
      The wrong QName was being used for org.apache.axis.types.Day.
      This is also fixed.
  
  Revision  Changes    Path
  1.57      +2 -2      
xml-axis/java/src/org/apache/axis/encoding/DefaultTypeMappingImpl.java
  
  Index: DefaultTypeMappingImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/DefaultTypeMappingImpl.java,v
  retrieving revision 1.56
  retrieving revision 1.57
  diff -u -r1.56 -r1.57
  --- DefaultTypeMappingImpl.java       25 Sep 2002 16:29:47 -0000      1.56
  +++ DefaultTypeMappingImpl.java       25 Sep 2002 18:27:03 -0000      1.57
  @@ -314,9 +314,9 @@
           );
           myRegister(Constants.XSD_DAY, org.apache.axis.types.Day.class,
                      new 
SimplePrimitiveSerializerFactory(org.apache.axis.types.Day.class,
  -                                             Constants.XSD_YEARMONTH),
  +                                             Constants.XSD_DAY),
                      new SimpleDeserializerFactory(org.apache.axis.types.Day.class,
  -                                             Constants.XSD_YEARMONTH)
  +                                             Constants.XSD_DAY)
           );
           myRegister(Constants.XSD_MONTHDAY, org.apache.axis.types.MonthDay.class,
                      new 
SimplePrimitiveSerializerFactory(org.apache.axis.types.MonthDay.class,
  
  
  
  1.74      +49 -15    
xml-axis/java/src/org/apache/axis/encoding/SerializationContextImpl.java
  
  Index: SerializationContextImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/SerializationContextImpl.java,v
  retrieving revision 1.73
  retrieving revision 1.74
  diff -u -r1.73 -r1.74
  --- SerializationContextImpl.java     25 Sep 2002 03:21:08 -0000      1.73
  +++ SerializationContextImpl.java     25 Sep 2002 18:27:03 -0000      1.74
  @@ -65,6 +65,7 @@
   import org.apache.axis.soap.SOAPConstants;
   import org.apache.axis.wsdl.symbolTable.SymbolTable;
   import org.apache.axis.wsdl.symbolTable.SchemaUtils;
  +import org.apache.axis.encoding.ser.BaseSerializerFactory;
   import org.apache.axis.enum.Style;
   import org.apache.axis.handlers.soap.SOAPService;
   import org.apache.axis.attachments.Attachments;
  @@ -90,6 +91,7 @@
   import org.xml.sax.helpers.AttributesImpl;
   
   import javax.xml.namespace.QName;
  +import javax.xml.rpc.holders.QNameHolder;
   import javax.xml.rpc.JAXRPCException;
   import java.io.IOException;
   import java.io.Writer;
  @@ -845,7 +847,7 @@
                   forceSer = mri.value;
   
                   // Now serialize the value.
  -                // The sendType parameter is set to true for interop purposes.
  +                // The sendType parameter is defaulted for interop purposes.
                   // Some of the remote services do not know how to
                   // ascertain the type in these circumstances (though Axis does).
                   serialize(multirefQName, attrs, mri.value,
  @@ -1199,17 +1201,28 @@
               }
   
               // Try getting a serializer for the prefered xmlType
  -            Serializer ser = getSerializer(javaType, xmlType);
  +            QNameHolder actualXMLType = new QNameHolder();
  +            Serializer ser = getSerializer(javaType, xmlType, 
  +                                           actualXMLType);
   
               if ( ser != null ) {
  -                // Send the xmlType if indicated.
  -                QName actualType = ((TypeMappingImpl)tm).getXMLType(javaType,
  -                                                               xmlType);
  -                
  -                if (shouldSendType || (xmlType != null &&
  -                                        (!actualType.equals(xmlType))))
  -                    attributes = setTypeAttribute(attributes, actualType);
  -                
  +                // Send the xmlType if indicated or if
  +                // the actual xmlType is different than the 
  +                // prefered xmlType
  +                if (shouldSendType || 
  +                    (xmlType != null && 
  +                     actualXMLType.value != null &&
  +                     (!xmlType.equals(actualXMLType.value)))) {
  +                    attributes = setTypeAttribute(attributes, 
  +                                                  actualXMLType.value);
  +                }
  +
  +                // -----------------
  +                // NOTE: I have seen doc/lit tests that use
  +                // the type name as the element name in multi-ref cases
  +                // (for example <soapenc:Array ... >)
  +                // In such cases the xsi:type is not passed along.
  +                // -----------------
                   // The multiref QName is our own fake name.
                   // It may be beneficial to set the name to the
                   // type name, but I didn't see any improvements
  @@ -1264,20 +1277,26 @@
        * getSerializer
        * Attempts to get a serializer for the indicated javaType and xmlType.
        * @param javaType is the type of the object
  -     * @param xmlType is the preferred qname type.
  +     * @param preferXmlType is the preferred qname type.
  +     * @param actualXmlType is set to a QNameHolder or null.  
  +     *                     If a QNameHolder, the actual xmlType is returned.
        * @return found class/serializer or null
        **/
  -    private Serializer getSerializer(Class javaType, QName xmlType) {
  +    private Serializer getSerializer(Class javaType, QName preferXMLType, 
  +                                     QNameHolder actualXMLType) {
           SerializerFactory  serFactory  = null ;
           TypeMapping tm = getTypeMapping();
  +        if (actualXMLType != null) {
  +            actualXMLType.value = null;
  +        }
   
           while (javaType != null) {
  -            serFactory = (SerializerFactory) tm.getSerializer(javaType, xmlType);
  +            serFactory = (SerializerFactory) tm.getSerializer(javaType, 
preferXMLType);
               if (serFactory != null)
                   break;
   
               // Walk my interfaces...
  -            serFactory = getSerializerFactoryFromInterface(javaType, xmlType, tm);
  +            serFactory = getSerializerFactoryFromInterface(javaType, preferXMLType, 
tm);
               
               // Finally, head to my superclass
               if (serFactory != null)
  @@ -1290,13 +1309,28 @@
           Serializer ser = null;
           if ( serFactory != null ) {
               ser = (Serializer) serFactory.getSerializerAs(Constants.AXIS_SAX);
  +            
  +            if (actualXMLType != null) {
  +                // Get the actual qname xmlType from the factory.
  +                // If not found via the factory, fall back to a less
  +                // performant solution.
  +                if (serFactory instanceof BaseSerializerFactory) {
  +                    actualXMLType.value = 
  +                        ((BaseSerializerFactory) serFactory).getXMLType();
  +                }
  +                if (actualXMLType.value == null) {
  +                    actualXMLType.value = 
  +                        ((TypeMappingImpl) tm).getXMLType(javaType, 
  +                                                          preferXMLType);
  +                }
  +            }
           }
   
           return ser;
       }
   
       public String getValueAsString(Object value, QName xmlType) throws IOException {
  -        Serializer ser = getSerializer(value.getClass(), xmlType);
  +        Serializer ser = getSerializer(value.getClass(), xmlType, null);
           if (!(ser instanceof SimpleValueSerializer)) {
               throw new IOException(
                       Messages.getMessage("needSimpleValueSer",
  
  
  
  1.16      +16 -0     
xml-axis/java/src/org/apache/axis/encoding/ser/BaseSerializerFactory.java
  
  Index: BaseSerializerFactory.java
  ===================================================================
  RCS file: 
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BaseSerializerFactory.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- BaseSerializerFactory.java        18 Sep 2002 16:10:35 -0000      1.15
  +++ BaseSerializerFactory.java        25 Sep 2002 18:27:03 -0000      1.16
  @@ -250,7 +250,23 @@
           }
           return mechanisms.iterator();
       }
  +
  +    /**
  +     * get xmlType
  +     * @return xmlType QName for this factory
  +     */
  +    public QName getXMLType() {
  +        return xmlType;
  +    }
       
  +    /**
  +     * get javaType
  +     * @return javaType Class for this factory
  +     */
  +    public Class getJavaType() {
  +        return javaType;
  +    }
  +
       /**
        * Utility method that intospects on a factory class to decide how to 
        * create the factory.  Tries in the following order:
  
  
  


Reply via email to