class HappyMapper::Item

Attributes

name[RW]
namespace[RW]
options[RW]
tag[RW]
type[RW]

Public Class Methods

new(name, type, options = {}) click to toggle source

options:

:deep   =>  Boolean False to only parse element's children, True to include
            grandchildren and all others down the chain (// in xpath)
:namespace => String Element's namespace if it's not the global or inherited
               default
:parser =>  Symbol Class method to use for type coercion.
:raw    =>  Boolean Use raw node value (inc. tags) when parsing.
:single =>  Boolean False if object should be collection, True for single object
:tag    =>  String Element name if it doesn't match the specified name.
# File lib/happymapper/item.rb, line 16
def initialize(name, type, options = {})
  self.name = name.to_s
  self.type = type
  # self.tag = options.delete(:tag) || name.to_s
  self.tag = options[:tag] || name.to_s
  self.options = { single: true }.merge(options.merge(name: self.name))

  @xml_type = self.class.to_s.split('::').last.downcase
end

Public Instance Methods

constant() click to toggle source
# File lib/happymapper/item.rb, line 26
def constant
  @constant ||= constantize(type)
end
from_xml_node(node, namespace, xpath_options) click to toggle source

@param [Nokogiri::XML::Element] node the xml node that is being parsed @param [String] namespace the name of the namespace @param [Hash] xpath_options additional xpath options

# File lib/happymapper/item.rb, line 35
def from_xml_node(node, namespace, xpath_options)
  namespace = options[:namespace] if options.key?(:namespace)

  if suported_type_registered?
    find(node, namespace, xpath_options) { |n| process_node_as_supported_type(n) }
  elsif constant == XmlContent
    find(node, namespace, xpath_options) { |n| process_node_as_xml_content(n) }
  elsif custom_parser_defined?
    find(node, namespace, xpath_options) { |n| process_node_with_custom_parser(n) }
  else
    process_node_with_default_parser(node, namespaces: xpath_options)
  end
end
method_name() click to toggle source
# File lib/happymapper/item.rb, line 58
def method_name
  @method_name ||= name.tr('-', '_')
end
typecast(value) click to toggle source

Convert the value into the correct type.

@param [String] value the string value parsed from the XML value that will

be converted to the particular primitive type.

@return [String,Float,Time,Date,DateTime,Boolean,Integer] the converted value

to the new type.
# File lib/happymapper/item.rb, line 71
def typecast(value)
  typecaster(value).apply(value)
end
xpath(namespace = self.namespace) click to toggle source
# File lib/happymapper/item.rb, line 49
def xpath(namespace = self.namespace)
  xpath  = ''
  xpath += './/' if options[:deep]
  xpath += "#{namespace}:" if namespace
  xpath += tag
  # puts "xpath: #{xpath}"
  xpath
end

Private Instance Methods

constantize(type) click to toggle source

Convert any String defined types into their constant version so that the method parse or the custom defined parser method would be used.

@param [String,Constant] type is the name of the class or the constant

for the class.

@return [Constant] the constant of the type

# File lib/happymapper/item.rb, line 140
def constantize(type)
  type.is_a?(String) ? convert_string_to_constant(type) : type
end
convert_string_to_constant(type) click to toggle source
# File lib/happymapper/item.rb, line 144
def convert_string_to_constant(type)
  names = type.split('::')
  constant = Object
  names.each do |name|
    constant =
      if constant.const_defined?(name)
        constant.const_get(name)
      else
        constant.const_missing(name)
      end
  end
  constant
end
custom_parser_defined?() click to toggle source

A custom parser is a custom parse method on the class. When the parser option has been set this value is the name of the method which will be used to parse the node content.

# File lib/happymapper/item.rb, line 110
def custom_parser_defined?
  options[:parser]
end
process_node_as_supported_type(node) click to toggle source

Processes a Nokogiri::XML::Node as a supported type

# File lib/happymapper/item.rb, line 92
def process_node_as_supported_type(node)
  content = node.respond_to?(:content) ? node.content : node
  typecast(content)
end
process_node_as_xml_content(node) click to toggle source

Process a Nokogiri::XML::Node as XML Content

# File lib/happymapper/item.rb, line 100
def process_node_as_xml_content(node)
  node = node.children if node.respond_to?(:children)
  node.respond_to?(:to_xml) ? node.to_xml : node.to_s
end
process_node_with_custom_parser(node) click to toggle source
# File lib/happymapper/item.rb, line 114
def process_node_with_custom_parser(node)
  value = if node.respond_to?(:content) && !options[:raw]
            node.content
          else
            node.to_s
          end

  begin
    constant.send(options[:parser].to_sym, value)
  rescue StandardError
    nil
  end
end
process_node_with_default_parser(node, parse_options) click to toggle source
# File lib/happymapper/item.rb, line 128
def process_node_with_default_parser(node, parse_options)
  constant.parse(node, options.merge(parse_options))
end
suported_type_registered?() click to toggle source

@return [Boolean] true if the type defined for the item is defined in the

list of support types.
# File lib/happymapper/item.rb, line 79
def suported_type_registered?
  SupportedTypes.types.map(&:type).include?(constant)
end
typecaster(value) click to toggle source

@return [#apply] the typecaster object that will be able to convert

the value into a value with the correct type.
# File lib/happymapper/item.rb, line 85
def typecaster(value)
  SupportedTypes.types.find { |caster| caster.apply?(value, constant) }
end