Module: Braintree::Xml::Parser

Defined in:
lib/braintree/xml/parser.rb

Overview

:nodoc:

Constant Summary

XML_PARSING =
{
  "datetime" => Proc.new { |time| ::Time.parse(time).utc },
  "integer"  => Proc.new { |integer| integer.to_i },
  "boolean"  => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
}

Class Method Summary (collapse)

Class Method Details

+ (Object) _determine_parser



21
22
23
24
25
26
27
# File 'lib/braintree/xml/parser.rb', line 21

def self._determine_parser
  if defined?(::LibXml::XML) && ::LibXml::XML.respond_to?(:default_keep_blanks=)
    ::Braintree::Xml::Libxml
  else
    ::Braintree::Xml::Rexml
  end
end

+ (Object) _typecast_xml_value(value)



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/braintree/xml/parser.rb', line 29

def self._typecast_xml_value(value)
  case value.class.to_s
    when 'Hash'
      if value['type'] == 'array'
        child_key, entries = value.detect { |k,v| k != 'type' }   # child_key is throwaway
        if entries.nil? || ((c = value[CONTENT_ROOT]) && c.strip.empty?)
          []
        else
          case entries.class.to_s   # something weird with classes not matching here.  maybe singleton methods breaking is_a?
          when "Array"
            entries.collect { |v| _typecast_xml_value(v) }
          when "Hash"
            [_typecast_xml_value(entries)]
          else
            raise "can't typecast #{entries.inspect}"
          end
        end
      elsif value.has_key?(CONTENT_ROOT)
        content = value[CONTENT_ROOT]
        if parser = XML_PARSING[value["type"]]
          XML_PARSING[value["type"]].call(content)
        else
          content
        end
      elsif value['type'] == 'string' && value['nil'] != 'true'
        ""
      elsif value == {}
        ""
      elsif value.nil? || value['nil'] == 'true'
        nil
      # If the type is the only element which makes it then
      # this still makes the value nil, except if type is
      # a XML node(where type['value'] is a Hash)
      elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
        raise "is this needed?"
        nil
      else
        xml_value = value.inject({}) do |h,(k,v)|
          h[k] = _typecast_xml_value(v)
          h
        end
        xml_value
      end
    when 'Array'
      value.map! { |i| _typecast_xml_value(i) }
      case value.length
        when 0 then nil
        when 1 then value.first
        else value
      end
    when 'String'
      value
    else
      raise "can't typecast #{value.class.name} - #{value.inspect}"
  end
end

+ (Object) _unrename_keys(params)



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/braintree/xml/parser.rb', line 86

def self._unrename_keys(params)
  case params.class.to_s
    when "Hash"
      params.inject({}) do |h,(k,v)|
        h[k.to_s.tr("-", "_")] = _unrename_keys(v)
        h
      end
    when "Array"
      params.map { |v| _unrename_keys(v) }
    else
      params
  end
end

+ (Object) hash_from_xml(xml, parser = _determine_parser)



14
15
16
17
18
19
# File 'lib/braintree/xml/parser.rb', line 14

def self.hash_from_xml(xml, parser = _determine_parser)
  standardized_hash_structure = parser.parse(xml)
  with_underscores_in_keys = _unrename_keys(standardized_hash_structure)
  typecasted_xml = _typecast_xml_value(with_underscores_in_keys)
  Util.symbolize_keys(typecasted_xml)
end