Welcome to the "trac"-ing site of soap4r!
[soap4r] [httpclient] [openpgp4u] [pkcs1] [logger] [csv] [vtr]

root/branches/1_5/lib/soap/mapping/wsdlliteralregistry.rb

Revision 2015, 6.5 kB (checked in by nahi, 12 hours ago)
  • ruby-1.8.7 warning cleanups. closes #497.
  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision
Line 
1 # SOAP4R - WSDL literal mapping registry.
2 # Copyright (C) 2000-2007  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
3
4 # This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
5 # redistribute it and/or modify it under the same terms of Ruby's license;
6 # either the dual license version in 2003, or any later version.
7
8
9 require 'soap/baseData'
10 require 'soap/mapping/mapping'
11 require 'soap/mapping/literalregistry'
12 require 'soap/mapping/typeMap'
13 require 'xsd/codegen/gensupport'
14 require 'xsd/namedelements'
15
16
17 module SOAP
18 module Mapping
19
20
21 class WSDLLiteralRegistry < LiteralRegistry
22   attr_reader :definedelements
23   attr_reader :definedtypes
24
25   def initialize(definedtypes = XSD::NamedElements::Empty,
26       definedelements = XSD::NamedElements::Empty)
27     super()
28     @definedtypes = definedtypes
29     @definedelements = definedelements
30   end
31
32   def obj2soap(obj, qname, obj_class = nil)
33     soap_obj = nil
34     if obj.is_a?(SOAPElement)
35       soap_obj = obj
36     elsif eledef = @definedelements[qname]
37       soap_obj = obj2elesoap(obj, eledef)
38     elsif type = @definedtypes[qname]
39       soap_obj = obj2typesoap(obj, type)
40     else
41       soap_obj = any2soap(obj, qname, obj_class)
42     end
43     return soap_obj if soap_obj
44     if @excn_handler_obj2soap
45       soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj|
46         Mapping.obj2soap(yield_obj, nil, nil, MAPPING_OPT)
47       }
48       return soap_obj if soap_obj
49     end
50     raise MappingError.new("cannot map #{obj.class.name} as #{qname}")
51   end
52
53   # node should be a SOAPElement
54   def soap2obj(node, obj_class = nil)
55     cause = nil
56     begin
57       return any2obj(node, obj_class)
58     rescue MappingError
59       cause = $!
60     end
61     if @excn_handler_soap2obj
62       begin
63         return @excn_handler_soap2obj.call(node) { |yield_node|
64             Mapping.soap2obj(yield_node, nil, nil, MAPPING_OPT)
65           }
66       rescue Exception
67       end
68     end
69     if node.respond_to?(:type)
70       raise MappingError.new("cannot map #{node.type.name} to Ruby object", cause)
71     else
72       raise MappingError.new("cannot map #{node.elename.name} to Ruby object", cause)
73     end
74   end
75
76 private
77
78   def obj2elesoap(obj, eledef)
79     ele = nil
80     qualified = (eledef.elementform == 'qualified')
81     if obj.is_a?(SOAPNil)
82       ele = obj
83     elsif eledef.type
84       if type = @definedtypes[eledef.type]
85         ele = obj2typesoap(obj, type)
86       elsif type = TypeMap[eledef.type]
87         ele = base2soap(obj, type)
88       else
89         raise MappingError.new("cannot find type #{eledef.type}")
90       end
91     elsif eledef.local_complextype
92       ele = obj2typesoap(obj, eledef.local_complextype)
93     elsif eledef.local_simpletype
94       ele = obj2typesoap(obj, eledef.local_simpletype)
95     else
96       raise MappingError.new('illegal schema?')
97     end
98     ele.elename = eledef.name
99     ele.qualified = qualified
100     ele
101   end
102
103   def obj2typesoap(obj, type)
104     ele = nil
105     if type.is_a?(::WSDL::XMLSchema::SimpleType)
106       ele = simpleobj2soap(obj, type)
107     else # complexType
108       if type.simplecontent
109         ele = simpleobj2soap(obj, type.simplecontent)
110       else
111         ele = complexobj2soap(obj, type)
112       end
113       ele.type = type.name
114       if type.base or Mapping.root_type_hint
115         Mapping.reset_root_type_hint
116         ele.force_typed = true
117       end
118       add_definedattributes2soap(obj, ele, type)
119     end
120     ele
121   end
122
123   def simpleobj2soap(obj, type)
124     type.check_lexical_format(obj)
125     return SOAPNil.new if obj.nil?
126     if type.base
127       ele = base2soap(obj, TypeMap[type.base])
128     elsif type.list
129       value = obj.is_a?(Array) ? obj.join(" ") : obj.to_s
130       ele = base2soap(value, SOAP::SOAPString)
131     else
132       raise MappingError.new("unsupported simpleType: #{type}")
133     end
134     ele
135   end
136
137   def complexobj2soap(obj, type)
138     ele = SOAPElement.new(type.name)
139     complexobj2sequencesoap(obj, ele, type, type.choice?, type.choice?)
140     ele
141   end
142
143   def complexobj2sequencesoap(obj, soap, type, nillable, is_choice)
144     added = false
145     type.elements.each do |child_ele|
146       case child_ele
147       when WSDL::XMLSchema::Any
148         any = Mapping.get_attributes_for_any(obj)
149         SOAPElement.from_objs(any).each do |child|
150           soap.add(child)
151         end
152         ele_added = true
153       when WSDL::XMLSchema::Element
154         ele_added = complexobj2soapchildren(obj, soap, child_ele, nillable)
155       when WSDL::XMLSchema::Sequence
156         ele_added = complexobj2sequencesoap(obj, soap, child_ele, nillable, false)
157       when WSDL::XMLSchema::Choice
158         ele_added = complexobj2sequencesoap(obj, soap, child_ele, true, true)
159       else
160         raise MappingError.new("unknown type: #{child_ele}")
161       end
162       added = true if ele_added
163       break if is_choice and ele_added
164     end
165     added
166   end
167
168   def complexobj2soapchildren(obj, soap, child_ele, nillable = false)
169     if child_ele.map_as_array?
170       complexobj2soapchildren_array(obj, soap, child_ele, nillable)
171     else
172       complexobj2soapchildren_single(obj, soap, child_ele, nillable)
173     end
174   end
175
176   def complexobj2soapchildren_array(obj, soap, child_ele, nillable)
177     child = Mapping.get_attribute(obj, child_ele.name.name)
178     if child.nil? and obj.is_a?(::Array)
179       child = obj
180     end
181     if child.nil?
182       return false if nillable
183       if child_soap = nil2soap(child_ele)
184         soap.add(child_soap)
185         return true
186       else
187         return false
188       end
189     end
190     unless child.is_a?(::Array)
191       return false
192     end
193     child.each do |item|
194       if item.is_a?(SOAPElement)
195         soap.add(item)
196       else
197         child_soap = obj2elesoap(item, child_ele)
198         soap.add(child_soap)
199       end
200     end
201     true
202   end
203
204   def complexobj2soapchildren_single(obj, soap, child_ele, nillable)
205     child = Mapping.get_attribute(obj, child_ele.name.name)
206     case child
207     when NilClass
208       return false if nillable
209       if child_soap = nil2soap(child_ele)
210         soap.add(child_soap)
211         true
212       else
213         false
214       end
215     when SOAPElement
216       soap.add(child)
217       true
218     else
219       child_soap = obj2elesoap(child, child_ele)
220       soap.add(child_soap)
221       true
222     end
223   end
224
225   def nil2soap(ele)
226     if ele.nillable
227       obj2elesoap(nil, ele)     # add an empty element
228     elsif ele.minoccurs == 0
229       nil       # intends no element
230     else
231       warn("nil not allowed: #{ele.name.name}")
232       nil
233     end
234   end
235
236   def add_definedattributes2soap(obj, ele, typedef)
237     if typedef.attributes
238       typedef.attributes.each do |at|
239         value = get_xmlattr_value(obj, at.name)
240         ele.extraattr[at.name] = value unless value.nil?
241       end
242     end
243   end
244 end
245
246
247 end
248 end
Note: See TracBrowser for help on using the browser.