diff options
Diffstat (limited to 'lib/soap/mapping')
-rw-r--r-- | lib/soap/mapping/factory.rb | 1 | ||||
-rw-r--r-- | lib/soap/mapping/mapping.rb | 20 | ||||
-rw-r--r-- | lib/soap/mapping/registry.rb | 99 | ||||
-rw-r--r-- | lib/soap/mapping/rubytypeFactory.rb | 73 | ||||
-rw-r--r-- | lib/soap/mapping/wsdlRegistry.rb | 48 |
5 files changed, 151 insertions, 90 deletions
diff --git a/lib/soap/mapping/factory.rb b/lib/soap/mapping/factory.rb index fe6a6de7ae..6b9ac1eeaa 100644 --- a/lib/soap/mapping/factory.rb +++ b/lib/soap/mapping/factory.rb @@ -70,6 +70,7 @@ class Factory end def setiv2soap(node, obj, map) + # should we sort instance_variables? obj.instance_variables.each do |var| name = var.sub(/^@/, '') node.add(Mapping.name2elename(name), diff --git a/lib/soap/mapping/mapping.rb b/lib/soap/mapping/mapping.rb index 38a01bac07..db7ea607fd 100644 --- a/lib/soap/mapping/mapping.rb +++ b/lib/soap/mapping/mapping.rb @@ -68,24 +68,26 @@ module Mapping md_ary end - def self.fault2exception(e, registry = nil) + def self.fault2exception(fault, registry = nil) registry ||= Mapping::DefaultRegistry - detail = if e.detail - soap2obj(e.detail, registry) || "" + detail = if fault.detail + soap2obj(fault.detail, registry) || "" else "" end if detail.is_a?(Mapping::SOAPException) begin - remote_backtrace = detail.to_e.backtrace - raise detail.to_e - rescue Exception => e2 - e2.set_backtrace(remote_backtrace + e2.backtrace) + e = detail.to_e + remote_backtrace = e.backtrace + e.set_backtrace(nil) + raise e # ruby sets current caller as local backtrace of e => e2. + rescue Exception => e + e.set_backtrace(remote_backtrace + e.backtrace[1..-1]) raise end else - e.detail = detail - e.set_backtrace( + fault.detail = detail + fault.set_backtrace( if detail.is_a?(Array) detail else diff --git a/lib/soap/mapping/registry.rb b/lib/soap/mapping/registry.rb index 8142047724..1317d40cd6 100644 --- a/lib/soap/mapping/registry.rb +++ b/lib/soap/mapping/registry.rb @@ -44,14 +44,15 @@ class SOAPException; include Marshallable if @cause.is_a?(::Exception) @cause.extend(::SOAP::Mapping::MappedException) return @cause + elsif @cause.respond_to?(:message) and @cause.respond_to?(:backtrace) + e = RuntimeError.new(@cause.message) + e.set_backtrace(@cause.backtrace) + return e end klass = Mapping.class_from_name( Mapping.elename2name(@excn_type_name.to_s)) - if klass.nil? - raise RuntimeError.new(@cause.message) - end - unless klass <= ::Exception - raise NameError.new + if klass.nil? or not klass <= ::Exception + return RuntimeError.new(@cause.inspect) end obj = klass.new(@cause.message) obj.extend(::SOAP::Mapping::MappedException) @@ -62,50 +63,78 @@ end # For anyType object: SOAP::Mapping::Object not ::Object class Object; include Marshallable - def set_property(name, value) - var_name = name - begin - instance_eval <<-EOS - def #{ var_name } - @#{ var_name } - end + def initialize + @__members = [] + @__value_type = {} + end - def #{ var_name }=(value) - @#{ var_name } = value - end - EOS - self.send(var_name + '=', value) - rescue SyntaxError - var_name = safe_name(var_name) - retry + def [](name) + if @__members.include?(name) + self.__send__(name) + else + self.__send__(Object.safe_name(name)) end + end + + def []=(name, value) + if @__members.include?(name) + self.__send__(name + '=', value) + else + self.__send__(Object.safe_name(name) + '=', value) + end + end + def __set_property(name, value) + var_name = name + unless @__members.include?(name) + var_name = __define_attr_accessor(var_name) + end + __set_property_value(var_name, value) var_name end - def members - instance_variables.collect { |str| str[1..-1] } + def __members + @__members end - def [](name) - if self.respond_to?(name) - self.send(name) +private + + def __set_property_value(name, value) + org = self.__send__(name) + case @__value_type[name] + when :single + self.__send__(name + '=', [org, value]) + @__value_type[name] = :multi + when :multi + org << value else - self.send(safe_name(name)) + self.__send__(name + '=', value) + @__value_type[name] = :single end + value end - def []=(name, value) - if self.respond_to?(name) - self.send(name + '=', value) - else - self.send(safe_name(name) + '=', value) + def __define_attr_accessor(name) + var_name = name + begin + instance_eval <<-EOS + def #{ var_name } + @#{ var_name } + end + + def #{ var_name }=(value) + @#{ var_name } = value + end + EOS + rescue SyntaxError + var_name = Object.safe_name(var_name) + retry end + @__members << var_name + var_name end -private - - def safe_name(name) + def Object.safe_name(name) require 'md5' "var_" << MD5.new(name).hexdigest end @@ -309,7 +338,7 @@ class Registry def add(obj_class, soap_class, factory, info = nil) @map.add(obj_class, soap_class, factory, info) end - alias :set :add + alias set add # This mapping registry ignores type hint. def obj2soap(klass, obj, type_qname = nil) diff --git a/lib/soap/mapping/rubytypeFactory.rb b/lib/soap/mapping/rubytypeFactory.rb index f79bc78cc7..a46d93275f 100644 --- a/lib/soap/mapping/rubytypeFactory.rb +++ b/lib/soap/mapping/rubytypeFactory.rb @@ -38,7 +38,7 @@ class RubytypeFactory < Factory def obj2soap(soap_class, obj, info, map) param = nil case obj - when String + when ::String unless @allow_original_mapping return nil end @@ -47,7 +47,7 @@ class RubytypeFactory < Factory param.extraattr[RubyTypeName] = obj.class.name end addiv2soapattr(param, obj, map) - when Time + when ::Time unless @allow_original_mapping return nil end @@ -56,7 +56,7 @@ class RubytypeFactory < Factory param.extraattr[RubyTypeName] = obj.class.name end addiv2soapattr(param, obj, map) - when Array + when ::Array unless @allow_original_mapping return nil end @@ -65,19 +65,19 @@ class RubytypeFactory < Factory param.extraattr[RubyTypeName] = obj.class.name end addiv2soapattr(param, obj, map) - when NilClass + when ::NilClass unless @allow_original_mapping return nil end param = @basetype_factory.obj2soap(SOAPNil, obj, info, map) addiv2soapattr(param, obj, map) - when FalseClass, TrueClass + when ::FalseClass, ::TrueClass unless @allow_original_mapping return nil end param = @basetype_factory.obj2soap(SOAPBoolean, obj, info, map) addiv2soapattr(param, obj, map) - when Integer + when ::Integer unless @allow_original_mapping return nil end @@ -85,7 +85,7 @@ class RubytypeFactory < Factory param ||= @basetype_factory.obj2soap(SOAPInteger, obj, info, map) param ||= @basetype_factory.obj2soap(SOAPDecimal, obj, info, map) addiv2soapattr(param, obj, map) - when Float + when ::Float unless @allow_original_mapping return nil end @@ -94,7 +94,7 @@ class RubytypeFactory < Factory param.extraattr[RubyTypeName] = obj.class.name end addiv2soapattr(param, obj, map) - when Hash + when ::Hash unless @allow_original_mapping return nil end @@ -114,7 +114,7 @@ class RubytypeFactory < Factory end param.add('default', Mapping._obj2soap(obj.default, map)) addiv2soapattr(param, obj, map) - when Regexp + when ::Regexp unless @allow_original_mapping return nil end @@ -150,7 +150,7 @@ class RubytypeFactory < Factory end param.add('options', SOAPInt.new(options)) addiv2soapattr(param, obj, map) - when Range + when ::Range unless @allow_original_mapping return nil end @@ -163,29 +163,29 @@ class RubytypeFactory < Factory param.add('end', Mapping._obj2soap(obj.end, map)) param.add('exclude_end', SOAP::SOAPBoolean.new(obj.exclude_end?)) addiv2soapattr(param, obj, map) - when Class + when ::Class unless @allow_original_mapping return nil end if obj.to_s[0] == ?# - raise TypeError.new("Can't dump anonymous class #{ obj }.") + raise TypeError.new("can't dump anonymous class #{ obj }") end param = SOAPStruct.new(TYPE_CLASS) mark_marshalled_obj(obj, param) param.add('name', SOAPString.new(obj.name)) addiv2soapattr(param, obj, map) - when Module + when ::Module unless @allow_original_mapping return nil end if obj.to_s[0] == ?# - raise TypeError.new("Can't dump anonymous module #{ obj }.") + raise TypeError.new("can't dump anonymous module #{ obj }") end param = SOAPStruct.new(TYPE_MODULE) mark_marshalled_obj(obj, param) param.add('name', SOAPString.new(obj.name)) addiv2soapattr(param, obj, map) - when Symbol + when ::Symbol unless @allow_original_mapping return nil end @@ -193,28 +193,37 @@ class RubytypeFactory < Factory mark_marshalled_obj(obj, param) param.add('id', SOAPString.new(obj.id2name)) addiv2soapattr(param, obj, map) - when Struct + when ::Struct unless @allow_original_mapping - return nil - end - param = SOAPStruct.new(TYPE_STRUCT) - mark_marshalled_obj(obj, param) - param.add('type', ele_type = SOAPString.new(obj.class.to_s)) - ele_member = SOAPStruct.new - obj.members.each do |member| - ele_member.add(Mapping.name2elename(member), - Mapping._obj2soap(obj[member], map)) + # treat it as an user defined class. [ruby-talk:104980] + #param = unknownobj2soap(soap_class, obj, info, map) + param = SOAPStruct.new(XSD::AnyTypeName) + mark_marshalled_obj(obj, param) + obj.members.each do |member| + param.add(Mapping.name2elename(member), + Mapping._obj2soap(obj[member], map)) + end + else + param = SOAPStruct.new(TYPE_STRUCT) + mark_marshalled_obj(obj, param) + param.add('type', ele_type = SOAPString.new(obj.class.to_s)) + ele_member = SOAPStruct.new + obj.members.each do |member| + ele_member.add(Mapping.name2elename(member), + Mapping._obj2soap(obj[member], map)) + end + param.add('member', ele_member) + addiv2soapattr(param, obj, map) end - param.add('member', ele_member) - addiv2soapattr(param, obj, map) - when IO, Binding, Continuation, Data, Dir, File::Stat, MatchData, Method, - Proc, Thread, ThreadGroup # from 1.8: Process::Status, UnboundMethod + when ::IO, ::Binding, ::Continuation, ::Data, ::Dir, ::File::Stat, + ::MatchData, Method, ::Proc, ::Thread, ::ThreadGroup + # from 1.8: Process::Status, UnboundMethod return nil when ::SOAP::Mapping::Object param = SOAPStruct.new(XSD::AnyTypeName) mark_marshalled_obj(obj, param) addiv2soapattr(param, obj, map) - when Exception + when ::Exception typestr = Mapping.name2elename(obj.class.to_s) param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, typestr)) mark_marshalled_obj(obj, param) @@ -249,7 +258,7 @@ private def unknownobj2soap(soap_class, obj, info, map) if obj.class.name.empty? - raise TypeError.new("Can't dump anonymous class #{ obj }.") + raise TypeError.new("can't dump anonymous class #{ obj }") end singleton_class = class << obj; self; end if !singleton_methods_true(obj).empty? or @@ -369,7 +378,7 @@ private obj = klass.new mark_unmarshalled_obj(node, obj) node.each do |name, value| - obj.set_property(name, Mapping._soap2obj(value, map)) + obj.__set_property(name, Mapping._soap2obj(value, map)) end return true, obj else diff --git a/lib/soap/mapping/wsdlRegistry.rb b/lib/soap/mapping/wsdlRegistry.rb index 66d16c6f90..64f49f2265 100644 --- a/lib/soap/mapping/wsdlRegistry.rb +++ b/lib/soap/mapping/wsdlRegistry.rb @@ -18,10 +18,10 @@ module Mapping class WSDLRegistry include TraverseSupport - attr_reader :complextypes + attr_reader :definedtypes - def initialize(complextypes, config = {}) - @complextypes = complextypes + def initialize(definedtypes, config = {}) + @definedtypes = definedtypes @config = config @excn_handler_obj2soap = nil # For mapping AnyType element. @@ -37,27 +37,20 @@ class WSDLRegistry soap_obj = SOAPNil.new elsif obj.is_a?(XSD::NSDBase) soap_obj = soap2soap(obj, type_qname) - elsif (type = @complextypes[type_qname]) - case type.compoundtype - when :TYPE_STRUCT - soap_obj = struct2soap(obj, type_qname, type) - when :TYPE_ARRAY - soap_obj = array2soap(obj, type_qname, type) - end + 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 @@ -74,12 +67,12 @@ private def soap2soap(obj, type_qname) if obj.is_a?(SOAPBasetype) obj - elsif obj.is_a?(SOAPStruct) && (type = @complextypes[type_qname]) + 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 = @complextypes[type_qname]) + elsif obj.is_a?(SOAPArray) && (type = @definedtypes[type_qname]) soap_obj = obj contenttype = type.child_type mark_marshalled_obj(obj, soap_obj) @@ -92,6 +85,33 @@ private 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 |