Module: HappyMapper::ClassMethods

Defined in:
lib/happymapper.rb

Instance Method Summary collapse

Instance Method Details

#_load(xml_str) ⇒ Object

Load for custom Marshaling



205
206
207
# File 'lib/happymapper.rb', line 205

def _load(xml_str)
  self.parse(xml_str)
end

#archive_raw_xmlObject

Tell HappyMapper to store the raw XML in the appropriately-named raw_xml instance variable when parsing



64
65
66
# File 'lib/happymapper.rb', line 64

def archive_raw_xml
  @store_raw_xml = true
end

#attribute(name, type, options = {}) ⇒ Object



72
73
74
75
76
77
# File 'lib/happymapper.rb', line 72

def attribute(name, type, options={})
  attribute = Attribute.new(name, type, options)
  @attributes[to_s] ||= []
  @attributes[to_s] << attribute
  attr_accessor attribute.method_name.intern
end

#attributesObject



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

def attributes
  @attributes[to_s] || []
end

#element(name, type, options = {}) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/happymapper.rb', line 83

def element(name, type, options={})
  options = {:namespace => @namespace}.merge(options)
  element = Element.new(name, type, options)
  @elements[to_s] ||= []
  @elements[to_s] << element
  attr_accessor element.method_name.intern
  
  # set the default value of a collection instance variable to [] instead of nil
  if options[:single] == false
    module_eval <<-eof
      def #{element.method_name}
        @#{element.method_name} ||= []
      end
    eof
  end
end

#elementsObject



100
101
102
# File 'lib/happymapper.rb', line 100

def elements
  @elements[to_s] || []
end

#has_many(name, type, options = {}) ⇒ Object



108
109
110
# File 'lib/happymapper.rb', line 108

def has_many(name, type, options={})
  element name, type, {:single => false}.merge(options)
end

#has_one(name, type, options = {}) ⇒ Object



104
105
106
# File 'lib/happymapper.rb', line 104

def has_one(name, type, options={})
  element name, type, {:single => true}.merge(options)
end

#namespace(namespace = nil) ⇒ Object

Specify a namespace if a node and all its children are all namespaced elements. This is simpler than passing the :namespace option to each defined element.

namespace can either be a string for the prefix or a hash with ‘prefix’ => ‘url’



117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/happymapper.rb', line 117

def namespace(namespace = nil)
  if namespace
    if namespace.is_a? Hash
      namespace.each_pair do |k,v|
        @namespace = k.to_s
        @namespace_url = v
      end
    else  
      @namespace = namespace 
    end
  end
  @namespace
end

#namespace_url(url = nil) ⇒ Object



131
132
133
134
# File 'lib/happymapper.rb', line 131

def namespace_url(url = nil)
  @namespace_url = url if url
  @namespace_url
end

#parse(xml, options = {}) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/happymapper.rb', line 144

def parse(xml, options = {})
  # locally scoped copy of namespace for this parse run
  namespace = @namespace

  if xml.is_a?(XML::Node)
    node = xml
  else
    if xml.is_a?(XML::Document)
      node = xml.root
    else
      node = XML::Parser.string(xml).parse.root
    end

    root = node.name == tag_name
  end

  # This is the entry point into the parsing pipeline, so the default
  # namespace prefix registered here will propagate down
  namespaces = node.namespaces
  if @namespace_url && namespaces.default.href != @namespace_url
    namespace = namespaces.find_by_href(@namespace_url).prefix
  elsif namespaces && namespaces.default
    # don't assign the default_prefix if it has already been assigned
    namespaces.default_prefix = DEFAULT_NS unless namespaces.find_by_prefix(DEFAULT_NS)
    namespace ||= DEFAULT_NS
  end

  xpath = root ? '/' : (options[:deep]) ? './/' : './'
  xpath += "#{namespace}:" if namespace
  xpath += tag_name
  # puts "parse: #{xpath}"

  nodes = node.find(xpath)
  collection = nodes.collect do |n|
    obj = new
    obj.raw_xml = n.to_s if obj.class.store_raw_xml?

    attributes.each do |attr|
      obj.send("#{attr.method_name}=",
                attr.from_xml_node(n, namespace))
    end

    elements.each do |elem|
      obj.send("#{elem.method_name}=",
                elem.from_xml_node(n, namespace))
    end

    obj
  end

  # per http://libxml.rubyforge.org/rdoc/classes/LibXML/XML/Document.html#M000354
  nodes = nil

  if options[:single] || root
    collection.first
  else
    collection
  end
end

#store_raw_xml?Boolean

Returns:



68
69
70
# File 'lib/happymapper.rb', line 68

def store_raw_xml?
  @store_raw_xml
end

#tag(new_tag_name) ⇒ Object



136
137
138
# File 'lib/happymapper.rb', line 136

def tag(new_tag_name)
  @tag_name = new_tag_name.to_s
end

#tag_nameObject



140
141
142
# File 'lib/happymapper.rb', line 140

def tag_name
  @tag_name ||= to_s.split('::')[-1].downcase
end