Index: [Article Count Order] [Thread]

Date:  Tue, 12 Feb 2002 19:14:54 +0900
From:  "NAKAMURA, Hiroshi" <nahi@keynauts.com>
Subject:  [webricken:11] Re: SOAPlets
To:  <webricken@notwork.org>
Message-Id:  <000601c1b3ae$1dc389c0$85222fc0@sarion.co.jp>
In-Reply-To:  <20020212090029.MBRQ12547.mta3-rme.xtra.co.nz@there>
X-Mail-Count: 00011

Hi,

> From: Holden Glova [mailto:dsafari@xtra.co.nz] 
> Sent: Tuesday, February 12, 2002 6:05 PM

> Thank you very much :)

welcome. :)

> Can you ellaborate how and why I might use this
> mysterious mappingRegistry?

In SOAP world, a data model called "SOAP Data Model"
is defined.  It's a graph of typed object.  Type is
Struct, Array and simple types like string, integer,
datetime, etc.

SOAP spec defines SOAP Data Model <-> XML instance.
No language mapping such as in CORBA world.  So to
define mapping between a language and SOAP Data Model
is user's responsibility.  Though SOAP4R defines
default mapping for easy use, you can use custom
mappingRegistry to define your mapping.

For example, under SOAP4R's default mapping,
Ruby's array is mapped to 'Array of anytype' in SOAP
Data Model.  Sending this array to remote endpoint,
it will be mapped to Variant array under SOAP/COM mapping,
or Vector under Java mapping.

Don't you want to map some array to 'Array of int'
exactly, do you?  Then, at first, define your own Array;

  class IntArray < Array; end

Create your custom mappingRegistry;

  map = SOAP::RPCUtils::MappingRegistry.new
  intArrayFactory =
    SOAP::RPCUtils::MappingRegistry::TypedArrayFactory
  map.set( IntArray, SOAP::SOAPArray, intArrayFactory,
    [ XSD::Namespace, XSD::IntLiteral ] )

Then, pass use this map in marshalling/unmarshalling
Ruby's object like;

  SOAP::Marshal.marshal( IntArray[ 1, 2, 3 ], map )

Other than Marshal interface, SOAP::Driver and
SOAP::Server has mappingRegistry attribute.

Regards,
// NaHi

PS. All example.

require 'soap/rpcUtils'
require 'soap/marshal'

class IntArray < Array; end

puts SOAP::Marshal.marshal( IntArray[ 1, 2, 3 ] )

puts

map = SOAP::RPCUtils::MappingRegistry.new
intArrayFactory =
  SOAP::RPCUtils::MappingRegistry::TypedArrayFactory
map.set( IntArray, SOAP::SOAPArray, intArrayFactory,
  [ XSD::Namespace, XSD::IntLiteral ] )

puts SOAP::Marshal.marshal( IntArray[ 1, 2, 3 ], map )

=>

<?xml version="1.0" ?>
<env:Envelope
  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/";
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<IntArray
  xsi:type="n1:Array"
  n1:arrayType="xsd:anyType[3]"		# ANYTYPE
  env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";
  xmlns:n1="http://schemas.xmlsoap.org/soap/encoding/">
<item xsi:type="xsd:int">1</item>
<item xsi:type="xsd:int">2</item>
<item xsi:type="xsd:int">3</item>
</IntArray>
</env:Body>
</env:Envelope>

<?xml version="1.0" ?>
<env:Envelope
  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/";
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<IntArray
  xsi:type="n1:Array"
  n1:arrayType="xsd:int[3]"		# INT
  env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";
  xmlns:n1="http://schemas.xmlsoap.org/soap/encoding/">
<item>1</item>
<item>2</item>
<item>3</item>
</IntArray>
</env:Body>
</env:Envelope>