savon 0.7.9 → 0.8.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|