savon 0.7.9 → 0.8.0.beta.1
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/.gitignore +9 -0
- data/.rspec +1 -0
- data/.yardopts +2 -0
- data/CHANGELOG.md +332 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +37 -0
- data/Rakefile +28 -39
- data/autotest/discover.rb +1 -0
- data/lib/savon.rb +10 -31
- data/lib/savon/client.rb +116 -98
- data/lib/savon/core_ext/array.rb +36 -22
- data/lib/savon/core_ext/datetime.rb +15 -6
- data/lib/savon/core_ext/hash.rb +122 -94
- data/lib/savon/core_ext/object.rb +19 -11
- data/lib/savon/core_ext/string.rb +62 -57
- data/lib/savon/core_ext/symbol.rb +13 -5
- data/lib/savon/error.rb +6 -0
- data/lib/savon/global.rb +75 -0
- data/lib/savon/http/error.rb +42 -0
- data/lib/savon/soap.rb +8 -283
- data/lib/savon/soap/fault.rb +48 -0
- data/lib/savon/soap/request.rb +61 -0
- data/lib/savon/soap/response.rb +65 -0
- data/lib/savon/soap/xml.rb +132 -0
- data/lib/savon/version.rb +2 -2
- data/lib/savon/wsdl/document.rb +107 -0
- data/lib/savon/wsdl/parser.rb +90 -0
- data/lib/savon/wsdl/request.rb +35 -0
- data/lib/savon/wsse.rb +42 -104
- data/savon.gemspec +26 -0
- data/spec/fixtures/response/response_fixture.rb +26 -26
- data/spec/fixtures/response/xml/list.xml +18 -0
- data/spec/fixtures/wsdl/wsdl_fixture.rb +6 -0
- data/spec/fixtures/wsdl/wsdl_fixture.yml +4 -4
- data/spec/savon/client_spec.rb +274 -51
- data/spec/savon/core_ext/datetime_spec.rb +1 -1
- data/spec/savon/core_ext/hash_spec.rb +40 -4
- data/spec/savon/core_ext/object_spec.rb +1 -1
- data/spec/savon/core_ext/string_spec.rb +0 -12
- data/spec/savon/http/error_spec.rb +52 -0
- data/spec/savon/savon_spec.rb +90 -0
- data/spec/savon/soap/fault_spec.rb +80 -0
- data/spec/savon/soap/request_spec.rb +45 -0
- data/spec/savon/soap/response_spec.rb +153 -0
- data/spec/savon/soap/xml_spec.rb +249 -0
- data/spec/savon/soap_spec.rb +4 -177
- data/spec/savon/{wsdl_spec.rb → wsdl/document_spec.rb} +54 -17
- data/spec/savon/wsdl/request_spec.rb +15 -0
- data/spec/savon/wsse_spec.rb +123 -92
- data/spec/spec_helper.rb +19 -4
- data/spec/support/endpoint.rb +25 -0
- metadata +97 -97
- data/.autotest +0 -5
- data/CHANGELOG +0 -176
- data/README.rdoc +0 -64
- data/lib/savon/core_ext.rb +0 -8
- data/lib/savon/core_ext/net_http.rb +0 -19
- data/lib/savon/core_ext/uri.rb +0 -10
- data/lib/savon/logger.rb +0 -56
- data/lib/savon/request.rb +0 -138
- data/lib/savon/response.rb +0 -174
- data/lib/savon/wsdl.rb +0 -137
- data/lib/savon/wsdl_stream.rb +0 -85
- data/spec/basic_spec_helper.rb +0 -11
- data/spec/endpoint_helper.rb +0 -23
- data/spec/http_stubs.rb +0 -26
- data/spec/integration/http_basic_auth_spec.rb +0 -16
- data/spec/integration/server.rb +0 -51
- data/spec/savon/core_ext/net_http_spec.rb +0 -38
- data/spec/savon/core_ext/uri_spec.rb +0 -19
- data/spec/savon/request_spec.rb +0 -117
- data/spec/savon/response_spec.rb +0 -179
- data/spec/spec.opts +0 -4
@@ -0,0 +1,48 @@
|
|
1
|
+
require "savon/error"
|
2
|
+
require "savon/soap/xml"
|
3
|
+
|
4
|
+
module Savon
|
5
|
+
module SOAP
|
6
|
+
|
7
|
+
# = Savon::SOAP::Fault
|
8
|
+
#
|
9
|
+
# Represents a SOAP fault. Contains the original <tt>HTTPI::Response</tt>.
|
10
|
+
class Fault < Error
|
11
|
+
|
12
|
+
# Expects an <tt>HTTPI::Response</tt>.
|
13
|
+
def initialize(http)
|
14
|
+
self.http = http
|
15
|
+
end
|
16
|
+
|
17
|
+
# Accessor for the <tt>HTTPI::Response</tt>.
|
18
|
+
attr_accessor :http
|
19
|
+
|
20
|
+
# Returns whether a SOAP fault is present.
|
21
|
+
def present?
|
22
|
+
@present ||= http.body =~ /<soap:Fault>/
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the SOAP fault message.
|
26
|
+
def to_s
|
27
|
+
return "" unless present?
|
28
|
+
@message ||= message_by_version to_hash[:fault]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the SOAP response body as a Hash.
|
32
|
+
def to_hash
|
33
|
+
@hash ||= Savon::SOAP::XML.to_hash http.body
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def message_by_version(fault)
|
39
|
+
if fault[:faultcode]
|
40
|
+
"(#{fault[:faultcode]}) #{fault[:faultstring]}"
|
41
|
+
elsif fault[:code]
|
42
|
+
"(#{fault[:code][:value]}) #{fault[:reason][:text]}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "httpi"
|
2
|
+
require "savon/soap/response"
|
3
|
+
|
4
|
+
module Savon
|
5
|
+
module SOAP
|
6
|
+
|
7
|
+
# = Savon::SOAP::Request
|
8
|
+
#
|
9
|
+
# Executes SOAP requests.
|
10
|
+
class Request
|
11
|
+
|
12
|
+
# Content-Types by SOAP version.
|
13
|
+
ContentType = { 1 => "text/xml;charset=UTF-8", 2 => "application/soap+xml;charset=UTF-8" }
|
14
|
+
|
15
|
+
# Expects an <tt>HTTPI::Request</tt> and a <tt>Savon::SOAP::XML</tt> object.
|
16
|
+
def initialize(request, soap)
|
17
|
+
self.request = setup(request, soap)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Accessor for the <tt>HTTPI::Request</tt>.
|
21
|
+
attr_accessor :request
|
22
|
+
|
23
|
+
# Executes the request and returns the response.
|
24
|
+
def response
|
25
|
+
@response ||= with_logging { HTTPI.post request }
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Sets up the +request+ using a given +soap+ object.
|
31
|
+
def setup(request, soap)
|
32
|
+
request.url = soap.endpoint
|
33
|
+
request.headers["Content-Type"] ||= ContentType[soap.version]
|
34
|
+
request.body = soap.to_xml
|
35
|
+
request
|
36
|
+
end
|
37
|
+
|
38
|
+
# Logs the HTTP request, yields to a given +block+ and returns a <tt>Savon::SOAP::Response</tt>.
|
39
|
+
def with_logging
|
40
|
+
log_request request.url, request.headers, request.body
|
41
|
+
response = yield
|
42
|
+
log_response response.code, response.body
|
43
|
+
SOAP::Response.new response
|
44
|
+
end
|
45
|
+
|
46
|
+
# Logs the SOAP request +url+, +headers+ and +body+.
|
47
|
+
def log_request(url, headers, body)
|
48
|
+
Savon.log "SOAP request: #{url}"
|
49
|
+
Savon.log headers.map { |key, value| "#{key}: #{value}" }.join(", ")
|
50
|
+
Savon.log body
|
51
|
+
end
|
52
|
+
|
53
|
+
# Logs the SOAP response +code+ and +body+.
|
54
|
+
def log_response(code, body)
|
55
|
+
Savon.log "SOAP response (status #{code}):"
|
56
|
+
Savon.log body
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "savon/soap/xml"
|
2
|
+
require "savon/soap/fault"
|
3
|
+
require "savon/http/error"
|
4
|
+
|
5
|
+
module Savon
|
6
|
+
module SOAP
|
7
|
+
|
8
|
+
# = Savon::SOAP::Response
|
9
|
+
#
|
10
|
+
# Represents the SOAP response and contains the HTTP response.
|
11
|
+
class Response
|
12
|
+
|
13
|
+
# Expects an <tt>HTTPI::Response</tt> and handles errors.
|
14
|
+
def initialize(response)
|
15
|
+
self.http = response
|
16
|
+
raise_errors if Savon.raise_errors?
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_accessor :http
|
20
|
+
|
21
|
+
# Returns whether the request was successful.
|
22
|
+
def success?
|
23
|
+
!soap_fault? && !http_error?
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns whether there was a SOAP fault.
|
27
|
+
def soap_fault?
|
28
|
+
soap_fault.present?
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the <tt>Savon::SOAP::Fault</tt>.
|
32
|
+
def soap_fault
|
33
|
+
@soap_fault ||= Fault.new http
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns whether there was an HTTP error.
|
37
|
+
def http_error?
|
38
|
+
http_error.present?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the <tt>Savon::HTTP::Error</tt>.
|
42
|
+
def http_error
|
43
|
+
@http_error ||= HTTP::Error.new http
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the SOAP response body as a Hash.
|
47
|
+
def to_hash
|
48
|
+
@hash ||= Savon::SOAP::XML.to_hash to_xml
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the SOAP response XML.
|
52
|
+
def to_xml
|
53
|
+
http.body
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def raise_errors
|
59
|
+
raise soap_fault if soap_fault?
|
60
|
+
raise http_error if http_error?
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require "builder"
|
2
|
+
require "crack/xml"
|
3
|
+
require "savon/soap"
|
4
|
+
require "savon/core_ext/hash"
|
5
|
+
|
6
|
+
module Savon
|
7
|
+
module SOAP
|
8
|
+
|
9
|
+
# = Savon::SOAP::XML
|
10
|
+
#
|
11
|
+
# Represents the SOAP request XML. Contains various global and per request/instance settings
|
12
|
+
# like the SOAP version, header, body and namespaces.
|
13
|
+
class XML
|
14
|
+
|
15
|
+
# XML Schema Type namespaces.
|
16
|
+
SchemaTypes = {
|
17
|
+
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
18
|
+
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance"
|
19
|
+
}
|
20
|
+
|
21
|
+
def self.to_hash(xml)
|
22
|
+
(Crack::XML.parse(xml) rescue {}).find_soap_body
|
23
|
+
end
|
24
|
+
|
25
|
+
# Accepts an +endpoint+, an +input+ tag and a SOAP +body+.
|
26
|
+
def initialize(endpoint = nil, input = nil, body = nil)
|
27
|
+
self.endpoint = endpoint if endpoint
|
28
|
+
self.input = input if input
|
29
|
+
self.body = body if body
|
30
|
+
end
|
31
|
+
|
32
|
+
# Accessor for the SOAP +input+ tag.
|
33
|
+
attr_accessor :input
|
34
|
+
|
35
|
+
# Accessor for the SOAP +endpoint+.
|
36
|
+
attr_accessor :endpoint
|
37
|
+
|
38
|
+
# Sets the SOAP +version+.
|
39
|
+
def version=(version)
|
40
|
+
raise ArgumentError, "Invalid SOAP version: #{version}" unless SOAP::Versions.include? version
|
41
|
+
@version = version
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the SOAP +version+. Defaults to <tt>Savon.soap_version</tt>.
|
45
|
+
def version
|
46
|
+
@version ||= Savon.soap_version
|
47
|
+
end
|
48
|
+
|
49
|
+
# Sets the SOAP +header+ Hash.
|
50
|
+
attr_writer :header
|
51
|
+
|
52
|
+
# Returns the SOAP +header+. Defaults to an empty Hash.
|
53
|
+
def header
|
54
|
+
@header ||= {}
|
55
|
+
end
|
56
|
+
|
57
|
+
# Sets the +namespaces+ Hash.
|
58
|
+
attr_writer :namespaces
|
59
|
+
|
60
|
+
# Returns the +namespaces+. Defaults to a Hash containing the <tt>xmlns:env</tt> namespace.
|
61
|
+
def namespaces
|
62
|
+
@namespaces ||= { "xmlns:env" => SOAP::Namespace[version] }
|
63
|
+
end
|
64
|
+
|
65
|
+
# Sets the default namespace identifier.
|
66
|
+
attr_writer :namespace_identifier
|
67
|
+
|
68
|
+
# Returns the default namespace identifier.
|
69
|
+
def namespace_identifier
|
70
|
+
@namespace_identifier ||= :wsdl
|
71
|
+
end
|
72
|
+
|
73
|
+
# Accessor for the default namespace URI.
|
74
|
+
attr_accessor :namespace
|
75
|
+
|
76
|
+
# Accessor for the <tt>Savon::WSSE</tt> object.
|
77
|
+
attr_accessor :wsse
|
78
|
+
|
79
|
+
# Accessor for the SOAP +body+. Expected to be a Hash that can be translated to XML via Hash.to_soap_xml
|
80
|
+
# or any other Object responding to to_s.
|
81
|
+
attr_accessor :body
|
82
|
+
|
83
|
+
# Accepts a +block+ and yields a <tt>Builder::XmlMarkup</tt> object to let you create custom XML.
|
84
|
+
def xml
|
85
|
+
@xml = yield builder if block_given?
|
86
|
+
end
|
87
|
+
|
88
|
+
# Accepts an XML String and lets you specify a completely custom request body.
|
89
|
+
attr_writer :xml
|
90
|
+
|
91
|
+
# Returns the XML for a SOAP request.
|
92
|
+
def to_xml
|
93
|
+
@xml ||= builder.env :Envelope, complete_namespaces do |xml|
|
94
|
+
xml.env(:Header) { xml << header_for_xml } unless header_for_xml.empty?
|
95
|
+
xml.env(:Body) { xml.tag!(*input) { xml << body_to_xml } }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# Returns a new <tt>Builder::XmlMarkup</tt> object.
|
102
|
+
def builder
|
103
|
+
builder = Builder::XmlMarkup.new
|
104
|
+
builder.instruct!
|
105
|
+
builder
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns the complete Hash of namespaces.
|
109
|
+
def complete_namespaces
|
110
|
+
defaults = SchemaTypes.dup
|
111
|
+
defaults["xmlns:#{namespace_identifier}"] = namespace if namespace
|
112
|
+
defaults.merge namespaces
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns the SOAP header as an XML String.
|
116
|
+
def header_for_xml
|
117
|
+
header.to_soap_xml + wsse_header
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns the WSSE header or an empty String in case WSSE was not set.
|
121
|
+
def wsse_header
|
122
|
+
wsse.respond_to?(:to_xml) ? wsse.to_xml : ""
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns the SOAP body as an XML String.
|
126
|
+
def body_to_xml
|
127
|
+
body.respond_to?(:to_soap_xml) ? body.to_soap_xml : body.to_s
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
data/lib/savon/version.rb
CHANGED
@@ -0,0 +1,107 @@
|
|
1
|
+
require "rexml/document"
|
2
|
+
|
3
|
+
require "savon/wsdl/request"
|
4
|
+
require "savon/wsdl/parser"
|
5
|
+
|
6
|
+
module Savon
|
7
|
+
module WSDL
|
8
|
+
|
9
|
+
# = Savon::WSDL::Document
|
10
|
+
#
|
11
|
+
# Represents the WSDL of your service, including information like the namespace URI,
|
12
|
+
# the SOAP endpoint and available SOAP actions.
|
13
|
+
class Document
|
14
|
+
|
15
|
+
# Accepts an <tt>HTTPI::Request</tt> and a +document+.
|
16
|
+
def initialize(request = nil, document = nil)
|
17
|
+
self.request = request
|
18
|
+
self.document = document
|
19
|
+
end
|
20
|
+
|
21
|
+
# Accessor for the <tt>HTTPI::Request</tt> to use.
|
22
|
+
attr_accessor :request
|
23
|
+
|
24
|
+
def present?
|
25
|
+
!!@document
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the namespace URI of the WSDL.
|
29
|
+
def namespace
|
30
|
+
@namespace ||= parser.namespace
|
31
|
+
end
|
32
|
+
|
33
|
+
# Sets the SOAP namespace.
|
34
|
+
attr_writer :namespace
|
35
|
+
|
36
|
+
# Returns the SOAP endpoint.
|
37
|
+
def endpoint
|
38
|
+
@endpoint ||= parser.endpoint
|
39
|
+
end
|
40
|
+
|
41
|
+
# Sets the SOAP endpoint.
|
42
|
+
attr_writer :endpoint
|
43
|
+
|
44
|
+
# Returns an Array of available SOAP actions.
|
45
|
+
def soap_actions
|
46
|
+
@soap_actions ||= parser.operations.keys
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns the SOAP action for a given +key+.
|
50
|
+
def soap_action(key)
|
51
|
+
operations[key][:action] if present? && operations[key]
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the SOAP input for a given +key+.
|
55
|
+
def soap_input(key)
|
56
|
+
operations[key][:input].to_sym if present? && operations[key]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns a Hash of SOAP operations.
|
60
|
+
def operations
|
61
|
+
@operations ||= parser.operations
|
62
|
+
end
|
63
|
+
|
64
|
+
# Sets the location of the WSDL document to use. This can either be a URL
|
65
|
+
# or a path to a local file.
|
66
|
+
attr_writer :document
|
67
|
+
|
68
|
+
# Returns the raw WSDL document.
|
69
|
+
def document
|
70
|
+
@wsdl_document ||= begin
|
71
|
+
raise ArgumentError, "No WSDL document given" if @document.blank?
|
72
|
+
remote? ? http_request : read_file
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
alias :to_xml :document
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# Returns whether the WSDL document is located on the Web.
|
81
|
+
def remote?
|
82
|
+
@document =~ /^http/
|
83
|
+
end
|
84
|
+
|
85
|
+
# Executes an HTTP GET request to retrieve a remote WSDL document.
|
86
|
+
def http_request
|
87
|
+
request.url = @document
|
88
|
+
Request.new(request).response.body
|
89
|
+
end
|
90
|
+
|
91
|
+
# Reads the WSDL document from a local file.
|
92
|
+
def read_file
|
93
|
+
File.read @document
|
94
|
+
end
|
95
|
+
|
96
|
+
# Parses the WSDL document and returns the <tt>Savon::WSDL::Parser</tt>.
|
97
|
+
def parser
|
98
|
+
@parser ||= begin
|
99
|
+
parser = Parser.new
|
100
|
+
REXML::Document.parse_stream document, parser
|
101
|
+
parser
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require "savon/core_ext/object"
|
2
|
+
require "savon/core_ext/string"
|
3
|
+
|
4
|
+
module Savon
|
5
|
+
module WSDL
|
6
|
+
|
7
|
+
# = Savon::WSDL::Parser
|
8
|
+
#
|
9
|
+
# Serves as a stream listener for parsing WSDL documents.
|
10
|
+
class Parser
|
11
|
+
|
12
|
+
# The main sections of a WSDL document.
|
13
|
+
Sections = %w(definitions types message portType binding service)
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@path, @operations, @namespaces = [], {}, {}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the namespace URI.
|
20
|
+
attr_reader :namespace
|
21
|
+
|
22
|
+
# Returns the SOAP operations.
|
23
|
+
attr_reader :operations
|
24
|
+
|
25
|
+
# Returns the SOAP endpoint.
|
26
|
+
attr_reader :endpoint
|
27
|
+
|
28
|
+
# Hook method called when the stream parser encounters a starting tag.
|
29
|
+
def tag_start(tag, attrs)
|
30
|
+
# read xml namespaces if root element
|
31
|
+
read_namespaces(attrs) if @path.empty?
|
32
|
+
|
33
|
+
tag, namespace = tag.split(":").reverse
|
34
|
+
@path << tag
|
35
|
+
|
36
|
+
if @section == :binding && tag == "binding"
|
37
|
+
# ensure that we are in an wsdl/soap namespace
|
38
|
+
@section = nil unless @namespaces[namespace].starts_with? "http://schemas.xmlsoap.org/wsdl/soap"
|
39
|
+
end
|
40
|
+
|
41
|
+
@section = tag.to_sym if Sections.include?(tag) && depth <= 2
|
42
|
+
|
43
|
+
@namespace ||= attrs["targetNamespace"] if @section == :definitions
|
44
|
+
@endpoint ||= URI(URI.escape(attrs["location"])) if @section == :service && tag == "address"
|
45
|
+
|
46
|
+
operation_from tag, attrs if @section == :binding && tag == "operation"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns our current depth in the WSDL document.
|
50
|
+
def depth
|
51
|
+
@path.size
|
52
|
+
end
|
53
|
+
|
54
|
+
# Reads namespace definitions from a given +attrs+ Hash.
|
55
|
+
def read_namespaces(attrs)
|
56
|
+
attrs.each do |key, value|
|
57
|
+
@namespaces[key.strip_namespace] = value if key.starts_with? "xmlns:"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Hook method called when the stream parser encounters a closing tag.
|
62
|
+
def tag_end(tag)
|
63
|
+
@path.pop
|
64
|
+
|
65
|
+
if @section == :binding && @input && tag.strip_namespace == "operation"
|
66
|
+
# no soapAction attribute found till now
|
67
|
+
operation_from tag, "soapAction" => @input
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Stores available operations from a given tag +name+ and +attrs+.
|
72
|
+
def operation_from(tag, attrs)
|
73
|
+
@input = attrs["name"] if attrs["name"]
|
74
|
+
|
75
|
+
if attrs["soapAction"]
|
76
|
+
@action = !attrs["soapAction"].blank? ? attrs["soapAction"] : @input
|
77
|
+
@input = @action.split("/").last if !@input || @input.empty?
|
78
|
+
|
79
|
+
@operations[@input.snakecase.to_sym] = { :action => @action, :input => @input }
|
80
|
+
@input, @action = nil, nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Catches calls to unimplemented hook methods.
|
85
|
+
def method_missing(method, *args)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|