diff options
author | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-09-15 14:33:53 +0000 |
---|---|---|
committer | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-09-15 14:33:53 +0000 |
commit | 29c5ab0b77feaf975d83ab340d7194c9c4dffc9d (patch) | |
tree | 6ac40e3bffcf1735c8b7efc0f412bccc15befa6a /lib/soap/mapping | |
parent | 071c45df939e962e8cd6ecc51bd402b6a7cc91f6 (diff) |
* lib/{soap,wsdl,xsd}, test/{soap,wsdl,xsd}: imported soap4r/1.5.5.
#nnn is a ticket number at http://dev.ctor.org/soap4r
* SOAP
* allow to configure an envelope namespace of SOAP request. (#124)
TemporaryNamespace = 'http://www.w3.org/2003/05/soap-envelope'
@client.options["soap.envelope.requestnamespace"] =
TemporaryNamespace
@client.options["soap.envelope.responsenamespace"] =
TemporaryNamespace
@client.do_proc(...)
* let SOAP request XML indent space configuable. see
"soap.envelope.no_indent" option. (#130)
* let external CES configuable.
ex. client["soap.mapping.external_ces"] = 'SJIS'. $KCODE is used
by default. (#133)
external CES ::= CES used in Ruby object of client and server
internal CES ::= CES used in SOAP/OM
* add iso-8859-1 external CES support. (#106)
* fixed illegal 'qualified' handling of elements. it caused
ASP.NET inteoperability problem. (#144)
* added 'soap.envelope.use_numeric_character_reference' (boolean)
option to let query XML use numeric character reference in XML,
not plain UTF-8 character. !GoogleSearch server seems to not
allow plain UTF-8 character since 2005-08-15 update. (#147)
* SOAP::Header::SimpleHeader (de)serialization throws an exception
on !SimpleHeader.on_(in|out)bound when header is a String. so we
could not use a simple single element headerItem. fixed. thanks
to emil. (#129)
* out parameter of rpc operation did not work. (#132)
* follow HTTP redirect only if using http-access2. (#125) (#145)
* add a workaround for importing an WSDL whose path begins with
drive letter. (#115)
* WSDL
* SOAP Data which is defined as a simpletype was not mapped
correctly to Ruby obj when using wsdl2ruby.rb generated classdef
file. (#123)
* rpc/literal support. (#118)
* re-implemented local element qualify/unqualify control. handles
elementFormDefault and form in WSDL. (#119)
* Array of an element which has simpleType causes a crash. (#128)
* prarmeterOrder may not contain return part so it can be shorter
than parts size. Thanks to Hugh. (#139)
* Samples
* added !BasicAuth client sample. (#117)
* added Base64 client/server sample.
* added Flickr SOAP interface client sample. (#122)
* added !SalesForce client sample. (#135)
* updated Thawte CA certificate for !GoogleAdWords sample.
* updated a client script with the newer version made by Johan.
thanks!
* shortened long file names. (#120)
* fixed typo in authheader sample. (#129)
* updated deprecated method usage. (#138)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9169 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/soap/mapping')
-rw-r--r-- | lib/soap/mapping/factory.rb | 10 | ||||
-rw-r--r-- | lib/soap/mapping/registry.rb | 7 | ||||
-rw-r--r-- | lib/soap/mapping/wsdlRegistry.rb | 155 | ||||
-rw-r--r-- | lib/soap/mapping/wsdlencodedregistry.rb | 17 | ||||
-rw-r--r-- | lib/soap/mapping/wsdlliteralregistry.rb | 90 |
5 files changed, 82 insertions, 197 deletions
diff --git a/lib/soap/mapping/factory.rb b/lib/soap/mapping/factory.rb index 13dffc2dd0..978b303b3d 100644 --- a/lib/soap/mapping/factory.rb +++ b/lib/soap/mapping/factory.rb @@ -87,10 +87,11 @@ class StringFactory_ < Factory return nil end begin - unless XSD::Charset.is_ces(obj, $KCODE) - return nil + unless XSD::Charset.is_ces(obj, Thread.current[:SOAPExternalCES]) + return nil end - encoded = XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) + encoded = XSD::Charset.encoding_conv(obj, + Thread.current[:SOAPExternalCES], XSD::Charset.encoding) soap_obj = soap_class.new(encoded) rescue XSD::ValueSpaceError return nil @@ -101,7 +102,8 @@ class StringFactory_ < Factory def soap2obj(obj_class, node, info, map) obj = Mapping.create_empty_object(obj_class) - decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding, $KCODE) + decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding, + Thread.current[:SOAPExternalCES]) obj.replace(decoded) mark_unmarshalled_obj(node, obj) return true, obj diff --git a/lib/soap/mapping/registry.rb b/lib/soap/mapping/registry.rb index e733f5c95f..823e80666d 100644 --- a/lib/soap/mapping/registry.rb +++ b/lib/soap/mapping/registry.rb @@ -49,8 +49,7 @@ class SOAPException; include Marshallable e.set_backtrace(@cause.backtrace) return e end - klass = Mapping.class_from_name( - Mapping.elename2name(@excn_type_name.to_s)) + klass = Mapping.class_from_name(Mapping.elename2name(@excn_type_name.to_s)) if klass.nil? or not klass <= ::Exception return RuntimeError.new(@cause.inspect) end @@ -89,6 +88,10 @@ class Object; include Marshallable @__xmlele.each do |k, v| return v if k == qname end + # fallback + @__xmlele.each do |k, v| + return v if k.name == qname.name + end nil end diff --git a/lib/soap/mapping/wsdlRegistry.rb b/lib/soap/mapping/wsdlRegistry.rb deleted file mode 100644 index 64f49f2265..0000000000 --- a/lib/soap/mapping/wsdlRegistry.rb +++ /dev/null @@ -1,155 +0,0 @@ -# SOAP4R - WSDL mapping registry. -# Copyright (C) 2000, 2001, 2002, 2003 NAKAMURA, Hiroshi <[email protected]>. - -# This program is copyrighted free software by NAKAMURA, Hiroshi. You can -# redistribute it and/or modify it under the same terms of Ruby's license; -# either the dual license version in 2003, or any later version. - - -require 'soap/baseData' -require 'soap/mapping/mapping' -require 'soap/mapping/typeMap' - - -module SOAP -module Mapping - - -class WSDLRegistry - include TraverseSupport - - attr_reader :definedtypes - - def initialize(definedtypes, config = {}) - @definedtypes = definedtypes - @config = config - @excn_handler_obj2soap = nil - # For mapping AnyType element. - @rubytype_factory = RubytypeFactory.new( - :allow_untyped_struct => true, - :allow_original_mapping => true - ) - end - - def obj2soap(klass, obj, type_qname) - soap_obj = nil - if obj.nil? - soap_obj = SOAPNil.new - elsif obj.is_a?(XSD::NSDBase) - soap_obj = soap2soap(obj, type_qname) - elsif type = @definedtypes[type_qname] - soap_obj = obj2type(obj, type) - elsif (type = TypeMap[type_qname]) - soap_obj = base2soap(obj, type) - elsif type_qname == XSD::AnyTypeName - soap_obj = @rubytype_factory.obj2soap(nil, obj, nil, nil) - end - return soap_obj if soap_obj - if @excn_handler_obj2soap - soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj| - Mapping._obj2soap(yield_obj, self) - } - end - return soap_obj if soap_obj - raise MappingError.new("Cannot map #{ klass.name } to SOAP/OM.") - end - - def soap2obj(klass, node) - raise RuntimeError.new("#{ self } is for obj2soap only.") - end - - def excn_handler_obj2soap=(handler) - @excn_handler_obj2soap = handler - end - -private - - def soap2soap(obj, type_qname) - if obj.is_a?(SOAPBasetype) - obj - elsif obj.is_a?(SOAPStruct) && (type = @definedtypes[type_qname]) - soap_obj = obj - mark_marshalled_obj(obj, soap_obj) - elements2soap(obj, soap_obj, type.content.elements) - soap_obj - elsif obj.is_a?(SOAPArray) && (type = @definedtypes[type_qname]) - soap_obj = obj - contenttype = type.child_type - mark_marshalled_obj(obj, soap_obj) - obj.replace do |ele| - Mapping._obj2soap(ele, self, contenttype) - end - soap_obj - else - nil - end - end - - def obj2type(obj, type) - if type.is_a?(::WSDL::XMLSchema::SimpleType) - simple2soap(obj, type) - else - complex2soap(obj, type) - end - end - - def simple2soap(obj, type) - o = base2soap(obj, TypeMap[type.base]) - if type.restriction.enumeration.empty? - STDERR.puts("#{type.name}: simpleType which is not enum type not supported.") - return o - end - type.check_lexical_format(obj) - o - end - - def complex2soap(obj, type) - case type.compoundtype - when :TYPE_STRUCT - struct2soap(obj, type.name, type) - when :TYPE_ARRAY - array2soap(obj, type.name, type) - end - end - - def base2soap(obj, type) - soap_obj = nil - if type <= XSD::XSDString - soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ? - XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj) - mark_marshalled_obj(obj, soap_obj) - else - soap_obj = type.new(obj) - end - soap_obj - end - - def struct2soap(obj, type_qname, type) - soap_obj = SOAPStruct.new(type_qname) - mark_marshalled_obj(obj, soap_obj) - elements2soap(obj, soap_obj, type.content.elements) - soap_obj - end - - def array2soap(obj, type_qname, type) - contenttype = type.child_type - soap_obj = SOAPArray.new(ValueArrayName, 1, contenttype) - mark_marshalled_obj(obj, soap_obj) - obj.each do |item| - soap_obj.add(Mapping._obj2soap(item, self, contenttype)) - end - soap_obj - end - - def elements2soap(obj, soap_obj, elements) - elements.each do |element| - name = element.name.name - child_obj = obj.instance_eval("@#{ name }") - soap_obj.add(name, Mapping._obj2soap(child_obj, self, element.type)) - end - end -end - - -end -end diff --git a/lib/soap/mapping/wsdlencodedregistry.rb b/lib/soap/mapping/wsdlencodedregistry.rb index 8d495668e9..4efb60188f 100644 --- a/lib/soap/mapping/wsdlencodedregistry.rb +++ b/lib/soap/mapping/wsdlencodedregistry.rb @@ -149,8 +149,9 @@ private def base2soap(obj, type) soap_obj = nil if type <= XSD::XSDString - soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ? - XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj) + str = XSD::Charset.encoding_conv(obj.to_s, + Thread.current[:SOAPExternalCES], XSD::Charset.encoding) + soap_obj = type.new(str) mark_marshalled_obj(obj, soap_obj) else soap_obj = type.new(obj) @@ -234,7 +235,9 @@ private elements, as_array = schema_element_definition(obj.class) vars = {} node.each do |name, value| - if class_name = elements[name] + item = elements.find { |k, v| k.name == name } + if item + elename, class_name = item if klass = Mapping.class_from_name(class_name) # klass must be a SOAPBasetype or a class if klass.ancestors.include?(::SOAP::SOAPBasetype) @@ -246,6 +249,14 @@ private else child = Mapping._soap2obj(value, self, klass) end + elsif klass = Mapping.module_from_name(class_name) + # simpletype + if value.respond_to?(:data) + child = value.data + else + raise MappingError.new( + "cannot map to a module value: #{class_name}") + end else raise MappingError.new("unknown class: #{class_name}") end diff --git a/lib/soap/mapping/wsdlliteralregistry.rb b/lib/soap/mapping/wsdlliteralregistry.rb index 59acf2f658..7bb8e12203 100644 --- a/lib/soap/mapping/wsdlliteralregistry.rb +++ b/lib/soap/mapping/wsdlliteralregistry.rb @@ -38,14 +38,14 @@ class WSDLLiteralRegistry < Registry if ele = @definedelements[qname] soap_obj = obj2elesoap(obj, ele) elsif type = @definedtypes[qname] - soap_obj = obj2typesoap(obj, type) + soap_obj = obj2typesoap(obj, type, true) else soap_obj = any2soap(obj, qname) end return soap_obj if soap_obj if @excn_handler_obj2soap soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj| - Mapping._obj2soap(yield_obj, self) + Mapping.obj2soap(yield_obj, nil, nil, MAPPING_OPT) } return soap_obj if soap_obj end @@ -54,9 +54,7 @@ class WSDLLiteralRegistry < Registry # node should be a SOAPElement def soap2obj(node, obj_class = nil) - unless obj_class.nil? - raise MappingError.new("must not reach here") - end + # obj_class is given when rpc/literal service. but ignored for now. begin return any2obj(node) rescue MappingError @@ -64,45 +62,50 @@ class WSDLLiteralRegistry < Registry if @excn_handler_soap2obj begin return @excn_handler_soap2obj.call(node) { |yield_node| - Mapping._soap2obj(yield_node, self) + Mapping.soap2obj(yield_node, nil, nil, MAPPING_OPT) } rescue Exception end end - raise MappingError.new("cannot map #{node.type.name} to Ruby object") + if node.respond_to?(:type) + raise MappingError.new("cannot map #{node.type.name} to Ruby object") + else + raise MappingError.new("cannot map #{node.elename.name} to Ruby object") + end end private + MAPPING_OPT = { :no_reference => true } + def obj2elesoap(obj, ele) o = nil + qualified = (ele.elementform == 'qualified') if ele.type if type = @definedtypes[ele.type] - o = obj2typesoap(obj, type) + o = obj2typesoap(obj, type, qualified) elsif type = TypeMap[ele.type] o = base2soap(obj, type) else raise MappingError.new("cannot find type #{ele.type}") end - o.elename = ele.name elsif ele.local_complextype - o = obj2typesoap(obj, ele.local_complextype) - o.elename = ele.name + o = obj2typesoap(obj, ele.local_complextype, qualified) add_attributes2soap(obj, o) elsif ele.local_simpletype - o = obj2typesoap(obj, ele.local_simpletype) - o.elename = ele.name + o = obj2typesoap(obj, ele.local_simpletype, qualified) else raise MappingError.new('illegal schema?') end + o.elename = ele.name o end - def obj2typesoap(obj, type) + def obj2typesoap(obj, type, qualified) if type.is_a?(::WSDL::XMLSchema::SimpleType) simpleobj2soap(obj, type) else - complexobj2soap(obj, type) + complexobj2soap(obj, type, qualified) end end @@ -113,15 +116,17 @@ private o end - def complexobj2soap(obj, type) + def complexobj2soap(obj, type, qualified) o = SOAPElement.new(type.name) + o.qualified = qualified type.each_element do |child_ele| child = Mapping.get_attribute(obj, child_ele.name.name) if child.nil? if child_ele.nillable # ToDo: test # add empty element - o.add(obj2elesoap(nil)) + child_soap = obj2elesoap(nil, child_ele) + o.add(child_soap) elsif Integer(child_ele.minoccurs) == 0 # nothing to do else @@ -129,10 +134,12 @@ private end elsif child_ele.map_as_array? child.each do |item| - o.add(obj2elesoap(item, child_ele)) + child_soap = obj2elesoap(item, child_ele) + o.add(child_soap) end else - o.add(obj2elesoap(child, child_ele)) + child_soap = obj2elesoap(child, child_ele) + o.add(child_soap) end end o @@ -153,7 +160,7 @@ private # expected to be a basetype or an anyType. # SOAPStruct, etc. is used instead of SOAPElement. begin - ele = Mapping.obj2soap(obj) + ele = Mapping.obj2soap(obj, nil, nil, MAPPING_OPT) ele.elename = qname ele rescue MappingError @@ -170,6 +177,9 @@ private def stubobj2soap(obj, qname) ele = SOAPElement.new(qname) + ele.qualified = + (obj.class.class_variables.include?('@@schema_qualified') and + obj.class.class_eval('@@schema_qualified')) add_elements2soap(obj, ele) add_attributes2soap(obj, ele) ele @@ -196,15 +206,17 @@ private elements, as_array = schema_element_definition(obj.class) if elements elements.each do |elename, type| - child = Mapping.get_attribute(obj, elename) - unless child.nil? - name = XSD::QName.new(nil, elename) - if as_array.include?(type) + if child = Mapping.get_attribute(obj, elename.name) + if as_array.include?(elename.name) child.each do |item| - ele.add(obj2soap(item, name)) + ele.add(obj2soap(item, elename)) end else - ele.add(obj2soap(child, name)) + ele.add(obj2soap(child, elename)) + end + elsif obj.is_a?(::Array) and as_array.include?(elename.name) + obj.each do |item| + ele.add(obj2soap(item, elename)) end end end @@ -225,8 +237,9 @@ private def base2soap(obj, type) soap_obj = nil if type <= XSD::XSDString - soap_obj = type.new(XSD::Charset.is_ces(obj, $KCODE) ? - XSD::Charset.encoding_conv(obj, $KCODE, XSD::Charset.encoding) : obj) + str = XSD::Charset.encoding_conv(obj.to_s, + Thread.current[:SOAPExternalCES], XSD::Charset.encoding) + soap_obj = type.new(str) else soap_obj = type.new(obj) end @@ -253,7 +266,7 @@ private # SOAPArray for literal? soapele2plainobj(node) else - obj = Mapping._soap2obj(node, Mapping::DefaultRegistry, obj_class) + obj = Mapping.soap2obj(node, nil, obj_class, MAPPING_OPT) add_attributes2plainobj(node, obj) obj end @@ -277,8 +290,11 @@ private elements, as_array = schema_element_definition(obj.class) vars = {} node.each do |name, value| - if class_name = elements[name] + item = elements.find { |k, v| k.name == name } + if item + elename, class_name = item if klass = Mapping.class_from_name(class_name) + # klass must be a SOAPBasetype or a class if klass.ancestors.include?(::SOAP::SOAPBasetype) if value.respond_to?(:data) child = klass.new(value.data).data @@ -288,13 +304,21 @@ private else child = any2obj(value, klass) end + elsif klass = Mapping.module_from_name(class_name) + # simpletype + if value.respond_to?(:data) + child = value.data + else + raise MappingError.new( + "cannot map to a module value: #{class_name}") + end else - raise MappingError.new("unknown class: #{class_name}") + raise MappingError.new("unknown class/module: #{class_name}") end else # untyped element is treated as anyType. child = any2obj(value) end - if as_array.include?(class_name) + if as_array.include?(elename.name) (vars[name] ||= []) << child else vars[name] = child @@ -323,7 +347,7 @@ private def add_elements2plainobj(node, obj) node.each do |name, value| - obj.__add_xmlele_value(XSD::QName.new(nil, name), any2obj(value)) + obj.__add_xmlele_value(value.elename, any2obj(value)) end end |