You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by bu...@apache.org on 2002/09/12 15:07:01 UTC
DO NOT REPLY [Bug 12572] New: -
none SOAP Array Deserialization in BeanDeserializer incl. fix
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12572>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND
INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12572
none SOAP Array Deserialization in BeanDeserializer incl. fix
Summary: none SOAP Array Deserialization in BeanDeserializer
incl. fix
Product: Axis
Version: current (nightly)
Platform: Other
OS/Version: Other
Status: NEW
Severity: Normal
Priority: Other
Component: Serialization/Deserialization
AssignedTo: axis-dev@xml.apache.org
ReportedBy: schmitz@objectcode.de
Hi
I am calling a SOAP service which sends messages containing elements with
multiple (as I have been told) non SOAP Arrays , which looks as follows:
<elem>
<arr1>xxx</arr1>
<arr2>xxx</arr2>
<arr1>xxx</arr1>
<arr2>xxx</arr2>
<arr1>xxx</arr1>
<arr2>xxx</arr2>
<arr1>xxx</arr1>
<arr2>xxx</arr2>
</elem>
The BeanDeserializer in the current implementation assumes, that multiple non
SOAP arrays elements appear sequentially as in:
<elem>
<arr1>xxx</arr1>
<arr1>xxx</arr1>
<arr1>xxx</arr1>
<arr1>xxx</arr1>
<arr2>xxx</arr2>
<arr2>xxx</arr2>
<arr2>xxx</arr2>
<arr2>xxx</arr2>
</elem>
This is expressed in the fact, that the IndexCounter inside the
org.apache.axis.encoding.ser.BeanDeserializer is reset to -1 each time a childs
qname is different from the previous childs qname. In the first case stated
above only one array element is filled instead of four for each array,
containing the last value in the list.
I do not have very good knowledge about the SOAP protocol, but a friend of mine
told me, that both ways should be XML conform.
So I would like to offer a fix for this problem.
Instead of using the prevQName (which can be removed) I use a Hashtable to
store the array indizes for each child Array. The Hash is initialized in the
onStartElement method.
It now looks like :
....
public void onStartElement(String namespace, String localName,
String prefix, Attributes attributes,
DeserializationContext context)
throws SAXException {
// Reset Array Indexes
collectionIndexHash = new Hashtable() ;
....
Further I removed the handling of the prevQName Attribute
// The collectionIndex needs to be reset for Beans with multiple arrays
/* if ((prevQName == null) || (!prevQName.equals(elemQName))) {
collectionIndex = -1;
}
prevQName = elemQName;
*/
finally I changed the onStartChild method. This may not be the most efficient
Method, but it works.
....
// Register value target
if (propDesc.isWriteable()) {
// If this is an indexed property, and the deserializer we found
// was NOT the ArrayDeserializer, this is a non-SOAP array:
// <bean>
// <field>value1</field>
// <field>value2</field>
// ...
// In this case, we want to use the collectionIndex and make sure
// the deserialized value for the child element goes into the
// right place in the collection.
if (propDesc.isIndexed() && !(dSer instanceof ArrayDeserializer)) {
Integer indexHolder = (Integer) collectionIndexHash.get
(localName);
if ( indexHolder == null ) {
collectionIndex = 0 ;
}else{
collectionIndex = indexHolder.intValue()+1;
}
collectionIndexHash.put(localName , new Integer
(collectionIndex));
dSer.registerValueTarget(new BeanPropertyTarget(value,
propDesc, collectionIndex));
} else {
// If we're here, the element maps to a single field value,
// whether that be a "basic" type or an array, so use the
// normal (non-indexed) BeanPropertyTarget form.
collectionIndex = -1;
dSer.registerValueTarget(new BeanPropertyTarget(value,
propDesc));
}
}
....
Here is a diff against Version 1.51
cvs -z9 diff -w BeanDeserializer.java (in directory C:\apache\xml-
axis.head\java\src\org\apache\axis\encoding\ser\)
Index: BeanDeserializer.java
===================================================================
RCS file: /home/cvspublic/xml-
axis/java/src/org/apache/axis/encoding/ser/BeanDeserializer.java,v
retrieving revision 1.51
diff -w -r1.51 BeanDeserializer.java
79a80,81
> import java.util.Hashtable;
>
96c98
< protected QName prevQName;
---
> // protected QName prevQName;
103a106,107
> protected Hashtable collectionIndexHash = null ;
>
161a166
>
198c203
< if ((prevQName == null) || (!prevQName.equals(elemQName))) {
---
> /* if ((prevQName == null) || (!prevQName.equals(elemQName))) {
202c207
<
---
> */
282c287,293
< collectionIndex++;
---
> Integer indexHolder = (Integer) collectionIndexHash.get
(localName);
> if ( indexHolder == null ) {
> collectionIndex = 0 ;
> }else{
> collectionIndex = indexHolder.intValue()+1;
> }
> collectionIndexHash.put(localName , new Integer
(collectionIndex));
328a340,342
> // Reset Array Indexes
> collectionIndexHash = new Hashtable() ;
>
335a350
>
I would like to see something like this implemented in 1.0 (because I need it
to call the service :-).
regards
Oliver Schmitz