Class: HappyMapper::Item

Inherits:
Object
  • Object
show all
Defined in:
lib/happymapper/item.rb

Direct Known Subclasses

Attribute, Element

Constant Summary collapse

Types =
[String, Float, Time, Date, DateTime, Integer, Boolean]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, type, o = {}) ⇒ Item

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.


16
17
18
19
20
21
22
23
24
# File 'lib/happymapper/item.rb', line 16

def initialize(name, type, o={})
  self.name = name.to_s
  self.type = type
  #self.tag = o.delete(:tag) || name.to_s
  self.tag = o[:tag] || name.to_s
  self.options = { :single => true }.merge(o.merge(:name => self.name))

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

Instance Attribute Details

#nameObject

Returns the value of attribute name.



3
4
5
# File 'lib/happymapper/item.rb', line 3

def name
  @name
end

#namespaceObject

Returns the value of attribute namespace.



3
4
5
# File 'lib/happymapper/item.rb', line 3

def namespace
  @namespace
end

#optionsObject

Returns the value of attribute options.



3
4
5
# File 'lib/happymapper/item.rb', line 3

def options
  @options
end

#tagObject

Returns the value of attribute tag.



3
4
5
# File 'lib/happymapper/item.rb', line 3

def tag
  @tag
end

#typeObject

Returns the value of attribute type.



3
4
5
# File 'lib/happymapper/item.rb', line 3

def type
  @type
end

Instance Method Details

#attribute?Boolean

Returns:



82
83
84
# File 'lib/happymapper/item.rb', line 82

def attribute?
  @xml_type == 'attribute'
end

#constantObject



26
27
28
# File 'lib/happymapper/item.rb', line 26

def constant
  @constant ||= constantize(type)
end

#element?Boolean

Returns:



78
79
80
# File 'lib/happymapper/item.rb', line 78

def element?
  @xml_type == 'element'
end

#from_xml_node(node, namespace, xpath_options) ⇒ Object



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
# File 'lib/happymapper/item.rb', line 30

def from_xml_node(node, namespace, xpath_options)
  if primitive?
    find(node, namespace, xpath_options) do |n|
      if n.respond_to?(:content)
        typecast(n.content)
      else
        typecast(n.to_s)
      end
    end
  elsif constant == XmlContent
    find(node, namespace, xpath_options) do |n|
      n = n.children if n.respond_to?(:children)
      n.respond_to?(:to_xml) ? n.to_xml : n.to_s
    end
  else
    if options[:parser]
      find(node, namespace, xpath_options) do |n|
        if n.respond_to?(:content) && !options[:raw]
          value = n.content
        else
          value = n.to_s
        end

        begin
          constant.send(options[:parser].to_sym, value)
        rescue
          nil
        end
      end
    else
      constant.parse(node, options.merge(:namespaces => xpath_options))
    end
  end
end

#method_nameObject



90
91
92
# File 'lib/happymapper/item.rb', line 90

def method_name
  @method_name ||= name.tr('-', '_')
end

#primitive?Boolean

Returns:



74
75
76
# File 'lib/happymapper/item.rb', line 74

def primitive?
  Types.include?(constant)
end

#text_node?Boolean

Returns:



86
87
88
# File 'lib/happymapper/item.rb', line 86

def text_node?
  @xml_type == 'textnode'
end

#typecast(value) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/happymapper/item.rb', line 94

def typecast(value)
  return value if value.kind_of?(constant) || value.nil?
  begin        
    if    constant == String    then value.to_s
    elsif constant == Float     then value.to_f
    elsif constant == Time      then Time.parse(value.to_s) rescue Time.at(value.to_i)
    elsif constant == Date      then Date.parse(value.to_s)
    elsif constant == DateTime  then DateTime.parse(value.to_s)
    elsif constant == Boolean   then ['true', 't', '1'].include?(value.to_s.downcase)
    elsif constant == Integer
      # ganked from datamapper
      value_to_i = value.to_i
      if value_to_i == 0 && value != '0'
        value_to_s = value.to_s
        begin
          Integer(value_to_s =~ /^(\d+)/ ? $1 : value_to_s)
        rescue ArgumentError
          nil
        end
      else
        value_to_i
      end
    else
      value
    end
  rescue
    value
  end
end

#xpath(namespace = self.namespace) ⇒ Object



65
66
67
68
69
70
71
72
# File 'lib/happymapper/item.rb', line 65

def xpath(namespace = self.namespace)
  xpath  = ''
  xpath += './/' if options[:deep]
  xpath += "#{namespace}:" if namespace
  xpath += tag
  # puts "xpath: #{xpath}"
  xpath
end