restfulie 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/Gemfile +10 -5
  2. data/Rakefile +5 -2
  3. data/lib/restfulie.rb +10 -5
  4. data/lib/restfulie/client.rb +13 -9
  5. data/lib/restfulie/client/base.rb +24 -65
  6. data/lib/restfulie/client/configuration.rb +62 -64
  7. data/lib/restfulie/client/entry_point.rb +36 -0
  8. data/lib/restfulie/client/ext/atom_ext.rb +12 -0
  9. data/lib/restfulie/client/ext/http_ext.rb +22 -0
  10. data/lib/restfulie/client/ext/json_ext.rb +12 -0
  11. data/lib/restfulie/client/ext/xml_ext.rb +4 -0
  12. data/lib/restfulie/client/http.rb +25 -13
  13. data/lib/restfulie/client/http/cache.rb +22 -22
  14. data/lib/restfulie/client/http/error.rb +70 -70
  15. data/lib/restfulie/client/http/link_request_builder.rb +15 -0
  16. data/lib/restfulie/client/http/request_adapter.rb +209 -0
  17. data/lib/restfulie/client/http/request_builder.rb +107 -0
  18. data/lib/restfulie/client/http/request_builder_executor.rb +24 -0
  19. data/lib/restfulie/client/http/request_executor.rb +17 -0
  20. data/lib/restfulie/client/http/request_follow.rb +42 -0
  21. data/lib/restfulie/client/http/request_follow_executor.rb +10 -0
  22. data/lib/restfulie/client/http/request_history.rb +69 -0
  23. data/lib/restfulie/client/http/request_history_executor.rb +10 -0
  24. data/lib/restfulie/client/http/request_marshaller.rb +127 -0
  25. data/lib/restfulie/client/http/request_marshaller_executor.rb +10 -0
  26. data/lib/restfulie/client/http/response.rb +23 -0
  27. data/lib/restfulie/client/http/response_handler.rb +67 -0
  28. data/lib/restfulie/client/http/response_holder.rb +9 -0
  29. data/lib/restfulie/client/mikyung.rb +17 -14
  30. data/lib/restfulie/client/mikyung/concatenator.rb +15 -12
  31. data/lib/restfulie/client/mikyung/core.rb +65 -39
  32. data/lib/restfulie/client/mikyung/languages.rb +8 -26
  33. data/lib/restfulie/client/mikyung/languages/german.rb +24 -0
  34. data/lib/restfulie/client/mikyung/languages/portuguese.rb +23 -0
  35. data/lib/restfulie/client/mikyung/rest_process_model.rb +184 -107
  36. data/lib/restfulie/client/mikyung/steady_state_walker.rb +34 -28
  37. data/lib/restfulie/client/mikyung/then_condition.rb +33 -27
  38. data/lib/restfulie/client/mikyung/when_condition.rb +53 -49
  39. data/lib/restfulie/common.rb +7 -12
  40. data/lib/restfulie/common/converter.rb +20 -9
  41. data/lib/restfulie/common/converter/atom.rb +8 -83
  42. data/lib/restfulie/common/converter/atom/base.rb +89 -0
  43. data/lib/restfulie/common/converter/atom/builder.rb +101 -99
  44. data/lib/restfulie/common/converter/atom/helpers.rb +16 -8
  45. data/lib/restfulie/common/converter/json.rb +12 -0
  46. data/lib/restfulie/common/converter/json/base.rb +84 -0
  47. data/lib/restfulie/common/converter/json/builder.rb +102 -0
  48. data/lib/restfulie/common/converter/json/helpers.rb +17 -0
  49. data/lib/restfulie/common/converter/values.rb +30 -26
  50. data/lib/restfulie/common/converter/xml.rb +14 -0
  51. data/lib/restfulie/common/converter/xml/base.rb +61 -0
  52. data/lib/restfulie/common/converter/xml/builder.rb +112 -0
  53. data/lib/restfulie/common/converter/xml/helpers.rb +17 -0
  54. data/lib/restfulie/common/converter/xml/link.rb +25 -0
  55. data/lib/restfulie/common/converter/xml/links.rb +25 -0
  56. data/lib/restfulie/common/core_ext.rb +1 -5
  57. data/lib/restfulie/common/core_ext/hash.rb +12 -0
  58. data/lib/restfulie/common/error.rb +19 -0
  59. data/lib/restfulie/common/logger.rb +17 -9
  60. data/lib/restfulie/common/representation.rb +9 -10
  61. data/lib/restfulie/common/representation/atom.rb +15 -47
  62. data/lib/restfulie/common/representation/atom/base.rb +122 -365
  63. data/lib/restfulie/common/representation/atom/category.rb +41 -0
  64. data/lib/restfulie/common/representation/atom/entry.rb +52 -100
  65. data/lib/restfulie/common/representation/atom/factory.rb +43 -0
  66. data/lib/restfulie/common/representation/atom/feed.rb +103 -99
  67. data/lib/restfulie/common/representation/atom/link.rb +68 -0
  68. data/lib/restfulie/common/representation/atom/person.rb +48 -0
  69. data/lib/restfulie/common/representation/atom/source.rb +59 -0
  70. data/lib/restfulie/common/representation/atom/tag_collection.rb +38 -0
  71. data/lib/restfulie/common/representation/atom/xml.rb +95 -0
  72. data/lib/restfulie/common/representation/generic.rb +30 -29
  73. data/lib/restfulie/common/representation/json.rb +10 -22
  74. data/lib/restfulie/common/representation/json/base.rb +27 -0
  75. data/lib/restfulie/common/representation/json/keys_as_methods.rb +72 -0
  76. data/lib/restfulie/common/representation/json/link.rb +29 -0
  77. data/lib/restfulie/common/representation/json/link_collection.rb +23 -0
  78. data/lib/restfulie/common/representation/xml.rb +18 -227
  79. data/lib/restfulie/server.rb +9 -10
  80. data/lib/restfulie/server/action_controller.rb +10 -12
  81. data/lib/restfulie/server/action_controller/base.rb +18 -15
  82. data/lib/restfulie/server/action_controller/{routing/patch.rb → patch.rb} +0 -0
  83. data/lib/restfulie/server/action_controller/restful_responder.rb +43 -35
  84. data/lib/restfulie/server/action_view.rb +8 -6
  85. data/lib/restfulie/server/action_view/helpers.rb +47 -41
  86. data/lib/restfulie/server/action_view/template_handlers.rb +24 -12
  87. data/lib/restfulie/server/action_view/template_handlers/tokamak.rb +17 -12
  88. data/lib/restfulie/server/configuration.rb +22 -19
  89. data/lib/restfulie/server/{restfulie_controller.rb → controller.rb} +1 -10
  90. data/lib/restfulie/server/core_ext.rb +1 -1
  91. data/lib/restfulie/version.rb +14 -0
  92. metadata +52 -16
  93. data/lib/restfulie/client/http/adapter.rb +0 -502
  94. data/lib/restfulie/client/http/atom_ext.rb +0 -4
  95. data/lib/restfulie/client/http/core_ext.rb +0 -6
  96. data/lib/restfulie/client/http/core_ext/http.rb +0 -19
  97. data/lib/restfulie/client/http/marshal.rb +0 -145
  98. data/lib/restfulie/client/http/xml_ext.rb +0 -7
  99. data/lib/restfulie/common/core_ext/proc.rb +0 -48
  100. data/lib/restfulie/common/errors.rb +0 -15
  101. data/lib/restfulie/server/action_controller/routing.rb +0 -12
  102. data/lib/restfulie/server/action_controller/routing/restful_route.rb +0 -14
@@ -0,0 +1,29 @@
1
+ module Restfulie
2
+ module Common
3
+ module Representation
4
+ class Json
5
+ class Link
6
+ def initialize(obj)
7
+ @obj = obj
8
+ end
9
+
10
+ def type
11
+ @obj.type
12
+ end
13
+
14
+ def href
15
+ @obj.href
16
+ end
17
+
18
+ def rel
19
+ @obj.rel
20
+ end
21
+
22
+ def method_missing(symbol, *args, &block)
23
+ @obj.send(symbol, *args, &block)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ module Restfulie
2
+ module Common
3
+ module Representation
4
+ class Json
5
+ class LinkCollection
6
+ def initialize(parent_node)
7
+ @node = parent_node
8
+ end
9
+
10
+ def method_missing(symbol, *args, &block)
11
+ linkset = @node.select {|link| link.rel == symbol.to_s }
12
+ linkset.map! { |link| Link.new(link) }
13
+ unless linkset.empty?
14
+ linkset.size == 1 ? linkset.first : linkset
15
+ else
16
+ nil
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,235 +1,26 @@
1
- module Restfulie::Common::Converter
2
- end
3
- module Restfulie::Common::Converter::Xml
4
- end
5
-
6
- class Hash
7
- def links(*args)
8
- links = fetch("link", [])
9
- Restfulie::Common::Converter::Xml::Links.new(links)
10
- end
11
- def method_missing(sym, *args)
12
- self[sym.to_s].nil? ? super(sym, args) : self[sym.to_s]
13
- end
14
- def respond_to?(sym)
15
- include?(sym.to_s) || super(sym)
16
- end
17
- end
18
-
19
- class Restfulie::Common::Converter::Xml::Links
20
-
21
- def initialize(links)
22
- links = [links] unless links.kind_of? Array
23
- links = [] unless links
24
- @links = links.map do |l|
25
- link = Restfulie::Common::Converter::Xml::Link.new(l)
26
- link.instance_eval { self.class.send :include, ::Restfulie::Client::HTTP::LinkRequestBuilder }
27
- link
28
- end
29
- end
30
-
31
- def method_missing(sym, *args)
32
- @links.find do |link|
33
- link.rel == sym.to_s
34
- end
35
- end
36
-
37
- end
38
-
39
- class Restfulie::Common::Converter::Xml::Link
40
-
41
- def initialize(options = {})
42
- @options = options
43
- end
44
- def href
45
- @options["href"]
46
- end
47
- def rel
48
- @options["rel"]
49
- end
50
- def content_type
51
- @options["type"]
52
- end
53
- def type
54
- content_type
55
- end
56
- end
57
-
58
- # Implements the interface for marshal Xml media type requests (application/xml)
59
- module Restfulie::Common::Converter::Xml
60
-
61
- mattr_reader :media_type_name
62
- @@media_type_name = 'application/xml'
63
-
64
- mattr_reader :headers
65
- @@headers = {
66
- :post => { 'Content-Type' => media_type_name }
67
- }
68
-
69
- def self.marshal(entity, options = {})
70
- to_xml(entity, options)
71
- end
72
-
73
- def self.unmarshal(string)
74
- Hash.from_xml string
75
- end
76
-
77
- mattr_reader :recipes
78
- @@recipes = {}
79
-
80
- def self.describe_recipe(recipe_name, options={}, &block)
81
- raise 'Undefined recipe' unless block_given?
82
- raise 'Undefined recipe_name' unless recipe_name
83
- @@recipes[recipe_name] = block
84
- end
85
-
86
- def self.to_xml(obj, options = {}, &block)
87
- return obj if obj.kind_of?(String)
88
-
89
- if block_given?
90
- recipe = block
91
- elsif options[:recipe]
92
- recipe = @@recipes[options[:recipe]]
93
- else
94
- return obj.values.first.to_xml(:root => obj.keys.first) if obj.kind_of?(Hash) && obj.size==1
95
- return obj.to_xml
96
- end
97
-
98
- # Create representation and proxy
99
- builder = Builder.new(obj)
100
-
101
- # Check recipe arity size before calling it
102
- recipe.call(*[builder, obj, options][0,recipe.arity])
103
- builder.doc.to_xml
104
- end
105
-
106
- def self.helper
107
- Restfulie::Common::Converter::Xml::Helpers
108
- end
109
-
110
- end
111
- class Restfulie::Common::Converter::Xml::Builder
112
- attr_reader :doc
113
- def initialize(obj, options = {})
114
- @doc = Nokogiri::XML::Document.new
115
- @obj = obj
116
- if options[:root]
117
- root = options[:root]
118
- else
119
- root = root_element_for(obj)
120
- end
121
- @parent = @doc.create_element(root)
122
- @parent.parent = @doc
123
- end
124
-
125
- def values(options = nil, &block)
126
- options.each do |key,value|
127
- attr = key.to_s
128
- if attr =~ /^xmlns(:\w+)?$/
129
- ns = attr.split(":", 2)[1]
130
- @parent.add_namespace_definition(ns, value)
131
- end
132
- end if options
1
+ module Restfulie
2
+ module Common
3
+ module Representation
4
+ # Implements the interface for marshal Xml media type requests (application/xml)
5
+ class XmlD
6
+ cattr_reader :media_type_name
7
+ @@media_type_name = 'application/xml'
133
8
 
134
- yield Restfulie::Common::Converter::Components::Values.new(self)
135
- end
136
-
137
- def insert_value(name, prefix, *args, &block)
138
- node = create_element(name.to_s, prefix, *args)
139
- node.parent = @parent
9
+ cattr_reader :headers
10
+ @@headers = {
11
+ :post => { 'Content-Type' => media_type_name }
12
+ }
140
13
 
141
- if block_given?
142
- @parent = node
143
- block.call
144
- @parent = node.parent
145
- end
146
- end
147
-
148
- def link(relationship, uri, options = {})
149
- options["rel"] = relationship.to_s
150
- options["href"] = uri
151
- options["type"] ||= "application/xml"
152
- insert_value("link", nil, options)
153
- end
154
-
155
- def members(a_collection = nil, &block)
156
- collection = a_collection || @obj
157
- raise Restfulie::Common::Error::BuilderError("Members method require a collection to execute") unless collection.respond_to?(:each)
158
- collection.each do |member|
159
- entry = @doc.create_element(root_element_for(member))
160
- entry.parent = @parent
161
- @parent = entry
162
- block.call(self, member)
163
- @parent = entry.parent
164
- end
165
- end
166
-
167
- private
168
-
169
- def root_element_for(obj)
170
- if obj.kind_of?(Hash) && obj.size==1
171
- obj.keys.first.to_s
172
- elsif obj.kind_of?(Array) && !obj.empty?
173
- root_element_for(obj.first).underscore.pluralize
174
- else
175
- obj.class.to_s.underscore
176
- end
177
- end
178
-
179
- def create_element(node, prefix, *args)
180
- node = @doc.create_element(node) do |n|
181
- if prefix
182
- if namespace = prefix_valid?(prefix)
183
- # Adding namespace prefix
184
- n.namespace = namespace
185
- namespace = nil
14
+ def unmarshal(string)
15
+ Hash.from_xml(string)
186
16
  end
187
- end
188
-
189
- args.each do |arg|
190
- case arg
191
- # Adding XML attributes
192
- when Hash
193
- arg.each { |k,v|
194
- key = k.to_s
195
- if key =~ /^xmlns(:\w+)?$/
196
- ns_name = key.split(":", 2)[1]
197
- n.add_namespace_definition(ns_name, v)
198
- next
199
- end
200
- n[k.to_s] = v.to_s
201
- }
202
- # Adding XML node content
203
- else
204
- arg.kind_of?(Time) || arg.kind_of?(DateTime) ? content = arg.xmlschema : content = arg
205
- n.content = content
17
+
18
+ def marshal(entity, rel)
19
+ return entity if entity.kind_of? String
20
+ return entity.values.first.to_xml(:root => entity.keys.first) if entity.kind_of?(Hash) && entity.size==1
21
+ entity.to_xml
206
22
  end
207
23
  end
208
24
  end
209
25
  end
210
-
211
- def prefix_valid?(prefix)
212
- ns = @parent.namespace_definitions.find { |x| x.prefix == prefix.to_s }
213
-
214
- unless ns
215
- @parent.ancestors.each do |a|
216
- next if a == @doc
217
- ns = a.namespace_definitions.find { |x| x.prefix == prefix.to_s }
218
- break if ns
219
- end
220
- end
221
-
222
- return ns
223
- end
224
-
225
- end
226
-
227
- module Restfulie::Common::Converter::Xml::Helpers
228
- def collection(obj, *args, &block)
229
- Restfulie::Common::Converter::Xml.to_xml(obj, {}, &block)
230
- end
231
-
232
- def member(obj, *args, &block)
233
- Restfulie::Common::Converter::Xml.to_xml(obj, {}, &block)
234
- end
235
26
  end
@@ -1,15 +1,14 @@
1
1
  require 'restfulie/common'
2
2
  require 'responders_backport'
3
3
 
4
- module Restfulie::Server; end
5
-
6
- %w(
7
- configuration
8
- action_controller
9
- action_view
10
- core_ext
11
- restfulie_controller
12
- ).each do |file|
13
- require "restfulie/server/#{file}"
4
+ module Restfulie
5
+ module Server
6
+ autoload :Configuration, 'restfulie/server/configuration'
7
+ autoload :ActionController, 'restfulie/server/action_controller'
8
+ autoload :ActionView, 'restfulie/server/action_view'
9
+ autoload :Controller, 'restfulie/server/controller'
10
+ end
14
11
  end
15
12
 
13
+ require 'restfulie/server/core_ext'
14
+ Restfulie::Server::ActionView::TemplateHandlers.activate!
@@ -1,15 +1,13 @@
1
- module Restfulie::Server::ActionController#:nodoc:
2
-
3
- if defined?(::ActionController) || defined?(::ApplicationController)
4
-
5
- %w(
6
- params_parser
7
- restful_responder
8
- base
9
- routing
10
- ).each do |file|
11
- autoload file.camelize.to_sym, "restfulie/server/action_controller/#{file}"
1
+ module Restfulie
2
+ module Server
3
+ module ActionController #:nodoc:
4
+ if defined?(::ActionController) || defined?(::ApplicationController)
5
+ autoload :ParamsParser, 'restfulie/server/action_controller/params_parser'
6
+ autoload :RestfulResponder, 'restfulie/server/action_controller/restful_responder'
7
+ autoload :Base, 'restfulie/server/action_controller/base'
8
+ end
12
9
  end
13
-
14
10
  end
15
11
  end
12
+
13
+ require 'restfulie/server/action_controller/patch'
@@ -1,16 +1,14 @@
1
1
  module Restfulie
2
2
  module Server
3
3
  module ActionController
4
-
5
4
  module Base
6
-
7
5
  def self.included(base)
8
6
  # Sets a default responder for this controller.
9
7
  # Needs to require responder_legacy.rb
10
8
  base.responder = Restfulie::Server::ActionController::RestfulResponder
11
9
  base.extend(Restfulie::Server::ActionController::Base::ClassMethods)
12
10
  # Atom representation is added by default
13
- ParamsParser.register('application/atom+xml', Restfulie::Common::Converter::Atom)
11
+ Restfulie::Server::ActionController::ParamsParser.register('application/atom+xml', Restfulie::Common::Converter::Atom)
14
12
  end
15
13
 
16
14
  module ClassMethods
@@ -31,20 +29,25 @@ module Restfulie
31
29
  end
32
30
  end
33
31
 
34
- protected
35
-
36
- # If your controller inherits from Restfulie::Server::Controller::Base,
37
- # it will have an :atom option, very similar to render :xml
38
- def render(options = {}, extra_options = {}, &block)
39
- if options && atom = options[:atom]
40
- response.content_type ||= Mime::ATOM
41
- render_for_text(atom.respond_to?(:to_atom) ? atom.to_atom.to_xml : atom.to_xml, options[:status])
42
- else
43
- super
44
- end
45
- end
32
+ protected
46
33
 
34
+ # If your controller inherits from Restfulie::Server::Controller::Base,
35
+ # it will have an :atom option, very similar to render :xml
36
+ def render(options = nil, extra_options = {}, &block)
37
+ if options && atom = options[:atom]
38
+ response.content_type ||= Mime::ATOM
39
+ render_for_text(atom.respond_to?(:to_atom) ? atom.to_atom.to_xml : atom.to_xml, options[:status])
40
+ else
41
+ super
42
+ end
43
+ end
47
44
  end
48
45
  end
49
46
  end
50
47
  end
48
+
49
+ class ActionController::Base
50
+ def self.acts_as_restfulie
51
+ include Restfulie::Server::ActionController::Base
52
+ end
53
+ end
@@ -1,39 +1,47 @@
1
- module Restfulie::Server::ActionController
2
- class RestfulResponder < ActionController::Responder
3
-
4
- def to_format
5
- return if do_http_cache? && do_http_cache!
6
- super
7
- end
1
+ module Restfulie
2
+ module Server
3
+ module ActionController
4
+ class RestfulResponder < ::ActionController::Responder
5
+ def to_format
6
+ return if do_http_cache? && do_http_cache!
7
+ super
8
+ end
9
+
10
+ protected
11
+ def do_http_cache!
12
+ timestamp = resources.flatten.select do |resource|
13
+ resource.respond_to?(:updated_at)
14
+ end.map do |resource|
15
+ (resource.updated_at || Time.now).utc
16
+ end.max
8
17
 
9
- protected
10
- def do_http_cache!
11
- timestamp = resources.flatten.map do |resource|
12
- (resource.updated_at || Time.now).utc if resource.respond_to?(:updated_at)
13
- end.compact.max
14
-
15
- controller.response.last_modified = timestamp if timestamp
16
- set_public_cache_control!
17
-
18
- head :not_modified if fresh = request.fresh?(controller.response)
19
- fresh
20
- end
21
-
22
- def do_http_cache?
23
- get? && @http_cache != false && ActionController::Base.perform_caching &&
24
- !new_record? && controller.response.last_modified.nil?
25
- end
26
-
27
- def new_record?
28
- resource.respond_to?(:new_record?) && resource.new_record?
29
- end
30
-
31
- def set_public_cache_control!
32
- cache_control = controller.response.headers["Cache-Control"].split(",").map {|k| k.strip }
33
- cache_control.delete("private")
34
- cache_control.delete("no-cache")
35
- cache_control << "public"
36
- controller.response.headers["Cache-Control"] = cache_control.join(', ')
18
+ controller.response.last_modified = timestamp if timestamp
19
+ set_public_cache_control!
20
+
21
+ head :not_modified if fresh = request.fresh?(controller.response)
22
+ fresh
23
+ end
24
+
25
+ def do_http_cache?
26
+ get? &&
27
+ @http_cache != false &&
28
+ ::ActionController::Base.perform_caching &&
29
+ !new_record? &&
30
+ controller.response.last_modified.nil?
31
+ end
32
+
33
+ def new_record?
34
+ resource.respond_to?(:new_record?) && resource.new_record?
35
+ end
36
+
37
+ def set_public_cache_control!
38
+ cache_control = controller.response.headers["Cache-Control"].split(",").map {|k| k.strip }
39
+ cache_control.delete("private")
40
+ cache_control.delete("no-cache")
41
+ cache_control << "public"
42
+ controller.response.headers["Cache-Control"] = cache_control.join(', ')
43
+ end
44
+ end
37
45
  end
38
46
  end
39
47
  end