restfulie 0.7.2 → 0.8.0
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/Gemfile +21 -0
- data/README.textile +10 -9
- data/Rakefile +12 -5
- data/lib/restfulie/client/base.rb +10 -6
- data/lib/restfulie/client/http/adapter.rb +48 -33
- data/lib/restfulie/client/http/atom_ext.rb +3 -68
- data/lib/restfulie/client/http/core_ext/http.rb +19 -0
- data/lib/restfulie/client/http/core_ext.rb +6 -0
- data/lib/restfulie/client/http/error.rb +3 -6
- data/lib/restfulie/client/http/marshal.rb +35 -49
- data/lib/restfulie/client/http/xml_ext.rb +7 -0
- data/lib/restfulie/client/http.rb +2 -2
- data/lib/restfulie/client/mikyung/concatenator.rb +15 -0
- data/lib/restfulie/client/mikyung/core.rb +44 -0
- data/lib/restfulie/client/mikyung/languages.rb +29 -0
- data/lib/restfulie/client/mikyung/rest_process_model.rb +114 -0
- data/lib/restfulie/client/mikyung/steady_state_walker.rb +32 -0
- data/lib/restfulie/client/mikyung/then_condition.rb +33 -0
- data/lib/restfulie/client/mikyung/when_condition.rb +53 -0
- data/lib/restfulie/client/mikyung.rb +19 -0
- data/lib/restfulie/client.rb +1 -0
- data/lib/restfulie/common/converter/atom/builder.rb +109 -0
- data/lib/restfulie/common/converter/atom/helpers.rb +9 -0
- data/lib/restfulie/common/converter/atom.rb +87 -0
- data/lib/restfulie/common/converter/values.rb +29 -0
- data/lib/restfulie/common/converter.rb +11 -0
- data/lib/restfulie/common/core_ext/proc.rb +48 -0
- data/lib/restfulie/common/core_ext.rb +5 -0
- data/lib/restfulie/common/errors.rb +6 -0
- data/lib/restfulie/common/representation/atom/atom.rng +597 -0
- data/lib/restfulie/common/representation/atom/base.rb +375 -0
- data/lib/restfulie/common/representation/atom/entry.rb +107 -0
- data/lib/restfulie/common/representation/atom/feed.rb +106 -0
- data/lib/restfulie/common/representation/atom.rb +43 -33
- data/lib/restfulie/common/representation/json.rb +1 -2
- data/lib/restfulie/common/representation/xml.rb +209 -23
- data/lib/restfulie/common/representation.rb +0 -1
- data/lib/restfulie/common.rb +2 -3
- data/lib/restfulie/server/action_controller/base.rb +21 -2
- data/lib/restfulie/server/action_controller/params_parser.rb +16 -16
- data/lib/restfulie/server/action_controller/restful_responder.rb +3 -3
- data/lib/restfulie/server/action_controller/routing/patch.rb +6 -0
- data/lib/restfulie/server/action_view/helpers.rb +8 -8
- data/lib/restfulie/server/action_view/template_handlers/tokamak.rb +3 -2
- data/lib/restfulie/server/core_ext/array.rb +13 -12
- metadata +51 -34
- data/lib/restfulie/client/http/link.rb +0 -39
- data/lib/restfulie/client/http/xml.rb +0 -4
- data/lib/restfulie/common/builder/builder_base.rb +0 -73
- data/lib/restfulie/common/builder/helpers.rb +0 -22
- data/lib/restfulie/common/builder/marshalling/atom.rb +0 -197
- data/lib/restfulie/common/builder/marshalling/base.rb +0 -12
- data/lib/restfulie/common/builder/marshalling/json.rb +0 -2
- data/lib/restfulie/common/builder/marshalling/xml.rb +0 -183
- data/lib/restfulie/common/builder/marshalling.rb +0 -16
- data/lib/restfulie/common/builder/rules/collection_rule.rb +0 -10
- data/lib/restfulie/common/builder/rules/custom_attributes.rb +0 -24
- data/lib/restfulie/common/builder/rules/link.rb +0 -20
- data/lib/restfulie/common/builder/rules/links.rb +0 -9
- data/lib/restfulie/common/builder/rules/member_rule.rb +0 -8
- data/lib/restfulie/common/builder/rules/namespace.rb +0 -35
- data/lib/restfulie/common/builder/rules/rules_base.rb +0 -77
- data/lib/restfulie/common/builder.rb +0 -17
- data/lib/vendor/atom/configuration.rb +0 -24
- data/lib/vendor/atom/pub.rb +0 -250
- data/lib/vendor/atom/xml/parser.rb +0 -373
- data/lib/vendor/atom.rb +0 -771
@@ -1,73 +0,0 @@
|
|
1
|
-
class Restfulie::Common::Builder::Base
|
2
|
-
attr_accessor :rules_blocks
|
3
|
-
attr_accessor :object
|
4
|
-
|
5
|
-
# TODO: Configurable
|
6
|
-
OPTIONS_DEFAULT = {
|
7
|
-
:eagerload => true,
|
8
|
-
:default_rule => true
|
9
|
-
}
|
10
|
-
|
11
|
-
def initialize(object, rules_blocks = [], options = {})
|
12
|
-
@options = OPTIONS_DEFAULT.merge(options)
|
13
|
-
@object = object
|
14
|
-
@rules_blocks = rules_blocks
|
15
|
-
end
|
16
|
-
|
17
|
-
# Remove to_json from ActiveSupport in the class
|
18
|
-
# I want my own to_json
|
19
|
-
undef_method :to_json if respond_to?(:to_json)
|
20
|
-
|
21
|
-
def respond_to?(symbol, include_private = false)
|
22
|
-
marshalling_class(symbol) || super
|
23
|
-
end
|
24
|
-
|
25
|
-
def method_missing(symbol, *args)
|
26
|
-
unless (marshalling = marshalling_class!(symbol)).nil?
|
27
|
-
return builder(marshalling, *args)
|
28
|
-
end
|
29
|
-
super
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def builder(marshalling, options = {})
|
35
|
-
@object.class.ancestors.include?(Enumerable) ? builder_collection(marshalling, options) : builder_member(marshalling, options)
|
36
|
-
end
|
37
|
-
|
38
|
-
def builder_member(marshalling, options = {})
|
39
|
-
marshalling.new(@object, rules_blocks).builder_member(@options.merge(options))
|
40
|
-
end
|
41
|
-
|
42
|
-
def builder_collection(marshalling, options = {})
|
43
|
-
marshalling.new(@object, rules_blocks).builder_collection(@options.merge(options))
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.marshalling_classes(media_type)
|
47
|
-
{"application/atom+xml" => Restfulie::Common::Builder::Marshalling::Atom,
|
48
|
-
"application/xml" => Restfulie::Common::Builder::Marshalling::Xml::Marshaller,
|
49
|
-
"application/json" => Restfulie::Common::Builder::Marshalling::Json,
|
50
|
-
"atom" => Restfulie::Common::Builder::Marshalling::Atom, # test only
|
51
|
-
"xml" => Restfulie::Common::Builder::Marshalling::Xml::Marshaller # test only
|
52
|
-
}[media_type.downcase]
|
53
|
-
end
|
54
|
-
|
55
|
-
def marshalling_class(method)
|
56
|
-
if (marshalling_name = method.to_s.match(/to_(.*)/))
|
57
|
-
marshalling = marshalling_name[1].downcase
|
58
|
-
Restfulie::Common::Builder::Base.marshalling_classes(marshalling)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def marshalling_class!(method)
|
63
|
-
if marshalling_name = method.to_s.match(/to_(.*)/)
|
64
|
-
marshalling = marshalling_name[1].downcase
|
65
|
-
if (marshaller = Restfulie::Common::Builder::Base.marshalling_classes(marshalling))
|
66
|
-
marshaller
|
67
|
-
else
|
68
|
-
raise Restfulie::Common::Error::UndefinedMarshallingError.new("Marshalling #{marshalling} not found.")
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Restfulie::Common::Builder::Helpers
|
2
|
-
|
3
|
-
def describe_member(member, options = {}, &block)
|
4
|
-
create_builder(member, options, &block)
|
5
|
-
end
|
6
|
-
|
7
|
-
def describe_collection(collection, options = {}, &block)
|
8
|
-
create_builder(collection, options, &block)
|
9
|
-
end
|
10
|
-
|
11
|
-
# Helper to create objects link
|
12
|
-
def link(*args)
|
13
|
-
Restfulie::Common::Builder::Rules::Link.new(*args)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def create_builder(object, options, &block)
|
19
|
-
Restfulie::Common::Builder::Base.new(object, block_given? ? [block] : [], options)
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
@@ -1,197 +0,0 @@
|
|
1
|
-
class Restfulie::Common::Builder::Marshalling::Atom < Restfulie::Common::Builder::Marshalling::Base
|
2
|
-
include ActionController::UrlWriter
|
3
|
-
include Restfulie::Common::Builder::Helpers
|
4
|
-
include Restfulie::Common::Error
|
5
|
-
|
6
|
-
ATOM_ATTRIBUTES = [
|
7
|
-
:title, :id, :updated, # Required
|
8
|
-
:author, :links, # Recommended
|
9
|
-
:category, :contributor, :rights # Optional
|
10
|
-
]
|
11
|
-
|
12
|
-
ATOM_ATTRIBUTES_ENTRY = ATOM_ATTRIBUTES + [
|
13
|
-
:content, :summary, # Required
|
14
|
-
:published, :source # Optional
|
15
|
-
]
|
16
|
-
|
17
|
-
ATOM_ATTRIBUTES_FEED = ATOM_ATTRIBUTES + [
|
18
|
-
:generator, :icon, :logo, :subtitle # Optional
|
19
|
-
]
|
20
|
-
|
21
|
-
ATTRIBUTES_ALREADY_IN_ATOM_SPEC = [
|
22
|
-
"id", "created_at", "updated_at", "title"
|
23
|
-
]
|
24
|
-
|
25
|
-
def initialize(object, rules)
|
26
|
-
@object = object
|
27
|
-
@rules = rules
|
28
|
-
end
|
29
|
-
|
30
|
-
def builder_collection(options = {})
|
31
|
-
builder_feed(@object, @rules, options).to_xml
|
32
|
-
end
|
33
|
-
|
34
|
-
def builder_member(options = {})
|
35
|
-
builder_entry(@object, @rules, options).to_xml
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def builder_feed(objects, rules_blocks, options = {})
|
41
|
-
rule = Restfulie::Common::Builder::CollectionRule.new(rules_blocks)
|
42
|
-
|
43
|
-
rule.blocks.unshift(default_collection_rule) if options[:default_rule]
|
44
|
-
rule.metaclass.send(:attr_accessor, *ATOM_ATTRIBUTES_FEED)
|
45
|
-
rule.apply(objects, options)
|
46
|
-
|
47
|
-
atom = ::Atom::Feed.new do |feed|
|
48
|
-
# Set values
|
49
|
-
(ATOM_ATTRIBUTES_FEED - [:links]).each do |field|
|
50
|
-
feed.send("#{field}=".to_sym, rule.send(field)) unless rule.send(field).nil?
|
51
|
-
end
|
52
|
-
|
53
|
-
# Namespaces
|
54
|
-
builder_namespaces(rule.namespaces, feed)
|
55
|
-
|
56
|
-
# Transitions
|
57
|
-
rule.links.each do |link|
|
58
|
-
atom_link = {:rel => link.rel, :href => link.href, :type => (link.type || 'application/atom+xml')}
|
59
|
-
feed.links << ::Atom::Link.new(atom_link) unless atom_link[:href].nil?
|
60
|
-
end
|
61
|
-
|
62
|
-
# Entries
|
63
|
-
options.delete(:values)
|
64
|
-
member_options = options.merge(rule.members_options || {})
|
65
|
-
objects.each do |member|
|
66
|
-
feed.entries << builder_entry(member, rule.members_blocks || [], member_options)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# TODO: Validate of the required fields
|
72
|
-
def default_collection_rule
|
73
|
-
Proc.new do |collection_rule, objects, options|
|
74
|
-
# Passed values
|
75
|
-
(options[:values] || {}).each { |key, value| collection_rule.send("#{key}=".to_sym, value)}
|
76
|
-
|
77
|
-
# Default values
|
78
|
-
collection_rule.id ||= options[:self]
|
79
|
-
collection_rule.title ||= "#{objects.first.class.to_s.pluralize.demodulize} feed"
|
80
|
-
collection_rule.updated ||= updated_collection(objects)
|
81
|
-
|
82
|
-
# Transitions
|
83
|
-
collection_rule.links << link(:rel => :self, :href => options[:self]) unless options[:self].nil?
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def builder_entry(object, rules_blocks, options = {})
|
88
|
-
rule = Restfulie::Common::Builder::MemberRule.new(rules_blocks)
|
89
|
-
options = namespace_enhance(options)
|
90
|
-
|
91
|
-
rule.blocks.unshift(default_member_rule) if options[:default_rule]
|
92
|
-
rule.metaclass.send(:attr_accessor, *ATOM_ATTRIBUTES_ENTRY)
|
93
|
-
rule.apply(object, options)
|
94
|
-
|
95
|
-
atom = ::Atom::Entry.new do |entry|
|
96
|
-
# Set values
|
97
|
-
(ATOM_ATTRIBUTES_ENTRY - [:links]).each do |field|
|
98
|
-
entry.send("#{field}=".to_sym, rule.send(field)) unless rule.send(field).nil?
|
99
|
-
end
|
100
|
-
|
101
|
-
# Namespaces
|
102
|
-
builder_namespaces(rule.namespaces, entry)
|
103
|
-
|
104
|
-
# Transitions
|
105
|
-
rule.links.each do |link|
|
106
|
-
atom_link = {:rel => link.rel, :href => link.href, :type => link.type}
|
107
|
-
|
108
|
-
# Self
|
109
|
-
if link.href.nil?
|
110
|
-
if link.rel == "self"
|
111
|
-
path = object
|
112
|
-
else
|
113
|
-
association = object.class.reflect_on_all_associations.find { |a| a.name.to_s == link.rel }
|
114
|
-
path = (association.macro == :has_many) ? [object, association.name] : object.send(association.name) unless association.nil?
|
115
|
-
end
|
116
|
-
atom_link[:href] = polymorphic_url(path, :host => host) rescue nil
|
117
|
-
atom_link[:type] = link.type || 'application/atom+xml'
|
118
|
-
end
|
119
|
-
|
120
|
-
entry.links << ::Atom::Link.new(atom_link) unless atom_link[:href].nil?
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def default_member_rule
|
126
|
-
Proc.new do |member_rule, object, options|
|
127
|
-
# Passed values
|
128
|
-
(options[:values] || {}).each { |key, value| set_attribute(member_rule, key, value) }
|
129
|
-
|
130
|
-
# Default values
|
131
|
-
member_rule.id ||= polymorphic_url(object, :host => host) rescue nil
|
132
|
-
member_rule.title ||= object.respond_to?(:title) && !object.title.nil? ? object.title : "Entry about #{object.class.to_s.demodulize}"
|
133
|
-
member_rule.updated ||= object.updated_at if object.respond_to?(:updated_at)
|
134
|
-
|
135
|
-
# Namespace
|
136
|
-
unless options[:namespace].nil?
|
137
|
-
member_rule.namespace(object, options[:namespace][:uri], options[:namespace])
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def updated_collection(objects)
|
143
|
-
objects.map { |item| item.updated_at if item.respond_to?(:updated_at) }.compact.max || Time.now
|
144
|
-
end
|
145
|
-
|
146
|
-
def builder_namespaces(namespaces, atom)
|
147
|
-
kclass = atom.class
|
148
|
-
namespaces.each do |ns|
|
149
|
-
register_namespace(ns.namespace, ns.uri, kclass)
|
150
|
-
ns.each do |key, value|
|
151
|
-
unless ATTRIBUTES_ALREADY_IN_ATOM_SPEC.include?(key.to_s)
|
152
|
-
register_element(ns.namespace, key, kclass)
|
153
|
-
atom.send("#{ns.namespace}_#{key}=".to_sym, value)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
def host
|
160
|
-
# TODO: If we split restfulie into 2 separate gems, we may need not to use Restfulie::Server
|
161
|
-
# inside Restfulie::Common
|
162
|
-
Restfulie::Server::Configuration.host
|
163
|
-
end
|
164
|
-
|
165
|
-
def register_namespace(namespace, uri, klass)
|
166
|
-
klass.add_extension_namespace(namespace, uri) unless klass.known_namespaces.include? uri
|
167
|
-
end
|
168
|
-
|
169
|
-
def register_element(namespace, attribute, klass)
|
170
|
-
attribute = "#{namespace}:#{attribute}"
|
171
|
-
klass.element(attribute) if element_unregistered?(attribute, klass)
|
172
|
-
end
|
173
|
-
|
174
|
-
def element_unregistered?(element, klass)
|
175
|
-
klass.element_specs.select { |k,v| v.name == element }.empty?
|
176
|
-
end
|
177
|
-
|
178
|
-
# TODO : Move error handling to class rule, maybe?
|
179
|
-
def set_attribute(rule, attribute, value)
|
180
|
-
begin
|
181
|
-
rule.send("#{attribute}=".to_sym, value)
|
182
|
-
rescue NoMethodError
|
183
|
-
raise AtomMarshallingError.new("Attribute #{attribute} unsupported in Atom #{rule_type_name(rule)}.")
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def rule_type_name(rule)
|
188
|
-
rule.kind_of?(Restfulie::Common::Builder::MemberRule) ? 'Entry' : 'Feed'
|
189
|
-
end
|
190
|
-
|
191
|
-
def namespace_enhance(options)
|
192
|
-
if options[:namespace] && options[:namespace].kind_of?(String)
|
193
|
-
options[:namespace] = { :uri => options[:namespace], :eager_load => true }
|
194
|
-
end
|
195
|
-
options
|
196
|
-
end
|
197
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
class Restfulie::Common::Builder::Marshalling::Base
|
2
|
-
def initialize(*args)
|
3
|
-
end
|
4
|
-
|
5
|
-
def builder_member(options = {})
|
6
|
-
"#{self.class.to_s.demodulize} Marshalling not implemented"
|
7
|
-
end
|
8
|
-
|
9
|
-
def builder_collection(options = {})
|
10
|
-
"#{self.class.to_s.demodulize} Marshalling not implemented"
|
11
|
-
end
|
12
|
-
end
|
@@ -1,183 +0,0 @@
|
|
1
|
-
# support xml serialization for custom attributes
|
2
|
-
module Restfulie::Common::Builder::Rules::CustomAttributes
|
3
|
-
|
4
|
-
def to_xml(writer)
|
5
|
-
custom_attributes.each do |key, value|
|
6
|
-
writer.tag!(key, value)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
module Restfulie::Common::Builder::Marshalling::Xml
|
13
|
-
end
|
14
|
-
|
15
|
-
# Xml collection rule answering to to_xml and allowing any custom element to be inserted
|
16
|
-
# All links will be automatically inserted.
|
17
|
-
class Restfulie::Common::Builder::Marshalling::Xml::CollectionRule < Restfulie::Common::Builder::CollectionRule
|
18
|
-
|
19
|
-
include Restfulie::Common::Builder::Rules::CustomAttributes
|
20
|
-
|
21
|
-
def to_xml(writer)
|
22
|
-
super(writer)
|
23
|
-
links.each do |link|
|
24
|
-
writer.link(:rel => link.rel, :href => link.href, :type => (link.type || 'application/xml')) if link.href
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
# Xml member rule answering to to_xml and allowing any custom element to be inserted.
|
31
|
-
# All links will be automatically inserted.
|
32
|
-
class Restfulie::Common::Builder::Marshalling::Xml::MemberRule < Restfulie::Common::Builder::MemberRule
|
33
|
-
|
34
|
-
include ActionController::UrlWriter
|
35
|
-
include Restfulie::Common::Builder::Rules::CustomAttributes
|
36
|
-
|
37
|
-
def to_xml(object, writer)
|
38
|
-
super(writer)
|
39
|
-
# Transitions
|
40
|
-
links.each do |link|
|
41
|
-
atom_link = {:rel => link.rel, :href => link.href, :type => link.type}
|
42
|
-
|
43
|
-
# Self
|
44
|
-
if link.href.nil?
|
45
|
-
if link.rel == "self"
|
46
|
-
path = object
|
47
|
-
else
|
48
|
-
association = object.class.reflect_on_all_associations.find { |a| a.name.to_s == link.rel }
|
49
|
-
path = (association.macro == :has_many) ? [object, association.name] : object.send(association.name) unless association.nil?
|
50
|
-
end
|
51
|
-
atom_link[:href] = polymorphic_url(path, :host => host) rescue nil
|
52
|
-
atom_link[:type] = link.type || 'application/xml'
|
53
|
-
end
|
54
|
-
writer.link(:rel => atom_link[:rel], :href => atom_link[:href], :type => (link.type || 'application/xml')) if atom_link[:href]
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
def host
|
61
|
-
# TODO: If we split restfulie into 2 separate gems, we may need not to use Restfulie::Server
|
62
|
-
# inside Restfulie::Common
|
63
|
-
Restfulie::Server::Configuration.host
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
class Restfulie::Common::Builder::Marshalling::Xml::Marshaller < Restfulie::Common::Builder::Marshalling::Base
|
69
|
-
include ActionController::UrlWriter
|
70
|
-
include Restfulie::Common::Builder::Helpers
|
71
|
-
include Restfulie::Common::Error
|
72
|
-
|
73
|
-
def initialize(object, rules)
|
74
|
-
@object = object
|
75
|
-
@rules = rules
|
76
|
-
end
|
77
|
-
|
78
|
-
def builder_collection(options = {})
|
79
|
-
builder_feed(@object, @rules, options)
|
80
|
-
end
|
81
|
-
|
82
|
-
def builder_member(options = {})
|
83
|
-
options[:indent] ||= 2
|
84
|
-
options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
|
85
|
-
options[:skip_types] = true
|
86
|
-
builder_entry(@object, options[:builder], @object.class.name.underscore, @rules, options)
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def builder_feed(objects, rules_blocks, options = {})
|
92
|
-
rule = Restfulie::Common::Builder::Marshalling::Xml::CollectionRule.new(rules_blocks)
|
93
|
-
|
94
|
-
rule.blocks.unshift(default_collection_rule) if options[:default_rule]
|
95
|
-
rule.apply(objects, options)
|
96
|
-
|
97
|
-
# setup code from Rails to_xml
|
98
|
-
|
99
|
-
options[:root] ||= objects.all? { |e| e.is_a?(objects.first.class) && objects.first.class.to_s != "Hash" } ? objects.first.class.to_s.underscore.pluralize : "records"
|
100
|
-
options[:children] ||= options[:root].singularize
|
101
|
-
options[:indent] ||= 2
|
102
|
-
options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
|
103
|
-
|
104
|
-
root = options.delete(:root).to_s
|
105
|
-
children = options.delete(:children)
|
106
|
-
|
107
|
-
if !options.has_key?(:dasherize) || options[:dasherize]
|
108
|
-
root = root.dasherize
|
109
|
-
end
|
110
|
-
|
111
|
-
options[:builder].instruct! unless options.delete(:skip_instruct)
|
112
|
-
|
113
|
-
opts = options.merge({ :root => children })
|
114
|
-
|
115
|
-
writer = options[:builder]
|
116
|
-
|
117
|
-
# Entries
|
118
|
-
options.delete(:values)
|
119
|
-
member_options = options.merge(rule.members_options || {})
|
120
|
-
member_options[:skip_instruct] = true
|
121
|
-
start_with_namespace(rule.namespaces, writer, root, options[:skip_types] ? {} : {}) do
|
122
|
-
rule.to_xml(writer)
|
123
|
-
yield writer if block_given?
|
124
|
-
|
125
|
-
objects.each { |e|
|
126
|
-
builder_entry(e, writer, children, rule.members_blocks || [], member_options)
|
127
|
-
}
|
128
|
-
end
|
129
|
-
|
130
|
-
end
|
131
|
-
|
132
|
-
def start_with_namespace(namespaces, writer, root, condition, &block)
|
133
|
-
spaces = condition.dup
|
134
|
-
namespaces.each do |ns|
|
135
|
-
ns.each do |key, value|
|
136
|
-
spaces["xmlns:#{ns.namespace}"] = ns.uri
|
137
|
-
end if ns.uri
|
138
|
-
end
|
139
|
-
result = writer.tag!(root, spaces) do |inner|
|
140
|
-
namespaces.each do |ns|
|
141
|
-
ns.each do |key, value|
|
142
|
-
tag = ns.namespace ? "#{key}" : "#{ns.namespace}:#{key}"
|
143
|
-
inner.tag! tag, value
|
144
|
-
end
|
145
|
-
end
|
146
|
-
block.call inner
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def default_collection_rule
|
151
|
-
Proc.new do |collection_rule, objects, options|
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def builder_entry(object, xml, children, rules_blocks, options)
|
156
|
-
rule = Restfulie::Common::Builder::Marshalling::Xml::MemberRule.new(rules_blocks)
|
157
|
-
options = namespace_enhance(options)
|
158
|
-
|
159
|
-
rule.blocks.unshift(default_member_rule) if options[:default_rule]
|
160
|
-
rule.apply(object, options)
|
161
|
-
|
162
|
-
start_with_namespace(rule.namespaces, xml, children, {}) do |inner_xml|
|
163
|
-
rule.to_xml(object, inner_xml)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def default_member_rule
|
168
|
-
Proc.new do |member_rule, object, options|
|
169
|
-
if options[:namespace]
|
170
|
-
member_rule.namespace(object, options[:namespace][:uri], options[:namespace])
|
171
|
-
else
|
172
|
-
member_rule.namespace(object, nil, options[:namespace] || {})
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
def namespace_enhance(options)
|
178
|
-
if !options[:namespace].nil? && options[:namespace].kind_of?(String)
|
179
|
-
options[:namespace] = { :uri => options[:namespace], :eager_load => true }
|
180
|
-
end
|
181
|
-
options
|
182
|
-
end
|
183
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Restfulie::Common::Builder::Marshalling
|
2
|
-
class << self
|
3
|
-
def add_autoload_path(path)
|
4
|
-
if File.directory?(path)
|
5
|
-
Dir["#{path}/*.rb"].each do |file|
|
6
|
-
marshalling_class = File.basename(file, ".rb").downcase.classify.to_sym
|
7
|
-
self.autoload(marshalling_class, file) if !self.const_defined?(marshalling_class) && self.autoload?(marshalling_class).nil?
|
8
|
-
end
|
9
|
-
else
|
10
|
-
raise Restfulie::Common::Error::MarshallingError.new("#{path} is not a path.")
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
self.add_autoload_path(File.join(File.dirname(__FILE__), 'marshalling'))
|
16
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
class Restfulie::Common::Builder::CollectionRule < Restfulie::Common::Builder::Rules::Base
|
2
|
-
attr_reader :members_blocks
|
3
|
-
attr_reader :members_options
|
4
|
-
|
5
|
-
def describe_members(options = {}, &block)
|
6
|
-
@members_blocks = block_given? ? [block] : []
|
7
|
-
@members_options = options
|
8
|
-
end
|
9
|
-
|
10
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# Rules that allow any type of content shall extend this one and provide valid serialization methods. i.e.: to_xml
|
2
|
-
module Restfulie::Common::Builder::Rules::CustomAttributes
|
3
|
-
|
4
|
-
# returns true if it's a valid attribute evaluation or
|
5
|
-
def method_missing(sym, *args)
|
6
|
-
if sym.to_s.last=="=" && args.size==1
|
7
|
-
custom_attributes[sym.to_s.chop] = args[0]
|
8
|
-
elsif custom_attributes[sym.to_s]
|
9
|
-
custom_attributes[sym.to_s]
|
10
|
-
else
|
11
|
-
super(sym, *args)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def respond_to?(sym)
|
16
|
-
super(sym) || (sym.to_s.last == "=") || custom_attributes[sym.to_s]
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def custom_attributes
|
22
|
-
@custom_attributes ||= {}
|
23
|
-
end
|
24
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
class Restfulie::Common::Builder::Rules::Link
|
2
|
-
# Required
|
3
|
-
attr_accessor :href
|
4
|
-
|
5
|
-
# Optional
|
6
|
-
attr_accessor :rel, :type
|
7
|
-
attr_accessor :hreflang, :title, :length
|
8
|
-
|
9
|
-
# TODO: Inline resource and collection support
|
10
|
-
def initialize(options = {})
|
11
|
-
options = { :rel => options } unless options.kind_of?(Hash)
|
12
|
-
options.each do |k, i|
|
13
|
-
self.send("#{k}=".to_sym, i)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def rel=(value)
|
18
|
-
@rel = value.kind_of?(String) ? value : value.to_s
|
19
|
-
end
|
20
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# Representation of a namespace. Allows any type of attribute setting and grabbing, i.e.:
|
2
|
-
#
|
3
|
-
# collection.namespace(:basket, "http://openbuy.com/basket") do |ns|
|
4
|
-
# ns.price = @basket.cost
|
5
|
-
# end
|
6
|
-
#
|
7
|
-
# or
|
8
|
-
#
|
9
|
-
# collection.describe_members(:namespaces => "http://localhost:3000/items") do |member, item|
|
10
|
-
# member.links << link( :rel => :self, :href => item_url(item))
|
11
|
-
# end
|
12
|
-
class Restfulie::Common::Builder::Rules::Namespace < Hash
|
13
|
-
attr_reader :namespace
|
14
|
-
attr_reader :uri
|
15
|
-
|
16
|
-
def initialize(ns, uri, *args)
|
17
|
-
@namespace = ns.to_sym
|
18
|
-
self.uri = uri
|
19
|
-
super(*args)
|
20
|
-
end
|
21
|
-
|
22
|
-
def uri=(value)
|
23
|
-
@uri = value
|
24
|
-
end
|
25
|
-
|
26
|
-
def method_missing(symbol, *args)
|
27
|
-
if ((key = symbol.to_s.match(/(.*)=/)) && args.size >= 1)
|
28
|
-
self[key[1].to_sym] = args.first
|
29
|
-
elsif(keys.include?(symbol))
|
30
|
-
self[symbol]
|
31
|
-
else
|
32
|
-
super
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|