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 James M Snell <ja...@us.ibm.com> on 2003/01/15 18:41:38 UTC

Fw: MessageElement is not for mortals

FYI: Attached is a note from an IBM researcher who has been using Axis to 
create some demos for the IBM Web Services Toolkit.  It details from 
issues she has had to deal with in regards to the MessageElement class. 
After the 1.1 Release, I will work on incorporating her suggested 
enhancements into the code but wanted to make folks aware of the issue.  I 
will also post this to the bugzilla database.

- James Snell
     IBM Emerging Technologies
     jasnell@us.ibm.com
     (559) 587-1233 (office)
     (700) 544-9035 (t/l)
     Programming Web Services With SOAP
         O'Reilly & Associates, ISBN 0596000952

     Have I not commanded you? Be strong and courageous. 
     Do not be terrified, do not be discouraged, for the Lord your 
     God will be with you whereever you go.    - Joshua 1:9
----- Forwarded by James M Snell/Fresno/IBM on 01/15/2003 09:35 AM -----

Julie Macnaught/Middletown/IBM wrote on 01/15/2003 09:09:34 AM:

> The purpose of this note is to document issues I encountered during 
> the development of the WSRP WSTK demo with respect to Axis and the 
> org.apache.axis.message.MessageElement class.  I suspect the 
> MessageElement class is not meant for programmers to use directly, 
> but this is a requirement in our case.
> 
> Background:
> 
> The WSDL for the demo makes use of "any" in several places in order 
> to allow user defined xml data to be passed in messages.  Here is an
> example of its use in defining the Property type:
> 
>       <complexType name="Property">
>         <sequence>
>           <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
>         </sequence>
>         <attribute name="name"         type="xsd:string" 
use="required"/>
>         <attribute name="lang"         type="xsd:string" 
use="required"/>
>       <!--
>         Would prefer this form, but Axis tools ignore the definition
>         <attribute ref="xml:lang"      use="required"/>
>       -->
>         <attribute name="resourceName" type="xsd:string"/>
>       </complexType>

> The WSDL2Java tool generates the type for this as a Property class 
> that contains an array of MessageElements like so:
> 
> public class Property  implements java.io.Serializable {
>     private org.apache.axis.message.MessageElement [] _any;
>     private java.lang.String name;  // attribute
>     private java.lang.String lang;  // attribute
>     private java.lang.String resourceName;  // attribute
> 
>     public Property() {
>     }
> 
>     public org.apache.axis.message.MessageElement [] get_any() {
>         return _any;
>     }
> 
>     public void set_any(org.apache.axis.message.MessageElement [] _any) 
{
>         this._any = _any;
>     }
>  .
>  .
>  .
> 
> In order to use the Property class, the programmer must create 
> MessageElements and MessageElement arrays as well as try to obtain 
> the contents of a MessageElement instance.
> 
> Issues:
> 
> 1.  Constructing a MessageElement:
>  If I want to create a Property, I must construct a MessageElement. 
> There are 9 constructors in the MessageElement class.  The Javadoc 
> does not describe any of the them.  It matters which one is chosen. 
> After a lot of experimentation,  I ended up using the 
> MessageElement(org.w3c.Element) constructor.   Under the covers, the
> MessageElement class has several member variables for holding value 
> information.  The constructor you use determines which member 
> variable gets used (e.g. Text vs Element vs children), and also 
> determines how you try to "get" the value later.   There are also 
> many possibilities for using the no-argument constructor and the 
> calling one of the multitude of set methods. The setObjectValue 
> method is tempting, but the value doesn't make it across the network
> connection.
> 
> 2. Retrieving the value:
>  There is no usable "get" method on a MessageElement.   Even if you 
> knew how it was created and where the data was stored in the 
> MessageElement (e.g. textRep, elementRep), there is no corresponding
> get method.  There is a method called  getAsDOM, but this method 
> calls getAsString and then parses the result.  The protected method 
> getAsString() method requires a MessageContext which is used to 
> obtain a SerializationContext.  Since I created the MessageElement 
> myself, there is no MessageContext.  If you call toString(), it just
> calls getAsString() .
> 
> Workarounds:
> 
> I ended up creating a class called MessageElementHelper which has 
> methods to create a MessageElement, to clone a MessageElement and to
> fetch its content.  It implements SerializationContext so I can use 
> the output() method and fake out the serialization context.   Note 
> that I had to inspect the source code for MessageElement in order to
> derive this solution.
> 
> Here it is:
> [attachment "MessageElementHelper.java" deleted by James M 
Snell/Fresno/IBM] 
> 
> Conclusions:
> 
> I hope I described the problem well enough without going in to too 
> much detail.  Folks using "any" in their messages are going to have 
> to use MessageElement and it's painful.  I have a couple of 
> suggestions going forward.
>  1. change the WSDL2Java program to generate something more useable 
> than MessageElement arrays.
>  2. document MessageElement more precisely, specifically for this use 
case
>  3. wrap MessageElement in a more usable form and change WSDL2Java 
> correspondingly. It would be nice to have setElement(w3c.dom.
> Element) and w3c.dom.Element getElement() . 
> 
> Please feel free to contact me for more information or to discuss my
> experiences.  My ultimate goal is to improve the product and help other 
users.
> 
> Thanks.
> 
> Julie E.MacNaught
> IBM Research
> (401) 849-3021  T/L 397-9977
> jmacna@us.ibm.com