clinth3o-acdc 0.1.0 → 0.1.1

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.
@@ -0,0 +1,20 @@
1
+ module AcDc
2
+
3
+ # Attribute object used in Element and Body.
4
+ # Not often used outside of these.
5
+ class Attribute
6
+
7
+ attr_accessor :name, :value
8
+
9
+ def initialize(name,value)
10
+ @name = name
11
+ @value = value
12
+ end
13
+
14
+ # Returns the values of this attribute in hash form
15
+ def to_hash
16
+ {@name => @value}
17
+ end
18
+
19
+ end
20
+ end
data/lib/acdc/body.rb ADDED
@@ -0,0 +1,165 @@
1
+ module AcDc
2
+ class Body
3
+
4
+ attr_accessor :attributes, :elements
5
+
6
+ # Populates the attributes and elements declared for this object.
7
+ #@option values [Hash] :attributes Hash list of attributes to populate
8
+ #@example Filling the values and attributes
9
+ # class ThunderStruck < Body
10
+ # attribute :thunder
11
+ # element :lightning
12
+ # end
13
+ # kaboom = ThunderStruck.new({:attributes => {:thunder => "boom"}, :lightning => "crash"})
14
+ def initialize(values = {})
15
+ @attributes ||= {}
16
+ @elements ||= {}
17
+ # catch default values for attributes
18
+ unless self.class.declared_attributes.values.all?{|val| val.nil?}
19
+ self.class.declared_attributes.each do |key,val|
20
+ attributes.update(key => Attribute(key,val)) unless val.nil?
21
+ end
22
+ end
23
+ # now set initialized attribute values
24
+ if values.has_key?(:attributes)
25
+ values.delete(:attributes).each do |key,val|
26
+ if self.class.declared_attributes.has_key?(key)
27
+ attributes.update(key => Attribute(key,val))
28
+ end
29
+ end
30
+ end
31
+ # and finally set values
32
+ values.each do |key,val|
33
+ if self.class.declared_elements.has_key?(key)
34
+ type = options_for(key)[:type]
35
+ if type
36
+ if val.respond_to?(:each)
37
+ val.each {|v| raise ArgumentError.new("Type is invalid") unless v.is_a?(type)}
38
+ else
39
+ raise ArgumentError.new("Type is invalid") unless val.is_a?(type)
40
+ end
41
+ elements.update(key => type.new(val,options_for(key),key))
42
+ else
43
+ elements.update(key => Element(val,options_for(key),key))
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ # Converts object to XML
50
+ def acdc
51
+ xml = Builder::XmlMarkup.new
52
+ attrs = attributes.inject({}){|acc,attr| acc.update(attr[1].to_hash)}
53
+ xml.tag!(tag_name,attrs){ |body|
54
+ elements.each do |key, elem|
55
+ body << elem.acdc
56
+ end
57
+ }
58
+ xml.target!
59
+ end
60
+
61
+ # The name to use for the tag
62
+ def tag_name
63
+ self.class.to_s.split("::").last
64
+ end
65
+
66
+ def method_missing(method_id, *args, &block)
67
+ key = method_id.to_s.gsub(/\=/,"").to_sym
68
+ if elements.has_key?(key) or attributes.has_key?(key)
69
+ (method_id.to_s.match(/\=$/)) ? write(method_id, *args, &block) : read(method_id)
70
+ else
71
+ super
72
+ end
73
+ end
74
+
75
+ class << self
76
+ def inherited(child)
77
+ child.instance_variable_set('@elements',@elements ||= {})
78
+ child.instance_variable_set('@attributes',@attributes ||= {})
79
+ end
80
+
81
+ # Declare an Element for this Body
82
+ #@param [Symbol] name A name to assign the Element (tag name)
83
+ #@param [Class] type A type to use for the element (enforcement)
84
+ #@option options [Boolean] :single False if object is a collection
85
+ def element(*options)
86
+ @elements ||= {}
87
+ name = options.first
88
+ type = options.second || nil
89
+ opts = options.extract_options!
90
+ @elements.update(name => opts.merge(:type => type))
91
+ end
92
+
93
+ # Declare an attribute for this Body
94
+ def attribute(name, value = nil)
95
+ @attributes ||= {}
96
+ @attributes.update(name => value)
97
+ end
98
+
99
+ # Returns the Hash list of Elements declared
100
+ def declared_elements
101
+ @elements
102
+ end
103
+
104
+ # Returns a Hash list of Attributes declared
105
+ def declared_attributes
106
+ @attributes
107
+ end
108
+
109
+ # Converts the XML to a Class object found in the library
110
+ def acdc(xml)
111
+ doc = Hpricot.XML(xml)
112
+ klass = doc.root.name.constantize
113
+ attributes = doc.root.attributes.inject({}){|acc,attr| acc.update(attr[0].to_sym => attr[1])}
114
+ values = doc.root.children.inject({}) do |acc, node|
115
+ name = node.name.underscore.to_sym
116
+ value = value_from_node(node)
117
+ attrs = node.attributes
118
+ acc.merge!({name => value, :attributes => attrs})
119
+ end
120
+ klass.new(values.merge(:attributes => attributes))
121
+ end
122
+
123
+ private
124
+ def value_from_node(node)
125
+ if node.respond_to?(:children) and node.children
126
+ values = node.children.collect do |child|
127
+ return child.inner_text if child.text?
128
+ instantiate(child)
129
+ end
130
+ (values.size == 1) ? values.first : values
131
+ end
132
+ end
133
+
134
+ def instantiate(node)
135
+ name = node.name
136
+ attrs = node.attributes
137
+ klass = name.constantize
138
+ klass.new(value_from_node(node), :attributes => attrs)
139
+ end
140
+ end
141
+
142
+ private
143
+ def options_for(key)
144
+ self.class.declared_elements[key]
145
+ end
146
+
147
+ def read(method_id)
148
+ if elements.has_key?(method_id)
149
+ elements[method_id].value
150
+ else
151
+ attributes[method_id].value
152
+ end
153
+ end
154
+
155
+ def write(method_id, *args, &block)
156
+ key = method_id.to_s.gsub(/\=$/,"").to_sym
157
+ if elements.has_key?(key)
158
+ elements.update(key => Element(args.first,options_for(key),key))
159
+ else
160
+ attributes.update(key => Attribute(key,args.first))
161
+ end
162
+ end
163
+
164
+ end
165
+ end
@@ -0,0 +1,73 @@
1
+ module AcDc
2
+
3
+ # Basic XML Element
4
+ class Element
5
+
6
+ attr_accessor :value, :tag, :attributes, :options
7
+
8
+ # Constructor with the following:
9
+ #@param [Object] value Any value to place in the tags
10
+ #@option options [Boolean] :single False if object is a collection
11
+ #@param [String] tag A tag name to use if not Element
12
+ def initialize(value, options={}, tag=nil)
13
+ @tag = tag ||= self.class.to_s.split("::").last
14
+ @value = value
15
+ @options = options
16
+ @attributes = options.delete(:attributes)
17
+ end
18
+
19
+ # Converts the object to XML
20
+ def acdc
21
+ xml = Builder::XmlMarkup.new
22
+ if value.nil?
23
+ xml.tag!(tag_content)
24
+ else
25
+ has_many? ? render_many(xml) : xml.tag!(tag_content) {|elem| elem << content}
26
+ end
27
+ xml.target!
28
+ end
29
+
30
+ # True if object has a collection of values
31
+ def has_many?
32
+ options.has_key?(:single) and !options[:single] and value.size > 1
33
+ end
34
+
35
+ # The name to use for the tag
36
+ def tag_name
37
+ tag.to_s.camelize
38
+ end
39
+
40
+ # Overridden to compare the values and not the whole object
41
+ def eql?(other)
42
+ return false if other.nil?
43
+ return false unless other.kind_of?(self.class)
44
+ value.eql?(other.value)
45
+ end
46
+
47
+ private
48
+ def tag_content
49
+ (attributes.nil? or attributes.empty?) ? tag_name : [tag_name,attributes]
50
+ end
51
+
52
+ def content
53
+ if has_many?
54
+ value.inject(""){|xml,val| xml << (val.is_a?(Element) ? val.acdc : val.to_s)}
55
+ else
56
+ value.is_a?(Element) ? value.acdc : value.to_s
57
+ end
58
+ end
59
+
60
+ def render_many(xml)
61
+ if value.respond_to?(:each)
62
+ xml.tag!(tag_content){|elem|
63
+ value.each{|val|
64
+ raise Exception.new("Can't render non-Element multiple times.") unless val.respond_to?(:acdc)
65
+ elem << val.acdc
66
+ }
67
+ }
68
+ else
69
+ xml.tag!(tag_content) {|elem| elem << content}
70
+ end
71
+ end
72
+ end
73
+ end
data/lib/acdc.rb ADDED
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'builder'
3
+ require 'activesupport'
4
+ require 'hpricot'
5
+
6
+ require File.join(File.dirname(__FILE__),"acdc","attribute")
7
+ require File.join(File.dirname(__FILE__),"acdc","element")
8
+ require File.join(File.dirname(__FILE__),"acdc","body")
9
+
10
+ module AcDc
11
+
12
+ VERSION = [0,1,1] unless defined?(AcDc::VERSION)
13
+
14
+ if defined?(JAIL_BREAK)
15
+ Element.class_eval{ alias :to_s :acdc }
16
+ Body.class_eval{ alias :to_s :acdc }
17
+ end
18
+
19
+ end
20
+
21
+ include AcDc
22
+
23
+ # Will construct a AcDc::Element classs
24
+ def Element(value, options = {}, name = nil)
25
+ Element.new(value,options,name)
26
+ end
27
+
28
+ # Will construct a AcDc::Attribute class
29
+ def Attribute(name,value)
30
+ Attribute.new(name,value)
31
+ end
32
+
33
+ # Will convert the XML to a class found in the library
34
+ def acdc(xml)
35
+ Body.acdc(xml)
36
+ end
37
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clinth3o-acdc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clint Hill
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-16 00:00:00 -07:00
12
+ date: 2009-09-19 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: "0"
23
+ version: 2.3.2
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: builder
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: "0"
33
+ version: 2.1.2
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: hpricot
@@ -40,7 +40,7 @@ dependencies:
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: "0"
43
+ version: "0.8"
44
44
  version:
45
45
  description: This is a little xml-to-object-to-xml library that gets Dirty Deeds Done Dirt Cheap.
46
46
  email: clint.hill@h3osoftware.com
@@ -54,8 +54,12 @@ files:
54
54
  - LICENSE
55
55
  - README
56
56
  - Rakefile
57
+ - lib/acdc.rb
58
+ - lib/acdc/attribute.rb
59
+ - lib/acdc/body.rb
60
+ - lib/acdc/element.rb
57
61
  has_rdoc: false
58
- homepage: http://h3osoftware.com/acdc
62
+ homepage: http://github.com/clinth3o/acdc
59
63
  licenses:
60
64
  post_install_message:
61
65
  rdoc_options: []
@@ -76,10 +80,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
80
  version:
77
81
  requirements: []
78
82
 
79
- rubyforge_project: acdc
83
+ rubyforge_project:
80
84
  rubygems_version: 1.3.5
81
85
  signing_key:
82
- specification_version: 2
83
- summary: AC/DC by h3o(software)
86
+ specification_version: 3
87
+ summary: This is a little xml-to-object-to-xml library that gets Dirty Deeds Done Dirt Cheap.
84
88
  test_files: []
85
89