| Class | SOAP::Mapping::RubytypeFactory |
| In: |
lib/soap/mapping/rubytypeFactory.rb
|
| Parent: | Factory |
| TYPE_STRING | = | XSD::QName.new(RubyTypeNamespace, 'String') |
| TYPE_TIME | = | XSD::QName.new(RubyTypeNamespace, 'Time') |
| TYPE_ARRAY | = | XSD::QName.new(RubyTypeNamespace, 'Array') |
| TYPE_REGEXP | = | XSD::QName.new(RubyTypeNamespace, 'Regexp') |
| TYPE_RANGE | = | XSD::QName.new(RubyTypeNamespace, 'Range') |
| TYPE_CLASS | = | XSD::QName.new(RubyTypeNamespace, 'Class') |
| TYPE_MODULE | = | XSD::QName.new(RubyTypeNamespace, 'Module') |
| TYPE_SYMBOL | = | XSD::QName.new(RubyTypeNamespace, 'Symbol') |
| TYPE_STRUCT | = | XSD::QName.new(RubyTypeNamespace, 'Struct') |
| TYPE_HASH | = | XSD::QName.new(RubyTypeNamespace, 'Map') |
# File lib/soap/mapping/rubytypeFactory.rb, line 25
25: def initialize(config = {})
26: @config = config
27: @allow_untyped_struct = @config.key?(:allow_untyped_struct) ?
28: @config[:allow_untyped_struct] : true
29: @allow_original_mapping = @config.key?(:allow_original_mapping) ?
30: @config[:allow_original_mapping] : false
31: @string_factory = StringFactory_.new(true)
32: @basetype_factory = BasetypeFactory_.new(true)
33: @datetime_factory = DateTimeFactory_.new(true)
34: @array_factory = ArrayFactory_.new(true)
35: @hash_factory = HashFactory_.new(true)
36: end
# File lib/soap/mapping/rubytypeFactory.rb, line 38
38: def obj2soap(soap_class, obj, info, map)
39: param = nil
40: case obj
41: when ::String
42: unless @allow_original_mapping
43: return nil
44: end
45: param = @string_factory.obj2soap(SOAPString, obj, info, map)
46: if obj.class != String
47: param.extraattr[RubyTypeName] = obj.class.name
48: end
49: addiv2soapattr(param, obj, map)
50: when ::Time
51: unless @allow_original_mapping
52: return nil
53: end
54: param = @datetime_factory.obj2soap(SOAPDateTime, obj, info, map)
55: if obj.class != Time
56: param.extraattr[RubyTypeName] = obj.class.name
57: end
58: addiv2soapattr(param, obj, map)
59: when ::Array
60: unless @allow_original_mapping
61: return nil
62: end
63: param = @array_factory.obj2soap(nil, obj, info, map)
64: if obj.class != Array
65: param.extraattr[RubyTypeName] = obj.class.name
66: end
67: addiv2soapattr(param, obj, map)
68: when ::NilClass
69: unless @allow_original_mapping
70: return nil
71: end
72: param = @basetype_factory.obj2soap(SOAPNil, obj, info, map)
73: addiv2soapattr(param, obj, map)
74: when ::FalseClass, ::TrueClass
75: unless @allow_original_mapping
76: return nil
77: end
78: param = @basetype_factory.obj2soap(SOAPBoolean, obj, info, map)
79: addiv2soapattr(param, obj, map)
80: when ::Integer
81: unless @allow_original_mapping
82: return nil
83: end
84: param = @basetype_factory.obj2soap(SOAPInt, obj, info, map)
85: param ||= @basetype_factory.obj2soap(SOAPInteger, obj, info, map)
86: param ||= @basetype_factory.obj2soap(SOAPDecimal, obj, info, map)
87: addiv2soapattr(param, obj, map)
88: when ::Float
89: unless @allow_original_mapping
90: return nil
91: end
92: param = @basetype_factory.obj2soap(SOAPDouble, obj, info, map)
93: if obj.class != Float
94: param.extraattr[RubyTypeName] = obj.class.name
95: end
96: addiv2soapattr(param, obj, map)
97: when ::Hash
98: unless @allow_original_mapping
99: return nil
100: end
101: if obj.respond_to?(:default_proc) && obj.default_proc
102: raise TypeError.new("cannot dump hash with default proc")
103: end
104: param = SOAPStruct.new(TYPE_HASH)
105: mark_marshalled_obj(obj, param)
106: if obj.class != Hash
107: param.extraattr[RubyTypeName] = obj.class.name
108: end
109: obj.each do |key, value|
110: elem = SOAPStruct.new # Undefined type.
111: elem.add("key", Mapping._obj2soap(key, map))
112: elem.add("value", Mapping._obj2soap(value, map))
113: param.add("item", elem)
114: end
115: param.add('default', Mapping._obj2soap(obj.default, map))
116: addiv2soapattr(param, obj, map)
117: when ::Regexp
118: unless @allow_original_mapping
119: return nil
120: end
121: param = SOAPStruct.new(TYPE_REGEXP)
122: mark_marshalled_obj(obj, param)
123: if obj.class != Regexp
124: param.extraattr[RubyTypeName] = obj.class.name
125: end
126: param.add('source', SOAPBase64.new(obj.source))
127: if obj.respond_to?('options')
128: # Regexp#options is from Ruby/1.7
129: options = obj.options
130: else
131: options = 0
132: obj.inspect.sub(/^.*\//, '').each_byte do |c|
133: options += case c
134: when ?i
135: 1
136: when ?x
137: 2
138: when ?m
139: 4
140: when ?n
141: 16
142: when ?e
143: 32
144: when ?s
145: 48
146: when ?u
147: 64
148: end
149: end
150: end
151: param.add('options', SOAPInt.new(options))
152: addiv2soapattr(param, obj, map)
153: when ::Range
154: unless @allow_original_mapping
155: return nil
156: end
157: param = SOAPStruct.new(TYPE_RANGE)
158: mark_marshalled_obj(obj, param)
159: if obj.class != Range
160: param.extraattr[RubyTypeName] = obj.class.name
161: end
162: param.add('begin', Mapping._obj2soap(obj.begin, map))
163: param.add('end', Mapping._obj2soap(obj.end, map))
164: param.add('exclude_end', SOAP::SOAPBoolean.new(obj.exclude_end?))
165: addiv2soapattr(param, obj, map)
166: when ::Class
167: unless @allow_original_mapping
168: return nil
169: end
170: if obj.to_s[0] == ?#
171: raise TypeError.new("can't dump anonymous class #{obj}")
172: end
173: param = SOAPStruct.new(TYPE_CLASS)
174: mark_marshalled_obj(obj, param)
175: param.add('name', SOAPString.new(obj.name))
176: addiv2soapattr(param, obj, map)
177: when ::Module
178: unless @allow_original_mapping
179: return nil
180: end
181: if obj.to_s[0] == ?#
182: raise TypeError.new("can't dump anonymous module #{obj}")
183: end
184: param = SOAPStruct.new(TYPE_MODULE)
185: mark_marshalled_obj(obj, param)
186: param.add('name', SOAPString.new(obj.name))
187: addiv2soapattr(param, obj, map)
188: when ::Symbol
189: unless @allow_original_mapping
190: return nil
191: end
192: param = SOAPStruct.new(TYPE_SYMBOL)
193: mark_marshalled_obj(obj, param)
194: param.add('id', SOAPString.new(obj.id2name))
195: addiv2soapattr(param, obj, map)
196: when ::Struct
197: unless @allow_original_mapping
198: # treat it as an user defined class. [ruby-talk:104980]
199: #param = unknownobj2soap(soap_class, obj, info, map)
200: param = SOAPStruct.new(XSD::AnyTypeName)
201: mark_marshalled_obj(obj, param)
202: obj.members.each do |member|
203: param.add(Mapping.name2elename(member),
204: Mapping._obj2soap(obj[member], map))
205: end
206: else
207: param = SOAPStruct.new(TYPE_STRUCT)
208: mark_marshalled_obj(obj, param)
209: param.add('type', ele_type = SOAPString.new(obj.class.to_s))
210: ele_member = SOAPStruct.new
211: obj.members.each do |member|
212: ele_member.add(Mapping.name2elename(member),
213: Mapping._obj2soap(obj[member], map))
214: end
215: param.add('member', ele_member)
216: addiv2soapattr(param, obj, map)
217: end
218: when ::IO, ::Binding, ::Continuation, ::Data, ::Dir, ::File::Stat,
219: ::MatchData, Method, ::Proc, ::Thread, ::ThreadGroup
220: # from 1.8: Process::Status, UnboundMethod
221: return nil
222: when ::SOAP::Mapping::Object
223: param = SOAPStruct.new(XSD::AnyTypeName)
224: mark_marshalled_obj(obj, param)
225: obj.__xmlele.each do |key, value|
226: param.add(key.name, Mapping._obj2soap(value, map))
227: end
228: obj.__xmlattr.each do |key, value|
229: param.extraattr[key] = value
230: end
231: when ::Exception
232: typestr = Mapping.name2elename(obj.class.to_s)
233: param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, typestr))
234: mark_marshalled_obj(obj, param)
235: param.add('message', Mapping._obj2soap(obj.message, map))
236: param.add('backtrace', Mapping._obj2soap(obj.backtrace, map))
237: addiv2soapattr(param, obj, map)
238: else
239: param = unknownobj2soap(soap_class, obj, info, map)
240: end
241: param
242: end
# File lib/soap/mapping/rubytypeFactory.rb, line 244
244: def soap2obj(obj_class, node, info, map)
245: rubytype = node.extraattr[RubyTypeName]
246: if rubytype or node.type.namespace == RubyTypeNamespace
247: rubytype2obj(node, info, map, rubytype)
248: elsif node.type == XSD::AnyTypeName or node.type == XSD::AnySimpleTypeName
249: anytype2obj(node, info, map)
250: else
251: unknowntype2obj(node, info, map)
252: end
253: end
# File lib/soap/mapping/rubytypeFactory.rb, line 257
257: def addiv2soapattr(node, obj, map)
258: return if obj.instance_variables.empty?
259: ivars = SOAPStruct.new # Undefined type.
260: setiv2soap(ivars, obj, map)
261: node.extraattr[RubyIVarName] = ivars
262: end
# File lib/soap/mapping/rubytypeFactory.rb, line 377
377: def anytype2obj(node, info, map)
378: case node
379: when SOAPBasetype
380: return true, node.data
381: when SOAPStruct
382: klass = ::SOAP::Mapping::Object
383: obj = klass.new
384: mark_unmarshalled_obj(node, obj)
385: node.each do |name, value|
386: obj.__add_xmlele_value(XSD::QName.new(nil, name),
387: Mapping._soap2obj(value, map))
388: end
389: unless node.extraattr.empty?
390: obj.instance_variable_set('@__xmlattr', node.extraattr)
391: end
392: return true, obj
393: else
394: return false
395: end
396: end
Only creates empty array. Do String#replace it with real string.
# File lib/soap/mapping/rubytypeFactory.rb, line 457
457: def array2obj(node, map, rubytype)
458: klass = rubytype ? Mapping.class_from_name(rubytype) : Array
459: obj = Mapping.create_empty_object(klass)
460: mark_unmarshalled_obj(node, obj)
461: obj
462: end
# File lib/soap/mapping/rubytypeFactory.rb, line 446
446: def exception2obj(klass, node, map)
447: message = Mapping._soap2obj(node['message'], map)
448: backtrace = Mapping._soap2obj(node['backtrace'], map)
449: obj = Mapping.create_empty_object(klass)
450: obj = obj.exception(message)
451: mark_unmarshalled_obj(node, obj)
452: obj.set_backtrace(backtrace)
453: obj
454: end
# File lib/soap/mapping/rubytypeFactory.rb, line 295
295: def rubytype2obj(node, info, map, rubytype)
296: klass = rubytype ? Mapping.class_from_name(rubytype) : nil
297: obj = nil
298: case node
299: when SOAPString
300: return @string_factory.soap2obj(klass || String, node, info, map)
301: when SOAPDateTime
302: #return @datetime_factory.soap2obj(klass || Time, node, info, map)
303: klass ||= Time
304: t = node.to_time
305: arg = [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.usec]
306: obj = t.gmt? ? klass.gm(*arg) : klass.local(*arg)
307: mark_unmarshalled_obj(node, obj)
308: return true, obj
309: when SOAPArray
310: return @array_factory.soap2obj(klass || Array, node, info, map)
311: when SOAPNil, SOAPBoolean, SOAPInt, SOAPInteger, SOAPDecimal, SOAPDouble
312: return @basetype_factory.soap2obj(nil, node, info, map)
313: when SOAPStruct
314: return rubytypestruct2obj(node, info, map, rubytype)
315: else
316: raise
317: end
318: end
# File lib/soap/mapping/rubytypeFactory.rb, line 320
320: def rubytypestruct2obj(node, info, map, rubytype)
321: klass = rubytype ? Mapping.class_from_name(rubytype) : nil
322: obj = nil
323: case node.type
324: when TYPE_HASH
325: klass = rubytype ? Mapping.class_from_name(rubytype) : Hash
326: obj = Mapping.create_empty_object(klass)
327: mark_unmarshalled_obj(node, obj)
328: node.each do |key, value|
329: next unless key == 'item'
330: obj[Mapping._soap2obj(value['key'], map)] =
331: Mapping._soap2obj(value['value'], map)
332: end
333: if node.key?('default')
334: obj.default = Mapping._soap2obj(node['default'], map)
335: end
336: when TYPE_REGEXP
337: klass = rubytype ? Mapping.class_from_name(rubytype) : Regexp
338: obj = Mapping.create_empty_object(klass)
339: mark_unmarshalled_obj(node, obj)
340: source = node['source'].string
341: options = node['options'].data || 0
342: Regexp.instance_method(:initialize).bind(obj).call(source, options)
343: when TYPE_RANGE
344: klass = rubytype ? Mapping.class_from_name(rubytype) : Range
345: obj = Mapping.create_empty_object(klass)
346: mark_unmarshalled_obj(node, obj)
347: first = Mapping._soap2obj(node['begin'], map)
348: last = Mapping._soap2obj(node['end'], map)
349: exclude_end = node['exclude_end'].data
350: Range.instance_method(:initialize).bind(obj).call(first, last, exclude_end)
351: when TYPE_CLASS
352: obj = Mapping.class_from_name(node['name'].data)
353: when TYPE_MODULE
354: obj = Mapping.class_from_name(node['name'].data)
355: when TYPE_SYMBOL
356: obj = node['id'].data.intern
357: when TYPE_STRUCT
358: typestr = Mapping.elename2name(node['type'].data)
359: klass = Mapping.class_from_name(typestr)
360: if klass.nil?
361: return false
362: end
363: unless klass <= ::Struct
364: return false
365: end
366: obj = Mapping.create_empty_object(klass)
367: mark_unmarshalled_obj(node, obj)
368: node['member'].each do |name, value|
369: obj[Mapping.elename2name(name)] = Mapping._soap2obj(value, map)
370: end
371: else
372: return unknowntype2obj(node, info, map)
373: end
374: return true, obj
375: end
# File lib/soap/mapping/rubytypeFactory.rb, line 290
290: def singleton_methods_true(obj)
291: obj.singleton_methods
292: end
# File lib/soap/mapping/rubytypeFactory.rb, line 286
286: def singleton_methods_true(obj)
287: obj.singleton_methods(true)
288: end
Only creates empty string. Do String#replace it with real string.
# File lib/soap/mapping/rubytypeFactory.rb, line 465
465: def string2obj(node, map, rubytype)
466: klass = rubytype ? Mapping.class_from_name(rubytype) : String
467: obj = Mapping.create_empty_object(klass)
468: mark_unmarshalled_obj(node, obj)
469: obj
470: end
# File lib/soap/mapping/rubytypeFactory.rb, line 264
264: def unknownobj2soap(soap_class, obj, info, map)
265: if obj.class.name.empty?
266: raise TypeError.new("can't dump anonymous class #{obj}")
267: end
268: singleton_class = class << obj; self; end
269: if !singleton_methods_true(obj).empty? or
270: !singleton_class.instance_variables.empty?
271: raise TypeError.new("singleton can't be dumped #{obj}")
272: end
273: if !(singleton_class.ancestors - obj.class.ancestors).empty?
274: typestr = Mapping.name2elename(obj.class.to_s)
275: type = XSD::QName.new(RubyTypeNamespace, typestr)
276: else
277: type = Mapping.class2element(obj.class)
278: end
279: param = SOAPStruct.new(type)
280: mark_marshalled_obj(obj, param)
281: setiv2soap(param, obj, map)
282: param
283: end
# File lib/soap/mapping/rubytypeFactory.rb, line 417
417: def unknownstruct2obj(node, info, map)
418: unless node.type.name
419: return nil
420: end
421: typestr = Mapping.elename2name(node.type.name)
422: klass = Mapping.class_from_name(typestr)
423: if klass.nil? and @allow_untyped_struct
424: klass = Mapping.class_from_name(typestr, true) # lenient
425: end
426: if klass.nil?
427: return nil
428: end
429: if klass <= ::Exception
430: return exception2obj(klass, node, map)
431: end
432: klass_type = Mapping.class2qname(klass)
433: return nil unless node.type.match(klass_type)
434: obj = nil
435: begin
436: obj = Mapping.create_empty_object(klass)
437: rescue
438: # type name "data" tries Data.new which raises TypeError
439: nil
440: end
441: mark_unmarshalled_obj(node, obj)
442: setiv2obj(obj, node, map)
443: obj
444: end
# File lib/soap/mapping/rubytypeFactory.rb, line 398
398: def unknowntype2obj(node, info, map)
399: case node
400: when SOAPBasetype
401: return true, node.data
402: when SOAPArray
403: return @array_factory.soap2obj(Array, node, info, map)
404: when SOAPStruct
405: obj = unknownstruct2obj(node, info, map)
406: return true, obj if obj
407: if !@allow_untyped_struct
408: return false
409: end
410: return anytype2obj(node, info, map)
411: else
412: # Basetype which is not defined...
413: return false
414: end
415: end