Hi,

The wrapper generation behavior is controlled at:

org.apache.tuscany.sca.interfacedef.java.jaxws.BaseBeanGenerator.BeanProperty.BeanProperty(String, String, Class<?>, Type, boolean)

Where we set the nillable flag for the field. See the FIXME in the source code.

           // FIXME: How to test nillable?
// this.nillable = (type instanceof GenericArrayType) || Collection.class.isAssignableFrom(javaClass) || javaClass.isArray(); // TUSCANY-2389: Set the nillable consistent with what wsgen produces
           this.nillable = javaClass.isArray();

Thanks,
Raymond

From: Scott Kurz
Sent: Monday, August 18, 2008 11:18 AM
To: [email protected]
Subject: Follow-up to TUSCANY-2389, nulls in arrays/collections, null vs. empty array/collection


Raymond,

So in the fix for TUSCANY-2389, as Raymond's comment along with his fix to BaseBeanGenerator indicates:

  "Set the nillable consistent with what wsgen produces.."

we use a different bottom-up mapping for arrays on parm/ret types than than we do for collections.

Specifically, in the generated wrapper element, the arrays get mapped to a sequence of nillable children whereas the other collections seem to get mapped to a sequence of non-nillable children.

Example:

Java:

   public String[] arrayMethod() { return null; }
   public List<String> listMethod() { return null; }

 generated XSD:

 <xs:complexType name="arrayMethodResponse">
   <xs:sequence>
<xs:element name="return" type="xs:string" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
   </xs:sequence>
 </xs:complexType>

 <xs:complexType name="listMethodResponse">
   <xs:sequence>
<xs:element name="return" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
   </xs:sequence>
 </xs:complexType>

The net of this is we still have a very similar problem as we saw in TUSCANY-2389 when using a collection type.

As our fix to TUSCANY-2389 shows, the key step here is the difference in generation of the wrapper bean classes:

public class ArrayMethodResponse {
   @XmlElement(name = "return", namespace = "", nillable = true)
   private String[] _return;

public class ListMethodResponse {
   @XmlElement(name = "return", namespace = "")
   private List<String> _return;


So, having finally set the stage, let me move on to ask the question: Where is this behavior specified?

To me it seems that the construction of the wrapper classes (the request bean and response bean) would be specified in the JAX-WS
spec, but I don't see that it goes into this detail.

Does anyone know?

The only thing I can guess that wsgen is doing is somehow leveraging some code which recognizes the distinction between JAXB Section 5.5.2.1, Indexed Property (array) and JAXB Section 5.5.2.2, List Property (collection). These two sections do mention how an unset indexed property should return null when read, though an unset list property should return an empty list.

Maybe someone could explain how this applies??

If this is not well-specified, then I'd ask... do we want to map collections as well in a similiar manner in the bottom-up cases, so as to be able to pass nulls into them? (Even though this is different than wsgen)

----

Extending this discussion a bit... even with arrays we are still left with another problem: "how to distinguish between a null array and an empty array?" It seems like the way to do this would be to use @XmlElementWrapper with nillable=true.

So we could generate:

public class ArrayMethodResponse {
   @XmlElementWrapper(name="returnArr", namespace = "", nillable = true)
   @XmlElement(name = "return", namespace = "", nillable = true)
   private String[] _return;

Now.. the extra wrapper obviously impacts performance somewhat, so it's not just a given that we do this. The fact that this problem is recognized in the world of web services: (e.g., http://www.ibm.com/developerworks/webservices/library/ws-array.html) says that we might be OK not doing this.

On the other hand, someone doing bottom-up interface design might be exactly the person who doesn't understand how to do WS-friendly interface design, and you could argue that these are exactly the people who would benefit by us supporting Java's null vs. empty distinction by default.

Any thoughts?

Thanks, Scott

Reply via email to