savon 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +127 -67
- data/lib/savon/client.rb +62 -83
- data/lib/savon/http/error.rb +1 -1
- data/lib/savon/soap/request_builder.rb +205 -0
- data/lib/savon/soap/xml.rb +1 -1
- data/lib/savon/version.rb +1 -1
- data/spec/fixtures/wsdl/multiple_namespaces.xml +31 -0
- data/spec/integration/request_spec.rb +50 -11
- data/spec/savon/client_spec.rb +181 -104
- data/spec/savon/http/error_spec.rb +1 -1
- data/spec/savon/soap/fault_spec.rb +1 -1
- data/spec/savon/soap/request_builder_spec.rb +207 -0
- metadata +42 -40
- data/lib/savon/wasabi/document.rb +0 -47
- data/spec/savon/wasabi/document_spec.rb +0 -58
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 1.2.0 (2012-09-15)
|
2
|
+
|
3
|
+
* Fix: [#312](https://github.com/rubiii/savon/pull/312) recursively determines the proper namespaces
|
4
|
+
for SOAP body Hashes with nested Arrays of Hashes.
|
5
|
+
|
6
|
+
* Improvement: [#318](https://github.com/rubiii/savon/pull/318) isolates building the request to
|
7
|
+
improve threadsafety.
|
8
|
+
|
9
|
+
* Refactoring: Use the `Wasabi::Document` with resolver instead of the custom `Savon::Wasabi::Document`.
|
10
|
+
|
1
11
|
## 1.1.0 (2012-06-28)
|
2
12
|
|
3
13
|
* Improvement: Changed Savon's core dependencies to be more strict and only allow bug fix changes.
|
@@ -5,7 +15,7 @@
|
|
5
15
|
This should improve the stability of the library and make it easier to update, because changes
|
6
16
|
to these core dependencies will be documented here as well.
|
7
17
|
|
8
|
-
* Fix: The latest version of Wasabi should now correctly detect the names of
|
18
|
+
* Fix: The latest version of Wasabi should now correctly detect the names of your operations.
|
9
19
|
So you should be able to just get the names of some operation:
|
10
20
|
|
11
21
|
``` ruby
|
@@ -13,19 +23,19 @@
|
|
13
23
|
# => [:authenticate, :find_user]
|
14
24
|
```
|
15
25
|
|
16
|
-
|
26
|
+
and pass the Symbol to execute a request:
|
17
27
|
|
18
28
|
``` ruby
|
19
29
|
client.request :authenticate, body: { token: "secret" }
|
20
30
|
```
|
21
31
|
|
22
|
-
|
23
|
-
|
32
|
+
If you still pass anything other than a single Symbol to that method, please open an issue!
|
33
|
+
You shouldn't need to specify a namespace or additional attributes for the tag.
|
24
34
|
|
25
35
|
* Refactoring: Moved code that sets the cookies from the last response for the
|
26
36
|
next request to `HTTPI::Request#set_cookies`.
|
27
37
|
|
28
|
-
|
38
|
+
### 1.0.0 (2012-06-09)
|
29
39
|
|
30
40
|
* Fix: `Savon.client` didn't pass the optional block.
|
31
41
|
|
@@ -34,7 +44,7 @@
|
|
34
44
|
the result of the callback to continue the request. It can also not call the callback block and return
|
35
45
|
some `HTTPI::Response` to mock the SOAP request.
|
36
46
|
|
37
|
-
|
47
|
+
As this change affects `savon_spec`, you need to update `savon_spec` to v1.3.0.
|
38
48
|
|
39
49
|
### 0.9.14 (2012-06-07)
|
40
50
|
|
@@ -99,8 +109,8 @@
|
|
99
109
|
The global config is cloned when a new client is initialized and gets used instead of the global one.
|
100
110
|
In addition, for `Savon::Model` classes, the config is cloned per class.
|
101
111
|
|
102
|
-
|
103
|
-
|
112
|
+
Closes [#84](https://github.com/rubiii/savon/issues/84) by allowing one logger per client and
|
113
|
+
[#270](https://github.com/rubiii/savon/issues/270) by allowing to specify error handling per client.
|
104
114
|
|
105
115
|
* Feature: Added an option to pretty print XML in log messages. Closes [#256](https://github.com/rubiii/savon/issues/256)
|
106
116
|
and [#280](https://github.com/rubiii/savon/issues/280).
|
@@ -309,16 +319,16 @@
|
|
309
319
|
Gyoku.xml(:first_name => "Mac") # => "<FirstName></Firstname>"
|
310
320
|
```
|
311
321
|
|
312
|
-
|
322
|
+
You can even define your own conversion formular.
|
313
323
|
|
314
324
|
``` ruby
|
315
325
|
Gyoku.convert_symbols_to { |key| key.upcase }
|
316
326
|
Gyoku.xml(:first_name => "Mac") # => "<FIRST_NAME></FIRST_NAME>"
|
317
327
|
```
|
318
328
|
|
319
|
-
|
320
|
-
|
321
|
-
|
329
|
+
This should also work for the SOAP input tag and SOAPAction header. So if you had to use a String for
|
330
|
+
the SOAP action to call because your services uses CamelCase instead of lowerCamelCase, you can now
|
331
|
+
change the default and use Symbols instead.
|
322
332
|
|
323
333
|
``` ruby
|
324
334
|
Gyoku.convert_symbols_to(:camelcase)
|
@@ -382,25 +392,31 @@
|
|
382
392
|
|
383
393
|
* Changed `Savon::WSSE` to be based on a Hash instead of relying on builder ([4cebc3](https://github.com/rubiii/savon/commit/4cebc3)).
|
384
394
|
|
385
|
-
|
386
|
-
|
395
|
+
`Savon::WSSE` now supports wsse:Timestamp headers ([issue #122](https://github.com/rubiii/savon/issues/122)) by setting
|
396
|
+
`Savon::WSSE#timestamp` to `true`:
|
387
397
|
|
388
|
-
|
389
|
-
|
390
|
-
|
398
|
+
``` ruby
|
399
|
+
client.request :some_method do
|
400
|
+
wsse.timestamp = true
|
401
|
+
end
|
402
|
+
```
|
391
403
|
|
392
|
-
|
404
|
+
or by setting `Savon::WSSE#created_at` or `Savon::WSSE#expires_at`:
|
393
405
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
406
|
+
``` ruby
|
407
|
+
client.request :some_method do
|
408
|
+
wsse.created_at = Time.now
|
409
|
+
wsse.expires_at = Time.now + 60
|
410
|
+
end
|
411
|
+
```
|
398
412
|
|
399
|
-
|
413
|
+
You can also add custom tags to the WSSE header ([issue #69](https://github.com/rubiii/savon/issues/69)):
|
400
414
|
|
401
|
-
|
402
|
-
|
403
|
-
|
415
|
+
``` ruby
|
416
|
+
client.request :some_method do
|
417
|
+
wsse["wsse:Security"]["wsse:UsernameToken"] = { "Organization" => "ACME", "Domain" => "acme.com" }
|
418
|
+
end
|
419
|
+
```
|
404
420
|
|
405
421
|
### 0.8.1 (2010-12-22)
|
406
422
|
|
@@ -430,8 +446,10 @@
|
|
430
446
|
([6df6a6](https://github.com/rubiii/savon/commit/6df6a6)). The method now accepts multiple arguments representing the response
|
431
447
|
Hash keys to traverse and returns the result as an Array or an empty Array in case the key is nil or does not exist.
|
432
448
|
|
433
|
-
|
434
|
-
|
449
|
+
``` ruby
|
450
|
+
response.to_array :get_user_response, :return
|
451
|
+
# => [{ :id => 1, :name => "foo"}, { :id => 2, :name => "bar"}]
|
452
|
+
```
|
435
453
|
|
436
454
|
### 0.8.0.beta.3 (2010-11-06)
|
437
455
|
|
@@ -444,6 +462,7 @@
|
|
444
462
|
the SOAP response Hash when a pattern (specified as an Array of Regexps and Symbols) matches the response. If for example
|
445
463
|
your response always looks like ".+Response/return" as in:
|
446
464
|
|
465
|
+
``` xml
|
447
466
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
448
467
|
<soap:Body>
|
449
468
|
<ns2:authenticateResponse xmlns:ns2="http://v1_0.ws.user.example.com">
|
@@ -453,23 +472,30 @@
|
|
453
472
|
</ns2:authenticateResponse>
|
454
473
|
</soap:Body>
|
455
474
|
</soap:Envelope>
|
475
|
+
```
|
456
476
|
|
457
|
-
|
477
|
+
you could set the response pattern to:
|
458
478
|
|
459
|
-
|
460
|
-
|
461
|
-
|
479
|
+
``` ruby
|
480
|
+
Savon.configure do |config|
|
481
|
+
config.response_pattern = [/.+_response/, :return]
|
482
|
+
end
|
483
|
+
```
|
462
484
|
|
463
|
-
|
485
|
+
then instead of calling:
|
464
486
|
|
465
|
-
|
487
|
+
``` ruby
|
488
|
+
response.to_hash[:authenticate_response][:return] # :some => "thing"
|
489
|
+
```
|
466
490
|
|
467
|
-
|
491
|
+
to get the actual content, Savon::SOAP::Response#to_hash will try to apply given the pattern:
|
468
492
|
|
469
|
-
|
493
|
+
``` ruby
|
494
|
+
response.to_hash # :some => "thing"
|
495
|
+
```
|
470
496
|
|
471
|
-
|
472
|
-
|
497
|
+
Please notice, that if you don't specify a response pattern or if the pattern doesn't match the
|
498
|
+
response, Savon will behave like it always did.
|
473
499
|
|
474
500
|
* Added `Savon::SOAP::Response#to_array` (which also uses the response pattern).
|
475
501
|
|
@@ -478,42 +504,52 @@
|
|
478
504
|
* Changed `Savon::Client.new` to accept a block instead of multiple Hash arguments. You can access the
|
479
505
|
wsdl, http and wsse objects inside the block to configure your client for a particular service.
|
480
506
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
507
|
+
``` ruby
|
508
|
+
# Instantiating a client to work with a WSDL document
|
509
|
+
client = Savon::Client.new do
|
510
|
+
wsdl.document = "http://example.com?wsdl"
|
511
|
+
end
|
512
|
+
```
|
485
513
|
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
514
|
+
``` ruby
|
515
|
+
# Directly accessing the SOAP endpoint
|
516
|
+
client = Savon::Client.new do
|
517
|
+
wsdl.endpoint = "http://example.com"
|
518
|
+
wsdl.namespace = "http://v1.example.com"
|
519
|
+
end
|
520
|
+
```
|
491
521
|
|
492
522
|
* Fix for [issue #77](https://github.com/rubiii/savon/issues/77), which means you can now use
|
493
523
|
local WSDL documents:
|
494
524
|
|
495
|
-
|
496
|
-
|
497
|
-
|
525
|
+
``` ruby
|
526
|
+
client = Savon::Client.new do
|
527
|
+
wsdl.document = "../wsdl/service.xml"
|
528
|
+
end
|
529
|
+
```
|
498
530
|
|
499
531
|
* Changed the way SOAP requests are being dispatched. Instead of using method_missing, you now use
|
500
532
|
the new `request` method, which also accepts a block for you to access the wsdl, http, wsse and
|
501
533
|
soap object. Please notice, that a new soap object is created for every request. So you can only
|
502
534
|
access it inside this block.
|
503
535
|
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
536
|
+
``` ruby
|
537
|
+
# A simple request to an :authenticate method
|
538
|
+
client.request :authenticate do
|
539
|
+
soap.body = { :id => 1 }
|
540
|
+
end
|
541
|
+
```
|
508
542
|
|
509
543
|
* The new `Savon::Client#request` method fixes issues [#37](https://github.com/rubiii/savon/issues/37),
|
510
544
|
[#61](https://github.com/rubiii/savon/issues/61) and [#64](https://github.com/rubiii/savon/issues/64),
|
511
545
|
which report problems with namespacing the SOAP input tag and attaching attributes to it.
|
512
546
|
Some usage examples:
|
513
547
|
|
514
|
-
|
515
|
-
|
516
|
-
|
548
|
+
``` ruby
|
549
|
+
client.request :get_user # Input tag: <getUser>
|
550
|
+
client.request :wsdl, "GetUser" # Input tag: <wsdl:GetUser>
|
551
|
+
client.request :get_user :active => true # Input tag: <getUser active="true">
|
552
|
+
```
|
517
553
|
|
518
554
|
* Savon's new `request` method respects the given namespace. If you don't give it a namespace,
|
519
555
|
Savon will set the target namespace to "xmlns:wsdl". But if you do specify a namespace, it will
|
@@ -571,13 +607,17 @@
|
|
571
607
|
* Added support for gzipped requests and responses (http://github.com/lucascs). While gzipped SOAP
|
572
608
|
responses are decoded automatically, you have to manually instruct Savon to gzip SOAP requests:
|
573
609
|
|
574
|
-
|
610
|
+
``` ruby
|
611
|
+
client = Savon::Client.new "http://example.com/UserService?wsdl", :gzip => true
|
612
|
+
```
|
575
613
|
|
576
614
|
* Fix for [issue #51](https://github.com/rubiii/savon/issues/51). Added the :soap_endpoint option to
|
577
615
|
`Savon::Client.new` which lets you specify a SOAP endpoint per client instance:
|
578
616
|
|
579
|
-
|
580
|
-
|
617
|
+
``` ruby
|
618
|
+
client = Savon::Client.new "http://example.com/UserService?wsdl",
|
619
|
+
:soap_endpoint => "http://localhost/UserService"
|
620
|
+
```
|
581
621
|
|
582
622
|
* Fix for [issue #50](https://github.com/rubiii/savon/issues/50). Savon still escapes special characters
|
583
623
|
in SOAP request Hash values, but you can now append an exclamation mark to Hash keys specifying that
|
@@ -667,28 +707,38 @@ Pay attention to the following list and read the updated Wiki: http://wiki.githu
|
|
667
707
|
|
668
708
|
* SSL client authentication needs to be defined directly on the `Net::HTTP` object:
|
669
709
|
|
710
|
+
``` ruby
|
670
711
|
client.request.http.client_cert = ...
|
712
|
+
```
|
671
713
|
|
672
714
|
I added a shortcut method for setting all options through a Hash similar to the previous implementation:
|
673
715
|
|
716
|
+
``` ruby
|
674
717
|
client.request.http.ssl_client_auth :client_cert => ...
|
718
|
+
```
|
675
719
|
|
676
720
|
* Open and read timeouts also need to be set on the `Net::HTTP` object:
|
677
|
-
|
721
|
+
|
722
|
+
``` ruby
|
678
723
|
client.request.http.open_timeout = 30
|
679
724
|
client.request.http.read_timeout = 30
|
725
|
+
```
|
680
726
|
|
681
727
|
* Please refer to the `Net::HTTP` documentation for more details:
|
682
728
|
http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/index.html
|
683
729
|
|
684
730
|
* Thanks to JulianMorrison, Savon now supports HTTP basic authentication:
|
685
731
|
|
732
|
+
``` ruby
|
686
733
|
client.request.http.basic_auth "username", "password"
|
734
|
+
```
|
687
735
|
|
688
736
|
* Julian also added a way to explicitly specify the order of Hash keys and values, so you should now be able
|
689
737
|
to work with services requiring a specific order of input parameters while still using Hash input.
|
690
738
|
|
691
|
-
|
739
|
+
``` ruby
|
740
|
+
client.find_user { |soap| soap.body = { :name => "Lucy", :id => 666, :@inorder => [:id, :name] } }
|
741
|
+
```
|
692
742
|
|
693
743
|
* `Savon::Response#to_hash` now returns the content inside of "soap:Body" instead of trying to go one
|
694
744
|
level deeper and return it's content. The previous implementation only worked when the "soap:Body" element
|
@@ -696,7 +746,9 @@ Pay attention to the following list and read the updated Wiki: http://wiki.githu
|
|
696
746
|
|
697
747
|
* Added `Savon::SOAP#namespace` as a shortcut for setting the "xmlns:wsdl" namespace.
|
698
748
|
|
749
|
+
``` ruby
|
699
750
|
soap.namespace = "http://example.com"
|
751
|
+
```
|
700
752
|
|
701
753
|
### 0.6.8 (2010-01-01)
|
702
754
|
|
@@ -709,9 +761,11 @@ Pay attention to the following list and read the updated Wiki: http://wiki.githu
|
|
709
761
|
please take a look at the `action` and `input` methods of the `Savon::SOAP` object.
|
710
762
|
One specific problem I know of is working with the createsend WSDL and its namespaced actions.
|
711
763
|
|
712
|
-
|
764
|
+
To make it work, call the SOAP action without namespace and specify the input manually:
|
713
765
|
|
766
|
+
``` ruby
|
714
767
|
client.get_api_key { |soap| soap.input = "User.GetApiKey" }
|
768
|
+
```
|
715
769
|
|
716
770
|
### 0.6.7 (2009-12-18)
|
717
771
|
|
@@ -743,11 +797,13 @@ Pay attention to the following list and read the updated Wiki: http://wiki.githu
|
|
743
797
|
|
744
798
|
* Replaced WSDL document with stream parsing.
|
745
799
|
|
746
|
-
|
800
|
+
```
|
801
|
+
Benchmarks (1000 SOAP calls):
|
747
802
|
|
748
|
-
|
749
|
-
|
750
|
-
|
803
|
+
user system total real
|
804
|
+
0.6.4 72.180000 8.280000 80.460000 (750.799011)
|
805
|
+
0.6.3 192.900000 19.630000 212.530000 (914.031865)
|
806
|
+
```
|
751
807
|
|
752
808
|
### 0.6.3 (2009-12-11)
|
753
809
|
|
@@ -755,19 +811,23 @@ Pay attention to the following list and read the updated Wiki: http://wiki.githu
|
|
755
811
|
|
756
812
|
* Added global and per request options for disabling `Savon::WSDL`.
|
757
813
|
|
814
|
+
```
|
758
815
|
Benchmarks (1000 SOAP calls):
|
759
816
|
|
760
817
|
user system total real
|
761
818
|
WSDL 192.900000 19.630000 212.530000 (914.031865)
|
762
819
|
disabled WSDL 5.680000 1.340000 7.020000 (298.265318)
|
820
|
+
```
|
763
821
|
|
764
822
|
* Improved XPath expressions for parsing the WSDL document.
|
765
823
|
|
824
|
+
```
|
766
825
|
Benchmarks (1000 SOAP calls):
|
767
826
|
|
768
827
|
user system total real
|
769
828
|
0.6.3 192.900000 19.630000 212.530000 (914.031865)
|
770
829
|
0.6.2 574.720000 78.380000 653.100000 (1387.778539)
|
830
|
+
```
|
771
831
|
|
772
832
|
### 0.6.2 (2009-12-06)
|
773
833
|
|
data/lib/savon/client.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
require "wasabi/document"
|
1
2
|
require "httpi/request"
|
2
3
|
require "akami"
|
3
4
|
|
4
|
-
require "savon/wasabi/document"
|
5
5
|
require "savon/soap/xml"
|
6
6
|
require "savon/soap/request"
|
7
7
|
require "savon/soap/response"
|
8
|
+
require "savon/soap/request_builder"
|
8
9
|
|
9
10
|
module Savon
|
10
11
|
|
@@ -40,7 +41,7 @@ module Savon
|
|
40
41
|
# Accessor for the <tt>Savon::Config</tt>.
|
41
42
|
attr_accessor :config
|
42
43
|
|
43
|
-
# Returns the <tt>
|
44
|
+
# Returns the <tt>Wasabi::Document</tt>.
|
44
45
|
def wsdl
|
45
46
|
@wsdl ||= Wasabi::Document.new
|
46
47
|
end
|
@@ -55,13 +56,9 @@ module Savon
|
|
55
56
|
@wsse ||= Akami.wsse
|
56
57
|
end
|
57
58
|
|
58
|
-
# Returns the <tt>Savon::SOAP::XML</tt> object. Please notice, that this object is only available
|
59
|
-
# in a block given to <tt>Savon::Client#request</tt>. A new instance of this object is created
|
60
|
-
# per SOAP request.
|
61
|
-
attr_reader :soap
|
62
|
-
|
63
59
|
# Executes a SOAP request for a given SOAP action. Accepts a +block+ which is evaluated in the
|
64
|
-
# context of
|
60
|
+
# context of the <tt>SOAP::RequestBuilder</tt> object to let you access its +soap+, +wsdl+,
|
61
|
+
# +http+ and +wsse+ methods.
|
65
62
|
#
|
66
63
|
# == Examples
|
67
64
|
#
|
@@ -76,12 +73,17 @@ module Savon
|
|
76
73
|
def request(*args, &block)
|
77
74
|
raise ArgumentError, "Savon::Client#request requires at least one argument" if args.empty?
|
78
75
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
76
|
+
options = extract_options(args)
|
77
|
+
|
78
|
+
request_builder = SOAP::RequestBuilder.new(options.delete(:input), options)
|
79
|
+
request_builder.wsdl = wsdl
|
80
|
+
request_builder.http = http.dup
|
81
|
+
request_builder.wsse = wsse.dup
|
82
|
+
request_builder.config = config.dup
|
83
83
|
|
84
|
-
|
84
|
+
post_configuration = lambda { process(0, request_builder, &block) if block }
|
85
|
+
|
86
|
+
response = request_builder.request(&post_configuration).response
|
85
87
|
http.set_cookies(response.http)
|
86
88
|
|
87
89
|
if wsse.verify_response
|
@@ -93,91 +95,68 @@ module Savon
|
|
93
95
|
|
94
96
|
private
|
95
97
|
|
96
|
-
#
|
97
|
-
|
98
|
-
|
99
|
-
#
|
100
|
-
attr_accessor :original_self
|
101
|
-
|
102
|
-
# Expects an Array of +args+ and returns an Array containing the namespace (might be +nil+),
|
103
|
-
# the SOAP input and a Hash of attributes for the input tag (which might be empty).
|
98
|
+
# Expects an Array of +args+ and returns a Hash containing the SOAP input,
|
99
|
+
# the namespace (might be +nil+), the SOAP action (might be +nil+),
|
100
|
+
# the SOAP body (might be +nil+), and a Hash of attributes for the input
|
101
|
+
# tag (which might be empty).
|
104
102
|
def extract_options(args)
|
105
103
|
attributes = Hash === args.last ? args.pop : {}
|
106
|
-
|
107
|
-
|
104
|
+
body = attributes.delete(:body)
|
105
|
+
soap_action = attributes.delete(:soap_action)
|
108
106
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
# Expects an Array of +args+ to preconfigure the system.
|
113
|
-
def preconfigure(args)
|
114
|
-
soap.endpoint = wsdl.endpoint
|
115
|
-
soap.element_form_default = wsdl.element_form_default
|
116
|
-
|
117
|
-
body = args[2].delete(:body)
|
118
|
-
soap.body = body if body
|
119
|
-
|
120
|
-
wsdl.type_namespaces.each do |path, uri|
|
121
|
-
soap.use_namespace(path, uri)
|
122
|
-
end
|
123
|
-
|
124
|
-
wsdl.type_definitions.each do |path, type|
|
125
|
-
soap.types[path] = type
|
126
|
-
end
|
127
|
-
|
128
|
-
soap_action = args[2].delete(:soap_action) || args[1]
|
129
|
-
set_soap_action soap_action
|
130
|
-
|
131
|
-
if wsdl.document? && (operation = wsdl.operations[args[1]]) && operation[:namespace_identifier]
|
132
|
-
soap.namespace_identifier = operation[:namespace_identifier].to_sym
|
133
|
-
soap.namespace = wsdl.parser.namespaces[soap.namespace_identifier.to_s]
|
134
|
-
|
135
|
-
# Override nil namespace with one specified in WSDL
|
136
|
-
args[0] = soap.namespace_identifier unless args[0]
|
137
|
-
else
|
138
|
-
soap.namespace_identifier = args[0]
|
139
|
-
soap.namespace = wsdl.namespace
|
140
|
-
end
|
141
|
-
|
142
|
-
set_soap_input *args
|
143
|
-
end
|
144
|
-
|
145
|
-
# Expects an +input+ and sets the +SOAPAction+ HTTP headers.
|
146
|
-
def set_soap_action(input_tag)
|
147
|
-
soap_action = wsdl.soap_action(input_tag.to_sym) if wsdl.document?
|
148
|
-
soap_action ||= Gyoku::XMLKey.create(input_tag).to_sym
|
149
|
-
http.headers["SOAPAction"] = %{"#{soap_action}"}
|
150
|
-
end
|
107
|
+
namespace_identifier = args.size > 1 ? args.shift.to_sym : nil
|
108
|
+
input = args.first
|
151
109
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
110
|
+
remove_blank_values(
|
111
|
+
:namespace_identifier => namespace_identifier,
|
112
|
+
:input => input,
|
113
|
+
:attributes => attributes,
|
114
|
+
:body => body,
|
115
|
+
:soap_action => soap_action
|
116
|
+
)
|
157
117
|
end
|
158
118
|
|
159
119
|
# Processes a given +block+. Yields objects if the block expects any arguments.
|
160
|
-
# Otherwise evaluates the block in the context of
|
161
|
-
def process(offset = 0, &block)
|
162
|
-
block.arity > 0 ? yield_objects(offset, &block) : evaluate(&block)
|
120
|
+
# Otherwise evaluates the block in the context of +instance+.
|
121
|
+
def process(offset = 0, instance = self, &block)
|
122
|
+
block.arity > 0 ? yield_objects(offset, instance, &block) : evaluate(instance, &block)
|
163
123
|
end
|
164
124
|
|
165
125
|
# Yields a number of objects to a given +block+ depending on how many arguments
|
166
126
|
# the block is expecting.
|
167
|
-
def yield_objects(offset, &block)
|
168
|
-
|
127
|
+
def yield_objects(offset, instance, &block)
|
128
|
+
to_yield = [:soap, :wsdl, :http, :wsse]
|
129
|
+
yield *(to_yield[offset, block.arity].map { |obj_name| instance.send(obj_name) })
|
169
130
|
end
|
170
131
|
|
171
|
-
# Evaluates a given +block+ inside
|
172
|
-
def evaluate(&block)
|
173
|
-
|
174
|
-
|
132
|
+
# Evaluates a given +block+ inside +instance+. Stores the original block binding.
|
133
|
+
def evaluate(instance, &block)
|
134
|
+
original_self = eval "self", block.binding
|
135
|
+
|
136
|
+
# A proxy that attemps to make method calls on +instance+. If a NoMethodError is
|
137
|
+
# raised, the call will be made on +original_self+.
|
138
|
+
proxy = Object.new
|
139
|
+
proxy.instance_eval do
|
140
|
+
class << self
|
141
|
+
attr_accessor :original_self, :instance
|
142
|
+
end
|
143
|
+
|
144
|
+
def method_missing(method, *args, &block)
|
145
|
+
instance.send(method, *args, &block)
|
146
|
+
rescue NoMethodError
|
147
|
+
original_self.send(method, *args, &block)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
proxy.instance = instance
|
152
|
+
proxy.original_self = original_self
|
153
|
+
|
154
|
+
proxy.instance_eval &block
|
175
155
|
end
|
176
156
|
|
177
|
-
#
|
178
|
-
def
|
179
|
-
|
180
|
-
original_self.send method, *args, &block
|
157
|
+
# Removes all blank values from a given +hash+.
|
158
|
+
def remove_blank_values(hash)
|
159
|
+
hash.delete_if { |_, value| value.respond_to?(:empty?) ? value.empty? : !value }
|
181
160
|
end
|
182
161
|
|
183
162
|
end
|