Recharge 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/recharge.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  module Recharge
2
+ require 'happymapper'
3
+
2
4
  require File.dirname(__FILE__) + '/recharge/base'
3
5
  require File.dirname(__FILE__) + '/recharge/paymethod'
4
6
  require File.dirname(__FILE__) + '/recharge/charge'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Recharge
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 1
10
- version: 1.1.1
9
+ - 3
10
+ version: 1.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Recharge
@@ -42,11 +42,6 @@ extensions: []
42
42
  extra_rdoc_files: []
43
43
 
44
44
  files:
45
- - lib/happymapper/attribute.rb
46
- - lib/happymapper/element.rb
47
- - lib/happymapper/item.rb
48
- - lib/happymapper/version.rb
49
- - lib/happymapper.rb
50
45
  - lib/recharge/base.rb
51
46
  - lib/recharge/charge.rb
52
47
  - lib/recharge/client.rb
data/lib/happymapper.rb DELETED
@@ -1,315 +0,0 @@
1
- require 'rubygems'
2
- require 'date'
3
- require 'time'
4
- require 'xml'
5
-
6
- class Boolean; end
7
-
8
- module HappyMapper
9
-
10
- DEFAULT_NS = "happymapper"
11
-
12
- def self.included(base)
13
- base.instance_variable_set("@attributes", {})
14
- base.instance_variable_set("@elements", {})
15
- base.instance_variable_set("@registered_namespaces", {})
16
-
17
- base.extend ClassMethods
18
- end
19
-
20
- module ClassMethods
21
- def attribute(name, type, options={})
22
- attribute = Attribute.new(name, type, options)
23
- @attributes[to_s] ||= []
24
- @attributes[to_s] << attribute
25
- attr_accessor attribute.method_name.intern
26
- end
27
-
28
- def attributes
29
- @attributes[to_s] || []
30
- end
31
-
32
- def element(name, type, options={})
33
- element = Element.new(name, type, options)
34
- @elements[to_s] ||= []
35
- @elements[to_s] << element
36
- attr_accessor element.method_name.intern
37
- end
38
-
39
- def content(name)
40
- @content = name
41
- attr_accessor name
42
- end
43
-
44
- def after_parse_callbacks
45
- @after_parse_callbacks ||= []
46
- end
47
-
48
- def after_parse(&block)
49
- after_parse_callbacks.push(block)
50
- end
51
-
52
- def elements
53
- @elements[to_s] || []
54
- end
55
-
56
- def has_one(name, type, options={})
57
- element name, type, {:single => true}.merge(options)
58
- end
59
-
60
- def has_many(name, type, options={})
61
- element name, type, {:single => false}.merge(options)
62
- end
63
-
64
- # Specify a namespace if a node and all its children are all namespaced
65
- # elements. This is simpler than passing the :namespace option to each
66
- # defined element.
67
- def namespace(namespace = nil)
68
- @namespace = namespace if namespace
69
- @namespace
70
- end
71
-
72
- def register_namespace(namespace, ns)
73
- @registered_namespaces.merge!(namespace => ns)
74
- end
75
-
76
- def tag(new_tag_name)
77
- @tag_name = new_tag_name.to_s
78
- end
79
-
80
- def tag_name
81
- @tag_name ||= to_s.split('::')[-1].downcase
82
- end
83
-
84
- def parse(xml, options = {})
85
- if xml.is_a?(XML::Node)
86
- node = xml
87
- else
88
- if xml.is_a?(XML::Document)
89
- node = xml.root
90
- else
91
- node = XML::Parser.string(xml).parse.root
92
- end
93
-
94
- root = node.name == tag_name
95
- end
96
-
97
- namespace = @namespace || (node.namespaces && node.namespaces.default)
98
- namespace = "#{DEFAULT_NS}:#{namespace}" if namespace
99
-
100
- xpath = root ? '/' : './/'
101
- xpath += "#{DEFAULT_NS}:" if namespace
102
- xpath += tag_name
103
-
104
- nodes = node.find(xpath, Array(namespace))
105
- collection = nodes.collect do |n|
106
- obj = new
107
-
108
- attributes.each do |attr|
109
- obj.send("#{attr.method_name}=",
110
- attr.from_xml_node(n, namespace))
111
- end
112
-
113
- elements.each do |elem|
114
- obj.send("#{elem.method_name}=",
115
- elem.from_xml_node(n, namespace))
116
- end
117
-
118
- obj.send("#{@content}=", n.content) if @content
119
-
120
- obj.class.after_parse_callbacks.each { |callback| callback.call(obj) }
121
-
122
- obj
123
- end
124
-
125
- # per http://libxml.rubyforge.org/rdoc/classes/LibXML/XML/Document.html#M000354
126
- nodes = nil
127
-
128
- if options[:single] || root
129
- collection.first
130
- else
131
- collection
132
- end
133
- end
134
-
135
- end
136
-
137
- #
138
- # Create an xml representation of the specified class based on defined
139
- # HappyMapper elements and attributes. The method is defined in a way
140
- # that it can be called recursively by classes that are also HappyMapper
141
- # classes, allowg for the composition of classes.
142
- #
143
- def to_xml(parent_node = nil, default_namespace = nil)
144
-
145
- #
146
- # Create a tag that uses the tag name of the class that has no contents
147
- # but has the specified namespace or uses the default namespace
148
- #
149
- current_node = XML::Node.new(self.class.tag_name)
150
-
151
-
152
- if parent_node
153
- #
154
- # if #to_xml has been called with a parent_node that means this method
155
- # is being called recursively (or a special case) and we want to return
156
- # the parent_node with the new node as a child
157
- #
158
- parent_node << current_node
159
- else
160
- #
161
- # If #to_xml has been called without a Node (and namespace) that
162
- # means we want to return an xml document
163
- #
164
- write_out_to_xml = true
165
- end
166
-
167
- #
168
- # Add all the registered namespaces to the current node and the current node's
169
- # root element. Without adding it to the root element it is not possible to
170
- # parse or use xpath to find elements.
171
- #
172
- if self.class.instance_variable_get('@registered_namespaces')
173
-
174
- # Given a node, continue moving up to parents until there are no more parents
175
- find_root_node = lambda {|node| while node.parent? ; node = node.parent ; end ; node }
176
- root_node = find_root_node.call(current_node)
177
-
178
- # Add the registered namespace to the found root node only if it does not already have one defined
179
- self.class.instance_variable_get('@registered_namespaces').each_pair do |prefix,href|
180
- XML::Namespace.new(current_node,prefix,href)
181
- XML::Namespace.new(root_node,prefix,href) unless root_node.namespaces.find_by_prefix(prefix)
182
- end
183
- end
184
-
185
- #
186
- # Determine the tag namespace if one has been specified. This value takes
187
- # precendence over one that is handed down to composed sub-classes.
188
- #
189
- tag_namespace = current_node.namespaces.find_by_prefix(self.class.namespace) || default_namespace
190
-
191
- # Set the namespace of the current node to the specified namespace
192
- current_node.namespaces.namespace = tag_namespace if tag_namespace
193
-
194
- #
195
- # Add all the attribute tags to the current node with their namespace, if one
196
- # is defined, or the namespace handed down to the node.
197
- #
198
- self.class.attributes.each do |attribute|
199
- attribute_namespace = current_node.namespaces.find_by_prefix(attribute.options[:namespace]) || default_namespace
200
-
201
- value = send(attribute.method_name)
202
-
203
- #
204
- # If the attribute has a :on_save attribute defined that is a proc or
205
- # a defined method, then call those with the current value.
206
- #
207
- if on_save_operation = attribute.options[:on_save]
208
- if on_save_operation.is_a?(Proc)
209
- value = on_save_operation.call(value)
210
- elsif respond_to?(on_save_operation)
211
- value = send(on_save_operation,value)
212
- end
213
- end
214
-
215
- current_node[ "#{attribute_namespace ? "#{attribute_namespace.prefix}:" : ""}#{attribute.tag}" ] = value
216
- end
217
-
218
- #
219
- # All all the elements defined (e.g. has_one, has_many, element) ...
220
- #
221
- self.class.elements.each do |element|
222
-
223
- tag = element.tag || element.name
224
-
225
- element_namespace = current_node.namespaces.find_by_prefix(element.options[:namespace]) || tag_namespace
226
-
227
- value = send(element.name)
228
-
229
- #
230
- # If the element defines an :on_save lambda/proc then we will call that
231
- # operation on the specified value. This allows for operations to be
232
- # performed to convert the value to a specific value to be saved to the xml.
233
- #
234
- if on_save_operation = element.options[:on_save]
235
- if on_save_operation.is_a?(Proc)
236
- value = on_save_operation.call(value)
237
- elsif respond_to?(on_save_operation)
238
- value = send(on_save_operation,value)
239
- end
240
- end
241
-
242
- #
243
- # Normally a nil value would be ignored, however if specified then
244
- # an empty element will be written to the xml
245
- #
246
- if value.nil? && element.options[:state_when_nil]
247
- current_node << XML::Node.new(tag,nil,element_namespace)
248
- end
249
-
250
- #
251
- # To allow for us to treat both groups of items and singular items
252
- # equally we wrap the value and treat it as an array.
253
- #
254
- if value.nil?
255
- values = []
256
- elsif value.respond_to?(:to_ary) && !element.options[:single]
257
- values = value.to_ary
258
- else
259
- values = [value]
260
- end
261
-
262
-
263
- values.each do |item|
264
-
265
- if item.is_a?(HappyMapper)
266
-
267
- #
268
- # Other HappyMapper items that are convertable should not be called
269
- # with the current node and the namespace defined for the element.
270
- #
271
- item.to_xml(current_node,element_namespace)
272
-
273
- elsif item
274
-
275
- #
276
- # When a value exists we should append the value for the tag
277
- #
278
- current_node << XML::Node.new(tag,item.to_s,element_namespace)
279
-
280
- else
281
-
282
- #
283
- # Normally a nil value would be ignored, however if specified then
284
- # an empty element will be written to the xml
285
- #
286
- current_node << XML.Node.new(tag,nil,element_namespace) if element.options[:state_when_nil]
287
-
288
- end
289
-
290
- end
291
-
292
- end
293
-
294
-
295
- #
296
- # Generate xml from a document if no node was passed as a parameter. Otherwise
297
- # this method is being called recursively (or special case) and we should
298
- # return the node with this node attached as a child.
299
- #
300
- if write_out_to_xml
301
- document = XML::Document.new
302
- document.root = current_node
303
- document.to_s
304
- else
305
- parent_node
306
- end
307
-
308
- end
309
-
310
-
311
- end
312
-
313
- require File.dirname(__FILE__) + '/happymapper/item'
314
- require File.dirname(__FILE__) + '/happymapper/attribute'
315
- require File.dirname(__FILE__) + '/happymapper/element'
@@ -1,3 +0,0 @@
1
- module HappyMapper
2
- class Attribute < Item; end
3
- end
@@ -1,3 +0,0 @@
1
- module HappyMapper
2
- class Element < Item; end
3
- end
@@ -1,179 +0,0 @@
1
- module HappyMapper
2
- class Item
3
- attr_accessor :name, :type, :tag, :options, :namespace
4
-
5
- Types = [String, Float, Time, Date, DateTime, Integer, Boolean]
6
-
7
- # options:
8
- # :deep => Boolean False to only parse element's children, True to include
9
- # grandchildren and all others down the chain (// in expath)
10
- # :namespace => String Element's namespace if it's not the global or inherited
11
- # default
12
- # :parser => Symbol Class method to use for type coercion.
13
- # :raw => Boolean Use raw node value (inc. tags) when parsing.
14
- # :single => Boolean False if object should be collection, True for single object
15
- # :tag => String Element name if it doesn't match the specified name.
16
- def initialize(name, type, o={})
17
- self.name = name.to_s
18
- self.type = type
19
- self.tag = o.delete(:tag) || name.to_s
20
- self.options = o
21
-
22
- @xml_type = self.class.to_s.split('::').last.downcase
23
- end
24
-
25
- def constant
26
- @constant ||= constantize(type)
27
- end
28
-
29
- def from_xml_node(node, namespace)
30
- if primitive?
31
- find(node, namespace) do |n|
32
- if n.respond_to?(:content)
33
- typecast(n.content)
34
- else
35
- typecast(n.to_s)
36
- end
37
- end
38
- else
39
- if options[:parser]
40
- find(node, namespace) do |n|
41
- if n.respond_to?(:content) && !options[:raw]
42
- value = n.content
43
- else
44
- value = n.to_s
45
- end
46
-
47
- begin
48
- constant.send(options[:parser].to_sym, value)
49
- rescue
50
- nil
51
- end
52
- end
53
- else
54
- constant.parse(node, options)
55
- end
56
- end
57
- end
58
-
59
- def xpath(namespace = self.namespace)
60
- xpath = ''
61
- xpath += './/' if options[:deep]
62
- xpath += "#{DEFAULT_NS}:" if namespace
63
- xpath += tag
64
- # puts "xpath: #{xpath}"
65
- xpath
66
- end
67
-
68
- def primitive?
69
- Types.include?(constant)
70
- end
71
-
72
- def element?
73
- @xml_type == 'element'
74
- end
75
-
76
- def attribute?
77
- !element?
78
- end
79
-
80
- def method_name
81
- @method_name ||= name.tr('-', '_')
82
- end
83
-
84
- def typecast(value)
85
- return value if value.kind_of?(constant) || value.nil?
86
- begin
87
- if constant == String then value.to_s
88
- elsif constant == Float then value.to_f
89
- elsif constant == Time then Time.parse(value.to_s)
90
- elsif constant == Date then Date.parse(value.to_s)
91
- elsif constant == DateTime then DateTime.parse(value.to_s)
92
- elsif constant == Boolean then ['true', 't', '1'].include?(value.to_s.downcase)
93
- elsif constant == Integer
94
- # ganked from datamapper
95
- value_to_i = value.to_i
96
- if value_to_i == 0 && value != '0'
97
- value_to_s = value.to_s
98
- begin
99
- Integer(value_to_s =~ /^(\d+)/ ? $1 : value_to_s)
100
- rescue ArgumentError
101
- nil
102
- end
103
- else
104
- value_to_i
105
- end
106
- else
107
- value
108
- end
109
- rescue
110
- value
111
- end
112
- end
113
-
114
- private
115
- def constantize(type)
116
- if type.is_a?(String)
117
- names = type.split('::')
118
- constant = Object
119
- names.each do |name|
120
- constant = constant.const_defined?(name) ?
121
- constant.const_get(name) :
122
- constant.const_missing(name)
123
- end
124
- constant
125
- else
126
- type
127
- end
128
- end
129
-
130
- def find(node, namespace, &block)
131
- if options[:namespace] == false
132
- namespace = nil
133
- elsif options[:namespace]
134
- # from an element definition
135
- namespace = "#{DEFAULT_NS}:#{options[:namespace]}"
136
- elsif self.namespace
137
- # this node has a custom namespace (that is present in the doc)
138
- namespace = "#{DEFAULT_NS}:#{self.namespace}"
139
- end
140
-
141
- if element?
142
- if(options[:single].nil? || options[:single])
143
- result = node.find_first(xpath(namespace), namespace)
144
- else
145
- result = node.find(xpath(namespace))
146
- end
147
- # puts "vfxn: #{xpath} #{result.inspect}"
148
- if result
149
- if(options[:single].nil? || options[:single])
150
- value = yield(result)
151
- else
152
- value = []
153
-
154
- result.each do |res|
155
- value << yield(res)
156
- end
157
- end
158
- if options[:attributes].is_a?(Hash)
159
- result.attributes.each do |xml_attribute|
160
- if attribute_options = options[:attributes][xml_attribute.name.to_sym]
161
- attribute_value = Attribute.new(xml_attribute.name.to_sym, *attribute_options).from_xml_node(result, namespace)
162
- result.instance_eval <<-EOV
163
- def value.#{xml_attribute.name}
164
- #{attribute_value.inspect}
165
- end
166
- EOV
167
- end
168
- end
169
- end
170
- value
171
- else
172
- nil
173
- end
174
- else
175
- yield(node[tag])
176
- end
177
- end
178
- end
179
- end
@@ -1,3 +0,0 @@
1
- module HappyMapper
2
- Version = '0.4.0'
3
- end