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.
- data/lib/acdc/attribute.rb +20 -0
- data/lib/acdc/body.rb +165 -0
- data/lib/acdc/element.rb +73 -0
- data/lib/acdc.rb +37 -0
- metadata +13 -9
@@ -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
|
data/lib/acdc/element.rb
ADDED
@@ -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.
|
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-
|
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:
|
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:
|
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://
|
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:
|
83
|
+
rubyforge_project:
|
80
84
|
rubygems_version: 1.3.5
|
81
85
|
signing_key:
|
82
|
-
specification_version:
|
83
|
-
summary:
|
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
|
|