snichol 2002/06/27 19:33:17 Modified: java/docs changes.html intro.html java/src/org/apache/soap Body.java java/src/org/apache/soap/encoding/soapenc BeanSerializer.java ParameterSerializer.java SoapEncUtils.java java/src/org/apache/soap/rpc SOAPContext.java Added: java/samples/multiref CircularBean.java DeploymentDescriptor.xml GetCircularBean.java MultiRefService.java README testit.cmd testit.sh java/src/org/apache/soap/encoding/soapenc BeanMultiRefSerializer.java MultiRefContext.java Log: Enhance multi-reference deserialization by only deserializing the object once, regardless of the number of references. Provide initial support for multi-reference serialization. The new BeanMultiRefSerializer is the only serializer for which multi-reference serialization is supported. Added a sample to demonstrate serialization and deserialization of a cyclic graph of beans. Revision Changes Path 1.30 +7 -0 xml-soap/java/docs/changes.html Index: changes.html =================================================================== RCS file: /home/cvs/xml-soap/java/docs/changes.html,v retrieving revision 1.29 retrieving revision 1.30 diff -u -r1.29 -r1.30 --- changes.html 26 Jun 2002 11:39:52 -0000 1.29 +++ changes.html 28 Jun 2002 02:33:16 -0000 1.30 @@ -39,6 +39,13 @@ namespace URI for SOAP-ENC to imply a type. For now, just support SOAP-ENC:Array. This allows interop with .NET arrays without a type mapping.</li> + <li>Enhance multi-reference deserialization by only deserializing + the object once, regardless of the number of references. Provide + initial support for multi-reference serialization. The new + BeanMultiRefSerializer is the only serializer for which + multi-reference serialization is supported. Added a sample to + demonstrate serialization and deserialization of a cyclic graph + of beans.</li> </ul> </li> </ul> 1.11 +0 -1 xml-soap/java/docs/intro.html Index: intro.html =================================================================== RCS file: /home/cvs/xml-soap/java/docs/intro.html,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- intro.html 2 May 2002 19:09:14 -0000 1.10 +++ intro.html 28 Jun 2002 02:33:16 -0000 1.11 @@ -95,7 +95,6 @@ checking</li> <li>root attribute</li> <li>actor attribute and SOAP intermediaries</li> - <li>does not use multi-ref accessors during serialization</li> </ul> <p>The following limitations on SOAP Messages with Attachments 1.1 xml-soap/java/samples/multiref/CircularBean.java Index: CircularBean.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2000 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 and was * originally based on software copyright (c) 2000, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package samples.multiref; /** * A simple class for making object graphs. * * @author Scott Nichol ([EMAIL PROTECTED]) */ public class CircularBean { private String name = null; private CircularBean relative = null; public String getName() { return name; } public CircularBean getRelative() { return relative; } public void setName(String name) { this.name = name; } public void setRelative(CircularBean relative) { this.relative = relative; } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("I am ").append(name); if (relative != null) { sb.append(" and I have a relative ").append(relative.getName()); if (relative.getRelative() == this) sb.append(" who acknowledges me as a relative"); else sb.append(" who does NOT acknowledge me as a relative"); } else sb.append(" and I have no relative"); return sb.toString(); } } 1.1 xml-soap/java/samples/multiref/DeploymentDescriptor.xml Index: DeploymentDescriptor.xml =================================================================== <isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" id="urn:MultiRefSample"> <isd:provider type="java" scope="Application" methods="getCircularBean"> <isd:java class="samples.multiref.MultiRefService" static="false"/> </isd:provider> <isd:faultListener>org.apache.soap.server.DOMFaultListener</isd:faultListener> <isd:mappings> <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:x="urn:xml-soap-multiref-sample" qname="x:circularbean" javaType="samples.multiref.CircularBean" java2XMLClassName="org.apache.soap.encoding.soapenc.BeanMultiRefSerializer" xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanMultiRefSerializer"/> </isd:mappings> </isd:service> 1.1 xml-soap/java/samples/multiref/GetCircularBean.java Index: GetCircularBean.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2000 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 and was * originally based on software copyright (c) 2000, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package samples.multiref; import java.io.*; import java.util.*; import java.net.*; import org.apache.soap.util.xml.*; import org.apache.soap.*; import org.apache.soap.encoding.*; import org.apache.soap.encoding.soapenc.*; import org.apache.soap.rpc.*; /** * See \samples\multiref\readme for info. * * @author Scott Nichol ([EMAIL PROTECTED]) */ public class GetCircularBean { public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage:"); System.err.println(" java " + GetCircularBean.class.getName() + " SOAP-router-URL"); System.exit(1); } URL url = new URL(args[0]); SOAPMappingRegistry smr = new SOAPMappingRegistry(); BeanMultiRefSerializer beanSer = new BeanMultiRefSerializer(); // Map the types. smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("urn:xml-soap-multiref-sample", "circularbean"), CircularBean.class, beanSer, beanSer); // Build the call. Call call = new Call(); call.setSOAPMappingRegistry(smr); call.setTargetObjectURI("urn:MultiRefSample"); call.setMethodName("getCircularBean"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); Vector params = new Vector(); call.setParams(params); // Invoke the call. Response resp; try { resp = call.invoke(url, ""); } catch (SOAPException e) { System.err.println("Caught SOAPException (" + e.getFaultCode() + "): " + e.getMessage()); return; } // Check the response. if (!resp.generatedFault()) { Parameter ret = resp.getReturnValue(); Object value = ret.getValue(); System.out.println(value != null ? value.toString() : "null?"); } else { Fault fault = resp.getFault(); System.err.println("Generated fault: " + fault); } } } 1.1 xml-soap/java/samples/multiref/MultiRefService.java Index: MultiRefService.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2000 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 and was * originally based on software copyright (c) 2000, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package samples.multiref; /** * Serves up a CircularBean. * * @author Scott Nichol ([EMAIL PROTECTED]) */ public class MultiRefService { public CircularBean getCircularBean() { CircularBean bean1 = new CircularBean(); CircularBean bean2 = new CircularBean(); bean1.setName("Number one"); bean2.setName("Number two"); bean1.setRelative(bean2); bean2.setRelative(bean1); return bean1; } } 1.1 xml-soap/java/samples/multiref/README Index: README =================================================================== Service: ------- To install this service on an Apache-SOAP listener, you need to make the samples.multiref package available on the Apache-SOAP listener's classpath. Then deploy this service by filling in the deployment template using the info in the deployment descriptor in this directory or by using the service manager client: java org.apache.soap.server.ServiceManagerClient routerURL deploy dd.xml where routerURL is the URL of the SOAP RPC router and dd.xml is the name of the deployment descriptor file. For example: java org.apache.soap.server.ServiceManagerClient \ http://localhost:8080/soap/servlet/rpcrouter deploy DeploymentDescriptor.xml Client: ------ There is 1 sample client: java samples.multiref.GetCircularBean Run it with no args to see the usage. Additional Client Classpath Requirements: ---------------------------------------- ../.. Explanation: ----------- This is a simple service that allows a client to retrieve a bean that is part of a cyclic object graph. Sample Usage: ------------ java samples.multiref.GetCircularBean \ http://localhost:2020/soap/servlet/rpcrouter Wire Dump: ---------- *** Request *** POST /soapcvs/servlet/rpcrouter HTTP/1.0 Host: localhost:8080 Content-Type: text/xml; charset=utf-8 Content-Length: 421 SOAPAction: "" <?xml version='1.0' encoding='UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:getCircularBean xmlns:ns1="urn:MultiRefSample" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> </ns1:getCircularBean> </SOAP-ENV:Body> </SOAP-ENV:Envelope> *** Response *** HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: 949 Date: Thu, 27 Jun 2002 21:03:52 GMT Server: Apache Tomcat/4.0.1 (HTTP/1.1 Connector) Set-Cookie: JSESSIONID=E38583C6360452A5B30247D152A3A228;Path=/soapcvs <?xml version='1.0' encoding='UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:getCircularBeanResponse xmlns:ns1="urn:MultiRefSample" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <return href="#id0" /> </ns1:getCircularBeanResponse> <multiRef id="id0" xmlns:ns2="urn:xml-soap-multiref-sample" xsi:type="ns2:circularbean" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <name xsi:type="xsd:string">Number one</name> <relative href="#id1" /> </multiRef> <multiRef id="id1" xmlns:ns3="urn:xml-soap-multiref-sample" xsi:type="ns3:circularbean" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <name xsi:type="xsd:string">Number two</name> <relative href="#id0" /> </multiRef> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 1.1 xml-soap/java/samples/multiref/testit.cmd Index: testit.cmd =================================================================== @echo off echo This test assumes a server URL of http://localhost:8080/soap/servlet/rpcrouter echo Deploying the multiref service... java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter deploy DeploymentDescriptor.xml echo . echo Verify that it's there java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list echo . echo Getting circular bean java samples.multiref.GetCircularBean http://localhost:8080/soap/servlet/rpcrouter echo . echo Undeploy it now java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter undeploy urn:MultiRefSample echo . echo Verify that it's gone java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list 1.1 xml-soap/java/samples/multiref/testit.sh Index: testit.sh =================================================================== echo This test assumes a server URL of http://localhost:8080/soap/servlet/rpcrouter echo Deploying the multiref service... java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter deploy DeploymentDescriptor.xml echo echo Verify that it\'s there java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list echo echo Getting bean java samples.multiref.GetCircularBean http://localhost:8080/soap/servlet/rpcrouter echo echo Undeploy it now java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter undeploy urn:MultiRefSample echo echo Verify that it\'s gone java org.apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list 1.7 +21 -0 xml-soap/java/src/org/apache/soap/Body.java Index: Body.java =================================================================== RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/Body.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- Body.java 14 Feb 2001 02:29:27 -0000 1.6 +++ Body.java 28 Jun 2002 02:33:16 -0000 1.7 @@ -63,6 +63,8 @@ import org.apache.soap.util.*; import org.apache.soap.util.xml.*; import org.apache.soap.encoding.*; +import org.apache.soap.encoding.soapenc.BeanSerializer; +import org.apache.soap.encoding.soapenc.MultiRefContext; import org.apache.soap.rpc.SOAPContext; /** @@ -71,6 +73,7 @@ * * @author Matthew J. Duftler ([EMAIL PROTECTED]) * @author Sanjiva Weerawarana ([EMAIL PROTECTED]) + * @author Scott Nichol ([EMAIL PROTECTED]) */ public class Body { @@ -166,6 +169,24 @@ throw new IllegalArgumentException("Unknown type of body entry: '" + obj.getClass () + "'"); } + sink.write(StringUtils.lineSeparator); + } + } + + // serialize any multiRefs + if (ctx.getMultiRefCount() > 0) { + // TODO: support other serializers by having them registered + // with the SOAPContext for each multiRef. + BeanSerializer ser = new BeanSerializer(); + MultiRefContext mrc = new MultiRefContext(); + // Note: it is *essential* that one keep calling the getMultiRefCount method + // rather than storing the result in a variable, as the act of serialization + // could generate additional multiRefs. + for (int id = 0; id < ctx.getMultiRefCount(); id++) { + Object o = ctx.getMultiRef(id); + mrc.setId(id); + ser.marshall(actualEncStyle, o.getClass(), o, mrc, + sink, nsStack, xjmr, ctx); sink.write(StringUtils.lineSeparator); } } 1.7 +8 -0 xml-soap/java/src/org/apache/soap/encoding/soapenc/BeanSerializer.java Index: BeanSerializer.java =================================================================== RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/encoding/soapenc/BeanSerializer.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- BeanSerializer.java 20 Jun 2001 02:20:53 -0000 1.6 +++ BeanSerializer.java 28 Jun 2002 02:33:16 -0000 1.7 @@ -73,6 +73,7 @@ * public properties of the bean become named accessors. * * @author Matthew J. Duftler ([EMAIL PROTECTED]) + * @author Scott Nichol ([EMAIL PROTECTED]) */ public class BeanSerializer implements Serializer, Deserializer { @@ -150,6 +151,13 @@ Class javaType = xjmr.queryJavaType(elementType, inScopeEncStyle); Object bean = instantiateBean(javaType); PropertyDescriptor[] properties = getPropertyDescriptors(javaType); + + // If we are deserializing a multiRef, register the bean + String id = ctx.getCurrentId(); + if (id != null) { + ctx.addDeserializedMultiRef(id, bean); + ctx.setCurrentId(null); + } while (tempEl != null) { 1.12 +39 -27 xml-soap/java/src/org/apache/soap/encoding/soapenc/ParameterSerializer.java Index: ParameterSerializer.java =================================================================== RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/encoding/soapenc/ParameterSerializer.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- ParameterSerializer.java 10 Jun 2002 03:49:03 -0000 1.11 +++ ParameterSerializer.java 28 Jun 2002 02:33:16 -0000 1.12 @@ -71,6 +71,7 @@ * @author Matthew J. Duftler ([EMAIL PROTECTED]) * @author Sander Brienen ([EMAIL PROTECTED]) * @author Sanjiva Weerawarana ([EMAIL PROTECTED]) + * @author Scott Nichol ([EMAIL PROTECTED]) */ public class ParameterSerializer implements Serializer, Deserializer { @@ -132,39 +133,50 @@ { href = href.substring(1); - Element el = - DOMUtils.getElementByID(src.getOwnerDocument().getDocumentElement(), - href); - - if (el == null) - { - throw new IllegalArgumentException("No such ID '" + href + "'."); - } - - QName soapType = SoapEncUtils.getTypeQName(el); + // See whether we've already deserialized it. + Object dmf = ctx.getDeserializedMultiRef(href); + if (dmf == null) { + // Not deserialized, so do it now. + Element el = + DOMUtils.getElementByID(src.getOwnerDocument().getDocumentElement(), + href); - if (soapType == null) - { - /* - No xsi:type attribute found: determine the type as the - qualified name of the parameter element (if the parameter - element is qualified) or as the qname formed by an empty - namespace URI and the tag name of the parameter element. - Is that a legal qname??? - */ - String paramNamespaceURI = paramEl.getNamespaceURI(); - - if (paramNamespaceURI != null) + if (el == null) { - soapType = new QName(paramNamespaceURI, name); + throw new IllegalArgumentException("No such ID '" + href + "'."); } - else + + QName soapType = SoapEncUtils.getTypeQName(el); + + if (soapType == null) { - soapType = new QName("", name); + /* + No xsi:type attribute found: determine the type as the + qualified name of the parameter element (if the parameter + element is qualified) or as the qname formed by an empty + namespace URI and the tag name of the parameter element. + Is that a legal qname??? + */ + String paramNamespaceURI = paramEl.getNamespaceURI(); + + if (paramNamespaceURI != null) + { + soapType = new QName(paramNamespaceURI, name); + } + else + { + soapType = new QName("", name); + } } - } - bean = xjmr.unmarshall(inScopeEncStyle, soapType, el, ctx); + ctx.setCurrentId(href); + bean = xjmr.unmarshall(inScopeEncStyle, soapType, el, ctx); + ctx.setCurrentId(null); // Note: a multiRef-aware deserializer + // will already have done this. + } else { + // Already deserialized. + bean = new Bean(dmf.getClass(), dmf); + } } else { 1.13 +3 -0 xml-soap/java/src/org/apache/soap/encoding/soapenc/SoapEncUtils.java Index: SoapEncUtils.java =================================================================== RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/encoding/soapenc/SoapEncUtils.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- SoapEncUtils.java 26 Jun 2002 11:39:52 -0000 1.12 +++ SoapEncUtils.java 28 Jun 2002 02:33:16 -0000 1.13 @@ -160,6 +160,9 @@ sink.write('<' + context.toString() + namespaceDecl); + if (context instanceof MultiRefContext) + sink.write(' ' + Constants.ATTR_ID + "=\"id" + ((MultiRefContext) context).getId() + "\""); + // Get prefixes for the needed namespaces. String elementTypeNS = elementType.getNamespaceURI(); String xsiNamespaceURI = Constants.NS_URI_CURRENT_SCHEMA_XSI; 1.1 xml-soap/java/src/org/apache/soap/encoding/soapenc/BeanMultiRefSerializer.java Index: BeanMultiRefSerializer.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2000 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 and was * originally based on software copyright (c) 2000, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.soap.encoding.soapenc; import java.io.*; import java.util.*; import org.w3c.dom.*; import org.apache.soap.util.*; import org.apache.soap.util.xml.*; import org.apache.soap.*; import org.apache.soap.rpc.*; /** * A <code>BeanMultiRefSerializer</code> can be used to serialize * <em>JavaBeans</em> using the multiRef <code>SOAP-ENC</code> encoding style. The * public properties of the bean become named accessors. * * @author Scott Nichol ([EMAIL PROTECTED]) */ public class BeanMultiRefSerializer implements Serializer, Deserializer { // Delegate de-serialization to the BeanSerializer private BeanSerializer deser = new BeanSerializer(); public void marshall(String inScopeEncStyle, Class javaType, Object src, Object context, Writer sink, NSStack nsStack, XMLJavaMappingRegistry xjmr, SOAPContext ctx) throws IllegalArgumentException, IOException { nsStack.pushScope(); int id = ctx.addMultiRef(src); sink.write("<" + context.toString() + " " + Constants.ATTR_REFERENCE + "=\"#id" + id + "\" />"); nsStack.popScope(); } public Bean unmarshall(String inScopeEncStyle, QName elementType, Node src, XMLJavaMappingRegistry xjmr, SOAPContext ctx) throws IllegalArgumentException { return deser.unmarshall(inScopeEncStyle, elementType, src, xjmr, ctx); } } 1.1 xml-soap/java/src/org/apache/soap/encoding/soapenc/MultiRefContext.java Index: MultiRefContext.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2000 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 and was * originally based on software copyright (c) 2000, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.soap.encoding.soapenc; /** * Provides the context for a multiRef's serialization. * * @author Scott Nichol ([EMAIL PROTECTED]) */ public class MultiRefContext { private static final int ILLEGAL_ID = -1; private static final String MULTIREF_NAME = "multiRef"; private int id; private String name; public MultiRefContext() { this(ILLEGAL_ID, MULTIREF_NAME); } public MultiRefContext(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String toString() { return name; } } 1.8 +90 -1 xml-soap/java/src/org/apache/soap/rpc/SOAPContext.java Index: SOAPContext.java =================================================================== RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/rpc/SOAPContext.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- SOAPContext.java 8 May 2002 04:22:36 -0000 1.7 +++ SOAPContext.java 28 Jun 2002 02:33:17 -0000 1.8 @@ -71,15 +71,20 @@ /** * SOAP context for a message. Encapsulates: * <ul> - * <li>MIME multipart + * <li>MIME multipart</li> + * <li>MultiRef elements</li> * </ul> * * @author Wouter Cloetens ([EMAIL PROTECTED]) + * @author Scott Nichol ([EMAIL PROTECTED]) */ public class SOAPContext { protected MimeMultipart parts; protected Hashtable bag = new Hashtable(); protected ClassLoader loader = null ; + protected Vector multiRef = new Vector(); + protected Hashtable deserializedMultiRef = new Hashtable(); + protected String currentId = null; /** * This flag indicates if setRootPart() was called, so we can distinguish @@ -565,6 +570,88 @@ } /** + * Gets the id attribute for the element currently being deserialized. + * This will be null if there is no current id. + * + * @return The current id. + */ + public String getCurrentId() { + return currentId; + } + + /** + * Sets the id attribute for the element currently being deserialized. + * This will be null if there is no current id. + * + * @param id The current id. + */ + public void setCurrentId(String id) { + currentId = id; + } + + /** + * Adds a multiRef element. This may actually add the object, + * or it may simply return the id of the object as previously added. + * The id of the object is always between 0 and the count of multiRefs + * minus 1. + * + * @param o The object for which a multiRef is desired. + * @return The id of the element. + */ + public int addMultiRef(Object o) { + // While a Hashtable might seem a better choice than a vector here, + // a Vector is easier to work with during serialization, since + // multiRefs may be added during the serialization of other multiRefs. + for (int i = 0; i < multiRef.size(); i++) { + if (multiRef.elementAt(i) == o) + return i; + } + multiRef.addElement(o); + return multiRef.size() - 1; + // TODO: support other serializers by having them registered + // with the SOAPContext for each multiRef object. + } + + /** + * Gets the multiRef for a particular id. + * + * @param id The id. + * @return The multiRef for the id. + */ + public Object getMultiRef(int id) { + return multiRef.elementAt(id); + } + + /** + * Gets the number of multiRefs. The multiRefs have id from 0 to count - 1. + * + * @return The number of multiRefs. + */ + public int getMultiRefCount() { + return multiRef.size(); + } + + /** + * Adds the multiRef deserialized for a particular id. + * + * @param id The element id, as referred to by an href. + * @param o The deserialized object. + */ + public void addDeserializedMultiRef(String id, Object o) { + deserializedMultiRef.put(id, o); + } + + /** + * Gets the multiRef deserialized for a particular id. + * + * @param id The id, as referred to by an href. + * @return The multiRef for the id. + */ + public Object getDeserializedMultiRef(String id) { + return deserializedMultiRef.get(id); + } + + /** * String representation for debug purposes. */ public String toString() { @@ -592,6 +679,8 @@ } pw.print("}]"); + + pw.print(" multiRefs: " + multiRef.size() + " deserializedMultiRefs: " + deserializedMultiRef.size()); return sw.toString(); }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>