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: