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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 90bf6e2e70c5439aebdc7f1c89011c637bfb4838
4
+ data.tar.gz: a5c2a4097f279c8278b0fa58136e196c2a13ee06
5
+ SHA512:
6
+ metadata.gz: 74f293ab6bff9f09dbdc734fa440775ff7b01274a64ccda84fa82f4f4b3743055a362e51ce7c3b02e107469b4fcf350fae95b3728eb7163281a11eb37126ddf6
7
+ data.tar.gz: f8edb839e9dc6b64b6a5e7c501997afc0858da3bbbc9397efea5cdde51247172cfce3b8c14d4b9727cc02b6450d867c4b07503be39abe379a7fbd42e88915cb1
data/.gitignore CHANGED
@@ -15,4 +15,3 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- .rbx
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem update --system
4
+ - gem --version
5
+ - gem install rubysl-bundler
6
+ script: bundle exec mspec spec
7
+ rvm:
8
+ - rbx-nightly-18mode
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RubySL::Soap
1
+ # Rubysl::Soap
2
2
 
3
3
  TODO: Write a gem description
4
4
 
@@ -24,6 +24,6 @@ TODO: Write usage instructions here
24
24
 
25
25
  1. Fork it
26
26
  2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Added some feature'`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
28
  4. Push to the branch (`git push origin my-new-feature`)
29
29
  5. Create new Pull Request
data/Rakefile CHANGED
@@ -1,2 +1 @@
1
- #!/usr/bin/env rake
2
1
  require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ require "rubysl/soap/version"
@@ -0,0 +1,5 @@
1
+ module RubySL
2
+ module SOAP
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,107 @@
1
+ # soap/attachment.rb: SOAP4R - SwA implementation.
2
+ # Copyright (C) 2002, 2003 Jamie Herre and 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'
11
+
12
+
13
+ module SOAP
14
+
15
+
16
+ class SOAPAttachment < SOAPExternalReference
17
+ attr_reader :data
18
+
19
+ def initialize(value)
20
+ super()
21
+ @data = value
22
+ end
23
+
24
+ private
25
+
26
+ def external_contentid
27
+ @data.contentid
28
+ end
29
+ end
30
+
31
+
32
+ class Attachment
33
+ attr_reader :io
34
+ attr_accessor :contenttype
35
+
36
+ def initialize(string_or_readable = nil)
37
+ @string_or_readable = string_or_readable
38
+ @contenttype = "application/octet-stream"
39
+ @contentid = nil
40
+ end
41
+
42
+ def contentid
43
+ @contentid ||= Attachment.contentid(self)
44
+ end
45
+
46
+ def contentid=(contentid)
47
+ @contentid = contentid
48
+ end
49
+
50
+ def mime_contentid
51
+ '<' + contentid + '>'
52
+ end
53
+
54
+ def content
55
+ if @content == nil and @string_or_readable != nil
56
+ @content = @string_or_readable.respond_to?(:read) ?
57
+ @string_or_readable.read : @string_or_readable
58
+ end
59
+ @content
60
+ end
61
+
62
+ def to_s
63
+ content
64
+ end
65
+
66
+ def write(out)
67
+ out.write(content)
68
+ end
69
+
70
+ def save(filename)
71
+ File.open(filename, "wb") do |f|
72
+ write(f)
73
+ end
74
+ end
75
+
76
+ def self.contentid(obj)
77
+ # this needs to be fixed
78
+ [obj.__id__.to_s, Process.pid.to_s].join('.')
79
+ end
80
+
81
+ def self.mime_contentid(obj)
82
+ '<' + contentid(obj) + '>'
83
+ end
84
+ end
85
+
86
+
87
+ module Mapping
88
+ class AttachmentFactory < SOAP::Mapping::Factory
89
+ def obj2soap(soap_class, obj, info, map)
90
+ soap_obj = soap_class.new(obj)
91
+ mark_marshalled_obj(obj, soap_obj)
92
+ soap_obj
93
+ end
94
+
95
+ def soap2obj(obj_class, node, info, map)
96
+ obj = node.data
97
+ mark_unmarshalled_obj(node, obj)
98
+ return true, obj
99
+ end
100
+ end
101
+
102
+ DefaultRegistry.add(::SOAP::Attachment, ::SOAP::SOAPAttachment,
103
+ AttachmentFactory.new, nil)
104
+ end
105
+
106
+
107
+ end
@@ -0,0 +1,942 @@
1
+ # soap/baseData.rb: SOAP4R - Base type library
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 'xsd/datatypes'
10
+ require 'soap/soap'
11
+
12
+
13
+ module SOAP
14
+
15
+
16
+ ###
17
+ ## Mix-in module for SOAP base type classes.
18
+ #
19
+ module SOAPModuleUtils
20
+ include SOAP
21
+
22
+ public
23
+
24
+ def decode(elename)
25
+ d = self.new
26
+ d.elename = elename
27
+ d
28
+ end
29
+ end
30
+
31
+
32
+ ###
33
+ ## for SOAP type(base and compound)
34
+ #
35
+ module SOAPType
36
+ attr_accessor :encodingstyle
37
+ attr_accessor :elename
38
+ attr_accessor :id
39
+ attr_reader :precedents
40
+ attr_accessor :root
41
+ attr_accessor :parent
42
+ attr_accessor :position
43
+ attr_reader :extraattr
44
+ attr_accessor :definedtype
45
+
46
+ def initialize(*arg)
47
+ super
48
+ @encodingstyle = nil
49
+ @elename = XSD::QName::EMPTY
50
+ @id = nil
51
+ @precedents = []
52
+ @root = false
53
+ @parent = nil
54
+ @position = nil
55
+ @definedtype = nil
56
+ @extraattr = {}
57
+ end
58
+
59
+ def inspect
60
+ if self.is_a?(XSD::NSDBase)
61
+ sprintf("#<%s:0x%x %s %s>", self.class.name, __id__, self.elename, self.type)
62
+ else
63
+ sprintf("#<%s:0x%x %s>", self.class.name, __id__, self.elename)
64
+ end
65
+ end
66
+
67
+ def rootnode
68
+ node = self
69
+ while node = node.parent
70
+ break if SOAPEnvelope === node
71
+ end
72
+ node
73
+ end
74
+ end
75
+
76
+
77
+ ###
78
+ ## for SOAP base type
79
+ #
80
+ module SOAPBasetype
81
+ include SOAPType
82
+ include SOAP
83
+
84
+ def initialize(*arg)
85
+ super
86
+ end
87
+ end
88
+
89
+
90
+ ###
91
+ ## for SOAP compound type
92
+ #
93
+ module SOAPCompoundtype
94
+ include SOAPType
95
+ include SOAP
96
+
97
+ def initialize(*arg)
98
+ super
99
+ end
100
+ end
101
+
102
+
103
+ ###
104
+ ## Convenience datatypes.
105
+ #
106
+ class SOAPReference < XSD::NSDBase
107
+ include SOAPBasetype
108
+ extend SOAPModuleUtils
109
+
110
+ public
111
+
112
+ attr_accessor :refid
113
+
114
+ # Override the definition in SOAPBasetype.
115
+ def initialize(obj = nil)
116
+ super()
117
+ @type = XSD::QName::EMPTY
118
+ @refid = nil
119
+ @obj = nil
120
+ __setobj__(obj) if obj
121
+ end
122
+
123
+ def __getobj__
124
+ @obj
125
+ end
126
+
127
+ def __setobj__(obj)
128
+ @obj = obj
129
+ @refid = @obj.id || SOAPReference.create_refid(@obj)
130
+ @obj.id = @refid unless @obj.id
131
+ @obj.precedents << self
132
+ # Copies NSDBase information
133
+ @obj.type = @type unless @obj.type
134
+ end
135
+
136
+ # Why don't I use delegate.rb?
137
+ # -> delegate requires target object type at initialize time.
138
+ # Why don't I use forwardable.rb?
139
+ # -> forwardable requires a list of forwarding methods.
140
+ #
141
+ # ToDo: Maybe I should use forwardable.rb and give it a methods list like
142
+ # delegate.rb...
143
+ #
144
+ def method_missing(msg_id, *params)
145
+ if @obj
146
+ @obj.send(msg_id, *params)
147
+ else
148
+ nil
149
+ end
150
+ end
151
+
152
+ def refidstr
153
+ '#' + @refid
154
+ end
155
+
156
+ def self.create_refid(obj)
157
+ 'id' + obj.__id__.to_s
158
+ end
159
+
160
+ def self.decode(elename, refidstr)
161
+ if /\A#(.*)\z/ =~ refidstr
162
+ refid = $1
163
+ elsif /\Acid:(.*)\z/ =~ refidstr
164
+ refid = $1
165
+ else
166
+ raise ArgumentError.new("illegal refid #{refidstr}")
167
+ end
168
+ d = super(elename)
169
+ d.refid = refid
170
+ d
171
+ end
172
+ end
173
+
174
+
175
+ class SOAPExternalReference < XSD::NSDBase
176
+ include SOAPBasetype
177
+ extend SOAPModuleUtils
178
+
179
+ def initialize
180
+ super()
181
+ @type = XSD::QName::EMPTY
182
+ end
183
+
184
+ def referred
185
+ rootnode.external_content[external_contentid] = self
186
+ end
187
+
188
+ def refidstr
189
+ 'cid:' + external_contentid
190
+ end
191
+
192
+ private
193
+
194
+ def external_contentid
195
+ raise NotImplementedError.new
196
+ end
197
+ end
198
+
199
+
200
+ class SOAPNil < XSD::XSDNil
201
+ include SOAPBasetype
202
+ extend SOAPModuleUtils
203
+ end
204
+
205
+ # SOAPRawString is for sending raw string. In contrast to SOAPString,
206
+ # SOAP4R does not do XML encoding and does not convert its CES. The string it
207
+ # holds is embedded to XML instance directly as a 'xsd:string'.
208
+ class SOAPRawString < XSD::XSDString
209
+ include SOAPBasetype
210
+ extend SOAPModuleUtils
211
+ end
212
+
213
+
214
+ ###
215
+ ## Basic datatypes.
216
+ #
217
+ class SOAPAnySimpleType < XSD::XSDAnySimpleType
218
+ include SOAPBasetype
219
+ extend SOAPModuleUtils
220
+ end
221
+
222
+ class SOAPString < XSD::XSDString
223
+ include SOAPBasetype
224
+ extend SOAPModuleUtils
225
+ end
226
+
227
+ class SOAPBoolean < XSD::XSDBoolean
228
+ include SOAPBasetype
229
+ extend SOAPModuleUtils
230
+ end
231
+
232
+ class SOAPDecimal < XSD::XSDDecimal
233
+ include SOAPBasetype
234
+ extend SOAPModuleUtils
235
+ end
236
+
237
+ class SOAPFloat < XSD::XSDFloat
238
+ include SOAPBasetype
239
+ extend SOAPModuleUtils
240
+ end
241
+
242
+ class SOAPDouble < XSD::XSDDouble
243
+ include SOAPBasetype
244
+ extend SOAPModuleUtils
245
+ end
246
+
247
+ class SOAPDuration < XSD::XSDDuration
248
+ include SOAPBasetype
249
+ extend SOAPModuleUtils
250
+ end
251
+
252
+ class SOAPDateTime < XSD::XSDDateTime
253
+ include SOAPBasetype
254
+ extend SOAPModuleUtils
255
+ end
256
+
257
+ class SOAPTime < XSD::XSDTime
258
+ include SOAPBasetype
259
+ extend SOAPModuleUtils
260
+ end
261
+
262
+ class SOAPDate < XSD::XSDDate
263
+ include SOAPBasetype
264
+ extend SOAPModuleUtils
265
+ end
266
+
267
+ class SOAPGYearMonth < XSD::XSDGYearMonth
268
+ include SOAPBasetype
269
+ extend SOAPModuleUtils
270
+ end
271
+
272
+ class SOAPGYear < XSD::XSDGYear
273
+ include SOAPBasetype
274
+ extend SOAPModuleUtils
275
+ end
276
+
277
+ class SOAPGMonthDay < XSD::XSDGMonthDay
278
+ include SOAPBasetype
279
+ extend SOAPModuleUtils
280
+ end
281
+
282
+ class SOAPGDay < XSD::XSDGDay
283
+ include SOAPBasetype
284
+ extend SOAPModuleUtils
285
+ end
286
+
287
+ class SOAPGMonth < XSD::XSDGMonth
288
+ include SOAPBasetype
289
+ extend SOAPModuleUtils
290
+ end
291
+
292
+ class SOAPHexBinary < XSD::XSDHexBinary
293
+ include SOAPBasetype
294
+ extend SOAPModuleUtils
295
+ end
296
+
297
+ class SOAPBase64 < XSD::XSDBase64Binary
298
+ include SOAPBasetype
299
+ extend SOAPModuleUtils
300
+ Type = QName.new(EncodingNamespace, Base64Literal)
301
+
302
+ public
303
+ # Override the definition in SOAPBasetype.
304
+ def initialize(value = nil)
305
+ super(value)
306
+ @type = Type
307
+ end
308
+
309
+ def as_xsd
310
+ @type = XSD::XSDBase64Binary::Type
311
+ end
312
+ end
313
+
314
+ class SOAPAnyURI < XSD::XSDAnyURI
315
+ include SOAPBasetype
316
+ extend SOAPModuleUtils
317
+ end
318
+
319
+ class SOAPQName < XSD::XSDQName
320
+ include SOAPBasetype
321
+ extend SOAPModuleUtils
322
+ end
323
+
324
+
325
+ class SOAPInteger < XSD::XSDInteger
326
+ include SOAPBasetype
327
+ extend SOAPModuleUtils
328
+ end
329
+
330
+ class SOAPNonPositiveInteger < XSD::XSDNonPositiveInteger
331
+ include SOAPBasetype
332
+ extend SOAPModuleUtils
333
+ end
334
+
335
+ class SOAPNegativeInteger < XSD::XSDNegativeInteger
336
+ include SOAPBasetype
337
+ extend SOAPModuleUtils
338
+ end
339
+
340
+ class SOAPLong < XSD::XSDLong
341
+ include SOAPBasetype
342
+ extend SOAPModuleUtils
343
+ end
344
+
345
+ class SOAPInt < XSD::XSDInt
346
+ include SOAPBasetype
347
+ extend SOAPModuleUtils
348
+ end
349
+
350
+ class SOAPShort < XSD::XSDShort
351
+ include SOAPBasetype
352
+ extend SOAPModuleUtils
353
+ end
354
+
355
+ class SOAPByte < XSD::XSDByte
356
+ include SOAPBasetype
357
+ extend SOAPModuleUtils
358
+ end
359
+
360
+ class SOAPNonNegativeInteger < XSD::XSDNonNegativeInteger
361
+ include SOAPBasetype
362
+ extend SOAPModuleUtils
363
+ end
364
+
365
+ class SOAPUnsignedLong < XSD::XSDUnsignedLong
366
+ include SOAPBasetype
367
+ extend SOAPModuleUtils
368
+ end
369
+
370
+ class SOAPUnsignedInt < XSD::XSDUnsignedInt
371
+ include SOAPBasetype
372
+ extend SOAPModuleUtils
373
+ end
374
+
375
+ class SOAPUnsignedShort < XSD::XSDUnsignedShort
376
+ include SOAPBasetype
377
+ extend SOAPModuleUtils
378
+ end
379
+
380
+ class SOAPUnsignedByte < XSD::XSDUnsignedByte
381
+ include SOAPBasetype
382
+ extend SOAPModuleUtils
383
+ end
384
+
385
+ class SOAPPositiveInteger < XSD::XSDPositiveInteger
386
+ include SOAPBasetype
387
+ extend SOAPModuleUtils
388
+ end
389
+
390
+
391
+ ###
392
+ ## Compound datatypes.
393
+ #
394
+ class SOAPStruct < XSD::NSDBase
395
+ include SOAPCompoundtype
396
+ include Enumerable
397
+
398
+ public
399
+
400
+ def initialize(type = nil)
401
+ super()
402
+ @type = type || XSD::QName::EMPTY
403
+ @array = []
404
+ @data = []
405
+ end
406
+
407
+ def to_s()
408
+ str = ''
409
+ self.each do |key, data|
410
+ str << "#{key}: #{data}\n"
411
+ end
412
+ str
413
+ end
414
+
415
+ def add(name, value)
416
+ add_member(name, value)
417
+ end
418
+
419
+ def [](idx)
420
+ if idx.is_a?(Range)
421
+ @data[idx]
422
+ elsif idx.is_a?(Integer)
423
+ if (idx > @array.size)
424
+ raise ArrayIndexOutOfBoundsError.new('In ' << @type.name)
425
+ end
426
+ @data[idx]
427
+ else
428
+ if @array.include?(idx)
429
+ @data[@array.index(idx)]
430
+ else
431
+ nil
432
+ end
433
+ end
434
+ end
435
+
436
+ def []=(idx, data)
437
+ if @array.include?(idx)
438
+ data.parent = self if data.respond_to?(:parent=)
439
+ @data[@array.index(idx)] = data
440
+ else
441
+ add(idx, data)
442
+ end
443
+ end
444
+
445
+ def key?(name)
446
+ @array.include?(name)
447
+ end
448
+
449
+ def members
450
+ @array
451
+ end
452
+
453
+ def to_obj
454
+ hash = {}
455
+ proptype = {}
456
+ each do |k, v|
457
+ value = v.respond_to?(:to_obj) ? v.to_obj : v.to_s
458
+ case proptype[k]
459
+ when :single
460
+ hash[k] = [hash[k], value]
461
+ proptype[k] = :multi
462
+ when :multi
463
+ hash[k] << value
464
+ else
465
+ hash[k] = value
466
+ proptype[k] = :single
467
+ end
468
+ end
469
+ hash
470
+ end
471
+
472
+ def each
473
+ idx = 0
474
+ while idx < @array.length
475
+ yield(@array[idx], @data[idx])
476
+ idx += 1
477
+ end
478
+ end
479
+
480
+ def replace
481
+ members.each do |member|
482
+ self[member] = yield(self[member])
483
+ end
484
+ end
485
+
486
+ def self.decode(elename, type)
487
+ s = SOAPStruct.new(type)
488
+ s.elename = elename
489
+ s
490
+ end
491
+
492
+ private
493
+
494
+ def add_member(name, value = nil)
495
+ value = SOAPNil.new() if value.nil?
496
+ @array.push(name)
497
+ value.elename = value.elename.dup_name(name)
498
+ @data.push(value)
499
+ value.parent = self if value.respond_to?(:parent=)
500
+ value
501
+ end
502
+ end
503
+
504
+
505
+ # SOAPElement is not typed so it is not derived from NSDBase.
506
+ class SOAPElement
507
+ include Enumerable
508
+
509
+ attr_accessor :encodingstyle
510
+
511
+ attr_accessor :elename
512
+ attr_accessor :id
513
+ attr_reader :precedents
514
+ attr_accessor :root
515
+ attr_accessor :parent
516
+ attr_accessor :position
517
+ attr_accessor :extraattr
518
+
519
+ attr_accessor :qualified
520
+
521
+ def initialize(elename, text = nil)
522
+ if !elename.is_a?(XSD::QName)
523
+ elename = XSD::QName.new(nil, elename)
524
+ end
525
+ @encodingstyle = LiteralNamespace
526
+ @elename = elename
527
+ @id = nil
528
+ @precedents = []
529
+ @root = false
530
+ @parent = nil
531
+ @position = nil
532
+ @extraattr = {}
533
+
534
+ @qualified = nil
535
+
536
+ @array = []
537
+ @data = []
538
+ @text = text
539
+ end
540
+
541
+ def inspect
542
+ sprintf("#<%s:0x%x %s>", self.class.name, __id__, self.elename)
543
+ end
544
+
545
+ # Text interface.
546
+ attr_accessor :text
547
+ alias data text
548
+
549
+ # Element interfaces.
550
+ def add(value)
551
+ add_member(value.elename.name, value)
552
+ end
553
+
554
+ def [](idx)
555
+ if @array.include?(idx)
556
+ @data[@array.index(idx)]
557
+ else
558
+ nil
559
+ end
560
+ end
561
+
562
+ def []=(idx, data)
563
+ if @array.include?(idx)
564
+ data.parent = self if data.respond_to?(:parent=)
565
+ @data[@array.index(idx)] = data
566
+ else
567
+ add(data)
568
+ end
569
+ end
570
+
571
+ def key?(name)
572
+ @array.include?(name)
573
+ end
574
+
575
+ def members
576
+ @array
577
+ end
578
+
579
+ def to_obj
580
+ if members.empty?
581
+ @text
582
+ else
583
+ hash = {}
584
+ proptype = {}
585
+ each do |k, v|
586
+ value = v.respond_to?(:to_obj) ? v.to_obj : v.to_s
587
+ case proptype[k]
588
+ when :single
589
+ hash[k] = [hash[k], value]
590
+ proptype[k] = :multi
591
+ when :multi
592
+ hash[k] << value
593
+ else
594
+ hash[k] = value
595
+ proptype[k] = :single
596
+ end
597
+ end
598
+ hash
599
+ end
600
+ end
601
+
602
+ def each
603
+ idx = 0
604
+ while idx < @array.length
605
+ yield(@array[idx], @data[idx])
606
+ idx += 1
607
+ end
608
+ end
609
+
610
+ def self.decode(elename)
611
+ o = SOAPElement.new(elename)
612
+ o
613
+ end
614
+
615
+ def self.from_obj(obj, namespace = nil)
616
+ o = SOAPElement.new(nil)
617
+ case obj
618
+ when nil
619
+ o.text = nil
620
+ when Hash
621
+ obj.each do |elename, value|
622
+ if value.is_a?(Array)
623
+ value.each do |subvalue|
624
+ child = from_obj(subvalue, namespace)
625
+ child.elename = to_elename(elename, namespace)
626
+ o.add(child)
627
+ end
628
+ else
629
+ child = from_obj(value, namespace)
630
+ child.elename = to_elename(elename, namespace)
631
+ o.add(child)
632
+ end
633
+ end
634
+ else
635
+ o.text = obj.to_s
636
+ end
637
+ o
638
+ end
639
+
640
+ def self.to_elename(obj, namespace = nil)
641
+ if obj.is_a?(XSD::QName)
642
+ obj
643
+ elsif /\A(.+):([^:]+)\z/ =~ obj.to_s
644
+ XSD::QName.new($1, $2)
645
+ else
646
+ XSD::QName.new(namespace, obj.to_s)
647
+ end
648
+ end
649
+
650
+ private
651
+
652
+ def add_member(name, value)
653
+ add_accessor(name)
654
+ @array.push(name)
655
+ @data.push(value)
656
+ value.parent = self if value.respond_to?(:parent=)
657
+ value
658
+ end
659
+
660
+ if RUBY_VERSION > "1.7.0"
661
+ def add_accessor(name)
662
+ methodname = name
663
+ if self.respond_to?(methodname)
664
+ methodname = safe_accessor_name(methodname)
665
+ end
666
+ Mapping.define_singleton_method(self, methodname) do
667
+ @data[@array.index(name)]
668
+ end
669
+ Mapping.define_singleton_method(self, methodname + '=') do |value|
670
+ @data[@array.index(name)] = value
671
+ end
672
+ end
673
+ else
674
+ def add_accessor(name)
675
+ methodname = safe_accessor_name(name)
676
+ instance_eval <<-EOS
677
+ def #{methodname}
678
+ @data[@array.index(#{name.dump})]
679
+ end
680
+
681
+ def #{methodname}=(value)
682
+ @data[@array.index(#{name.dump})] = value
683
+ end
684
+ EOS
685
+ end
686
+ end
687
+
688
+ def safe_accessor_name(name)
689
+ "var_" << name.gsub(/[^a-zA-Z0-9_]/, '')
690
+ end
691
+ end
692
+
693
+
694
+ class SOAPArray < XSD::NSDBase
695
+ include SOAPCompoundtype
696
+ include Enumerable
697
+
698
+ public
699
+
700
+ attr_accessor :sparse
701
+
702
+ attr_reader :offset, :rank
703
+ attr_accessor :size, :size_fixed
704
+ attr_reader :arytype
705
+
706
+ def initialize(type = nil, rank = 1, arytype = nil)
707
+ super()
708
+ @type = type || ValueArrayName
709
+ @rank = rank
710
+ @data = Array.new
711
+ @sparse = false
712
+ @offset = Array.new(rank, 0)
713
+ @size = Array.new(rank, 0)
714
+ @size_fixed = false
715
+ @position = nil
716
+ @arytype = arytype
717
+ end
718
+
719
+ def offset=(var)
720
+ @offset = var
721
+ @sparse = true
722
+ end
723
+
724
+ def add(value)
725
+ self[*(@offset)] = value
726
+ end
727
+
728
+ def [](*idxary)
729
+ if idxary.size != @rank
730
+ raise ArgumentError.new("given #{idxary.size} params does not match rank: #{@rank}")
731
+ end
732
+
733
+ retrieve(idxary)
734
+ end
735
+
736
+ def []=(*idxary)
737
+ value = idxary.slice!(-1)
738
+
739
+ if idxary.size != @rank
740
+ raise ArgumentError.new("given #{idxary.size} params(#{idxary})" +
741
+ " does not match rank: #{@rank}")
742
+ end
743
+
744
+ idx = 0
745
+ while idx < idxary.size
746
+ if idxary[idx] + 1 > @size[idx]
747
+ @size[idx] = idxary[idx] + 1
748
+ end
749
+ idx += 1
750
+ end
751
+
752
+ data = retrieve(idxary[0, idxary.size - 1])
753
+ data[idxary.last] = value
754
+
755
+ if value.is_a?(SOAPType)
756
+ value.elename = ITEM_NAME
757
+ # Sync type
758
+ unless @type.name
759
+ @type = XSD::QName.new(value.type.namespace,
760
+ SOAPArray.create_arytype(value.type.name, @rank))
761
+ end
762
+ value.type ||= @type
763
+ end
764
+
765
+ @offset = idxary
766
+ value.parent = self if value.respond_to?(:parent=)
767
+ offsetnext
768
+ end
769
+
770
+ def each
771
+ @data.each do |data|
772
+ yield(data)
773
+ end
774
+ end
775
+
776
+ def to_a
777
+ @data.dup
778
+ end
779
+
780
+ def replace
781
+ @data = deep_map(@data) do |ele|
782
+ yield(ele)
783
+ end
784
+ end
785
+
786
+ def deep_map(ary, &block)
787
+ ary.collect do |ele|
788
+ if ele.is_a?(Array)
789
+ deep_map(ele, &block)
790
+ else
791
+ new_obj = block.call(ele)
792
+ new_obj.elename = ITEM_NAME
793
+ new_obj
794
+ end
795
+ end
796
+ end
797
+
798
+ def include?(var)
799
+ traverse_data(@data) do |v, *rank|
800
+ if v.is_a?(SOAPBasetype) && v.data == var
801
+ return true
802
+ end
803
+ end
804
+ false
805
+ end
806
+
807
+ def traverse
808
+ traverse_data(@data) do |v, *rank|
809
+ unless @sparse
810
+ yield(v)
811
+ else
812
+ yield(v, *rank) if v && !v.is_a?(SOAPNil)
813
+ end
814
+ end
815
+ end
816
+
817
+ def soap2array(ary)
818
+ traverse_data(@data) do |v, *position|
819
+ iteary = ary
820
+ rank = 1
821
+ while rank < position.size
822
+ idx = position[rank - 1]
823
+ if iteary[idx].nil?
824
+ iteary = iteary[idx] = Array.new
825
+ else
826
+ iteary = iteary[idx]
827
+ end
828
+ rank += 1
829
+ end
830
+ if block_given?
831
+ iteary[position.last] = yield(v)
832
+ else
833
+ iteary[position.last] = v
834
+ end
835
+ end
836
+ end
837
+
838
+ def position
839
+ @position
840
+ end
841
+
842
+ private
843
+
844
+ ITEM_NAME = XSD::QName.new(nil, 'item')
845
+
846
+ def retrieve(idxary)
847
+ data = @data
848
+ rank = 1
849
+ while rank <= idxary.size
850
+ idx = idxary[rank - 1]
851
+ if data[idx].nil?
852
+ data = data[idx] = Array.new
853
+ else
854
+ data = data[idx]
855
+ end
856
+ rank += 1
857
+ end
858
+ data
859
+ end
860
+
861
+ def traverse_data(data, rank = 1)
862
+ idx = 0
863
+ while idx < ranksize(rank)
864
+ if rank < @rank
865
+ traverse_data(data[idx], rank + 1) do |*v|
866
+ v[1, 0] = idx
867
+ yield(*v)
868
+ end
869
+ else
870
+ yield(data[idx], idx)
871
+ end
872
+ idx += 1
873
+ end
874
+ end
875
+
876
+ def ranksize(rank)
877
+ @size[rank - 1]
878
+ end
879
+
880
+ def offsetnext
881
+ move = false
882
+ idx = @offset.size - 1
883
+ while !move && idx >= 0
884
+ @offset[idx] += 1
885
+ if @size_fixed
886
+ if @offset[idx] < @size[idx]
887
+ move = true
888
+ else
889
+ @offset[idx] = 0
890
+ idx -= 1
891
+ end
892
+ else
893
+ move = true
894
+ end
895
+ end
896
+ end
897
+
898
+ # Module function
899
+
900
+ public
901
+
902
+ def self.decode(elename, type, arytype)
903
+ typestr, nofary = parse_type(arytype.name)
904
+ rank = nofary.count(',') + 1
905
+ plain_arytype = XSD::QName.new(arytype.namespace, typestr)
906
+ o = SOAPArray.new(type, rank, plain_arytype)
907
+ size = []
908
+ nofary.split(',').each do |s|
909
+ if s.empty?
910
+ size.clear
911
+ break
912
+ else
913
+ size << s.to_i
914
+ end
915
+ end
916
+ unless size.empty?
917
+ o.size = size
918
+ o.size_fixed = true
919
+ end
920
+ o.elename = elename
921
+ o
922
+ end
923
+
924
+ private
925
+
926
+ def self.create_arytype(typename, rank)
927
+ "#{typename}[" << ',' * (rank - 1) << ']'
928
+ end
929
+
930
+ TypeParseRegexp = Regexp.new('^(.+)\[([\d,]*)\]$')
931
+
932
+ def self.parse_type(string)
933
+ TypeParseRegexp =~ string
934
+ return $1, $2
935
+ end
936
+ end
937
+
938
+
939
+ require 'soap/mapping/typeMap'
940
+
941
+
942
+ end