Class SOAP::Mapping::RubytypeFactory
In: lib/soap/mapping/rubytypeFactory.rb
Parent: Factory

Methods

Constants

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')

Public Class methods

[Source]

    # 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

Public Instance methods

[Source]

     # 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

[Source]

     # 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

Private Instance methods

[Source]

     # 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

[Source]

     # 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.

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # File lib/soap/mapping/rubytypeFactory.rb, line 290
290:     def singleton_methods_true(obj)
291:       obj.singleton_methods
292:     end

[Source]

     # 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.

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Validate]