class EbayTrader::SaxHandler

Attributes

known_arrays[R]
path[RW]
skip_type_casting[R]
stack[RW]

Public Class Methods

new(args = {}) click to toggle source
# File lib/ebay_trader/sax_handler.rb, line 15
def initialize(args = {})
  @stack = []
  @stack.push(HashWithIndifferentAccess.new)
  @path = []
  @hash = nil
  @attributes = {}

  @skip_type_casting = args[:skip_type_casting] || []
  @skip_type_casting = [@skip_type_casting] unless @skip_type_casting.is_a?(Array)
  @skip_type_casting.map! { |key| format(key.to_s) }

  @known_arrays = args[:known_arrays] || []
  @known_arrays = [@known_arrays] unless @known_arrays.is_a?(Array)
  @known_arrays.map! { |key| format(key.to_s) }
end

Public Instance Methods

append(key, value) click to toggle source
# File lib/ebay_trader/sax_handler.rb, line 113
def append(key, value)
  key = key.to_s
  h = @stack.last
  if h.key?(key)
    v = h[key]
    if v.is_a?(Array)
      v << value
    else
      h[key] = [v, value]
    end
  else
    if known_arrays.include?(key)
      h[key] = [value]
    else
      h[key] = value
    end
  end
end
attr(name, value) click to toggle source
# File lib/ebay_trader/sax_handler.rb, line 100
def attr(name, value)
  return if name.to_s.downcase == 'xmlns'
  last = path.last
  return if last.nil?

  name = name[0].upcase + name[1...name.length]
  @attributes[name] = value
end
cdata(value) click to toggle source
# File lib/ebay_trader/sax_handler.rb, line 94
def cdata(value)
  key = format_key(path.last)
  parent = @stack[-2]
  parent[key] = value
end
end_element(_) click to toggle source
# File lib/ebay_trader/sax_handler.rb, line 45
def end_element(_)
  @stack.pop
  @path.pop
end
error(message, line, column) click to toggle source
# File lib/ebay_trader/sax_handler.rb, line 109
def error(message, line, column)
  raise Exception.new("#{message} at #{line}:#{column}")
end
start_element(name) click to toggle source
# File lib/ebay_trader/sax_handler.rb, line 35
def start_element(name)
  @attributes.clear
  name = name.to_s
  path.push(name)

  hash = HashWithIndifferentAccess.new
  append(format_key(name), hash)
  stack.push(hash)
end
text(value) click to toggle source
# File lib/ebay_trader/sax_handler.rb, line 50
def text(value)
  key = format_key(path.last)
  auto_cast = !(skip_type_casting.include?(path.last) || skip_type_casting.include?(key.to_s))
  parent = @stack[-2]

  # If 'CurrencyID' is a defined attribute we are dealing with money type
  if @attributes.key?('CurrencyID')
    currency = @attributes.delete('CurrencyID')
    value = BigDecimal.new(value)
    if EbayTrader.configuration.price_type == :money && EbayTrader.is_money_gem_installed?
      value = Money.new((value * 100).round.to_i, currency)
    else
      @attributes['Currency'] = currency
      value = value.to_f if EbayTrader.configuration.price_type == :float
      value = (value * 100).round.to_i if EbayTrader.configuration.price_type == :fixnum
    end
  end

  if auto_cast && value.is_a?(String)
    case
      when value.downcase == 'false' then value = false
      when value.downcase == 'true'  then value = true
      when value.match(/^[0-9]+$/) then value = value.to_i
      when value.match(/^[0-9]+[.][0-9]+$/) then value = value.to_f
      when value.match(/^[0-9]{4}-[0-9]{2}-[0-9]{2}[T ][0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9a-z]+)?$/i)
        value = Time.parse(value)
    end
  end

  if parent[key].is_a?(Array)
    parent[key].pop if parent[key].last.is_a?(Hash) && parent[key].last.empty?
    parent[key] << value
  else
    parent[key] = value
  end

  unless @attributes.empty?
    @attributes.each_pair do |attr_key, attr_value|
      attr_key_element_name = format_key("#{path.last}#{attr_key}")
      parent[attr_key_element_name] = attr_value
    end
  end
end
to_hash() click to toggle source
# File lib/ebay_trader/sax_handler.rb, line 31
def to_hash
  stack[0]
end

Private Instance Methods

format_key(key) click to toggle source

Ensure the key is an underscored Symbol.

Examples:

'ApplyBuyerProtection' -> :apply_buyer_protection
'PayPalEmailAddress'   -> :paypal_email_address
'SoldOffeBay'          -> :sold_off_ebay

@return [Symbol] the reformatted key.

# File lib/ebay_trader/sax_handler.rb, line 145
def format_key(key)
  key = key.to_s
  key = key.gsub('PayPal', 'Paypal')
  key = key.gsub('eBay',   'Ebay')
  key = key.gsub('EBay',   'Ebay')
  key.underscore.to_sym
end