scheu 02/04/04 14:30:24
Modified: java/src/org/apache/axis/encoding SerializationContext.java
SerializationContextImpl.java
TypeMappingDelegate.java
java/src/org/apache/axis/encoding/ser ArraySerializer.java
BeanSerializer.java
java/src/org/apache/axis/message RPCElement.java
Log:
The following changes are made:
- SerializationContext changes (described below)
- Fixed minor problem in TypeMappingDelegate
- Minor changes to BeanSerializer.
- Minor change to RPCElement to save and
rethrow SAXException if no operation is found.
Here's my note to axis-dev explaining the changes:
I am making some additions to the serialize method
of SerializationContext. (I will commit the
changes after I do some more testing.)
I thought it would be a good idea to explain why the
additions are useful.
So here is the new serialize method signature.
(The old signature is retained and delegates
to the new method).
public void serialize(QName elemQName,
Attributes attributes,
Object value,
Class javaType,
QName xmlType, // new
boolean sendNull, // new
boolean sendType) // new
Here is a description of the old parameters:
elemQName - This is the name of the element.
Nothing fancy here.
attributes - These are additional attributes
that are to be serialized on the element.
Normally one would pass in null. The
serialize method is in charge of
adding attributes to deal with types,
null values and multi-ref values.
value - This is the value to be serialized.
Note that it is an Object, so if the
value that you want serialized is a
primitive it must be wrapped.
javaType - This is a parameter that I added several
months ago. The javaType is the class
of the value. Why not just do a value.getClass()?
Well...the value could be null or the value
could be a wrapped primitive. So the
javaType is necessary to know the class
of the value and is very useful for distinguishing
between actual primitives and wrappers.
------------------------
Problem 1:
Isn't there something missing ? How does the serializer know
what QName to use for the xsi:type attribute ?
Prior to my change, it used the javaType information to get
a type QName from the TypeMappingRegistry. However this
algorithm has its flaws. For example a javaType=String.class
actually has 2 type QNames (xsd:string and soapenc:string).
The runtime will always pick xsd:string. This may cause
a remote service to fail if it was expecting a soapenc:string.
Solution 1:
A new xmlType parameter:
xmlType - This new parameter is the preferred type QName.
If present, the serialize method will
use the (javaType, xmlType) pair to find
the appropriate serializer. If a serializer is
not found, the code uses the old serializer search
algorithm.
This allows a custom serializer or meta data aware serializer
to give the serialize method the proper xmlType from the wsdl/xml
schema. Pretty cool!
------------------------
Problem 2:
XML has two ways of dealing with missing information.
1) An element could be defined with the attribute xsi:nillable="true",
which means that if the value is missing, the element should be
serialized with the xsi:nil="true" flag.
2) An element could be defined with the attribute minOccurs="0",
which means that if the value is missing, don't serialize it at all.
The runtime (before my change) treats everything as (1).
Solution 2:
sendNull - The sendNull flag indicates how null values should
be processed. The default (true) handles situation (1).
And sendNull=false handles situation (2).
This allows a custom serializer or meta data aware serializer
to tell the serialize method how to deal with null values.
---------------
Problem 3:
Ever notice that xsi:types are serialized on every single element.
It looks pretty silly to see an array that has arrayType="xsd:string[100]"
followed by 100 items that each have xsi:type="xsd:string".
There needs to be a way to turn off the xsi:type in a reasonable way.
(Aside: I know there is a sendXSIType global property. But this doesn't
cut the mustard. There are a number of problems with using the sendXSIType
property:
1) When serialize is called, is the value serialized ? Uh No. If the
item is an object it is simply stored away and serialized later.
So toggling sendXSIType doesn't help much here.
2) We really want to only send the xsi:type when it is necessary.
Lets say that we have an array with arrayType="my:Foo[100]".
The xsi:type setting is not necessary for the array elements
that are of type "my:Foo". However the xsi:type setting is
necessary for the array elements that are derived from "my:Foo".
)
Solution 3:
sendType - The sendType flag works with the xmlType parameter.
The default, sendType=true, is the current behavior, which
cause xsi:type to be set for everything.
The setting sendType=false, indicates that the xsi:type
should not be sent if a serializer was found for
the (javaType, xmlType) pair (i.e. if the value is
not serialized in the expected way, attach an xsi:type.)
I changed the ArraySerializer to use sendType=true so that it
only uses xsi:type for array elements when truly necessary. Cool!
There are other reasons to set sendType=true.
i) Elements with anonymous types don't have a type QName. Axis
sends a make-believe type qname over the wire in such cases.
It would be nice to turn off this behavior!
ii) The BeanDeserializer deserializes property values even
if the xsi:type is not set. It automatically deserializes into the
property type. So it might be an improvement to not serialize
the xmi:types for bean properties when the javaType matches the
bean property type.
Aside: I ran the interop tests to verify my ArraySerializer changes.
All of the remote services correctly handled the StringArray and IntegerArray
without the xsi:types. However, some of the services could not handle
StructArray...perhaps because the Struct array items are treated as multiref
elements. So I made a small change to SerializationContext to make sure
xsi:types are generated for multiref elements.
----------------------
Revision Changes Path
1.75 +43 -14
xml-axis/java/src/org/apache/axis/encoding/SerializationContext.java
Index: SerializationContext.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/SerializationContext.java,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -r1.74 -r1.75
--- SerializationContext.java 6 Mar 2002 19:35:49 -0000 1.74
+++ SerializationContext.java 4 Apr 2002 22:30:24 -0000 1.75
@@ -73,33 +73,62 @@
*/
public interface SerializationContext extends
javax.xml.rpc.encoding.SerializationContext {
-
/**
- * Serialize the indicated value as an element named qName. The attributes
object are
- * additional attributes that will be serialized with the qName. The value
- * could be serialized directly or could be serialized as an href (with the
- * actual serialize taking place later)
- * @param qName is the QName of the element
+ * Serialize the indicated value as an element with the name
+ * indicated by elemQName.
+ * The attributes are additional attribute to be serialized on the element.
+ * The value is the object being serialized. (It may be serialized
+ * directly or serialized as an mult-ref'd item)
+ * The value is an Object, which may be a wrapped primitive, the
+ * javaType is the actual unwrapped object type.
+ * The xmlType (if specified) is the QName of the type that is used to set
+ * xsi:type. If not specified, xsi:type is set by using the javaType to
+ * find an appopriate xmlType from the TypeMappingRegistry.
+ * The sendNull flag indicates whether null values should be sent over the
+ * wire (default is to send such values with xsi:nil="true").
+ * The sendType flag indicates whether the xsi:type flag should be sent
+ * (default is true).
+ * @param elemQName is the QName of the element
* @param attributes are additional attributes
* @param value is the object to serialize
- * @param javaType is the "real" type of the value. For primitives, the value
is the
- * associated java.lang class. So the javaType is needed to know that the value
- * is really a wrapped primitive.
+ * @param javaType is the "real" type of the value.
+ * @param xmlType is the qname of the type or null. (default is null)
+ * @param sendNull determines whether to send null values. (default is true)
+ * @param sendType determines whether to set xsi:type attribute. (default is
true)
*/
- public void serialize(QName qName, Attributes attributes, Object value, Class
javaType)
+ public void serialize(QName elemQName,
+ Attributes attributes,
+ Object value,
+ Class javaType)
+ throws IOException;
+
+ public void serialize(QName elemQName,
+ Attributes attributes,
+ Object value,
+ Class javaType,
+ QName xmlType,
+ boolean sendNull,
+ boolean sendType)
throws IOException;
/**
* Invoked to do the actual serialization of the qName (called by serialize
above).
- * additional attributes that will be serialized with the qName.
- * @param qName is the QName of the element
+ * additional attributes that will be serialized with the qName.
+ * @param elemQName is the QName of the element
* @param attributes are additional attributes
* @param value is the object to serialize
* @param javaType is the "real" type of the value. For primitives, the value
is the
- * associated java.lang class. So the javaType is needed to know that the
value
+ * associated java.lang class. So the javaType is needed to know that the value
* is really a wrapped primitive.
+ * @param xmlType (optional) is the desired type QName.
+ * @param sendType indicates whether the xsi:type attribute should be set.
*/
- public void serializeActual(QName qName, Attributes attributes, Object value,
Class javaType)
+ public void serializeActual(QName elemQName,
+ Attributes attributes,
+ Object value,
+ Class javaType,
+ QName xmlType,
+ boolean sendType)
throws IOException;
/**
1.17 +170 -70
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.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- SerializationContextImpl.java 3 Apr 2002 21:44:41 -0000 1.16
+++ SerializationContextImpl.java 4 Apr 2002 22:30:24 -0000 1.17
@@ -142,6 +142,19 @@
private HashMap multiRefValues = null;
private int multiRefIndex = -1;
+ class MultiRefItem {
+ String id;
+ Class javaType;
+ QName xmlType;
+ boolean sendType;
+ MultiRefItem(String id, Class javaType, QName xmlType, boolean sendType) {
+ this.id = id;
+ this.javaType = javaType;
+ this.xmlType = xmlType;
+ this.sendType = sendType;
+ }
+
+ }
/**
* These three variables are necessary to process multi-level object graphs for
multi-ref
* serialization.
@@ -468,51 +481,74 @@
}
/**
- * Serialize the indicated value as an element named qName. The attributes
object are
- * additional attributes that will be serialized with the qName. The value
- * could be serialized directly or could be serialized as an href (with the
- * actual serialize taking place later)
- * @param qName is the QName of the element
+ * Serialize the indicated value as an element with the name
+ * indicated by elemQName.
+ * The attributes are additional attribute to be serialized on the element.
+ * The value is the object being serialized. (It may be serialized
+ * directly or serialized as an mult-ref'd item)
+ * The value is an Object, which may be a wrapped primitive, the
+ * javaType is the actual unwrapped object type.
+ * The xmlType (if specified) is the QName of the type that is used to set
+ * xsi:type. If not specified, xsi:type is set by using the javaType to
+ * find an appopriate xmlType from the TypeMappingRegistry.
+ * The sendNull flag indicates whether null values should be sent over the
+ * wire (default is to send such values with xsi:nil="true").
+ * The sendType flag indicates whether the xsi:type flag should be sent
+ * (default is true).
+ * @param elemQName is the QName of the element
* @param attributes are additional attributes
* @param value is the object to serialize
- * @param javaType is the "real" type of the value. For primitives, the value
is the
- * associated java.lang class. So the javaType is needed to know that the value
- * is really a wrapped primitive.
- */
- public void serialize(QName qName, Attributes attributes, Object value, Class
javaType)
+ * @param javaType is the "real" type of the value.
+ * @param xmlType is the qname of the type or null.
+ * @param sendNull determines whether to send null values.
+ * @param sendType determines whether to set xsi:type attribute.
+ */
+ public void serialize(QName elemQName,
+ Attributes attributes,
+ Object value,
+ Class javaType)
+ throws IOException {
+ serialize(elemQName, attributes, value, javaType, null, true, true);
+ }
+
+ public void serialize(QName elemQName,
+ Attributes attributes,
+ Object value,
+ Class javaType,
+ QName xmlType,
+ boolean sendNull,
+ boolean sendType)
throws IOException
{
if (value == null) {
// If the value is null, the element is
// passed with xsi:nil="true" to indicate that no object is present.
- //
- // There are three approaches that could be taken...
- // 1) (Currently Implemented) Use xsi:nil="true".
- // 2) Emit an empty element. (This would be deserialized incorrectly.)
- // 3) Don't emit an element. (This could also cause deserialization
problems.)
- AttributesImpl attrs = new AttributesImpl();
- if (attributes != null)
- attrs.setAttributes(attributes);
- attrs.addAttribute(Constants.URI_2001_SCHEMA_XSI, "nil", "xsi:nil",
- "CDATA", "true");
- startElement(qName, attrs);
- endElement();
+ if (sendNull) {
+ AttributesImpl attrs = new AttributesImpl();
+ if (attributes != null)
+ attrs.setAttributes(attributes);
+ attrs.addAttribute(Constants.URI_2001_SCHEMA_XSI, "nil", "xsi:nil",
+ "CDATA", "true");
+ startElement(elemQName, attrs);
+ endElement();
+ }
+ return;
}
Message msg= getCurrentMessage();
if(null != msg){
//Get attachments. returns null if no attachment support.
Attachments attachments= getCurrentMessage().getAttachments();
-
+
if( null != attachments && attachments.isAttachment(value)){
- //Attachment support and this is an object that should be treated as
an attachment.
-
- //Allow an the attachment to do its own serialization.
- serializeActual(qName, attributes, value, javaType);
-
- //No need to add to mulitRefs. Attachment data stream handled by
- // the message;
- return;
+ //Attachment support and this is an object that should be treated
as an attachment.
+
+ //Allow an the attachment to do its own serialization.
+ serializeActual(elemQName, attributes, value, javaType, xmlType,
sendType);
+
+ //No need to add to mulitRefs. Attachment data stream handled by
+ // the message;
+ return;
}
}
@@ -524,15 +560,17 @@
if (multiRefIndex == -1)
multiRefValues = new HashMap();
- String href = (String)multiRefValues.get(value);
- if (href == null) {
+ String id;
+ MultiRefItem mri = (MultiRefItem)multiRefValues.get(value);
+ if (mri == null) {
multiRefIndex++;
- href = "id" + multiRefIndex;
- multiRefValues.put(value, href);
+ id = "id" + multiRefIndex;
+ mri = new MultiRefItem (id, javaType, xmlType, sendType);
+ multiRefValues.put(value, mri);
/** Problem - if we're in the middle of writing out
* the multi-refs and hit another level of the
- * object graph, we need to make sure this object
+ * object graph, we need to make sure this object
* will get written. For now, add it to a list
* which we'll check each time we're done with
* outputMultiRefs().
@@ -542,15 +580,17 @@
secondLevelObjects = new HashSet();
secondLevelObjects.add(value);
}
+ } else {
+ id = mri.id;
}
AttributesImpl attrs = new AttributesImpl();
if (attributes != null)
attrs.setAttributes(attributes);
attrs.addAttribute("", Constants.ATTR_HREF, "href",
- "CDATA", "#" + href);
+ "CDATA", "#" + id);
- startElement(qName, attrs);
+ startElement(elemQName, attrs);
endElement();
return;
}
@@ -564,7 +604,7 @@
forceSer = null;
// Actually serialize the value. (i.e. not an href like above)
- serializeActual(qName, attributes, value, javaType);
+ serializeActual(elemQName, attributes, value, javaType, xmlType, sendType);
}
/**
@@ -590,15 +630,19 @@
while (i.hasNext()) {
while (i.hasNext()) {
Object val = i.next();
- String id = (String)multiRefValues.get(val);
+ MultiRefItem mri = (MultiRefItem) multiRefValues.get(val);
attrs.setAttribute(0, "", Constants.ATTR_ID, "id", "CDATA",
- id);
+ mri.id);
forceSer = val;
- // Now serialize the value. Note that it is safe to
- // set the javaType argument using value.getClass() because
- // values that represent primitives will never get to this point
- // because they cannot be multi-ref'ed
- serialize(multirefQName, attrs, val, val.getClass());
+
+ // Now serialize the value.
+ // The sendType parameter is set to true 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, val,
+ mri.javaType, mri.xmlType,
+ true,
+ true); // mri.sendType
}
if (secondLevelObjects != null) {
@@ -887,17 +931,21 @@
/**
* Invoked to do the actual serialization of the qName (called by serialize
above).
* additional attributes that will be serialized with the qName.
- * @param qName is the QName of the element
+ * @param elemQName is the QName of the element
* @param attributes are additional attributes
* @param value is the object to serialize
* @param javaType is the "real" type of the value. For primitives, the value
is the
* associated java.lang class. So the javaType is needed to know that the value
* is really a wrapped primitive.
+ * @param xmlType (optional) is the desired type QName.
+ * @param sendType indicates whether the xsi:type attribute should be set.
*/
- public void serializeActual(QName qName,
+ public void serializeActual(QName elemQName,
Attributes attributes,
- Object value,
- Class javaType)
+ Object value,
+ Class javaType,
+ QName xmlType,
+ boolean sendType)
throws IOException
{
if (value != null) {
@@ -910,18 +958,35 @@
"" + this));
}
- Class_Serializer pair = getSerializer(javaType, value);
- if ( pair != null ) {
- QName type = tm.getTypeQName(pair.javaType);
- attributes = setTypeAttribute(attributes, type);
-
+ SerializerInfo info = null;
+ if (xmlType != null) {
+ info = getSerializer(javaType, xmlType);
+ }
+
+ // If a serializer was not found using the preferred xmlType,
+ // try getting any serializer.
+ if (info == null) {
+ info = getSerializer(javaType, value);
+ sendType = true; // Must send type if it does not match preferred
type
+ xmlType = null;
+ }
+
+ if ( info != null ) {
+
+ // Send the xmlType if indicated.
+ if (sendType) {
+ if (xmlType == null) {
+ xmlType = tm.getTypeQName(info.javaType);
+ }
+ attributes = setTypeAttribute(attributes, xmlType);
+ }
// 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
// in the interop tests.
//if (name.equals(multirefQName) && type != null)
// name = type;
- pair.ser.serialize(qName, attributes, value, this);
+ info.ser.serialize(elemQName, attributes, value, this);
return;
}
@@ -931,10 +996,47 @@
// !!! Write out a generic null, or get type info from somewhere else?
}
- class Class_Serializer {
+ class SerializerInfo {
Serializer ser;
Class javaType;
}
+
+ /**
+ * 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.
+ * @return found class/serializer or null
+ **/
+ private SerializerInfo getSerializer(Class javaType, QName xmlType) {
+ SerializerInfo info = null;
+ SerializerFactory serFactory = null ;
+ TypeMapping tm = getTypeMapping();
+
+ try {
+ if (!javaType.getName().equals("java.lang.Object") &&
+ tm.isRegistered(javaType, xmlType)) {
+ serFactory = (SerializerFactory) tm.getSerializer(javaType,
xmlType);
+ }
+ } catch(JAXRPCException e) {}
+
+
+ // Using the serialization factory, create a serializer
+ Serializer ser = null;
+ if ( serFactory != null ) {
+ try {
+ ser = (Serializer) serFactory.getSerializerAs(Constants.AXIS_SAX);
+ } catch (JAXRPCException e) {
+ }
+ }
+ if (ser != null) {
+ info = new SerializerInfo();
+ info.ser = ser;
+ info.javaType = javaType;
+ }
+ return info;
+ }
+
/**
* getSerializer
* Attempts to get a serializer for the indicated type. Failure to
@@ -945,8 +1047,8 @@
* @param value is the object (which may have a different type due to
conversions)
* @return found class/serializer or null
**/
- private Class_Serializer getSerializer(Class javaType, Object value) {
- Class_Serializer pair = null;
+ private SerializerInfo getSerializer(Class javaType, Object value) {
+ SerializerInfo info = null;
SerializerFactory serFactory = null ;
TypeMapping tm = getTypeMapping();
@@ -959,7 +1061,9 @@
Class _class = javaType;
while( _class != null ) {
try {
- serFactory = (SerializerFactory) tm.getSerializer(_class);
+ if (!_class.getName().equals("java.lang.Object")) {
+ serFactory = (SerializerFactory) tm.getSerializer(_class);
+ }
} catch(JAXRPCException e) {
// For now continue if JAXRPCException
}
@@ -976,10 +1080,7 @@
_class = _class.getSuperclass();
// Add any non-null (and non-Object) class. We skip
- // the Object class because if we reach that then
- // there's an error and this error message return
- // here is better than the one returned by the
- // ObjSerializer.
+ // the Object class.
if ( _class != null &&
!_class.getName().equals("java.lang.Object")) {
classes.add( _class );
@@ -1000,8 +1101,7 @@
}
}
- // Using the serialization factory, create a serializer and
- // serialize the value.
+ // Using the serialization factory, create a serializer
Serializer ser = null;
if ( serFactory != null ) {
try {
@@ -1010,11 +1110,11 @@
}
}
if (ser != null) {
- pair = new Class_Serializer();
- pair.ser = ser;
- pair.javaType = _class;
+ info = new SerializerInfo();
+ info.ser = ser;
+ info.javaType = _class;
}
- return pair;
+ return info;
}
}
1.2 +3 -2
xml-axis/java/src/org/apache/axis/encoding/TypeMappingDelegate.java
Index: TypeMappingDelegate.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/TypeMappingDelegate.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TypeMappingDelegate.java 1 Feb 2002 22:08:26 -0000 1.1
+++ TypeMappingDelegate.java 4 Apr 2002 22:30:24 -0000 1.2
@@ -147,8 +147,9 @@
}
public boolean isRegistered(Class javaType, QName xmlType) {
- if (delegate != null)
- delegate.isRegistered(javaType, xmlType);
+ if (delegate != null) {
+ return delegate.isRegistered(javaType, xmlType);
+ }
return false;
}
1.15 +7 -2
xml-axis/java/src/org/apache/axis/encoding/ser/ArraySerializer.java
Index: ArraySerializer.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/ArraySerializer.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- ArraySerializer.java 8 Mar 2002 19:13:01 -0000 1.14
+++ ArraySerializer.java 4 Apr 2002 22:30:24 -0000 1.15
@@ -104,6 +104,7 @@
protected static Log log =
LogFactory.getLog(ArraySerializer.class.getName());
+ QName componentQName;
/**
* Serialize an element that is an array.
* @param name is the element name
@@ -151,7 +152,7 @@
}
- QName componentQName = context.getQNameForClass(componentType);
+ componentQName = context.getQNameForClass(componentType);
if (componentQName == null)
throw new IOException(
JavaUtils.getMessage("noType00", componentType.getName()));
@@ -279,7 +280,11 @@
Object aValue = (list == null) ? Array.get(value, index) :
list.get(index);
Class aClass = (aValue == null) ? null : aValue.getClass();
- context.serialize(elementName, null, aValue, aClass);
+ // Serialize the element.
+ context.serialize(elementName, null, aValue, aClass,
+ componentQName, // prefered type QName
+ true, // Send null values
+ false); // Don't send xsi:type if it matches
preferred QName
}
} else {
// Serialize as a 2 dimensional array
1.25 +15 -8
xml-axis/java/src/org/apache/axis/encoding/ser/BeanSerializer.java
Index: BeanSerializer.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/ser/BeanSerializer.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- BeanSerializer.java 1 Apr 2002 20:12:16 -0000 1.24
+++ BeanSerializer.java 4 Apr 2002 22:30:24 -0000 1.25
@@ -168,29 +168,36 @@
}
Method readMethod = propertyDescriptor[i].getReadMethod();
- if (readMethod != null && readMethod.getParameterTypes().length ==
0) {
+ Class baseJavaType = readMethod.getReturnType();
+ Class javaType;
+ if (readMethod != null &&
+ readMethod.getParameterTypes().length == 0) {
// Normal case: serialize the value
- Object propValue =
propertyDescriptor[i].getReadMethod().invoke(value,noArgs);
+ Object propValue = readMethod.invoke(value,noArgs);
+ javaType = (propValue == null || baseJavaType.isPrimitive())
+ ? baseJavaType : propValue.getClass();
context.serialize(qname,
null,
- propValue,
-
propertyDescriptor[i].getReadMethod().getReturnType());
+ propValue, javaType);
} else {
// Collection of properties: serialize each one
int j=0;
while(j >= 0) {
Object propValue = null;
try {
- propValue =
propertyDescriptor[i].getReadMethod().invoke(value,
- new Object[] {
new Integer(j) });
+ propValue =
+ readMethod.invoke(value,
+ new Object[] { new Integer(j) });
j++;
} catch (Exception e) {
j = -1;
}
if (j >= 0) {
+ javaType = (propValue == null ||
+ baseJavaType.isPrimitive())
+ ? baseJavaType : propValue.getClass();
context.serialize(qname, null,
- propValue,
-
propertyDescriptor[i].getReadMethod().getReturnType());
+ propValue, javaType);
}
}
}
1.47 +8 -1 xml-axis/java/src/org/apache/axis/message/RPCElement.java
Index: RPCElement.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/RPCElement.java,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- RPCElement.java 31 Mar 2002 04:15:31 -0000 1.46
+++ RPCElement.java 4 Apr 2002 22:30:24 -0000 1.47
@@ -202,6 +202,8 @@
if (operations != null) {
int numParams = (getChildren() == null) ? 0 : getChildren().size();
+ SAXException savedException = null;
+
// We now have an array of all operations by this name. Try to
// find the right one. For each matching operation which has an
// equal number of "in" parameters, try deserializing. If we
@@ -229,14 +231,19 @@
return;
} catch (SAXException e) {
// If there was a problem, try the next one.
+ savedException = e;
params = new Vector();
continue;
}
}
}
- throw new SAXException(
+ if (savedException != null) {
+ throw savedException;
+ } else {
+ throw new SAXException(
JavaUtils.getMessage("noSuchOperation", name));
+ }
}
if (elementIsFirstParam) {