Class: ApricotEatsGorilla

Inherits:
Object
  • Object
show all
Defined in:
lib/apricoteatsgorilla/apricoteatsgorilla.rb

Overview

ApricotEatsGorilla

Apricot eats Gorilla is a SOAP communication helper. It translates between SOAP messages (XML) and Ruby Hashes and comes with some additional helpers for working with SOAP services.

Constant Summary collapse

SOAPDateTimeFormat =

SOAP dateTime format.

"%Y-%m-%dT%H:%M:%S"
SOAPDateTimeRegexp =

SOAP dateTime Regexp.

/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/
SOAPNamespace =

SOAP namespaces by SOAP version.

{
  1 => "http://schemas.xmlsoap.org/soap/envelope/",
  2 => "http://www.w3.org/2003/05/soap-envelope"
}

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.disable_hash_keys_to_snake_caseObject

Flag to disable conversion of Hash keys to snake_case.



33
34
35
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 33

def disable_hash_keys_to_snake_case
  @disable_hash_keys_to_snake_case
end

.disable_hash_keys_to_symbolsObject

Flag to disable conversion of Hash keys to Symbols.



36
37
38
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 36

def disable_hash_keys_to_symbols
  @disable_hash_keys_to_symbols
end

.disable_tag_names_to_lower_camel_caseObject

Flag to disable conversion of XML tags to lowerCamelCase.



30
31
32
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 30

def disable_tag_names_to_lower_camel_case
  @disable_tag_names_to_lower_camel_case
end

.nodes_to_namespaceObject

Hash of namespaces (keys) and XML nodes (values) to apply these namespaces to.



40
41
42
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 40

def nodes_to_namespace
  @nodes_to_namespace
end

.sort_keysObject

Flag to enable sorting of Hash keys.



27
28
29
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 27

def sort_keys
  @sort_keys
end

Class Method Details

.[](source, root_node = nil) ⇒ Object

Shortcut method for translating between XML Strings and Ruby Hashes. Delegates to xml_to_hash in case source is a String or delegates to hash_to_xml in case source is a Hash. Returns nil otherwise.



45
46
47
48
49
50
51
52
53
54
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 45

def [](source, root_node = nil)
  case source
    when String
      xml_to_hash(source, root_node)
    when Hash
      hash_to_xml(source)
    else
      nil
  end
end

.hash_to_xml(hash) ⇒ Object

Translates a given Ruby hash into an XML String.

Examples

hash = { :apricot => { :eats => "Gorilla" } }
ApricotEatsGorilla.hash_to_xml(hash)

# => "<apricot><eats>Gorilla</eats></apricot>"

hash = { :apricot => { :eats => ["Gorillas", "Snakes"] } }
ApricotEatsGorilla.hash_to_xml(hash)

# => "<apricot><eats>Gorillas</eats><eats>Snakes</eats></apricot>"


117
118
119
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 117

def hash_to_xml(hash)
  nested_data_to_xml(hash.keys.first, hash.values.first)
end

.setup {|_self| ... } ⇒ Object

Yields this class to a given block for wrapping the setup of multiple flags at once.

Yields:

  • (_self)

Yield Parameters:



58
59
60
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 58

def setup
  yield self if block_given?
end

.soap_envelope(namespaces = nil, wsse = nil, version = 1) ⇒ Object

Builds a SOAP request envelope and includes the content of a given block into the envelope body.

Takes an optional Hash of additional namespaces to set on the SOAP envelope. Takes an optional Hash of wsse details for WSSE authentication. Furthermore accepts an optional version to specify the SOAP envelope namespace to use by SOAP version.

Examples

ApricotEatsGorilla.soap_envelope do
  "<apricot><eats>Gorilla</eats></apricot>"
end

# => '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
# =>    <env:Header />
# =>    <env:Body>
# =>      <apricot><eats>Gorilla</eats></apricot>
# =>    </env:Body>
# =>  </env:Envelope>'

Customize namespaces:

soap_env = { "xmlns:wsdl" => "http://example.com" }
ApricotEatsGorilla.soap_envelope(soap_env)

# => '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://example.com">
# =>    <env:Header />
# =>    <env:Body />
# =>  </env:Envelope>'

WSSE authentication (PasswordText):

wsse_args = { :username => 'dude', :password => 'secret' }
ApricotEatsGorilla.soap_envelope(nil, wsse_args)

# => '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
# =>    <env:Header>
# =>      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
# =>        <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
# =>          <wsse:Username>dude</wsse:Username>
# =>          <wsse:Password>secret</wsse:Password>
# =>          <wsse:Nonce>c5e4eab16eed977a71fa6797999319e0749b3a70</wsse:Nonce>
# =>          <wsu:Created>2009-10-06T14:48:13</wsu:Created>
# =>        </wsse:UsernameToken>
# =>      </wsse:Security>
# =>    </env:Header>
# =>    <env:Body />
# =>  </env:Envelope>'

WSSE authentication (PasswordDigest):

wsse_args = { :username => 'dude', :password => 'secret', :digest => true }
ApricotEatsGorilla.soap_envelope(nil, wsse_args)

# => '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
# =>    <env:Header>
# =>      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
# =>        <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
# =>          <wsse:Username>dude</wsse:Username>
# =>          <wsse:Password Type="wsse:PasswordDigest">MTJjYzcyNjY1MDM5MzJmYjZlYzRmMGZhZDY2YTI0MjFiMzYwYzE0ZQ==</wsse:Password>
# =>          <wsse:Nonce>fea0cf847cf2d1f9e402975b359e7268cc3a65d4</wsse:Nonce>
# =>          <wsu:Created>2009-10-06T19:24:30</wsu:Created>
# =>        </wsse:UsernameToken>
# =>      </wsse:Security>
# =>    </env:Header>
# =>    <env:Body />
# =>  </env:Envelope>'


189
190
191
192
193
194
195
196
197
198
199
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 189

def soap_envelope(namespaces = nil, wsse = nil, version = 1)
  namespaces = {} unless namespaces.kind_of? Hash
  if namespaces["xmlns:env"].nil? && SOAPNamespace[version]
    namespaces["xmlns:env"] = SOAPNamespace[version]
  end

  header = xml_node("env:Header") { wsse_soap_header(wsse) }
  body = xml_node("env:Body") { (yield if block_given?) || nil }

  xml_node("env:Envelope", namespaces) { header + body }
end

.xml_to_hash(xml, root_node = nil) ⇒ Object

Translates a given xml String into a Ruby Hash.

Starts parsing at the XML root node by default. Accepts an optional root_node parameter for defining a custom root node to start parsing at using an XPath-Expression (Hpricot search).

Notice that both namespaces and attributes get removed and the root node itself won’t be included in the Hash.

Examples

xml = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
      <ns2:authenticateResponse xmlns:ns2="http://v1_0.ws.example.com/">
        <return>
          <apricot>
            <eats>Gorilla</eats>
          </apricot>
        </return>
      </ns2:authenticateResponse>
    </soap:Body>
  </soap:Envelope>'

ApricotEatsGorilla.xml_to_hash(xml)
# => { :body => { :authenticate_response => { :return => { :apricot => { :eats => "Gorilla" } } } } }

ApricotEatsGorilla.xml_to_hash(xml, "//return")
# => { :apricot => { :eats => "Gorilla" } }


90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/apricoteatsgorilla/apricoteatsgorilla.rb', line 90

def xml_to_hash(xml, root_node = nil)
  doc = Hpricot.XML remove_whitespace(xml)
  root = root_node ? doc.search(root_node) : doc.root

  return nil if empty_root_node? root
  if !root.respond_to? :each
    xml_node_to_hash(root)
  elsif root.size == 1
    single_xml_root_node_to_hash(root)
  else
    multiple_xml_root_nodes_to_hash(root)
  end
end