reidiculous-actionwebservice 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. data/CHANGELOG +320 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +381 -0
  4. data/Rakefile +180 -0
  5. data/TODO +32 -0
  6. data/examples/googlesearch/autoloading/google_search_api.rb +50 -0
  7. data/examples/googlesearch/autoloading/google_search_controller.rb +57 -0
  8. data/examples/googlesearch/delegated/google_search_service.rb +108 -0
  9. data/examples/googlesearch/delegated/search_controller.rb +7 -0
  10. data/examples/googlesearch/direct/google_search_api.rb +50 -0
  11. data/examples/googlesearch/direct/search_controller.rb +58 -0
  12. data/examples/metaWeblog/apis/blogger_api.rb +60 -0
  13. data/examples/metaWeblog/apis/blogger_service.rb +34 -0
  14. data/examples/metaWeblog/apis/meta_weblog_api.rb +67 -0
  15. data/examples/metaWeblog/apis/meta_weblog_service.rb +48 -0
  16. data/examples/metaWeblog/controllers/xmlrpc_controller.rb +16 -0
  17. data/generators/web_service/USAGE +28 -0
  18. data/generators/web_service/templates/api_definition.rb +5 -0
  19. data/generators/web_service/templates/controller.rb +8 -0
  20. data/generators/web_service/templates/functional_test.rb +19 -0
  21. data/generators/web_service/web_service_generator.rb +29 -0
  22. data/lib/action_web_service.rb +71 -0
  23. data/lib/action_web_service/api.rb +297 -0
  24. data/lib/action_web_service/base.rb +38 -0
  25. data/lib/action_web_service/casting.rb +149 -0
  26. data/lib/action_web_service/client.rb +3 -0
  27. data/lib/action_web_service/client/base.rb +28 -0
  28. data/lib/action_web_service/client/soap_client.rb +113 -0
  29. data/lib/action_web_service/client/xmlrpc_client.rb +58 -0
  30. data/lib/action_web_service/container.rb +3 -0
  31. data/lib/action_web_service/container/action_controller_container.rb +93 -0
  32. data/lib/action_web_service/container/delegated_container.rb +86 -0
  33. data/lib/action_web_service/container/direct_container.rb +69 -0
  34. data/lib/action_web_service/dispatcher.rb +2 -0
  35. data/lib/action_web_service/dispatcher/abstract.rb +207 -0
  36. data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +379 -0
  37. data/lib/action_web_service/invocation.rb +202 -0
  38. data/lib/action_web_service/protocol.rb +4 -0
  39. data/lib/action_web_service/protocol/abstract.rb +115 -0
  40. data/lib/action_web_service/protocol/discovery.rb +37 -0
  41. data/lib/action_web_service/protocol/soap_protocol.rb +176 -0
  42. data/lib/action_web_service/protocol/soap_protocol/marshaler.rb +242 -0
  43. data/lib/action_web_service/protocol/xmlrpc_protocol.rb +122 -0
  44. data/lib/action_web_service/scaffolding.rb +281 -0
  45. data/lib/action_web_service/soap/attachment.rb +107 -0
  46. data/lib/action_web_service/soap/baseData.rb +942 -0
  47. data/lib/action_web_service/soap/element.rb +258 -0
  48. data/lib/action_web_service/soap/encodingstyle/aspDotNetHandler.rb +213 -0
  49. data/lib/action_web_service/soap/encodingstyle/handler.rb +100 -0
  50. data/lib/action_web_service/soap/encodingstyle/literalHandler.rb +226 -0
  51. data/lib/action_web_service/soap/encodingstyle/soapHandler.rb +582 -0
  52. data/lib/action_web_service/soap/generator.rb +268 -0
  53. data/lib/action_web_service/soap/header/handler.rb +57 -0
  54. data/lib/action_web_service/soap/header/handlerset.rb +70 -0
  55. data/lib/action_web_service/soap/header/simplehandler.rb +44 -0
  56. data/lib/action_web_service/soap/httpconfigloader.rb +119 -0
  57. data/lib/action_web_service/soap/mapping.rb +10 -0
  58. data/lib/action_web_service/soap/mapping/factory.rb +355 -0
  59. data/lib/action_web_service/soap/mapping/mapping.rb +381 -0
  60. data/lib/action_web_service/soap/mapping/registry.rb +541 -0
  61. data/lib/action_web_service/soap/mapping/rubytypeFactory.rb +475 -0
  62. data/lib/action_web_service/soap/mapping/typeMap.rb +50 -0
  63. data/lib/action_web_service/soap/mapping/wsdlencodedregistry.rb +280 -0
  64. data/lib/action_web_service/soap/mapping/wsdlliteralregistry.rb +418 -0
  65. data/lib/action_web_service/soap/marshal.rb +59 -0
  66. data/lib/action_web_service/soap/mimemessage.rb +240 -0
  67. data/lib/action_web_service/soap/netHttpClient.rb +190 -0
  68. data/lib/action_web_service/soap/parser.rb +251 -0
  69. data/lib/action_web_service/soap/processor.rb +66 -0
  70. data/lib/action_web_service/soap/property.rb +333 -0
  71. data/lib/action_web_service/soap/rpc/cgistub.rb +206 -0
  72. data/lib/action_web_service/soap/rpc/driver.rb +254 -0
  73. data/lib/action_web_service/soap/rpc/element.rb +325 -0
  74. data/lib/action_web_service/soap/rpc/httpserver.rb +129 -0
  75. data/lib/action_web_service/soap/rpc/proxy.rb +497 -0
  76. data/lib/action_web_service/soap/rpc/router.rb +594 -0
  77. data/lib/action_web_service/soap/rpc/rpc.rb +25 -0
  78. data/lib/action_web_service/soap/rpc/soaplet.rb +162 -0
  79. data/lib/action_web_service/soap/rpc/standaloneServer.rb +43 -0
  80. data/lib/action_web_service/soap/soap.rb +140 -0
  81. data/lib/action_web_service/soap/streamHandler.rb +229 -0
  82. data/lib/action_web_service/soap/wsdlDriver.rb +575 -0
  83. data/lib/action_web_service/struct.rb +64 -0
  84. data/lib/action_web_service/support/class_inheritable_options.rb +28 -0
  85. data/lib/action_web_service/support/signature_types.rb +227 -0
  86. data/lib/action_web_service/test_invoke.rb +110 -0
  87. data/lib/action_web_service/version.rb +9 -0
  88. data/lib/action_web_service/wsdl/binding.rb +65 -0
  89. data/lib/action_web_service/wsdl/data.rb +64 -0
  90. data/lib/action_web_service/wsdl/definitions.rb +250 -0
  91. data/lib/action_web_service/wsdl/documentation.rb +32 -0
  92. data/lib/action_web_service/wsdl/import.rb +80 -0
  93. data/lib/action_web_service/wsdl/importer.rb +38 -0
  94. data/lib/action_web_service/wsdl/info.rb +39 -0
  95. data/lib/action_web_service/wsdl/message.rb +54 -0
  96. data/lib/action_web_service/wsdl/operation.rb +130 -0
  97. data/lib/action_web_service/wsdl/operationBinding.rb +108 -0
  98. data/lib/action_web_service/wsdl/param.rb +85 -0
  99. data/lib/action_web_service/wsdl/parser.rb +163 -0
  100. data/lib/action_web_service/wsdl/part.rb +52 -0
  101. data/lib/action_web_service/wsdl/port.rb +84 -0
  102. data/lib/action_web_service/wsdl/portType.rb +73 -0
  103. data/lib/action_web_service/wsdl/service.rb +61 -0
  104. data/lib/action_web_service/wsdl/soap/address.rb +40 -0
  105. data/lib/action_web_service/wsdl/soap/binding.rb +49 -0
  106. data/lib/action_web_service/wsdl/soap/body.rb +56 -0
  107. data/lib/action_web_service/wsdl/soap/cgiStubCreator.rb +76 -0
  108. data/lib/action_web_service/wsdl/soap/classDefCreator.rb +314 -0
  109. data/lib/action_web_service/wsdl/soap/classDefCreatorSupport.rb +126 -0
  110. data/lib/action_web_service/wsdl/soap/clientSkeltonCreator.rb +78 -0
  111. data/lib/action_web_service/wsdl/soap/complexType.rb +161 -0
  112. data/lib/action_web_service/wsdl/soap/data.rb +42 -0
  113. data/lib/action_web_service/wsdl/soap/definitions.rb +149 -0
  114. data/lib/action_web_service/wsdl/soap/driverCreator.rb +95 -0
  115. data/lib/action_web_service/wsdl/soap/element.rb +28 -0
  116. data/lib/action_web_service/wsdl/soap/fault.rb +56 -0
  117. data/lib/action_web_service/wsdl/soap/header.rb +86 -0
  118. data/lib/action_web_service/wsdl/soap/headerfault.rb +56 -0
  119. data/lib/action_web_service/wsdl/soap/mappingRegistryCreator.rb +92 -0
  120. data/lib/action_web_service/wsdl/soap/methodDefCreator.rb +228 -0
  121. data/lib/action_web_service/wsdl/soap/operation.rb +122 -0
  122. data/lib/action_web_service/wsdl/soap/servantSkeltonCreator.rb +67 -0
  123. data/lib/action_web_service/wsdl/soap/standaloneServerStubCreator.rb +85 -0
  124. data/lib/action_web_service/wsdl/soap/wsdl2ruby.rb +176 -0
  125. data/lib/action_web_service/wsdl/types.rb +43 -0
  126. data/lib/action_web_service/wsdl/wsdl.rb +23 -0
  127. data/lib/action_web_service/wsdl/xmlSchema/all.rb +69 -0
  128. data/lib/action_web_service/wsdl/xmlSchema/annotation.rb +34 -0
  129. data/lib/action_web_service/wsdl/xmlSchema/any.rb +56 -0
  130. data/lib/action_web_service/wsdl/xmlSchema/attribute.rb +127 -0
  131. data/lib/action_web_service/wsdl/xmlSchema/choice.rb +69 -0
  132. data/lib/action_web_service/wsdl/xmlSchema/complexContent.rb +92 -0
  133. data/lib/action_web_service/wsdl/xmlSchema/complexType.rb +139 -0
  134. data/lib/action_web_service/wsdl/xmlSchema/content.rb +96 -0
  135. data/lib/action_web_service/wsdl/xmlSchema/data.rb +80 -0
  136. data/lib/action_web_service/wsdl/xmlSchema/element.rb +154 -0
  137. data/lib/action_web_service/wsdl/xmlSchema/enumeration.rb +36 -0
  138. data/lib/action_web_service/wsdl/xmlSchema/import.rb +65 -0
  139. data/lib/action_web_service/wsdl/xmlSchema/importer.rb +87 -0
  140. data/lib/action_web_service/wsdl/xmlSchema/include.rb +54 -0
  141. data/lib/action_web_service/wsdl/xmlSchema/length.rb +35 -0
  142. data/lib/action_web_service/wsdl/xmlSchema/parser.rb +166 -0
  143. data/lib/action_web_service/wsdl/xmlSchema/pattern.rb +36 -0
  144. data/lib/action_web_service/wsdl/xmlSchema/schema.rb +143 -0
  145. data/lib/action_web_service/wsdl/xmlSchema/sequence.rb +69 -0
  146. data/lib/action_web_service/wsdl/xmlSchema/simpleContent.rb +65 -0
  147. data/lib/action_web_service/wsdl/xmlSchema/simpleExtension.rb +54 -0
  148. data/lib/action_web_service/wsdl/xmlSchema/simpleRestriction.rb +73 -0
  149. data/lib/action_web_service/wsdl/xmlSchema/simpleType.rb +73 -0
  150. data/lib/action_web_service/wsdl/xmlSchema/unique.rb +34 -0
  151. data/lib/action_web_service/wsdl/xmlSchema/xsd2ruby.rb +107 -0
  152. data/lib/action_web_service/xsd/charset.rb +187 -0
  153. data/lib/action_web_service/xsd/codegen.rb +12 -0
  154. data/lib/action_web_service/xsd/codegen/classdef.rb +203 -0
  155. data/lib/action_web_service/xsd/codegen/commentdef.rb +34 -0
  156. data/lib/action_web_service/xsd/codegen/gensupport.rb +166 -0
  157. data/lib/action_web_service/xsd/codegen/methoddef.rb +63 -0
  158. data/lib/action_web_service/xsd/codegen/moduledef.rb +191 -0
  159. data/lib/action_web_service/xsd/datatypes.rb +1269 -0
  160. data/lib/action_web_service/xsd/datatypes1999.rb +20 -0
  161. data/lib/action_web_service/xsd/iconvcharset.rb +33 -0
  162. data/lib/action_web_service/xsd/mapping.rb +42 -0
  163. data/lib/action_web_service/xsd/namedelements.rb +95 -0
  164. data/lib/action_web_service/xsd/ns.rb +140 -0
  165. data/lib/action_web_service/xsd/qname.rb +78 -0
  166. data/lib/action_web_service/xsd/xmlparser.rb +61 -0
  167. data/lib/action_web_service/xsd/xmlparser/parser.rb +96 -0
  168. data/lib/action_web_service/xsd/xmlparser/rexmlparser.rb +54 -0
  169. data/lib/action_web_service/xsd/xmlparser/xmlparser.rb +50 -0
  170. data/lib/action_web_service/xsd/xmlparser/xmlscanner.rb +147 -0
  171. data/lib/actionwebservice.rb +1 -0
  172. data/setup.rb +1379 -0
  173. data/test/abstract_client.rb +183 -0
  174. data/test/abstract_dispatcher.rb +548 -0
  175. data/test/abstract_unit.rb +45 -0
  176. data/test/api_test.rb +103 -0
  177. data/test/apis/auto_load_api.rb +3 -0
  178. data/test/apis/broken_auto_load_api.rb +2 -0
  179. data/test/base_test.rb +42 -0
  180. data/test/casting_test.rb +95 -0
  181. data/test/client_soap_test.rb +156 -0
  182. data/test/client_xmlrpc_test.rb +153 -0
  183. data/test/container_test.rb +73 -0
  184. data/test/dispatcher_action_controller_soap_test.rb +139 -0
  185. data/test/dispatcher_action_controller_xmlrpc_test.rb +59 -0
  186. data/test/fixtures/db_definitions/mysql.sql +8 -0
  187. data/test/fixtures/db_definitions/sqlite3.sql +8 -0
  188. data/test/fixtures/users.yml +12 -0
  189. data/test/gencov +3 -0
  190. data/test/invocation_test.rb +185 -0
  191. data/test/run +6 -0
  192. data/test/scaffolded_controller_test.rb +146 -0
  193. data/test/struct_test.rb +52 -0
  194. data/test/test_invoke_test.rb +112 -0
  195. metadata +281 -0
@@ -0,0 +1,10 @@
1
+ # SOAP4R - Ruby type mapping utility.
2
+ # Copyright (C) 2003 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 'action_web_service/soap/mapping/mapping'
10
+ require 'action_web_service/soap/mapping/registry'
@@ -0,0 +1,355 @@
1
+ # SOAP4R - Mapping factory.
2
+ # Copyright (C) 2000, 2001, 2002, 2003 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
+ module SOAP
10
+ module Mapping
11
+
12
+
13
+ class Factory
14
+ include TraverseSupport
15
+
16
+ def initialize
17
+ # nothing to do
18
+ end
19
+
20
+ def obj2soap(soap_class, obj, info, map)
21
+ raise NotImplementError.new
22
+ # return soap_obj
23
+ end
24
+
25
+ def soap2obj(obj_class, node, info, map)
26
+ raise NotImplementError.new
27
+ # return convert_succeeded_or_not, obj
28
+ end
29
+
30
+ def setiv2obj(obj, node, map)
31
+ return if node.nil?
32
+ if obj.is_a?(Array)
33
+ setiv2ary(obj, node, map)
34
+ else
35
+ setiv2struct(obj, node, map)
36
+ end
37
+ end
38
+
39
+ def setiv2soap(node, obj, map)
40
+ if obj.class.class_variables.include?('@@schema_element')
41
+ obj.class.class_eval('@@schema_element').each do |name, info|
42
+ type, qname = info
43
+ if qname
44
+ elename = qname.name
45
+ else
46
+ elename = Mapping.name2elename(name)
47
+ end
48
+ node.add(elename,
49
+ Mapping._obj2soap(obj.instance_variable_get('@' + name), map))
50
+ end
51
+ else
52
+ # should we sort instance_variables?
53
+ obj.instance_variables.each do |var|
54
+ name = var.sub(/^@/, '')
55
+ elename = Mapping.name2elename(name)
56
+ node.add(elename,
57
+ Mapping._obj2soap(obj.instance_variable_get(var), map))
58
+ end
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def setiv2ary(obj, node, map)
65
+ node.each do |name, value|
66
+ Array.instance_method(:<<).bind(obj).call(Mapping._soap2obj(value, map))
67
+ end
68
+ end
69
+
70
+ def setiv2struct(obj, node, map)
71
+ vars = {}
72
+ node.each do |name, value|
73
+ vars[Mapping.elename2name(name)] = Mapping._soap2obj(value, map)
74
+ end
75
+ Mapping.set_attributes(obj, vars)
76
+ end
77
+ end
78
+
79
+ class StringFactory_ < Factory
80
+ def initialize(allow_original_mapping = false)
81
+ super()
82
+ @allow_original_mapping = allow_original_mapping
83
+ end
84
+
85
+ def obj2soap(soap_class, obj, info, map)
86
+ if !@allow_original_mapping and !obj.instance_variables.empty?
87
+ return nil
88
+ end
89
+ begin
90
+ unless XSD::Charset.is_ces(obj, Thread.current[:SOAPExternalCES])
91
+ return nil
92
+ end
93
+ encoded = XSD::Charset.encoding_conv(obj,
94
+ Thread.current[:SOAPExternalCES], XSD::Charset.encoding)
95
+ soap_obj = soap_class.new(encoded)
96
+ rescue XSD::ValueSpaceError
97
+ return nil
98
+ end
99
+ mark_marshalled_obj(obj, soap_obj)
100
+ soap_obj
101
+ end
102
+
103
+ def soap2obj(obj_class, node, info, map)
104
+ obj = Mapping.create_empty_object(obj_class)
105
+ decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding,
106
+ Thread.current[:SOAPExternalCES])
107
+ obj.replace(decoded)
108
+ mark_unmarshalled_obj(node, obj)
109
+ return true, obj
110
+ end
111
+ end
112
+
113
+ class BasetypeFactory_ < Factory
114
+ def initialize(allow_original_mapping = false)
115
+ super()
116
+ @allow_original_mapping = allow_original_mapping
117
+ end
118
+
119
+ def obj2soap(soap_class, obj, info, map)
120
+ if !@allow_original_mapping and !obj.instance_variables.empty?
121
+ return nil
122
+ end
123
+ soap_obj = nil
124
+ begin
125
+ soap_obj = soap_class.new(obj)
126
+ rescue XSD::ValueSpaceError
127
+ return nil
128
+ end
129
+ if @allow_original_mapping
130
+ # Basetype except String should not be multiref-ed in SOAP/1.1.
131
+ mark_marshalled_obj(obj, soap_obj)
132
+ end
133
+ soap_obj
134
+ end
135
+
136
+ def soap2obj(obj_class, node, info, map)
137
+ obj = node.data
138
+ mark_unmarshalled_obj(node, obj)
139
+ return true, obj
140
+ end
141
+ end
142
+
143
+ class DateTimeFactory_ < Factory
144
+ def initialize(allow_original_mapping = false)
145
+ super()
146
+ @allow_original_mapping = allow_original_mapping
147
+ end
148
+
149
+ def obj2soap(soap_class, obj, info, map)
150
+ if !@allow_original_mapping and
151
+ Time === obj and !obj.instance_variables.empty?
152
+ return nil
153
+ end
154
+ soap_obj = nil
155
+ begin
156
+ soap_obj = soap_class.new(obj)
157
+ rescue XSD::ValueSpaceError
158
+ return nil
159
+ end
160
+ mark_marshalled_obj(obj, soap_obj)
161
+ soap_obj
162
+ end
163
+
164
+ def soap2obj(obj_class, node, info, map)
165
+ if node.respond_to?(:to_obj)
166
+ obj = node.to_obj(obj_class)
167
+ return false if obj.nil?
168
+ mark_unmarshalled_obj(node, obj)
169
+ return true, obj
170
+ else
171
+ return false
172
+ end
173
+ end
174
+ end
175
+
176
+ class Base64Factory_ < Factory
177
+ def obj2soap(soap_class, obj, info, map)
178
+ return nil unless obj.instance_variables.empty?
179
+ soap_obj = soap_class.new(obj)
180
+ mark_marshalled_obj(obj, soap_obj) if soap_obj
181
+ soap_obj
182
+ end
183
+
184
+ def soap2obj(obj_class, node, info, map)
185
+ obj = node.string
186
+ mark_unmarshalled_obj(node, obj)
187
+ return true, obj
188
+ end
189
+ end
190
+
191
+ class URIFactory_ < Factory
192
+ def obj2soap(soap_class, obj, info, map)
193
+ soap_obj = soap_class.new(obj)
194
+ mark_marshalled_obj(obj, soap_obj) if soap_obj
195
+ soap_obj
196
+ end
197
+
198
+ def soap2obj(obj_class, node, info, map)
199
+ obj = node.data
200
+ mark_unmarshalled_obj(node, obj)
201
+ return true, obj
202
+ end
203
+ end
204
+
205
+ class ArrayFactory_ < Factory
206
+ def initialize(allow_original_mapping = false)
207
+ super()
208
+ @allow_original_mapping = allow_original_mapping
209
+ end
210
+
211
+ # [[1], [2]] is converted to Array of Array, not 2-D Array.
212
+ # To create M-D Array, you must call Mapping.ary2md.
213
+ def obj2soap(soap_class, obj, info, map)
214
+ if !@allow_original_mapping and !obj.instance_variables.empty?
215
+ return nil
216
+ end
217
+ arytype = Mapping.obj2element(obj)
218
+ if arytype.name
219
+ arytype.namespace ||= RubyTypeNamespace
220
+ else
221
+ arytype = XSD::AnyTypeName
222
+ end
223
+ soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)
224
+ mark_marshalled_obj(obj, soap_obj)
225
+ obj.each do |item|
226
+ soap_obj.add(Mapping._obj2soap(item, map))
227
+ end
228
+ soap_obj
229
+ end
230
+
231
+ def soap2obj(obj_class, node, info, map)
232
+ obj = Mapping.create_empty_object(obj_class)
233
+ mark_unmarshalled_obj(node, obj)
234
+ node.soap2array(obj) do |elem|
235
+ elem ? Mapping._soap2obj(elem, map) : nil
236
+ end
237
+ return true, obj
238
+ end
239
+ end
240
+
241
+ class TypedArrayFactory_ < Factory
242
+ def initialize(allow_original_mapping = false)
243
+ super()
244
+ @allow_original_mapping = allow_original_mapping
245
+ end
246
+
247
+ def obj2soap(soap_class, obj, info, map)
248
+ if !@allow_original_mapping and !obj.instance_variables.empty?
249
+ return nil
250
+ end
251
+ arytype = info[:type] || info[0]
252
+ soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)
253
+ mark_marshalled_obj(obj, soap_obj)
254
+ obj.each do |var|
255
+ soap_obj.add(Mapping._obj2soap(var, map))
256
+ end
257
+ soap_obj
258
+ end
259
+
260
+ def soap2obj(obj_class, node, info, map)
261
+ if node.rank > 1
262
+ return false
263
+ end
264
+ arytype = info[:type] || info[0]
265
+ unless node.arytype == arytype
266
+ return false
267
+ end
268
+ obj = Mapping.create_empty_object(obj_class)
269
+ mark_unmarshalled_obj(node, obj)
270
+ node.soap2array(obj) do |elem|
271
+ elem ? Mapping._soap2obj(elem, map) : nil
272
+ end
273
+ return true, obj
274
+ end
275
+ end
276
+
277
+ class TypedStructFactory_ < Factory
278
+ def obj2soap(soap_class, obj, info, map)
279
+ type = info[:type] || info[0]
280
+ soap_obj = soap_class.new(type)
281
+ mark_marshalled_obj(obj, soap_obj)
282
+ if obj.class <= SOAP::Marshallable
283
+ setiv2soap(soap_obj, obj, map)
284
+ else
285
+ setiv2soap(soap_obj, obj, map)
286
+ end
287
+ soap_obj
288
+ end
289
+
290
+ def soap2obj(obj_class, node, info, map)
291
+ type = info[:type] || info[0]
292
+ unless node.type == type
293
+ return false
294
+ end
295
+ obj = Mapping.create_empty_object(obj_class)
296
+ mark_unmarshalled_obj(node, obj)
297
+ setiv2obj(obj, node, map)
298
+ return true, obj
299
+ end
300
+ end
301
+
302
+ MapQName = XSD::QName.new(ApacheSOAPTypeNamespace, 'Map')
303
+ class HashFactory_ < Factory
304
+ def initialize(allow_original_mapping = false)
305
+ super()
306
+ @allow_original_mapping = allow_original_mapping
307
+ end
308
+
309
+ def obj2soap(soap_class, obj, info, map)
310
+ if !@allow_original_mapping and !obj.instance_variables.empty?
311
+ return nil
312
+ end
313
+ if !obj.default.nil? or
314
+ (obj.respond_to?(:default_proc) and obj.default_proc)
315
+ return nil
316
+ end
317
+ soap_obj = SOAPStruct.new(MapQName)
318
+ mark_marshalled_obj(obj, soap_obj)
319
+ obj.each do |key, value|
320
+ elem = SOAPStruct.new
321
+ elem.add("key", Mapping._obj2soap(key, map))
322
+ elem.add("value", Mapping._obj2soap(value, map))
323
+ # ApacheAxis allows only 'item' here.
324
+ soap_obj.add("item", elem)
325
+ end
326
+ soap_obj
327
+ end
328
+
329
+ def soap2obj(obj_class, node, info, map)
330
+ unless node.type == MapQName
331
+ return false
332
+ end
333
+ if node.class == SOAPStruct and node.key?('default')
334
+ return false
335
+ end
336
+ obj = Mapping.create_empty_object(obj_class)
337
+ mark_unmarshalled_obj(node, obj)
338
+ if node.class == SOAPStruct
339
+ node.each do |key, value|
340
+ obj[Mapping._soap2obj(value['key'], map)] =
341
+ Mapping._soap2obj(value['value'], map)
342
+ end
343
+ else
344
+ node.each do |value|
345
+ obj[Mapping._soap2obj(value['key'], map)] =
346
+ Mapping._soap2obj(value['value'], map)
347
+ end
348
+ end
349
+ return true, obj
350
+ end
351
+ end
352
+
353
+
354
+ end
355
+ end
@@ -0,0 +1,381 @@
1
+ # SOAP4R - Ruby type mapping utility.
2
+ # Copyright (C) 2000, 2001, 2003-2005 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 'action_web_service/xsd/codegen/gensupport'
10
+
11
+
12
+ module SOAP
13
+
14
+
15
+ module Mapping
16
+ RubyTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/1.6'
17
+ RubyTypeInstanceNamespace =
18
+ 'http://www.ruby-lang.org/xmlns/ruby/type-instance'
19
+ RubyCustomTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/custom'
20
+ ApacheSOAPTypeNamespace = 'http://xml.apache.org/xml-soap'
21
+
22
+
23
+ # TraverseSupport breaks following thread variables.
24
+ # Thread.current[:SOAPMarshalDataKey]
25
+ module TraverseSupport
26
+ def mark_marshalled_obj(obj, soap_obj)
27
+ raise if obj.nil?
28
+ Thread.current[:SOAPMarshalDataKey][obj.__id__] = soap_obj
29
+ end
30
+
31
+ def mark_unmarshalled_obj(node, obj)
32
+ return if obj.nil?
33
+ # node.id is not Object#id but SOAPReference#id
34
+ Thread.current[:SOAPMarshalDataKey][node.id] = obj
35
+ end
36
+ end
37
+
38
+
39
+ EMPTY_OPT = {}
40
+ def self.obj2soap(obj, registry = nil, type = nil, opt = EMPTY_OPT)
41
+ registry ||= Mapping::DefaultRegistry
42
+ soap_obj = nil
43
+ protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
44
+ Thread.current[:SOAPMarshalDataKey] = {}
45
+ Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
46
+ Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
47
+ soap_obj = _obj2soap(obj, registry, type)
48
+ end
49
+ soap_obj
50
+ end
51
+
52
+ def self.soap2obj(node, registry = nil, klass = nil, opt = EMPTY_OPT)
53
+ registry ||= Mapping::DefaultRegistry
54
+ obj = nil
55
+ protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
56
+ Thread.current[:SOAPMarshalDataKey] = {}
57
+ Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
58
+ Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
59
+ obj = _soap2obj(node, registry, klass)
60
+ end
61
+ obj
62
+ end
63
+
64
+ def self.ary2soap(ary, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT)
65
+ registry ||= Mapping::DefaultRegistry
66
+ type = XSD::QName.new(type_ns, typename)
67
+ soap_ary = SOAPArray.new(ValueArrayName, 1, type)
68
+ protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
69
+ Thread.current[:SOAPMarshalDataKey] = {}
70
+ Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
71
+ Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
72
+ ary.each do |ele|
73
+ soap_ary.add(_obj2soap(ele, registry, type))
74
+ end
75
+ end
76
+ soap_ary
77
+ end
78
+
79
+ def self.ary2md(ary, rank, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT)
80
+ registry ||= Mapping::DefaultRegistry
81
+ type = XSD::QName.new(type_ns, typename)
82
+ md_ary = SOAPArray.new(ValueArrayName, rank, type)
83
+ protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do
84
+ Thread.current[:SOAPMarshalDataKey] = {}
85
+ Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE
86
+ Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]
87
+ add_md_ary(md_ary, ary, [], registry)
88
+ end
89
+ md_ary
90
+ end
91
+
92
+ def self.fault2exception(fault, registry = nil)
93
+ registry ||= Mapping::DefaultRegistry
94
+ detail = if fault.detail
95
+ soap2obj(fault.detail, registry) || ""
96
+ else
97
+ ""
98
+ end
99
+ if detail.is_a?(Mapping::SOAPException)
100
+ begin
101
+ e = detail.to_e
102
+ remote_backtrace = e.backtrace
103
+ e.set_backtrace(nil)
104
+ raise e # ruby sets current caller as local backtrace of e => e2.
105
+ rescue Exception => e
106
+ e.set_backtrace(remote_backtrace + e.backtrace[1..-1])
107
+ raise
108
+ end
109
+ else
110
+ fault.detail = detail
111
+ fault.set_backtrace(
112
+ if detail.is_a?(Array)
113
+ detail
114
+ else
115
+ [detail.to_s]
116
+ end
117
+ )
118
+ raise
119
+ end
120
+ end
121
+
122
+ def self._obj2soap(obj, registry, type = nil)
123
+ if referent = Thread.current[:SOAPMarshalDataKey][obj.__id__] and
124
+ !Thread.current[:SOAPMarshalNoReference]
125
+ SOAPReference.new(referent)
126
+ elsif registry
127
+ registry.obj2soap(obj, type)
128
+ else
129
+ raise MappingError.new("no mapping registry given")
130
+ end
131
+ end
132
+
133
+ def self._soap2obj(node, registry, klass = nil)
134
+ if node.nil?
135
+ return nil
136
+ elsif node.is_a?(SOAPReference)
137
+ target = node.__getobj__
138
+ # target.id is not Object#id but SOAPReference#id
139
+ if referent = Thread.current[:SOAPMarshalDataKey][target.id] and
140
+ !Thread.current[:SOAPMarshalNoReference]
141
+ return referent
142
+ else
143
+ return _soap2obj(target, registry, klass)
144
+ end
145
+ end
146
+ return registry.soap2obj(node, klass)
147
+ end
148
+
149
+ if Object.respond_to?(:allocate)
150
+ # ruby/1.7 or later.
151
+ def self.create_empty_object(klass)
152
+ klass.allocate
153
+ end
154
+ else
155
+ MARSHAL_TAG = {
156
+ String => ['"', 1],
157
+ Regexp => ['/', 2],
158
+ Array => ['[', 1],
159
+ Hash => ['{', 1]
160
+ }
161
+ def self.create_empty_object(klass)
162
+ if klass <= Struct
163
+ name = klass.name
164
+ return ::Marshal.load(sprintf("\004\006S:%c%s\000", name.length + 5, name))
165
+ end
166
+ if MARSHAL_TAG.has_key?(klass)
167
+ tag, terminate = MARSHAL_TAG[klass]
168
+ return ::Marshal.load(sprintf("\004\006%s%s", tag, "\000" * terminate))
169
+ end
170
+ MARSHAL_TAG.each do |k, v|
171
+ if klass < k
172
+ name = klass.name
173
+ tag, terminate = v
174
+ return ::Marshal.load(sprintf("\004\006C:%c%s%s%s", name.length + 5, name, tag, "\000" * terminate))
175
+ end
176
+ end
177
+ name = klass.name
178
+ ::Marshal.load(sprintf("\004\006o:%c%s\000", name.length + 5, name))
179
+ end
180
+ end
181
+
182
+ # Allow only (Letter | '_') (Letter | Digit | '-' | '_')* here.
183
+ # Caution: '.' is not allowed here.
184
+ # To follow XML spec., it should be NCName.
185
+ # (denied chars) => .[0-F][0-F]
186
+ # ex. a.b => a.2eb
187
+ #
188
+ def self.name2elename(name)
189
+ name.gsub(/([^a-zA-Z0-9:_\-]+)/n) {
190
+ '.' << $1.unpack('H2' * $1.size).join('.')
191
+ }.gsub(/::/n, '..')
192
+ end
193
+
194
+ def self.elename2name(name)
195
+ name.gsub(/\.\./n, '::').gsub(/((?:\.[0-9a-fA-F]{2})+)/n) {
196
+ [$1.delete('.')].pack('H*')
197
+ }
198
+ end
199
+
200
+ def self.const_from_name(name, lenient = false)
201
+ const = ::Object
202
+ name.sub(/\A::/, '').split('::').each do |const_str|
203
+ if XSD::CodeGen::GenSupport.safeconstname?(const_str)
204
+ if const.const_defined?(const_str)
205
+ const = const.const_get(const_str)
206
+ next
207
+ end
208
+ elsif lenient
209
+ const_str = XSD::CodeGen::GenSupport.safeconstname(const_str)
210
+ if const.const_defined?(const_str)
211
+ const = const.const_get(const_str)
212
+ next
213
+ end
214
+ end
215
+ return nil
216
+ end
217
+ const
218
+ end
219
+
220
+ def self.class_from_name(name, lenient = false)
221
+ const = const_from_name(name, lenient)
222
+ if const.is_a?(::Class)
223
+ const
224
+ else
225
+ nil
226
+ end
227
+ end
228
+
229
+ def self.module_from_name(name, lenient = false)
230
+ const = const_from_name(name, lenient)
231
+ if const.is_a?(::Module)
232
+ const
233
+ else
234
+ nil
235
+ end
236
+ end
237
+
238
+ def self.class2qname(klass)
239
+ name = schema_type_definition(klass)
240
+ namespace = schema_ns_definition(klass)
241
+ XSD::QName.new(namespace, name)
242
+ end
243
+
244
+ def self.class2element(klass)
245
+ type = Mapping.class2qname(klass)
246
+ type.name ||= Mapping.name2elename(klass.name)
247
+ type.namespace ||= RubyCustomTypeNamespace
248
+ type
249
+ end
250
+
251
+ def self.obj2element(obj)
252
+ name = namespace = nil
253
+ ivars = obj.instance_variables
254
+ if ivars.include?('@schema_type')
255
+ name = obj.instance_variable_get('@schema_type')
256
+ end
257
+ if ivars.include?('@schema_ns')
258
+ namespace = obj.instance_variable_get('@schema_ns')
259
+ end
260
+ if !name or !namespace
261
+ class2qname(obj.class)
262
+ else
263
+ XSD::QName.new(namespace, name)
264
+ end
265
+ end
266
+
267
+ def self.define_singleton_method(obj, name, &block)
268
+ sclass = (class << obj; self; end)
269
+ sclass.class_eval {
270
+ define_method(name, &block)
271
+ }
272
+ end
273
+
274
+ def self.get_attribute(obj, attr_name)
275
+ if obj.is_a?(::Hash)
276
+ obj[attr_name] || obj[attr_name.intern]
277
+ else
278
+ name = XSD::CodeGen::GenSupport.safevarname(attr_name)
279
+ if obj.instance_variables.include?('@' + name)
280
+ obj.instance_variable_get('@' + name)
281
+ elsif ((obj.is_a?(::Struct) or obj.is_a?(Marshallable)) and
282
+ obj.respond_to?(name))
283
+ obj.__send__(name)
284
+ end
285
+ end
286
+ end
287
+
288
+ def self.set_attributes(obj, values)
289
+ if obj.is_a?(::SOAP::Mapping::Object)
290
+ values.each do |attr_name, value|
291
+ obj.__add_xmlele_value(attr_name, value)
292
+ end
293
+ else
294
+ values.each do |attr_name, value|
295
+ name = XSD::CodeGen::GenSupport.safevarname(attr_name)
296
+ setter = name + "="
297
+ if obj.respond_to?(setter)
298
+ obj.__send__(setter, value)
299
+ else
300
+ obj.instance_variable_set('@' + name, value)
301
+ begin
302
+ define_attr_accessor(obj, name,
303
+ proc { instance_variable_get('@' + name) },
304
+ proc { |value| instance_variable_set('@' + name, value) })
305
+ rescue TypeError
306
+ # singleton class may not exist (e.g. Float)
307
+ end
308
+ end
309
+ end
310
+ end
311
+ end
312
+
313
+ def self.define_attr_accessor(obj, name, getterproc, setterproc = nil)
314
+ define_singleton_method(obj, name, &getterproc)
315
+ define_singleton_method(obj, name + '=', &setterproc) if setterproc
316
+ end
317
+
318
+ def self.schema_type_definition(klass)
319
+ class_schema_variable(:schema_type, klass)
320
+ end
321
+
322
+ def self.schema_ns_definition(klass)
323
+ class_schema_variable(:schema_ns, klass)
324
+ end
325
+
326
+ def self.schema_element_definition(klass)
327
+ schema_element = class_schema_variable(:schema_element, klass) or return nil
328
+ schema_ns = schema_ns_definition(klass)
329
+ elements = []
330
+ as_array = []
331
+ schema_element.each do |varname, definition|
332
+ class_name, name = definition
333
+ if /\[\]$/ =~ class_name
334
+ class_name = class_name.sub(/\[\]$/, '')
335
+ as_array << (name ? name.name : varname)
336
+ end
337
+ elements << [name || XSD::QName.new(schema_ns, varname), class_name]
338
+ end
339
+ [elements, as_array]
340
+ end
341
+
342
+ def self.schema_attribute_definition(klass)
343
+ class_schema_variable(:schema_attribute, klass)
344
+ end
345
+
346
+ class << Mapping
347
+ private
348
+
349
+ def class_schema_variable(sym, klass)
350
+ var = "@@#{sym}"
351
+ klass.class_variables.include?(var) ? klass.class_eval(var) : nil
352
+ end
353
+
354
+ def protect_threadvars(*symbols)
355
+ backup = {}
356
+ begin
357
+ symbols.each do |sym|
358
+ backup[sym] = Thread.current[sym]
359
+ end
360
+ yield
361
+ ensure
362
+ symbols.each do |sym|
363
+ Thread.current[sym] = backup[sym]
364
+ end
365
+ end
366
+ end
367
+
368
+ def add_md_ary(md_ary, ary, indices, registry)
369
+ for idx in 0..(ary.size - 1)
370
+ if ary[idx].is_a?(Array)
371
+ add_md_ary(md_ary, ary[idx], indices + [idx], registry)
372
+ else
373
+ md_ary[*(indices + [idx])] = _obj2soap(ary[idx], registry)
374
+ end
375
+ end
376
+ end
377
+ end
378
+ end
379
+
380
+
381
+ end