You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@ws.apache.org by sn...@apache.org on 2002/09/10 09:27:25 UTC

cvs commit: xml-soap/java/src/org/apache/soap/util Bean.java

snichol     2002/09/10 00:27:25

  Modified:    java/samples/interop DataSerializer.java
               java/src/org/apache/soap/encoding/soapenc
                        ArraySerializer.java
               java/src/org/apache/soap/server/http RPCRouterServlet.java
               java/src/org/apache/soap/util Bean.java
  Added:       java/samples/interop NullEchoTestClient.java
  Log:
  Test handling of nulls for various data types.  Improve text for faults
  thrown when nulls of primitive types cannot be handled.
  
  Revision  Changes    Path
  1.3       +4 -1      xml-soap/java/samples/interop/DataSerializer.java
  
  Index: DataSerializer.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/samples/interop/DataSerializer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DataSerializer.java	30 Aug 2002 21:38:59 -0000	1.2
  +++ DataSerializer.java	10 Sep 2002 07:27:25 -0000	1.3
  @@ -152,7 +152,10 @@
         throw new IllegalArgumentException("No 'varString' Element (deserializing Data struct)");
       }
       el = (Element)list.item(0);
  -    ret.myString = ((Text)el.getFirstChild()).getData();
  +    if (SoapEncUtils.isNull(el))
  +      ret.myString = null;
  +    else
  +      ret.myString = ((Text)el.getFirstChild()).getData();
       
       return new Bean(Data.class, ret);
     }
  
  
  
  1.1                  xml-soap/java/samples/interop/NullEchoTestClient.java
  
  Index: NullEchoTestClient.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "SOAP" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package samples.interop;
  
  import java.util.Vector;
  import org.apache.soap.*;
  import org.apache.soap.encoding.Hex;
  import org.apache.soap.encoding.SOAPMappingRegistry;
  import org.apache.soap.encoding.soapenc.*;
  import org.apache.soap.rpc.*;
  import org.apache.soap.messaging.*;
  import java.net.URL;
  import org.apache.soap.util.xml.*;
  import java.io.*;
  import org.w3c.dom.*;
  import org.apache.soap.util.*;
  import java.lang.reflect.*;
  import java.util.Date;
  import java.util.Hashtable;
  import java.math.BigDecimal;
  
  /**
   * A quick-and-dirty client for the Interop echo test services as defined
   * at http://www.xmethods.net/ilab.  THIS CLIENT SENDS NULL VALUES.
   * 
   * Defaults to the Apache endpoint, but you can point it somewhere else via
   * the command line:
   * 
   *    EchoTestClient http://some.other.place/
   * 
   * DOES NOT SUPPORT DIFFERENT SOAPACTION URIS YET.
   * 
   * @author Glen Daniels (gdaniels@macromedia.com)
   * @author Sam Ruby (rubys@us.ibm.com)
   * @author Scott Nichol (snichol@computer.org)
   */
  public class NullEchoTestClient
  {
    SOAPMappingRegistry smr = new SOAPMappingRegistry();
  
    public static final String DEFAULT_URL = "http://nagoya.apache.org:5089/soap/servlet/rpcrouter";
    public static final String ACTION_URI = "http://soapinterop.org/";
    public static final String OBJECT_URI = "http://soapinterop.org/xsd";
    public Header header = null;
    
    public static void main(String args[])
    {
      URL url = null;
  
      try {
        if (args.length > 0) {
          url = new URL(args[0]);
        } else {
          url = new URL(DEFAULT_URL);
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
      
      NullEchoTestClient eTest = new NullEchoTestClient();
      eTest.doWork(url);
    }
  
    private static boolean equals(Object obj1, Object obj2) {
      if ((obj1==null) || (obj2==null)) return (obj1==obj2);
      if (obj1.equals(obj2)) return true;
      if (obj1 instanceof Date && obj2 instanceof Date)
        if (Math.abs(((Date)obj1).getTime()-((Date)obj2).getTime())<1000)
          return true;
      if (!obj2.getClass().isArray()) return false;
      if (!obj1.getClass().isArray()) return false;
      if (Array.getLength(obj1) != Array.getLength(obj2)) return false;
      for (int i=0; i<Array.getLength(obj1); i++)
        if (!equals(Array.get(obj1,i),Array.get(obj2,i))) return false;
      return true;
    }
    
    public void doWork(URL url)
    {
      IntDeserializer intDser = new IntDeserializer();
      FloatDeserializer floatDser = new FloatDeserializer();
      StringDeserializer stringDser = new StringDeserializer();
      ArraySerializer arraySer = new ArraySerializer();
      DataSerializer dataSer = new DataSerializer();
      Base64Serializer base64Ser = new Base64Serializer();
      DateSerializer dateSer = new DateSerializer();
      DecimalDeserializer decimalSer = new DecimalDeserializer();
      BooleanDeserializer booleanSer = new BooleanDeserializer();
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName(OBJECT_URI, "SOAPStruct"), Data.class, dataSer, dataSer);
      
      Parameter p = new Parameter("inputString", String.class, null, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, stringDser);
      doCall(url, "echoString", p);
  
      p = new Parameter("inputStringArray", String[].class,
                        new String[]{null, null, null}, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, arraySer);
      doCall(url, "echoStringArray", p);
  
      p = new Parameter("inputStringArray", String[].class,
                        null, null);
      doCall(url, "echoStringArray", p);
  
      p = new Parameter("inputInteger", Integer.class, null, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, intDser);
      doCall(url, "echoInteger", p);
      
      p = new Parameter("inputIntegerArray", Integer[].class,
                        new Integer[]{null, null, null}, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, arraySer);
      doCall(url, "echoIntegerArray", p);
      
      p = new Parameter("inputIntegerArray", Integer[].class,
                        null, null);
      doCall(url, "echoIntegerArray", p);
      
      p = new Parameter("inputFloat", Float.class, null, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, floatDser);
      doCall(url, "echoFloat", p);
  
      p = new Parameter("inputFloatArray", Float[].class,
                        new Float[]{null, null, null}, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, arraySer);
      doCall(url, "echoFloatArray", p);
      
      p = new Parameter("inputFloatArray", Float[].class,
                        null, null);
      doCall(url, "echoFloatArray", p);
      
      p = new Parameter("inputStruct", Data.class, new Data(5, null, (float)10.0), null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, dataSer);
      doCall(url, "echoStruct", p);
  
      p = new Parameter("inputStruct", Data.class, null, null);
      doCall(url, "echoStruct", p);
  
      p = new Parameter("inputStructArray", Data[].class,
                        new Data[]{null, null, null}, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, arraySer);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC,
          new QName(OBJECT_URI, "ArrayOfSOAPStruct"),
          Data[].class, arraySer, arraySer);
      doCall(url, "echoStructArray", p);
  
      p = new Parameter("inputStructArray", Data[].class,
                        null, null);
      doCall(url, "echoStructArray", p);
  
      doCall(url, "echoVoid", null);
  
      p = new Parameter("inputBase64", byte[].class, null, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, base64Ser);
      doCall(url, "echoBase64", p);
  
      p = new Parameter("inputHexBinary", Hex.class, null, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, dataSer);
      doCall(url, "echoHexBinary", p);
  
      p = new Parameter("inputDate", Date.class, null, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, dateSer);
      doCall(url, "echoDate", p);
  
      p = new Parameter("inputDecimal", BigDecimal.class, null, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, decimalSer);
      doCall(url, "echoDecimal", p);
  
      p = new Parameter("inputBoolean", Boolean.class, null, null);
      smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null, null, booleanSer);
      doCall(url, "echoBoolean", p);
  
      p = new Parameter("inputMap", Hashtable.class, null, null);
      doCall(url, "echoMap", p);
  
      p = new Parameter("inputMapArray", Hashtable[].class, null, null);
      doCall(url, "echoMapArray", p);
    }
    
    public void doCall(URL url, String methodName, Parameter param)
    {
      try {
        Call call = new Call();
        Vector params = new Vector();
        if (param != null) 
          params.addElement(param);
        call.setSOAPMappingRegistry(smr);
        call.setTargetObjectURI(ACTION_URI);
        call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
        call.setMethodName(methodName);
        call.setParams(params);
        if (header != null)
          call.setHeader(header);
        
        String soapAction = ACTION_URI;
        if (false) {
          soapAction = soapAction + methodName;
        }
        
        call.setTimeout(60000);
        Response resp = call.invoke(url, soapAction);
        
        // check response 
        if (resp.generatedFault()) {
          Fault fault = resp.getFault ();
  
          System.out.println(methodName + "\t Fault: " + fault);
        } else {
          Parameter ret = resp.getReturnValue();
          Object output = (ret==null) ? null : ret.getValue();
          Object input = (param==null) ? null : param.getValue();
  
          if (equals(input,output)) {
            System.out.println(methodName + "\t OK");
          } else {
            System.out.println(methodName + "\t Fail: " + output);
          }
        }
        
      } catch (SOAPException se) {
        System.out.println(methodName + "\t Fault: " + se.getMessage());
        System.out.println(se.toString());
      } catch (Exception e) {
        System.out.println(methodName + "\t Exception: " + e);
      }
    }
  }
  
  
  
  1.13      +8 -1      xml-soap/java/src/org/apache/soap/encoding/soapenc/ArraySerializer.java
  
  Index: ArraySerializer.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/encoding/soapenc/ArraySerializer.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ArraySerializer.java	30 Aug 2002 21:39:00 -0000	1.12
  +++ ArraySerializer.java	10 Sep 2002 07:27:25 -0000	1.13
  @@ -72,6 +72,7 @@
    * arrays using the <code>SOAP-ENC</code> encoding style.
    *
    * @author Matthew J. Duftler (duftler@us.ibm.com)
  + * @author Scott Nichol (snichol@computer.org)
    */
   public class ArraySerializer implements Serializer, Deserializer
   {
  @@ -198,7 +199,13 @@
   
           Array.set(array, i, itemBean.value);
         }
  -
  +      else
  +      {
  +        Class javaType =  xjmr.queryJavaType(actualItemType, actualEncStyle);
  +        if (javaType.isPrimitive())
  +          throw new IllegalArgumentException("Cannot set null value for array element of primitive type: " + javaType.getName());
  +      }
  +    
         tempEl = DOMUtils.getNextSiblingElement(tempEl);
       }
   
  
  
  
  1.42      +2 -2      xml-soap/java/src/org/apache/soap/server/http/RPCRouterServlet.java
  
  Index: RPCRouterServlet.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/http/RPCRouterServlet.java,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- RPCRouterServlet.java	6 Sep 2002 06:14:10 -0000	1.41
  +++ RPCRouterServlet.java	10 Sep 2002 07:27:25 -0000	1.42
  @@ -386,12 +386,12 @@
           else
             e = new SOAPException(Constants.FAULT_CODE_SERVER +
                                   ".Exception:", "", t);
  -  
  +
           Fault fault = new Fault (e);
           fault.setFaultActorURI (req.getRequestURI ());
           if (dd != null)
             dd.buildFaultRouter(reqCtx).notifyListeners(fault, e);
  -  
  +
           // the status code for faults should always be the internal
           // server error status code (per soap spec)
           status = res.SC_INTERNAL_SERVER_ERROR;
  
  
  
  1.3       +3 -0      xml-soap/java/src/org/apache/soap/util/Bean.java
  
  Index: Bean.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/util/Bean.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Bean.java	30 May 2000 10:24:21 -0000	1.2
  +++ Bean.java	10 Sep 2002 07:27:25 -0000	1.3
  @@ -64,6 +64,7 @@
    * originally in the BML player.
    *
    * @author   Sanjiva Weerawarana
  + * @author   Scott Nichol (snichol@computer.org)
    */
   public class Bean {
     // type of this bean
  @@ -73,6 +74,8 @@
     public Object value;
   
     public Bean (Class type, Object value) {
  +    if (value == null && type.isPrimitive() && !type.equals(void.class))
  +      throw new IllegalArgumentException("Cannot set null value for primitive type " + type.getName());
       this.type = type;
       this.value = value;
     }