Class: Allorails::Response::ApiMappingResponse

Inherits:
ApiResponse
  • Object
show all
Defined in:
lib/allorails/response/api_mapping_response.rb

Overview

Basis of an object mapped API response

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(signature, headers, body) ⇒ ApiMappingResponse

Constructor

@param signature (string) Expected response signature
@param headers (list) Response HTTP headers
@param body (string) Raw response data


16
17
18
19
20
21
22
23
24
# File 'lib/allorails/response/api_mapping_response.rb', line 16

def initialize(signature, headers, body)
  super(signature, headers, body)
  # parse the XML response
  @xml = Nokogiri.XML(body)
  # error if no root element
  raise Allorails::ApiWrongFormatResponseError if @xml.root.nil?
  # verify the response
  _verify
end

Instance Attribute Details

#xmlObject (readonly)

Returns the value of attribute xml.



9
10
11
# File 'lib/allorails/response/api_mapping_response.rb', line 9

def xml
  @xml
end

Class Method Details

.attribute_reader(attr_name, type = String) ⇒ Object

Internal method allowing easy reading of XML attributes

@param (sym) name of the attribute that needs to be read
@param (Class) type to which the result should be cast


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/allorails/response/api_mapping_response.rb', line 67

def self.attribute_reader(attr_name, type = String)
  # define a Proc to cast the attribute's value to the specified type
  attr_value = case true
    when type == String then Proc.new{|x| x.value}
    when type == Integer then Proc.new{|x| x.value.to_i}
    when type == Float then Proc.new{|x| x.value.to_f}
    when type == DateTime then Proc.new{|x|
      if x.respond_to?(:attribute) && (ts = x.attribute('timestamp'))
        DateTime.strptime(ts.value, "%s")
      elsif x.respond_to?(:attribute) && (d = x.attribute('date'))
        DateTime.strptime(d.value)
      else
        nil
      end
    }
    else Proc.new{|x| type.new x}
  end
  # add a method accessing the node and casting the text
  send :define_method, attr_name do
    att = xml.attribute(attr_name.to_s)
    return attr_value.call(att) unless att.nil?
  end
end

.node_reader(node_name, type = String) ⇒ Object

Internal method allowing easy reading of XML nodes

@param (sym) name of the node that needs to be read
@param (Class) type to which the result should be cast


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/allorails/response/api_mapping_response.rb', line 39

def self.node_reader(node_name, type = String)
  # define a Proc to cast the node's text to the specified type
  node_value = case true
    when type == String then Proc.new{|x| x.text}
    when type == Integer then Proc.new{|x| x.text.to_i}
    when type == Float then Proc.new{|x| x.text.to_f}
    when type == DateTime then Proc.new{|x|
      if x.respond_to?(:attribute) && (ts = x.attribute('timestamp'))
        DateTime.strptime(ts.value, "%s")
      elsif x.respond_to?(:attribute) && (d = x.attribute('date'))
        DateTime.strptime(d.value)
      else
        nil
      end
    }
    else Proc.new{|x| type.new x}
  end
  # add a method accessing the node and casting the text
  send :define_method, node_name do
    node = xml.css(node_name.to_s).first
    return node_value.call(node) unless node.nil?
  end
end

Instance Method Details

#_verifyObject

Internal method checking the response



29
30
31
32
33
# File 'lib/allorails/response/api_mapping_response.rb', line 29

def _verify
  raise Allorails::ApiRemoteErrorError if @xml.root[:code] != '0'
  # call the parent _verify method which will check the signature
  super
end