Class: EMIS::Responses::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/emis/responses/response.rb

Overview

Generic EMIS response wrapper used to translate the XML data into a model object

Instance Method Summary collapse

Constructor Details

#initialize(raw_response) ⇒ Response

Returns a new instance of Response.

Parameters:

  • raw_response (Faraday::Env)

    Faraday response object



11
12
13
# File 'lib/emis/responses/response.rb', line 11

def initialize(raw_response)
  @root = raw_response.body
end

Instance Method Details

#build_item(el, schema: item_schema, model_class: self.model_class) ⇒ EMIS::Models (protected)

Build model class populated with XML data

Parameters:

  • el (Ox::Element)

    Root XML element

  • schema (Hash) (defaults to: item_schema)

    Schema for translating XML data to model attributes

  • model_class (EMIS::Models) (defaults to: self.model_class)

    Data model class

Returns:



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/emis/responses/response.rb', line 70

def build_item(el, schema: item_schema, model_class: self.model_class)
  model_class.new.tap do |model|
    schema.each do |tag, data|
      field_name = data[:rename] || tag.snakecase
      if data[:schema]
        tags = locate(tag, el)
        model[field_name] = tags.map { |t| build_item(t, schema: data[:schema], model_class: data[:model_class]) }
      else
        build_item_value(el, tag, field_name, model)
      end
    end
  end
end

#build_item_value(el, tag, field_name, model) ⇒ Object (protected)

Set an attribute of a model class with XML data

Parameters:

  • el (Ox::Element)

    XML element

  • tag (String)

    XML tag name

  • field_name (String)

    Model setter name

  • model (EMIS::Models)

    Model class



89
90
91
92
93
94
95
# File 'lib/emis/responses/response.rb', line 89

def build_item_value(el, tag, field_name, model)
  value = locate_one(tag, el)
  if value
    value = value.nodes[0]
    model[field_name] = value unless value.is_a?(Ox::Element)
  end
end

#cache?Boolean

Returns true if response code was successful.

Returns:

  • (Boolean)

    true if response code was successful



29
30
31
# File 'lib/emis/responses/response.rb', line 29

def cache?
  ok?
end

#empty?Boolean

Returns true if data set is empty.

Returns:

  • (Boolean)

    true if data set is empty



51
52
53
# File 'lib/emis/responses/response.rb', line 51

def empty?
  locate_one('essResponseCode')&.nodes&.first.nil?
end

#errorEMIS::Errors::ServiceError

Returns Translates XML error data into an error class.

Returns:



40
41
42
43
44
45
46
47
48
# File 'lib/emis/responses/response.rb', line 40

def error
  return nil unless error?

  code = locate_one('code')&.nodes&.first
  text = locate_one('text')&.nodes&.first
  ess_text = locate_one('essText')&.nodes&.first

  EMIS::Errors::ServiceError.new("#{code} #{text} #{ess_text}")
end

#error?Boolean

Returns true if response code had an error.

Returns:

  • (Boolean)

    true if response code had an error



34
35
36
# File 'lib/emis/responses/response.rb', line 34

def error?
  locate_one('essResponseCode')&.nodes&.first == 'ERROR'
end

#find_all_elements_by_tag_name(tag_without_namespace, el, skip_el: false) ⇒ Array<Ox::Element> (protected)

Finds elements by XML tag name

Parameters:

  • tag_without_namespace (String)

    XML tag name without namespace

  • el (Ox::Document)

    Root element to search from

  • skip_el (Boolean) (defaults to: false)

    Skip root element in results if true

Returns:

  • (Array<Ox::Element>)

    Elements found



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/emis/responses/response.rb', line 110

def find_all_elements_by_tag_name(tag_without_namespace, el, skip_el: false)
  #
  # This bit of unpleasantness is because the SOAP responses from eMIS have
  # a separate namespace FOR EVERY SINGLE TAG. It's not possible to find all the tags
  # of a specific type, since Ox also doesn't support real XPath and therefore doesn't
  # allow wildcards on parts of the tag. So this finds all of the elements and caches
  # them by tag so that later we can pull those tags out by a regex that ignores the
  # namespaces. For extra fun, the casing is sometimes different for the tags, so we must
  # do a case-insensitive regex.
  #
  [].tap do |result|
    result << el if !skip_el && el.respond_to?(:value) && el.value.match?(/^NS\d+:#{tag_without_namespace}$/i)

    if el.respond_to?(:nodes)
      el.nodes.each do |node|
        result.concat(find_all_elements_by_tag_name(tag_without_namespace, node, skip_el: false))
      end
    end
  end
end

#itemsEMIS::Models

Returns Response translated into array of model_class.

Returns:

  • (EMIS::Models)

    Response translated into array of model_class



17
18
19
20
21
# File 'lib/emis/responses/response.rb', line 17

def items
  locate(item_tag_name).map do |el|
    build_item(el)
  end
end

#locate(tag_without_namespace, el = @root) ⇒ Array<Ox::Element>

Locate elements from root element by tag name

Parameters:

  • tag_without_namespace (String)

    XML tag name without namespace

  • el (Ox::Document) (defaults to: @root)

    Root element to search from

Returns:

  • (Array<Ox::Element>)

    Elements found



59
60
61
# File 'lib/emis/responses/response.rb', line 59

def locate(tag_without_namespace, el = @root)
  find_all_elements_by_tag_name(tag_without_namespace, el, skip_el: true)
end

#locate_one(tag_without_namespace, el = @root) ⇒ Ox::Element (protected)

Locate one element from root element by tag name

Parameters:

  • tag_without_namespace (String)

    XML tag name without namespace

  • el (Ox::Document) (defaults to: @root)

    Root element to search from

Returns:

  • (Ox::Element)

    Element found



101
102
103
# File 'lib/emis/responses/response.rb', line 101

def locate_one(tag_without_namespace, el = @root)
  locate(tag_without_namespace, el).first
end

#ok?Boolean

Returns true if response code was successful.

Returns:

  • (Boolean)

    true if response code was successful



24
25
26
# File 'lib/emis/responses/response.rb', line 24

def ok?
  locate_one('essResponseCode')&.nodes&.first == 'Success'
end