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 [EMAIL PROTECTED] * * 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 ([EMAIL PROTECTED]) * @author Sam Ruby ([EMAIL PROTECTED]) * @author Scott Nichol ([EMAIL PROTECTED]) */ 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 ([EMAIL PROTECTED]) + * @author Scott Nichol ([EMAIL PROTECTED]) */ 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 ([EMAIL PROTECTED]) */ 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; }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>