You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@xml.apache.org by du...@apache.org on 2001/01/27 21:52:42 UTC

cvs commit: xml-axis/java/src/org/apache/axis/message SOAPEnvelope.java

dug         01/01/27 12:52:42

  Modified:    java/samples/stock GetQuote.java README
               java/src/org/apache/axis/handlers RPCDispatchHandler.java
               java/src/org/apache/axis/message SOAPEnvelope.java
  Log:
  Add support for mutliple children elements of the SOAPBody element.
  This is a really cool feature, with this we'll be able to do multiple
  RPC calls within one SOAPBody.  Run samples.stock.GetQuote IBM CSCO
  to see.  Yes - it's possible to implement this by assuming that the
  service will accept multiple symbols in the arg, but let's assume
  that it doesn't - it only takes one symbol - using multiple body
  elements we can save ourselves the overhead of multiple network calls.
  
  Revision  Changes    Path
  1.3       +14 -10    xml-axis/java/samples/stock/GetQuote.java
  
  Index: GetQuote.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/samples/stock/GetQuote.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- GetQuote.java	2001/01/26 20:54:54	1.2
  +++ GetQuote.java	2001/01/27 20:52:41	1.3
  @@ -79,17 +79,20 @@
                     "http://schemas.xmlsoap.org/soap/envelope/\" " +
                     "xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"" + 
                     " xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\">\n" +
  -                  "<SOAP-ENV:Body>\n" +
  -                  "<m:getQuote xmlns:m=\"urn:xmltoday-delayed-quotes\">" ;
  -    String msg2 = "</m:getQuote>" +
  -                  "</SOAP-ENV:Body>\n" +
  +                  "<SOAP-ENV:Body>\n" ;
  +    String head = "<m:getQuote xmlns:m=\"urn:xmltoday-delayed-quotes\">\n" +
  +                  "<symbol>" ;
  +    String tail = "</symbol>\n</m:getQuote>\n" ;
  +    String msg2 = "</SOAP-ENV:Body>\n" +
                     "</SOAP-ENV:Envelope>" ;
   
       try {
         String  host   = "localhost" ;
         int     port   = 8080 ;
  -      String  symbol = null ;
  +      boolean atLeastOne = false ;
   
  +      msg = msg1 ;
  +
         for ( int i = 0 ; i < args.length ; i++ ) {
           if ( args[i].charAt(0) == '-' ) {
             switch( args[i].toLowerCase().charAt(1) ) {
  @@ -103,17 +106,18 @@
                                            args[i].charAt(1) + "'" );
                        System.exit(1);
             }
  +        }
  +        else {
  +          atLeastOne = true ;
  +          msg += head + args[i] + tail ;
           }
  -        else
  -          symbol = args[i] ;
         }
  +      msg += msg2 ;
   
  -      if ( symbol == null ) {
  +      if ( !atLeastOne ) {
           System.err.println( "Usage: GetQuote <symbol>" );
           System.exit(1);
         }
  -
  -      msg = msg1 + "<symbol>" + symbol + "</symbol>" + msg2 ;
   
         String         cl = "Content-Length: " + msg.length() + "\n\n" ;
         Socket         sock = new Socket( host, port );
  
  
  
  1.2       +8 -1      xml-axis/java/samples/stock/README
  
  Index: README
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/samples/stock/README,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- README	2001/01/26 19:20:16	1.1
  +++ README	2001/01/27 20:52:41	1.2
  @@ -2,4 +2,11 @@
     java org.apache.axis.client.AdminClient deploy.xml
   
   Usage:
  -  java samples.stock.GetQuoteClient <symbol>
  +  java samples.stock.GetQuoteClient <symbol>...
  +
  +
  +NOTE!!!
  +  Each symbol will be it's own Body element.  This samples demonstates
  +  that it's possible to have multiple children of the SOAPBody element,
  +  which can be used as an optimization - ie. do multiple RPC calls
  +  with one SOAPEnvelope.
  
  
  
  1.6       +39 -34    xml-axis/java/src/org/apache/axis/handlers/RPCDispatchHandler.java
  
  Index: RPCDispatchHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/handlers/RPCDispatchHandler.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- RPCDispatchHandler.java	2001/01/26 20:55:02	1.5
  +++ RPCDispatchHandler.java	2001/01/27 20:52:42	1.6
  @@ -93,43 +93,48 @@
         // We know we're doing a java call so find the class, create a
         // new instance of it.
         int          i ;
  -      Class        cls   = Class.forName(clsName);
  -      Object       obj   = cls.newInstance();
  -      Message      inMsg = msgContext.getIncomingMessage();
  -      SOAPEnvelope env   = (SOAPEnvelope) inMsg.getAs("SOAPEnvelope");
  -      RPCBody      body  = env.getAsRPCBody();
  -      String       mName = body.getMethodName();
  -      Vector       args  = body.getArgs();        //RPCArg's
  -
  -      if ( !methodName.equals(mName) )
  -        throw new AxisFault( "AxisServier.error", "Method names don't match",
  -                             null, null );  // Should they??
  -
  -      Class[]  argClasses = new Class[ args.size() ];
  -      Object[] argValues  = new Object[ args.size()];
  -      for ( i = 0 ; i < args.size() ; i++ ) {
  -        argClasses[i] = Class.forName("java.lang.String") ;
  -        argValues[i]  = ((RPCArg)args.get(i)).getValue() ; // only String 4now
  +      Class        cls    = Class.forName(clsName);
  +      Object       obj    = cls.newInstance();
  +      Message      inMsg  = msgContext.getIncomingMessage();
  +      SOAPEnvelope env    = (SOAPEnvelope) inMsg.getAs("SOAPEnvelope");
  +      Vector       bodies = env.getAsRPCBody();
  +      SOAPEnvelope resEnv = null ;
  +
  +      for ( int bNum = 0 ; bNum < bodies.size() ; bNum++ ) {
  +        RPCBody      body  = (RPCBody) bodies.get( bNum );
  +        String       mName = body.getMethodName();
  +        Vector       args  = body.getArgs();        //RPCArg's
  +  
  +        if ( !methodName.equals(mName) )
  +          throw new AxisFault( "AxisServier.error", "Method names don't match",
  +                               null, null );  // Should they??
  +  
  +        Class[]  argClasses = new Class[ args.size() ];
  +        Object[] argValues  = new Object[ args.size()];
  +        for ( i = 0 ; i < args.size() ; i++ ) {
  +          argClasses[i] = Class.forName("java.lang.String") ;
  +          argValues[i]  = ((RPCArg)args.get(i)).getValue() ; // only String 4now
  +        }
  +  
  +        Method method = cls.getMethod( mName, argClasses );
  +        Object objRes = method.invoke( obj, argValues );
  +  
  +        // Now put the result in a result SOAPEnvelope
  +        if ( resEnv == null )
  +          resEnv = new SOAPEnvelope();
  +        RPCBody resBody = new RPCBody();
  +        resBody.setMethodName( mName + "Response" );
  +        resBody.setNamespace( body.getNamespace() );
  +        resBody.setNamespaceURI( body.getNamespaceURI() );
  +        RPCArg  arg = new RPCArg();
  +        arg.setName( "return" );
  +        arg.setValue( objRes.toString() );
  +        resBody.addArg( arg );
  +        resEnv.addBody( resBody );
         }
   
  -      Method method = cls.getMethod( mName, argClasses );
  -      Object objRes = method.invoke( obj, argValues );
  -
  -      // Now put the result in a result SOAPEnvelope
  -      env = new SOAPEnvelope();
  -      RPCBody resBody = new RPCBody();
  -      resBody.setMethodName( mName + "Response" );
  -      resBody.setNamespace( body.getNamespace() );
  -      resBody.setNamespaceURI( body.getNamespaceURI() );
  -      RPCArg  arg = new RPCArg();
  -      arg.setName( "return" );
  -      arg.setValue( objRes.toString() );
  -      resBody.addArg( arg );
  -      env.setBody( resBody );
  -
  -
         // Message outMsg = new Message( objRes.toString(), "String" );
  -      Message outMsg = new Message( env, "SOAPEnvelope" );
  +      Message outMsg = new Message( resEnv, "SOAPEnvelope" );
         msgContext.setOutgoingMessage( outMsg );
       }
       catch( Exception e ) {
  
  
  
  1.6       +34 -11    xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java
  
  Index: SOAPEnvelope.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- SOAPEnvelope.java	2001/01/27 19:55:05	1.5
  +++ SOAPEnvelope.java	2001/01/27 20:52:42	1.6
  @@ -74,7 +74,7 @@
   public class SOAPEnvelope {
     protected String       prefix ;
     protected ArrayList    headers ;
  -  protected SOAPBody     body ;    
  +  protected Vector       body ; // Vector of SOAPBody's
   
     public SOAPEnvelope() {
     }
  @@ -117,8 +117,8 @@
           for ( i = 0 ; i < list.getLength() ; i++ ) {
             Node n = list.item(i);
             if ( n.getNodeType() != Node.ELEMENT_NODE ) continue ;
  -          body = new SOAPBody( (Element) n );
  -          break ;
  +          if ( body == null ) body = new Vector();
  +          body.add( new SOAPBody( (Element) n ) );
           }
         }
       }
  @@ -134,17 +134,39 @@
       headers.add( header );
     }
   
  -  public SOAPBody getBody() { return( body ); }
  -  public void     setBody(SOAPBody b) { body = b ; }
  -
  -  public RPCBody  getAsRPCBody() {
  -    if ( body instanceof RPCBody ) return( (RPCBody) body );
  -    return( (RPCBody) (body = new RPCBody( getBody()) ) );
  +  /**
  +   * Returns a vector of SOAPBody's - could be more than one
  +   */
  +  public Vector getBody() { 
  +    return( body ); 
  +  }
  +
  +  public SOAPBody getFirstBody() {
  +    return( (body == null) ? null : (SOAPBody) body.get(0) );
  +  }
  +
  +  public void addBody(SOAPBody b) {
  +    if ( body == null ) body = new Vector();
  +    body.add( b );
  +  }
  +
  +  /**
  +   * Returns a vector of RPCBody's because there could be more than
  +   * one in there.
  +   */
  +  public Vector  getAsRPCBody() {
  +    if ( body == null ) return( null );
  +    SOAPBody b = (SOAPBody) body.get(0);
  +    for ( int i = 0 ; i < body.size() ; i++ )
  +      if ( !(body.get(i) instanceof RPCBody) )
  +        body.set(i, new RPCBody( (SOAPBody) body.get(i) ) );
  +    return( body );
     }
   
     public Document getAsDOM() {
       Document doc = null ;
       Element  elem ;
  +    int      i ;
   
       doc = new DocumentImpl();
       elem = doc.createElementNS(Constants.NSPREFIX_SOAP_ENV, 
  @@ -159,7 +181,7 @@
                                            Constants.NSPREFIX_SOAP_ENV + ":" +
                                            Constants.ELEM_HEADER);
         elem.appendChild( root );
  -      for ( int i = 0 ; i < headers.size() ; i++ ) {
  +      for ( i = 0 ; i < headers.size() ; i++ ) {
           SOAPHeader h = (SOAPHeader) headers.get(i);
           root.appendChild( h.getAsXML(doc) );
         }
  @@ -169,7 +191,8 @@
                                            Constants.NSPREFIX_SOAP_ENV + ":" + 
                                            Constants.ELEM_BODY);
         elem.appendChild( root );
  -      root.appendChild( body.getAsXML(doc) );
  +      for ( i = 0 ; i < body.size() ; i++ )
  +        root.appendChild( ((SOAPBody)body.get(i)).getAsXML(doc) );
       }
       return( doc );
     }
  
  
  

Re: cvs commit: xml-axis/java/src/org/apache/axis/message SOAPEnvelope.java

Posted by Jacek Kopecky <ja...@idoox.com>.
 Hello Dug. 8-)
 Are you sure SOAP allows multiple message bodies? Or more
precisely: does SOAP RPC allow for multiple calls within one body? I
always thought that the body maps to a single RPC call. My
understanding might have been too narrow, that's true.
 But still, wouldn't passing more than one RPC call in a single SOAP
message be problematic in means of recognizing what is an RPC function
invocation and what is just an independent structure accessed via an
href? The SOAP spec says the RPC call is modelled as a struct, in this
the subsequent method calls would be indistniguishable from data. 
 I don't know, this just looks crazy. 8-)

                            Jacek Kopecky
                               Idoox



On 27 Jan 2001 dug@apache.org wrote:

 > dug         01/01/27 12:52:42
 > 
 >   Modified:    java/samples/stock GetQuote.java README
 >                java/src/org/apache/axis/handlers RPCDispatchHandler.java
 >                java/src/org/apache/axis/message SOAPEnvelope.java
 >   Log:
 >   Add support for mutliple children elements of the SOAPBody element.
 >   This is a really cool feature, with this we'll be able to do multiple
 >   RPC calls within one SOAPBody.  Run samples.stock.GetQuote IBM CSCO
 >   to see.  Yes - it's possible to implement this by assuming that the
 >   service will accept multiple symbols in the arg, but let's assume
 >   that it doesn't - it only takes one symbol - using multiple body
 >   elements we can save ourselves the overhead of multiple network calls.
 >   
 >   Revision  Changes    Path
 >   1.3       +14 -10    xml-axis/java/samples/stock/GetQuote.java
 >   
 >   Index: GetQuote.java
 >   ===================================================================
 >   RCS file: /home/cvs/xml-axis/java/samples/stock/GetQuote.java,v
 >   retrieving revision 1.2
 >   retrieving revision 1.3
 >   diff -u -r1.2 -r1.3
 >   --- GetQuote.java	2001/01/26 20:54:54	1.2
 >   +++ GetQuote.java	2001/01/27 20:52:41	1.3
 >   @@ -79,17 +79,20 @@
 >                      "http://schemas.xmlsoap.org/soap/envelope/\" " +
 >                      "xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"" + 
 >                      " xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\">\n" +
 >   -                  "<SOAP-ENV:Body>\n" +
 >   -                  "<m:getQuote xmlns:m=\"urn:xmltoday-delayed-quotes\">" ;
 >   -    String msg2 = "</m:getQuote>" +
 >   -                  "</SOAP-ENV:Body>\n" +
 >   +                  "<SOAP-ENV:Body>\n" ;
 >   +    String head = "<m:getQuote xmlns:m=\"urn:xmltoday-delayed-quotes\">\n" +
 >   +                  "<symbol>" ;
 >   +    String tail = "</symbol>\n</m:getQuote>\n" ;
 >   +    String msg2 = "</SOAP-ENV:Body>\n" +
 >                      "</SOAP-ENV:Envelope>" ;
 >    
 >        try {
 >          String  host   = "localhost" ;
 >          int     port   = 8080 ;
 >   -      String  symbol = null ;
 >   +      boolean atLeastOne = false ;
 >    
 >   +      msg = msg1 ;
 >   +
 >          for ( int i = 0 ; i < args.length ; i++ ) {
 >            if ( args[i].charAt(0) == '-' ) {
 >              switch( args[i].toLowerCase().charAt(1) ) {
 >   @@ -103,17 +106,18 @@
 >                                             args[i].charAt(1) + "'" );
 >                         System.exit(1);
 >              }
 >   +        }
 >   +        else {
 >   +          atLeastOne = true ;
 >   +          msg += head + args[i] + tail ;
 >            }
 >   -        else
 >   -          symbol = args[i] ;
 >          }
 >   +      msg += msg2 ;
 >    
 >   -      if ( symbol == null ) {
 >   +      if ( !atLeastOne ) {
 >            System.err.println( "Usage: GetQuote <symbol>" );
 >            System.exit(1);
 >          }
 >   -
 >   -      msg = msg1 + "<symbol>" + symbol + "</symbol>" + msg2 ;
 >    
 >          String         cl = "Content-Length: " + msg.length() + "\n\n" ;
 >          Socket         sock = new Socket( host, port );
 >   
 >   
 >   
 >   1.2       +8 -1      xml-axis/java/samples/stock/README
 >   
 >   Index: README
 >   ===================================================================
 >   RCS file: /home/cvs/xml-axis/java/samples/stock/README,v
 >   retrieving revision 1.1
 >   retrieving revision 1.2
 >   diff -u -r1.1 -r1.2
 >   --- README	2001/01/26 19:20:16	1.1
 >   +++ README	2001/01/27 20:52:41	1.2
 >   @@ -2,4 +2,11 @@
 >      java org.apache.axis.client.AdminClient deploy.xml
 >    
 >    Usage:
 >   -  java samples.stock.GetQuoteClient <symbol>
 >   +  java samples.stock.GetQuoteClient <symbol>...
 >   +
 >   +
 >   +NOTE!!!
 >   +  Each symbol will be it's own Body element.  This samples demonstates
 >   +  that it's possible to have multiple children of the SOAPBody element,
 >   +  which can be used as an optimization - ie. do multiple RPC calls
 >   +  with one SOAPEnvelope.
 >   
 >   
 >   
 >   1.6       +39 -34    xml-axis/java/src/org/apache/axis/handlers/RPCDispatchHandler.java
 >   
 >   Index: RPCDispatchHandler.java
 >   ===================================================================
 >   RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/handlers/RPCDispatchHandler.java,v
 >   retrieving revision 1.5
 >   retrieving revision 1.6
 >   diff -u -r1.5 -r1.6
 >   --- RPCDispatchHandler.java	2001/01/26 20:55:02	1.5
 >   +++ RPCDispatchHandler.java	2001/01/27 20:52:42	1.6
 >   @@ -93,43 +93,48 @@
 >          // We know we're doing a java call so find the class, create a
 >          // new instance of it.
 >          int          i ;
 >   -      Class        cls   = Class.forName(clsName);
 >   -      Object       obj   = cls.newInstance();
 >   -      Message      inMsg = msgContext.getIncomingMessage();
 >   -      SOAPEnvelope env   = (SOAPEnvelope) inMsg.getAs("SOAPEnvelope");
 >   -      RPCBody      body  = env.getAsRPCBody();
 >   -      String       mName = body.getMethodName();
 >   -      Vector       args  = body.getArgs();        //RPCArg's
 >   -
 >   -      if ( !methodName.equals(mName) )
 >   -        throw new AxisFault( "AxisServier.error", "Method names don't match",
 >   -                             null, null );  // Should they??
 >   -
 >   -      Class[]  argClasses = new Class[ args.size() ];
 >   -      Object[] argValues  = new Object[ args.size()];
 >   -      for ( i = 0 ; i < args.size() ; i++ ) {
 >   -        argClasses[i] = Class.forName("java.lang.String") ;
 >   -        argValues[i]  = ((RPCArg)args.get(i)).getValue() ; // only String 4now
 >   +      Class        cls    = Class.forName(clsName);
 >   +      Object       obj    = cls.newInstance();
 >   +      Message      inMsg  = msgContext.getIncomingMessage();
 >   +      SOAPEnvelope env    = (SOAPEnvelope) inMsg.getAs("SOAPEnvelope");
 >   +      Vector       bodies = env.getAsRPCBody();
 >   +      SOAPEnvelope resEnv = null ;
 >   +
 >   +      for ( int bNum = 0 ; bNum < bodies.size() ; bNum++ ) {
 >   +        RPCBody      body  = (RPCBody) bodies.get( bNum );
 >   +        String       mName = body.getMethodName();
 >   +        Vector       args  = body.getArgs();        //RPCArg's
 >   +  
 >   +        if ( !methodName.equals(mName) )
 >   +          throw new AxisFault( "AxisServier.error", "Method names don't match",
 >   +                               null, null );  // Should they??
 >   +  
 >   +        Class[]  argClasses = new Class[ args.size() ];
 >   +        Object[] argValues  = new Object[ args.size()];
 >   +        for ( i = 0 ; i < args.size() ; i++ ) {
 >   +          argClasses[i] = Class.forName("java.lang.String") ;
 >   +          argValues[i]  = ((RPCArg)args.get(i)).getValue() ; // only String 4now
 >   +        }
 >   +  
 >   +        Method method = cls.getMethod( mName, argClasses );
 >   +        Object objRes = method.invoke( obj, argValues );
 >   +  
 >   +        // Now put the result in a result SOAPEnvelope
 >   +        if ( resEnv == null )
 >   +          resEnv = new SOAPEnvelope();
 >   +        RPCBody resBody = new RPCBody();
 >   +        resBody.setMethodName( mName + "Response" );
 >   +        resBody.setNamespace( body.getNamespace() );
 >   +        resBody.setNamespaceURI( body.getNamespaceURI() );
 >   +        RPCArg  arg = new RPCArg();
 >   +        arg.setName( "return" );
 >   +        arg.setValue( objRes.toString() );
 >   +        resBody.addArg( arg );
 >   +        resEnv.addBody( resBody );
 >          }
 >    
 >   -      Method method = cls.getMethod( mName, argClasses );
 >   -      Object objRes = method.invoke( obj, argValues );
 >   -
 >   -      // Now put the result in a result SOAPEnvelope
 >   -      env = new SOAPEnvelope();
 >   -      RPCBody resBody = new RPCBody();
 >   -      resBody.setMethodName( mName + "Response" );
 >   -      resBody.setNamespace( body.getNamespace() );
 >   -      resBody.setNamespaceURI( body.getNamespaceURI() );
 >   -      RPCArg  arg = new RPCArg();
 >   -      arg.setName( "return" );
 >   -      arg.setValue( objRes.toString() );
 >   -      resBody.addArg( arg );
 >   -      env.setBody( resBody );
 >   -
 >   -
 >          // Message outMsg = new Message( objRes.toString(), "String" );
 >   -      Message outMsg = new Message( env, "SOAPEnvelope" );
 >   +      Message outMsg = new Message( resEnv, "SOAPEnvelope" );
 >          msgContext.setOutgoingMessage( outMsg );
 >        }
 >        catch( Exception e ) {
 >   
 >   
 >   
 >   1.6       +34 -11    xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java
 >   
 >   Index: SOAPEnvelope.java
 >   ===================================================================
 >   RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/SOAPEnvelope.java,v
 >   retrieving revision 1.5
 >   retrieving revision 1.6
 >   diff -u -r1.5 -r1.6
 >   --- SOAPEnvelope.java	2001/01/27 19:55:05	1.5
 >   +++ SOAPEnvelope.java	2001/01/27 20:52:42	1.6
 >   @@ -74,7 +74,7 @@
 >    public class SOAPEnvelope {
 >      protected String       prefix ;
 >      protected ArrayList    headers ;
 >   -  protected SOAPBody     body ;    
 >   +  protected Vector       body ; // Vector of SOAPBody's
 >    
 >      public SOAPEnvelope() {
 >      }
 >   @@ -117,8 +117,8 @@
 >            for ( i = 0 ; i < list.getLength() ; i++ ) {
 >              Node n = list.item(i);
 >              if ( n.getNodeType() != Node.ELEMENT_NODE ) continue ;
 >   -          body = new SOAPBody( (Element) n );
 >   -          break ;
 >   +          if ( body == null ) body = new Vector();
 >   +          body.add( new SOAPBody( (Element) n ) );
 >            }
 >          }
 >        }
 >   @@ -134,17 +134,39 @@
 >        headers.add( header );
 >      }
 >    
 >   -  public SOAPBody getBody() { return( body ); }
 >   -  public void     setBody(SOAPBody b) { body = b ; }
 >   -
 >   -  public RPCBody  getAsRPCBody() {
 >   -    if ( body instanceof RPCBody ) return( (RPCBody) body );
 >   -    return( (RPCBody) (body = new RPCBody( getBody()) ) );
 >   +  /**
 >   +   * Returns a vector of SOAPBody's - could be more than one
 >   +   */
 >   +  public Vector getBody() { 
 >   +    return( body ); 
 >   +  }
 >   +
 >   +  public SOAPBody getFirstBody() {
 >   +    return( (body == null) ? null : (SOAPBody) body.get(0) );
 >   +  }
 >   +
 >   +  public void addBody(SOAPBody b) {
 >   +    if ( body == null ) body = new Vector();
 >   +    body.add( b );
 >   +  }
 >   +
 >   +  /**
 >   +   * Returns a vector of RPCBody's because there could be more than
 >   +   * one in there.
 >   +   */
 >   +  public Vector  getAsRPCBody() {
 >   +    if ( body == null ) return( null );
 >   +    SOAPBody b = (SOAPBody) body.get(0);
 >   +    for ( int i = 0 ; i < body.size() ; i++ )
 >   +      if ( !(body.get(i) instanceof RPCBody) )
 >   +        body.set(i, new RPCBody( (SOAPBody) body.get(i) ) );
 >   +    return( body );
 >      }
 >    
 >      public Document getAsDOM() {
 >        Document doc = null ;
 >        Element  elem ;
 >   +    int      i ;
 >    
 >        doc = new DocumentImpl();
 >        elem = doc.createElementNS(Constants.NSPREFIX_SOAP_ENV, 
 >   @@ -159,7 +181,7 @@
 >                                             Constants.NSPREFIX_SOAP_ENV + ":" +
 >                                             Constants.ELEM_HEADER);
 >          elem.appendChild( root );
 >   -      for ( int i = 0 ; i < headers.size() ; i++ ) {
 >   +      for ( i = 0 ; i < headers.size() ; i++ ) {
 >            SOAPHeader h = (SOAPHeader) headers.get(i);
 >            root.appendChild( h.getAsXML(doc) );
 >          }
 >   @@ -169,7 +191,8 @@
 >                                             Constants.NSPREFIX_SOAP_ENV + ":" + 
 >                                             Constants.ELEM_BODY);
 >          elem.appendChild( root );
 >   -      root.appendChild( body.getAsXML(doc) );
 >   +      for ( i = 0 ; i < body.size() ; i++ )
 >   +        root.appendChild( ((SOAPBody)body.get(i)).getAsXML(doc) );
 >        }
 >        return( doc );
 >      }
 >   
 >   
 >   
 >