rubysl-soap 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -1
  3. data/.travis.yml +8 -0
  4. data/README.md +2 -2
  5. data/Rakefile +0 -1
  6. data/lib/rubysl/soap.rb +1 -0
  7. data/lib/rubysl/soap/version.rb +5 -0
  8. data/lib/soap/attachment.rb +107 -0
  9. data/lib/soap/baseData.rb +942 -0
  10. data/lib/soap/element.rb +258 -0
  11. data/lib/soap/encodingstyle/aspDotNetHandler.rb +213 -0
  12. data/lib/soap/encodingstyle/handler.rb +100 -0
  13. data/lib/soap/encodingstyle/literalHandler.rb +226 -0
  14. data/lib/soap/encodingstyle/soapHandler.rb +582 -0
  15. data/lib/soap/generator.rb +268 -0
  16. data/lib/soap/header/handler.rb +57 -0
  17. data/lib/soap/header/handlerset.rb +70 -0
  18. data/lib/soap/header/simplehandler.rb +44 -0
  19. data/lib/soap/httpconfigloader.rb +119 -0
  20. data/lib/soap/mapping.rb +10 -0
  21. data/lib/soap/mapping/factory.rb +355 -0
  22. data/lib/soap/mapping/mapping.rb +381 -0
  23. data/lib/soap/mapping/registry.rb +541 -0
  24. data/lib/soap/mapping/rubytypeFactory.rb +475 -0
  25. data/lib/soap/mapping/typeMap.rb +50 -0
  26. data/lib/soap/mapping/wsdlencodedregistry.rb +280 -0
  27. data/lib/soap/mapping/wsdlliteralregistry.rb +418 -0
  28. data/lib/soap/marshal.rb +59 -0
  29. data/lib/soap/mimemessage.rb +240 -0
  30. data/lib/soap/netHttpClient.rb +190 -0
  31. data/lib/soap/parser.rb +251 -0
  32. data/lib/soap/processor.rb +66 -0
  33. data/lib/soap/property.rb +333 -0
  34. data/lib/soap/rpc/cgistub.rb +206 -0
  35. data/lib/soap/rpc/driver.rb +254 -0
  36. data/lib/soap/rpc/element.rb +325 -0
  37. data/lib/soap/rpc/httpserver.rb +129 -0
  38. data/lib/soap/rpc/proxy.rb +497 -0
  39. data/lib/soap/rpc/router.rb +594 -0
  40. data/lib/soap/rpc/rpc.rb +25 -0
  41. data/lib/soap/rpc/soaplet.rb +162 -0
  42. data/lib/soap/rpc/standaloneServer.rb +43 -0
  43. data/lib/soap/soap.rb +140 -0
  44. data/lib/soap/streamHandler.rb +229 -0
  45. data/lib/soap/wsdlDriver.rb +575 -0
  46. data/rubysl-soap.gemspec +19 -18
  47. metadata +115 -86
  48. data/lib/rubysl-soap.rb +0 -7
  49. data/lib/rubysl-soap/version.rb +0 -5
@@ -0,0 +1,497 @@
1
+ # SOAP4R - RPC Proxy library.
2
+ # Copyright (C) 2000, 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 'soap/soap'
10
+ require 'soap/processor'
11
+ require 'soap/mapping'
12
+ require 'soap/rpc/rpc'
13
+ require 'soap/rpc/element'
14
+ require 'soap/streamHandler'
15
+ require 'soap/mimemessage'
16
+
17
+
18
+ module SOAP
19
+ module RPC
20
+
21
+
22
+ class Proxy
23
+ include SOAP
24
+
25
+ public
26
+
27
+ attr_accessor :soapaction
28
+ attr_accessor :mandatorycharset
29
+ attr_accessor :allow_unqualified_element
30
+ attr_accessor :default_encodingstyle
31
+ attr_accessor :generate_explicit_type
32
+ attr_reader :headerhandler
33
+ attr_reader :streamhandler
34
+
35
+ attr_accessor :mapping_registry
36
+ attr_accessor :literal_mapping_registry
37
+
38
+ attr_reader :operation
39
+
40
+ def initialize(endpoint_url, soapaction, options)
41
+ @endpoint_url = endpoint_url
42
+ @soapaction = soapaction
43
+ @options = options
44
+ @streamhandler = HTTPStreamHandler.new(
45
+ @options["protocol.http"] ||= ::SOAP::Property.new)
46
+ @operation = {}
47
+ @mandatorycharset = nil
48
+ @allow_unqualified_element = true
49
+ @default_encodingstyle = nil
50
+ @generate_explicit_type = true
51
+ @headerhandler = Header::HandlerSet.new
52
+ @mapping_registry = nil
53
+ @literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new
54
+ end
55
+
56
+ def inspect
57
+ "#<#{self.class}:#{@endpoint_url}>"
58
+ end
59
+
60
+ def endpoint_url
61
+ @endpoint_url
62
+ end
63
+
64
+ def endpoint_url=(endpoint_url)
65
+ @endpoint_url = endpoint_url
66
+ reset_stream
67
+ end
68
+
69
+ def reset_stream
70
+ @streamhandler.reset(@endpoint_url)
71
+ end
72
+
73
+ def set_wiredump_file_base(wiredump_file_base)
74
+ @streamhandler.wiredump_file_base = wiredump_file_base
75
+ end
76
+
77
+ def test_loopback_response
78
+ @streamhandler.test_loopback_response
79
+ end
80
+
81
+ def add_rpc_operation(qname, soapaction, name, param_def, opt = {})
82
+ opt[:request_qname] = qname
83
+ opt[:request_style] ||= :rpc
84
+ opt[:response_style] ||= :rpc
85
+ opt[:request_use] ||= :encoded
86
+ opt[:response_use] ||= :encoded
87
+ @operation[name] = Operation.new(soapaction, param_def, opt)
88
+ end
89
+
90
+ def add_document_operation(soapaction, name, param_def, opt = {})
91
+ opt[:request_style] ||= :document
92
+ opt[:response_style] ||= :document
93
+ opt[:request_use] ||= :literal
94
+ opt[:response_use] ||= :literal
95
+ # default values of these values are unqualified in XML Schema.
96
+ # set true for backward compatibility.
97
+ unless opt.key?(:elementformdefault)
98
+ opt[:elementformdefault] = true
99
+ end
100
+ unless opt.key?(:attributeformdefault)
101
+ opt[:attributeformdefault] = true
102
+ end
103
+ @operation[name] = Operation.new(soapaction, param_def, opt)
104
+ end
105
+
106
+ # add_method is for shortcut of typical rpc/encoded method definition.
107
+ alias add_method add_rpc_operation
108
+ alias add_rpc_method add_rpc_operation
109
+ alias add_document_method add_document_operation
110
+
111
+ def invoke(req_header, req_body, opt = nil)
112
+ opt ||= create_encoding_opt
113
+ route(req_header, req_body, opt, opt)
114
+ end
115
+
116
+ def call(name, *params)
117
+ unless op_info = @operation[name]
118
+ raise MethodDefinitionError, "method: #{name} not defined"
119
+ end
120
+ mapping_opt = create_mapping_opt
121
+ req_header = create_request_header
122
+ req_body = SOAPBody.new(
123
+ op_info.request_body(params, @mapping_registry,
124
+ @literal_mapping_registry, mapping_opt)
125
+ )
126
+ reqopt = create_encoding_opt(
127
+ :soapaction => op_info.soapaction || @soapaction,
128
+ :envelopenamespace => @options["soap.envelope.requestnamespace"],
129
+ :default_encodingstyle =>
130
+ @default_encodingstyle || op_info.request_default_encodingstyle,
131
+ :elementformdefault => op_info.elementformdefault,
132
+ :attributeformdefault => op_info.attributeformdefault
133
+ )
134
+ resopt = create_encoding_opt(
135
+ :envelopenamespace => @options["soap.envelope.responsenamespace"],
136
+ :default_encodingstyle =>
137
+ @default_encodingstyle || op_info.response_default_encodingstyle,
138
+ :elementformdefault => op_info.elementformdefault,
139
+ :attributeformdefault => op_info.attributeformdefault
140
+ )
141
+ env = route(req_header, req_body, reqopt, resopt)
142
+ raise EmptyResponseError unless env
143
+ receive_headers(env.header)
144
+ begin
145
+ check_fault(env.body)
146
+ rescue ::SOAP::FaultError => e
147
+ op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)
148
+ end
149
+ op_info.response_obj(env.body, @mapping_registry,
150
+ @literal_mapping_registry, mapping_opt)
151
+ end
152
+
153
+ def route(req_header, req_body, reqopt, resopt)
154
+ req_env = ::SOAP::SOAPEnvelope.new(req_header, req_body)
155
+ unless reqopt[:envelopenamespace].nil?
156
+ set_envelopenamespace(req_env, reqopt[:envelopenamespace])
157
+ end
158
+ reqopt[:external_content] = nil
159
+ conn_data = marshal(req_env, reqopt)
160
+ if ext = reqopt[:external_content]
161
+ mime = MIMEMessage.new
162
+ ext.each do |k, v|
163
+ mime.add_attachment(v.data)
164
+ end
165
+ mime.add_part(conn_data.send_string + "\r\n")
166
+ mime.close
167
+ conn_data.send_string = mime.content_str
168
+ conn_data.send_contenttype = mime.headers['content-type'].str
169
+ end
170
+ conn_data = @streamhandler.send(@endpoint_url, conn_data,
171
+ reqopt[:soapaction])
172
+ if conn_data.receive_string.empty?
173
+ return nil
174
+ end
175
+ unmarshal(conn_data, resopt)
176
+ end
177
+
178
+ def check_fault(body)
179
+ if body.fault
180
+ raise SOAP::FaultError.new(body.fault)
181
+ end
182
+ end
183
+
184
+ private
185
+
186
+ def set_envelopenamespace(env, namespace)
187
+ env.elename = XSD::QName.new(namespace, env.elename.name)
188
+ if env.header
189
+ env.header.elename = XSD::QName.new(namespace, env.header.elename.name)
190
+ end
191
+ if env.body
192
+ env.body.elename = XSD::QName.new(namespace, env.body.elename.name)
193
+ end
194
+ end
195
+
196
+ def create_request_header
197
+ headers = @headerhandler.on_outbound
198
+ if headers.empty?
199
+ nil
200
+ else
201
+ h = ::SOAP::SOAPHeader.new
202
+ headers.each do |header|
203
+ h.add(header.elename.name, header)
204
+ end
205
+ h
206
+ end
207
+ end
208
+
209
+ def receive_headers(headers)
210
+ @headerhandler.on_inbound(headers) if headers
211
+ end
212
+
213
+ def marshal(env, opt)
214
+ send_string = Processor.marshal(env, opt)
215
+ StreamHandler::ConnectionData.new(send_string)
216
+ end
217
+
218
+ def unmarshal(conn_data, opt)
219
+ contenttype = conn_data.receive_contenttype
220
+ if /#{MIMEMessage::MultipartContentType}/i =~ contenttype
221
+ opt[:external_content] = {}
222
+ mime = MIMEMessage.parse("Content-Type: " + contenttype,
223
+ conn_data.receive_string)
224
+ mime.parts.each do |part|
225
+ value = Attachment.new(part.content)
226
+ value.contentid = part.contentid
227
+ obj = SOAPAttachment.new(value)
228
+ opt[:external_content][value.contentid] = obj if value.contentid
229
+ end
230
+ opt[:charset] = @mandatorycharset ||
231
+ StreamHandler.parse_media_type(mime.root.headers['content-type'].str)
232
+ env = Processor.unmarshal(mime.root.content, opt)
233
+ else
234
+ opt[:charset] = @mandatorycharset ||
235
+ ::SOAP::StreamHandler.parse_media_type(contenttype)
236
+ env = Processor.unmarshal(conn_data.receive_string, opt)
237
+ end
238
+ unless env.is_a?(::SOAP::SOAPEnvelope)
239
+ raise ResponseFormatError.new(
240
+ "response is not a SOAP envelope: #{conn_data.receive_string}")
241
+ end
242
+ env
243
+ end
244
+
245
+ def create_header(headers)
246
+ header = SOAPHeader.new()
247
+ headers.each do |content, mustunderstand, encodingstyle|
248
+ header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle))
249
+ end
250
+ header
251
+ end
252
+
253
+ def create_encoding_opt(hash = nil)
254
+ opt = {}
255
+ opt[:default_encodingstyle] = @default_encodingstyle
256
+ opt[:allow_unqualified_element] = @allow_unqualified_element
257
+ opt[:generate_explicit_type] = @generate_explicit_type
258
+ opt[:no_indent] = @options["soap.envelope.no_indent"]
259
+ opt[:use_numeric_character_reference] =
260
+ @options["soap.envelope.use_numeric_character_reference"]
261
+ opt.update(hash) if hash
262
+ opt
263
+ end
264
+
265
+ def create_mapping_opt(hash = nil)
266
+ opt = {
267
+ :external_ces => @options["soap.mapping.external_ces"]
268
+ }
269
+ opt.update(hash) if hash
270
+ opt
271
+ end
272
+
273
+ class Operation
274
+ attr_reader :soapaction
275
+ attr_reader :request_style
276
+ attr_reader :response_style
277
+ attr_reader :request_use
278
+ attr_reader :response_use
279
+ attr_reader :elementformdefault
280
+ attr_reader :attributeformdefault
281
+
282
+ def initialize(soapaction, param_def, opt)
283
+ @soapaction = soapaction
284
+ @request_style = opt[:request_style]
285
+ @response_style = opt[:response_style]
286
+ @request_use = opt[:request_use]
287
+ @response_use = opt[:response_use]
288
+ # set nil(unqualified) by default
289
+ @elementformdefault = opt[:elementformdefault]
290
+ @attributeformdefault = opt[:attributeformdefault]
291
+ check_style(@request_style)
292
+ check_style(@response_style)
293
+ check_use(@request_use)
294
+ check_use(@response_use)
295
+ if @request_style == :rpc
296
+ @rpc_request_qname = opt[:request_qname]
297
+ if @rpc_request_qname.nil?
298
+ raise MethodDefinitionError.new("rpc_request_qname must be given")
299
+ end
300
+ @rpc_method_factory =
301
+ RPC::SOAPMethodRequest.new(@rpc_request_qname, param_def, @soapaction)
302
+ else
303
+ @doc_request_qnames = []
304
+ @doc_request_qualified = []
305
+ @doc_response_qnames = []
306
+ @doc_response_qualified = []
307
+ param_def.each do |inout, paramname, typeinfo, eleinfo|
308
+ klass_not_used, nsdef, namedef = typeinfo
309
+ qualified = eleinfo
310
+ if namedef.nil?
311
+ raise MethodDefinitionError.new("qname must be given")
312
+ end
313
+ case inout
314
+ when SOAPMethod::IN
315
+ @doc_request_qnames << XSD::QName.new(nsdef, namedef)
316
+ @doc_request_qualified << qualified
317
+ when SOAPMethod::OUT
318
+ @doc_response_qnames << XSD::QName.new(nsdef, namedef)
319
+ @doc_response_qualified << qualified
320
+ else
321
+ raise MethodDefinitionError.new(
322
+ "illegal inout definition for document style: #{inout}")
323
+ end
324
+ end
325
+ end
326
+ end
327
+
328
+ def request_default_encodingstyle
329
+ (@request_use == :encoded) ? EncodingNamespace : LiteralNamespace
330
+ end
331
+
332
+ def response_default_encodingstyle
333
+ (@response_use == :encoded) ? EncodingNamespace : LiteralNamespace
334
+ end
335
+
336
+ def request_body(values, mapping_registry, literal_mapping_registry, opt)
337
+ if @request_style == :rpc
338
+ request_rpc(values, mapping_registry, literal_mapping_registry, opt)
339
+ else
340
+ request_doc(values, mapping_registry, literal_mapping_registry, opt)
341
+ end
342
+ end
343
+
344
+ def response_obj(body, mapping_registry, literal_mapping_registry, opt)
345
+ if @response_style == :rpc
346
+ response_rpc(body, mapping_registry, literal_mapping_registry, opt)
347
+ else
348
+ response_doc(body, mapping_registry, literal_mapping_registry, opt)
349
+ end
350
+ end
351
+
352
+ def raise_fault(e, mapping_registry, literal_mapping_registry)
353
+ if @response_style == :rpc
354
+ Mapping.fault2exception(e, mapping_registry)
355
+ else
356
+ Mapping.fault2exception(e, literal_mapping_registry)
357
+ end
358
+ end
359
+
360
+ private
361
+
362
+ def check_style(style)
363
+ unless [:rpc, :document].include?(style)
364
+ raise MethodDefinitionError.new("unknown style: #{style}")
365
+ end
366
+ end
367
+
368
+ def check_use(use)
369
+ unless [:encoded, :literal].include?(use)
370
+ raise MethodDefinitionError.new("unknown use: #{use}")
371
+ end
372
+ end
373
+
374
+ def request_rpc(values, mapping_registry, literal_mapping_registry, opt)
375
+ if @request_use == :encoded
376
+ request_rpc_enc(values, mapping_registry, opt)
377
+ else
378
+ request_rpc_lit(values, literal_mapping_registry, opt)
379
+ end
380
+ end
381
+
382
+ def request_doc(values, mapping_registry, literal_mapping_registry, opt)
383
+ if @request_use == :encoded
384
+ request_doc_enc(values, mapping_registry, opt)
385
+ else
386
+ request_doc_lit(values, literal_mapping_registry, opt)
387
+ end
388
+ end
389
+
390
+ def request_rpc_enc(values, mapping_registry, opt)
391
+ method = @rpc_method_factory.dup
392
+ names = method.input_params
393
+ obj = create_request_obj(names, values)
394
+ soap = Mapping.obj2soap(obj, mapping_registry, @rpc_request_qname, opt)
395
+ method.set_param(soap)
396
+ method
397
+ end
398
+
399
+ def request_rpc_lit(values, mapping_registry, opt)
400
+ method = @rpc_method_factory.dup
401
+ params = {}
402
+ idx = 0
403
+ method.input_params.each do |name|
404
+ params[name] = Mapping.obj2soap(values[idx], mapping_registry,
405
+ XSD::QName.new(nil, name), opt)
406
+ idx += 1
407
+ end
408
+ method.set_param(params)
409
+ method
410
+ end
411
+
412
+ def request_doc_enc(values, mapping_registry, opt)
413
+ (0...values.size).collect { |idx|
414
+ ele = Mapping.obj2soap(values[idx], mapping_registry, nil, opt)
415
+ ele.elename = @doc_request_qnames[idx]
416
+ ele
417
+ }
418
+ end
419
+
420
+ def request_doc_lit(values, mapping_registry, opt)
421
+ (0...values.size).collect { |idx|
422
+ ele = Mapping.obj2soap(values[idx], mapping_registry,
423
+ @doc_request_qnames[idx], opt)
424
+ ele.encodingstyle = LiteralNamespace
425
+ if ele.respond_to?(:qualified)
426
+ ele.qualified = @doc_request_qualified[idx]
427
+ end
428
+ ele
429
+ }
430
+ end
431
+
432
+ def response_rpc(body, mapping_registry, literal_mapping_registry, opt)
433
+ if @response_use == :encoded
434
+ response_rpc_enc(body, mapping_registry, opt)
435
+ else
436
+ response_rpc_lit(body, literal_mapping_registry, opt)
437
+ end
438
+ end
439
+
440
+ def response_doc(body, mapping_registry, literal_mapping_registry, opt)
441
+ if @response_use == :encoded
442
+ return *response_doc_enc(body, mapping_registry, opt)
443
+ else
444
+ return *response_doc_lit(body, literal_mapping_registry, opt)
445
+ end
446
+ end
447
+
448
+ def response_rpc_enc(body, mapping_registry, opt)
449
+ ret = nil
450
+ if body.response
451
+ ret = Mapping.soap2obj(body.response, mapping_registry,
452
+ @rpc_method_factory.retval_class_name, opt)
453
+ end
454
+ if body.outparams
455
+ outparams = body.outparams.collect { |outparam|
456
+ Mapping.soap2obj(outparam, mapping_registry, nil, opt)
457
+ }
458
+ [ret].concat(outparams)
459
+ else
460
+ ret
461
+ end
462
+ end
463
+
464
+ def response_rpc_lit(body, mapping_registry, opt)
465
+ body.root_node.collect { |key, value|
466
+ Mapping.soap2obj(value, mapping_registry,
467
+ @rpc_method_factory.retval_class_name, opt)
468
+ }
469
+ end
470
+
471
+ def response_doc_enc(body, mapping_registry, opt)
472
+ body.collect { |key, value|
473
+ Mapping.soap2obj(value, mapping_registry, nil, opt)
474
+ }
475
+ end
476
+
477
+ def response_doc_lit(body, mapping_registry, opt)
478
+ body.collect { |key, value|
479
+ Mapping.soap2obj(value, mapping_registry)
480
+ }
481
+ end
482
+
483
+ def create_request_obj(names, params)
484
+ o = Object.new
485
+ idx = 0
486
+ while idx < params.length
487
+ o.instance_variable_set('@' + names[idx], params[idx])
488
+ idx += 1
489
+ end
490
+ o
491
+ end
492
+ end
493
+ end
494
+
495
+
496
+ end
497
+ end