| Class | SOAP::Mapping::WSDLLiteralRegistry |
| In: |
lib/soap/mapping/wsdlliteralregistry.rb
|
| Parent: | Registry |
| MAPPING_OPT | = | { :no_reference => true } |
| definedelements | [R] | |
| definedtypes | [R] | |
| excn_handler_obj2soap | [RW] | |
| excn_handler_soap2obj | [RW] |
# File lib/soap/mapping/wsdlliteralregistry.rb, line 26
26: def initialize(definedtypes = XSD::NamedElements::Empty,
27: definedelements = XSD::NamedElements::Empty)
28: @definedtypes = definedtypes
29: @definedelements = definedelements
30: @excn_handler_obj2soap = nil
31: @excn_handler_soap2obj = nil
32: @schema_element_cache = {}
33: @schema_attribute_cache = {}
34: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 36
36: def obj2soap(obj, qname)
37: soap_obj = nil
38: if ele = @definedelements[qname]
39: soap_obj = obj2elesoap(obj, ele)
40: elsif type = @definedtypes[qname]
41: soap_obj = obj2typesoap(obj, type, true)
42: else
43: soap_obj = any2soap(obj, qname)
44: end
45: return soap_obj if soap_obj
46: if @excn_handler_obj2soap
47: soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj|
48: Mapping.obj2soap(yield_obj, nil, nil, MAPPING_OPT)
49: }
50: return soap_obj if soap_obj
51: end
52: raise MappingError.new("cannot map #{obj.class.name} as #{qname}")
53: end
node should be a SOAPElement
# File lib/soap/mapping/wsdlliteralregistry.rb, line 56
56: def soap2obj(node, obj_class = nil)
57: # obj_class is given when rpc/literal service. but ignored for now.
58: begin
59: return any2obj(node)
60: rescue MappingError
61: end
62: if @excn_handler_soap2obj
63: begin
64: return @excn_handler_soap2obj.call(node) { |yield_node|
65: Mapping.soap2obj(yield_node, nil, nil, MAPPING_OPT)
66: }
67: rescue Exception
68: end
69: end
70: if node.respond_to?(:type)
71: raise MappingError.new("cannot map #{node.type.name} to Ruby object")
72: else
73: raise MappingError.new("cannot map #{node.elename.name} to Ruby object")
74: end
75: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 354
354: def add_attributes2plainobj(node, obj)
355: return if node.extraattr.empty?
356: define_xmlattr(obj)
357: node.extraattr.each do |qname, value|
358: obj.__xmlattr[qname] = value
359: define_xmlattr_accessor(obj, qname)
360: end
361: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 226
226: def add_attributes2soap(obj, ele)
227: attributes = schema_attribute_definition(obj.class)
228: if attributes
229: attributes.each do |qname, param|
230: attr = obj.__send__('xmlattr_' +
231: XSD::CodeGen::GenSupport.safevarname(qname.name))
232: ele.extraattr[qname] = attr
233: end
234: end
235: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 330
330: def add_attributes2stubobj(node, obj)
331: if attributes = schema_attribute_definition(obj.class)
332: define_xmlattr(obj)
333: attributes.each do |qname, class_name|
334: attr = node.extraattr[qname]
335: next if attr.nil? or attr.empty?
336: klass = Mapping.class_from_name(class_name)
337: if klass.ancestors.include?(::SOAP::SOAPBasetype)
338: child = klass.new(attr).data
339: else
340: child = attr
341: end
342: obj.__xmlattr[qname] = child
343: define_xmlattr_accessor(obj, qname)
344: end
345: end
346: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 348
348: def add_elements2plainobj(node, obj)
349: node.each do |name, value|
350: obj.__add_xmlele_value(value.elename, any2obj(value))
351: end
352: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 205
205: def add_elements2soap(obj, ele)
206: elements, as_array = schema_element_definition(obj.class)
207: if elements
208: elements.each do |elename, type|
209: if child = Mapping.get_attribute(obj, elename.name)
210: if as_array.include?(elename.name)
211: child.each do |item|
212: ele.add(obj2soap(item, elename))
213: end
214: else
215: ele.add(obj2soap(child, elename))
216: end
217: elsif obj.is_a?(::Array) and as_array.include?(elename.name)
218: obj.each do |item|
219: ele.add(obj2soap(item, elename))
220: end
221: end
222: end
223: end
224: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 289
289: def add_elements2stubobj(node, obj)
290: elements, as_array = schema_element_definition(obj.class)
291: vars = {}
292: node.each do |name, value|
293: item = elements.find { |k, v| k.name == name }
294: if item
295: elename, class_name = item
296: if klass = Mapping.class_from_name(class_name)
297: # klass must be a SOAPBasetype or a class
298: if klass.ancestors.include?(::SOAP::SOAPBasetype)
299: if value.respond_to?(:data)
300: child = klass.new(value.data).data
301: else
302: child = klass.new(nil).data
303: end
304: else
305: child = any2obj(value, klass)
306: end
307: elsif klass = Mapping.module_from_name(class_name)
308: # simpletype
309: if value.respond_to?(:data)
310: child = value.data
311: else
312: raise MappingError.new(
313: "cannot map to a module value: #{class_name}")
314: end
315: else
316: raise MappingError.new("unknown class/module: #{class_name}")
317: end
318: else # untyped element is treated as anyType.
319: child = any2obj(value)
320: end
321: if as_array.include?(elename.name)
322: (vars[name] ||= []) << child
323: else
324: vars[name] = child
325: end
326: end
327: Mapping.set_attributes(obj, vars)
328: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 258
258: def any2obj(node, obj_class = nil)
259: unless obj_class
260: typestr = XSD::CodeGen::GenSupport.safeconstname(node.elename.name)
261: obj_class = Mapping.class_from_name(typestr)
262: end
263: if obj_class and obj_class.class_variables.include?('@@schema_element')
264: soapele2stubobj(node, obj_class)
265: elsif node.is_a?(SOAPElement) or node.is_a?(SOAPStruct)
266: # SOAPArray for literal?
267: soapele2plainobj(node)
268: else
269: obj = Mapping.soap2obj(node, nil, obj_class, MAPPING_OPT)
270: add_attributes2plainobj(node, obj)
271: obj
272: end
273: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 148
148: def any2soap(obj, qname)
149: if obj.is_a?(SOAPElement)
150: obj
151: elsif obj.class.class_variables.include?('@@schema_element')
152: stubobj2soap(obj, qname)
153: elsif obj.is_a?(SOAP::Mapping::Object)
154: mappingobj2soap(obj, qname)
155: elsif obj.is_a?(Hash)
156: ele = SOAPElement.from_obj(obj)
157: ele.elename = qname
158: ele
159: else
160: # expected to be a basetype or an anyType.
161: # SOAPStruct, etc. is used instead of SOAPElement.
162: begin
163: ele = Mapping.obj2soap(obj, nil, nil, MAPPING_OPT)
164: ele.elename = qname
165: ele
166: rescue MappingError
167: ele = SOAPElement.new(qname, obj.to_s)
168: end
169: if obj.respond_to?(:__xmlattr)
170: obj.__xmlattr.each do |key, value|
171: ele.extraattr[key] = value
172: end
173: end
174: ele
175: end
176: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 249
249: def anytype2obj(node)
250: if node.is_a?(::SOAP::SOAPBasetype)
251: return node.data
252: end
253: klass = ::SOAP::Mapping::Object
254: obj = klass.new
255: obj
256: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 237
237: def base2soap(obj, type)
238: soap_obj = nil
239: if type <= XSD::XSDString
240: str = XSD::Charset.encoding_conv(obj.to_s,
241: Thread.current[:SOAPExternalCES], XSD::Charset.encoding)
242: soap_obj = type.new(str)
243: else
244: soap_obj = type.new(obj)
245: end
246: soap_obj
247: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 119
119: def complexobj2soap(obj, type, qualified)
120: o = SOAPElement.new(type.name)
121: o.qualified = qualified
122: type.each_element do |child_ele|
123: child = Mapping.get_attribute(obj, child_ele.name.name)
124: if child.nil?
125: if child_ele.nillable
126: # ToDo: test
127: # add empty element
128: child_soap = obj2elesoap(nil, child_ele)
129: o.add(child_soap)
130: elsif Integer(child_ele.minoccurs) == 0
131: # nothing to do
132: else
133: raise MappingError.new("nil not allowed: #{child_ele.name.name}")
134: end
135: elsif child_ele.map_as_array?
136: child.each do |item|
137: child_soap = obj2elesoap(item, child_ele)
138: o.add(child_soap)
139: end
140: else
141: child_soap = obj2elesoap(child, child_ele)
142: o.add(child_soap)
143: end
144: end
145: o
146: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 387
387: def define_xmlattr(obj)
388: obj.instance_variable_set('@__xmlattr', {})
389: unless obj.respond_to?(:__xmlattr)
390: Mapping.define_attr_accessor(obj, :__xmlattr, proc { @__xmlattr })
391: end
392: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 394
394: def define_xmlattr(obj)
395: obj.instance_variable_set('@__xmlattr', {})
396: unless obj.respond_to?(:__xmlattr)
397: obj.instance_eval "def __xmlattr\n@__xmlattr\nend\n"
398: end
399: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 371
371: def define_xmlattr_accessor(obj, qname)
372: name = XSD::CodeGen::GenSupport.safemethodname(qname.name)
373: obj.instance_eval "def \#{name}\n@__xmlattr[\#{qname.dump}]\nend\n\ndef \#{name}=(value)\n@__xmlattr[\#{qname.dump}] = value\nend\n"
374: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 364
364: def define_xmlattr_accessor(obj, qname)
365: name = XSD::CodeGen::GenSupport.safemethodname(qname.name)
366: Mapping.define_attr_accessor(obj, 'xmlattr_' + name,
367: proc { @__xmlattr[qname] },
368: proc { |value| @__xmlattr[qname] = value })
369: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 188
188: def mappingobj2soap(obj, qname)
189: ele = SOAPElement.new(qname)
190: obj.__xmlele.each do |key, value|
191: if value.is_a?(::Array)
192: value.each do |item|
193: ele.add(obj2soap(item, key))
194: end
195: else
196: ele.add(obj2soap(value, key))
197: end
198: end
199: obj.__xmlattr.each do |key, value|
200: ele.extraattr[key] = value
201: end
202: ele
203: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 81
81: def obj2elesoap(obj, ele)
82: o = nil
83: qualified = (ele.elementform == 'qualified')
84: if ele.type
85: if type = @definedtypes[ele.type]
86: o = obj2typesoap(obj, type, qualified)
87: elsif type = TypeMap[ele.type]
88: o = base2soap(obj, type)
89: else
90: raise MappingError.new("cannot find type #{ele.type}")
91: end
92: elsif ele.local_complextype
93: o = obj2typesoap(obj, ele.local_complextype, qualified)
94: add_attributes2soap(obj, o)
95: elsif ele.local_simpletype
96: o = obj2typesoap(obj, ele.local_simpletype, qualified)
97: else
98: raise MappingError.new('illegal schema?')
99: end
100: o.elename = ele.name
101: o
102: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 104
104: def obj2typesoap(obj, type, qualified)
105: if type.is_a?(::WSDL::XMLSchema::SimpleType)
106: simpleobj2soap(obj, type)
107: else
108: complexobj2soap(obj, type, qualified)
109: end
110: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 413
413: def schema_attribute_definition(klass)
414: @schema_attribute_cache[klass] ||= Mapping.schema_attribute_definition(klass)
415: end
it caches @@schema_element. this means that @@schema_element must not be changed while a lifetime of a WSDLLiteralRegistry.
# File lib/soap/mapping/wsdlliteralregistry.rb, line 409
409: def schema_element_definition(klass)
410: @schema_element_cache[klass] ||= Mapping.schema_element_definition(klass)
411: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 112
112: def simpleobj2soap(obj, type)
113: type.check_lexical_format(obj)
114: return SOAPNil.new if obj.nil? # ToDo: check nillable.
115: o = base2soap(obj, TypeMap[type.base])
116: o
117: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 282
282: def soapele2plainobj(node)
283: obj = anytype2obj(node)
284: add_elements2plainobj(node, obj)
285: add_attributes2plainobj(node, obj)
286: obj
287: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 275
275: def soapele2stubobj(node, obj_class)
276: obj = Mapping.create_empty_object(obj_class)
277: add_elements2stubobj(node, obj)
278: add_attributes2stubobj(node, obj)
279: obj
280: end
# File lib/soap/mapping/wsdlliteralregistry.rb, line 178
178: def stubobj2soap(obj, qname)
179: ele = SOAPElement.new(qname)
180: ele.qualified =
181: (obj.class.class_variables.include?('@@schema_qualified') and
182: obj.class.class_eval('@@schema_qualified'))
183: add_elements2soap(obj, ele)
184: add_attributes2soap(obj, ele)
185: ele
186: end