Recharge 1.1.1 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
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