restfulie 0.9.3 → 1.0.0.beta1
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 +2 -0
- data/Gemfile.lock +2 -2
- data/README.textile +4 -2
- data/Rakefile +12 -13
- data/lib/restfulie/client/base.rb +9 -2
- data/lib/restfulie/client/cache/basic.rb +6 -5
- data/lib/restfulie/client/cache/http_ext.rb +10 -8
- data/lib/restfulie/client/cache/restrictions.rb +1 -6
- data/lib/restfulie/client/dsl.rb +66 -0
- data/lib/restfulie/client/entry_point.rb +34 -9
- data/lib/restfulie/client/ext/atom_ext.rb +4 -2
- data/lib/restfulie/client/ext/json_ext.rb +5 -1
- data/lib/restfulie/client/feature/base.rb +75 -0
- data/lib/restfulie/client/feature/base_request.rb +35 -0
- data/lib/restfulie/client/feature/cache.rb +16 -0
- data/lib/restfulie/client/feature/enhance_response.rb +12 -0
- data/lib/restfulie/client/feature/follow_request.rb +41 -0
- data/lib/restfulie/client/feature/history.rb +26 -0
- data/lib/restfulie/client/feature/history_request.rb +19 -0
- data/lib/restfulie/client/feature/open_search/pattern_matcher.rb +25 -0
- data/lib/restfulie/client/feature/open_search.rb +21 -0
- data/lib/restfulie/client/feature/serialize_body.rb +32 -0
- data/lib/restfulie/client/feature/setup_header.rb +22 -0
- data/lib/restfulie/client/feature/throw_error.rb +41 -0
- data/lib/restfulie/client/feature/verb.rb +119 -0
- data/lib/restfulie/client/feature.rb +5 -0
- data/lib/restfulie/client/http/response_holder.rb +26 -6
- data/lib/restfulie/client/http.rb +1 -21
- data/lib/restfulie/client/master_delegator.rb +31 -0
- data/lib/restfulie/client/mikyung/core.rb +5 -4
- data/lib/restfulie/client/mikyung/steady_state_walker.rb +1 -1
- data/lib/restfulie/client/mikyung.rb +1 -8
- data/lib/restfulie/client.rb +3 -1
- data/lib/restfulie/common/converter/atom/base.rb +2 -0
- data/lib/restfulie/common/converter/form_url_encoded.rb +16 -0
- data/lib/restfulie/common/converter/json/base.rb +5 -2
- data/lib/restfulie/common/converter/open_search/descriptor.rb +32 -0
- data/lib/restfulie/common/converter/open_search.rb +16 -0
- data/lib/restfulie/common/converter/xml/base.rb +3 -1
- data/lib/restfulie/common/converter/xml/builder.rb +3 -2
- data/lib/restfulie/common/converter/xml/helpers.rb +4 -4
- data/lib/restfulie/common/converter/xml/link.rb +5 -0
- data/lib/restfulie/common/converter/xml/links.rb +1 -5
- data/lib/restfulie/common/converter.rb +25 -4
- data/lib/restfulie/common/core_ext/hash.rb +6 -0
- data/lib/restfulie/common/links.rb +9 -0
- data/lib/restfulie/common/representation/atom/base.rb +34 -33
- data/lib/restfulie/common/representation/atom/xml.rb +5 -10
- data/lib/restfulie/common/representation/generic.rb +0 -12
- data/lib/restfulie/common/representation/json/keys_as_methods.rb +2 -0
- data/lib/restfulie/common/representation.rb +2 -9
- data/lib/restfulie/common.rb +2 -1
- data/lib/restfulie/server/action_controller/trait/cacheable.rb +81 -0
- data/lib/restfulie/server/action_controller/trait/created.rb +17 -0
- data/lib/restfulie/server/action_controller/trait/save_prior_to_create.rb +13 -0
- data/lib/restfulie/server/action_controller/trait.rb +9 -0
- data/lib/restfulie/server/action_controller.rb +1 -5
- data/lib/restfulie/server/action_view/template_handlers/tokamak.rb +1 -1
- data/lib/restfulie/server.rb +6 -0
- data/lib/restfulie/version.rb +4 -4
- data/lib/restfulie.rb +21 -3
- metadata +37 -26
- data/lib/restfulie/client/ext/xml_ext.rb +0 -4
- data/lib/restfulie/client/http/link_request_builder.rb +0 -16
- data/lib/restfulie/client/http/request_adapter.rb +0 -213
- data/lib/restfulie/client/http/request_builder.rb +0 -114
- data/lib/restfulie/client/http/request_builder_executor.rb +0 -24
- data/lib/restfulie/client/http/request_executor.rb +0 -17
- data/lib/restfulie/client/http/request_follow.rb +0 -42
- data/lib/restfulie/client/http/request_follow_executor.rb +0 -10
- data/lib/restfulie/client/http/request_history.rb +0 -71
- data/lib/restfulie/client/http/request_history_executor.rb +0 -10
- data/lib/restfulie/client/http/request_marshaller.rb +0 -129
- data/lib/restfulie/client/http/request_marshaller_executor.rb +0 -10
- data/lib/restfulie/client/http/response.rb +0 -23
- data/lib/restfulie/client/http/response_handler.rb +0 -67
- data/lib/restfulie/server/action_controller/cacheable_responder.rb +0 -77
- data/lib/restfulie/server/action_controller/created_responder.rb +0 -19
@@ -0,0 +1,22 @@
|
|
1
|
+
module Restfulie::Client::Feature
|
2
|
+
|
3
|
+
class SetupHeader
|
4
|
+
|
5
|
+
def execute(flow, request, response, env)
|
6
|
+
headers = request.default_headers.dup.merge(request.headers)
|
7
|
+
host = request.host
|
8
|
+
if host.user || host.password
|
9
|
+
headers["Authorization"] = "Basic " + ["#{host.user}:#{host.password}"].pack("m").delete("\r\n")
|
10
|
+
end
|
11
|
+
headers.delete :recipe
|
12
|
+
headers['cookie'] = request.cookies if request.cookies
|
13
|
+
|
14
|
+
# gs: this should not be overriden, do it in some other way
|
15
|
+
request.headers = headers
|
16
|
+
|
17
|
+
flow.continue(request, response, env)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class Restfulie::Client::Feature::ThrowError
|
2
|
+
def execute(flow, request, result_so_far, env)
|
3
|
+
result = flow.continue(request, result_so_far, env)
|
4
|
+
if result.kind_of? Exception
|
5
|
+
Restfulie::Common::Logger.logger.error(result)
|
6
|
+
raise Restfulie::Client::HTTP::Error::ServerNotAvailableError.new(request, Restfulie::Client::HTTP::Response.new(request.verb, request.path, 503, nil, {}), result )
|
7
|
+
end
|
8
|
+
case result.response.code.to_i
|
9
|
+
when 100..299
|
10
|
+
result
|
11
|
+
when 300..399
|
12
|
+
raise Restfulie::Client::HTTP::Error::Redirection.new(request, result)
|
13
|
+
when 400
|
14
|
+
raise Restfulie::Client::HTTP::Error::BadRequest.new(request, result)
|
15
|
+
when 401
|
16
|
+
raise Restfulie::Client::HTTP::Error::Unauthorized.new(request, result)
|
17
|
+
when 403
|
18
|
+
raise Restfulie::Client::HTTP::Error::Forbidden.new(request, result)
|
19
|
+
when 404
|
20
|
+
raise Restfulie::Client::HTTP::Error::NotFound.new(request, result)
|
21
|
+
when 405
|
22
|
+
raise Restfulie::Client::HTTP::Error::MethodNotAllowed.new(request, result)
|
23
|
+
when 407
|
24
|
+
raise Restfulie::Client::HTTP::Error::ProxyAuthenticationRequired.new(request, result)
|
25
|
+
when 409
|
26
|
+
raise Restfulie::Client::HTTP::Error::Conflict.new(request, result)
|
27
|
+
when 410
|
28
|
+
raise Restfulie::Client::HTTP::Error::Gone.new(request, result)
|
29
|
+
when 412
|
30
|
+
raise Restfulie::Client::HTTP::Error::PreconditionFailed.new(request, result)
|
31
|
+
when 402, 406, 408, 411, 413..499
|
32
|
+
raise Restfulie::Client::HTTP::Error::ClientError.new(request, result)
|
33
|
+
when 501
|
34
|
+
raise Restfulie::Client::HTTP::Error::NotImplemented.new(request, result)
|
35
|
+
when 500, 502..599
|
36
|
+
raise Restfulie::Client::HTTP::Error::ServerError.new(request, result)
|
37
|
+
else
|
38
|
+
raise Restfulie::Client::HTTP::Error::UnknownError.new(request, result)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Restfulie::Client::Feature::Verb
|
2
|
+
|
3
|
+
# GET HTTP verb without {Error}
|
4
|
+
# * <tt>path: '/posts'</tt>
|
5
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
6
|
+
def get(params = {})
|
7
|
+
@verb = :get
|
8
|
+
at query_string(params)
|
9
|
+
request_flow
|
10
|
+
end
|
11
|
+
|
12
|
+
# HEAD HTTP verb without {Error}
|
13
|
+
# * <tt>path: '/posts'</tt>
|
14
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
15
|
+
def head
|
16
|
+
@verb = :head
|
17
|
+
request_flow
|
18
|
+
end
|
19
|
+
|
20
|
+
# POST HTTP verb without {Error}
|
21
|
+
# * <tt>path: '/posts'</tt>
|
22
|
+
# * <tt>payload: 'some text'</tt>
|
23
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
24
|
+
def post(payload, options = {:recipe => nil})
|
25
|
+
@verb = :post
|
26
|
+
request_flow :body => payload
|
27
|
+
end
|
28
|
+
|
29
|
+
# PATCH HTTP verb without {Error}
|
30
|
+
# * <tt>path: '/posts'</tt>
|
31
|
+
# * <tt>payload: 'some text'</tt>
|
32
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
33
|
+
def patch(payload)
|
34
|
+
@verb = :patch
|
35
|
+
request_flow :body => payload
|
36
|
+
end
|
37
|
+
|
38
|
+
# PUT HTTP verb without {Error}
|
39
|
+
# * <tt>path: '/posts'</tt>
|
40
|
+
# * <tt>payload: 'some text'</tt>
|
41
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
42
|
+
def put(payload)
|
43
|
+
@verb = :put
|
44
|
+
request_flow :body => payload
|
45
|
+
end
|
46
|
+
|
47
|
+
# DELETE HTTP verb without {Error}
|
48
|
+
# * <tt>path: '/posts'</tt>
|
49
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
50
|
+
def delete
|
51
|
+
@verb = :delete
|
52
|
+
request_flow
|
53
|
+
end
|
54
|
+
|
55
|
+
# GET HTTP verb {Error}
|
56
|
+
# * <tt>path: '/posts'</tt>
|
57
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
58
|
+
def get!(params = {})
|
59
|
+
@verb = :get
|
60
|
+
at query_string(params)
|
61
|
+
request :throw_error
|
62
|
+
request_flow
|
63
|
+
end
|
64
|
+
|
65
|
+
# HEAD HTTP verb {Error}
|
66
|
+
# * <tt>path: '/posts'</tt>
|
67
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
68
|
+
def head!
|
69
|
+
@verb = :head
|
70
|
+
request :throw_error
|
71
|
+
request_flow
|
72
|
+
end
|
73
|
+
|
74
|
+
# POST HTTP verb {Error}
|
75
|
+
# * <tt>path: '/posts'</tt>
|
76
|
+
# * <tt>payload: 'some text'</tt>
|
77
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
78
|
+
def post!(payload, options = {:recipe => nil})
|
79
|
+
@verb = :post
|
80
|
+
request :throw_error
|
81
|
+
request_flow :body => payload
|
82
|
+
end
|
83
|
+
|
84
|
+
# PATCH HTTP verb {Error}
|
85
|
+
# * <tt>path: '/posts'</tt>
|
86
|
+
# * <tt>payload: 'some text'</tt>
|
87
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
88
|
+
def patch!(payload)
|
89
|
+
@verb = :patch
|
90
|
+
request :throw_error
|
91
|
+
request_flow :body => payload
|
92
|
+
end
|
93
|
+
|
94
|
+
# PUT HTTP verb {Error}
|
95
|
+
# * <tt>path: '/posts'</tt>
|
96
|
+
# * <tt>payload: 'some text'</tt>
|
97
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
98
|
+
def put!(payload)
|
99
|
+
@verb = :put
|
100
|
+
request :throw_error
|
101
|
+
request_flow :body => payload
|
102
|
+
end
|
103
|
+
|
104
|
+
# DELETE HTTP verb {Error}
|
105
|
+
# * <tt>path: '/posts'</tt>
|
106
|
+
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
107
|
+
def delete!
|
108
|
+
@verb = :delete
|
109
|
+
request :throw_error
|
110
|
+
request_flow
|
111
|
+
end
|
112
|
+
|
113
|
+
protected
|
114
|
+
|
115
|
+
def query_string(params)
|
116
|
+
params = params.map { |param, value| "#{param}=#{value}"}.join("&")
|
117
|
+
params.blank? ? "" : URI.escape("?#{params}")
|
118
|
+
end
|
119
|
+
end
|
@@ -1,9 +1,29 @@
|
|
1
|
-
module Restfulie
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Restfulie::Client::HTTP
|
2
|
+
module ResponseHolder
|
3
|
+
attr_reader :response, :request
|
4
|
+
|
5
|
+
def resource
|
6
|
+
type = headers['content-type'] || response['Content-Type']
|
7
|
+
representation = Restfulie::Common::Converter.content_type_for(type[0]) || Restfulie::Common::Representation::Generic.new
|
8
|
+
representation.unmarshal(response.body)
|
7
9
|
end
|
10
|
+
|
11
|
+
def at(uri)
|
12
|
+
request.clone.at(uri)
|
13
|
+
end
|
14
|
+
|
15
|
+
def headers
|
16
|
+
response.to_hash
|
17
|
+
end
|
18
|
+
|
19
|
+
def results_from(request, response)
|
20
|
+
@request = request
|
21
|
+
@response = response
|
22
|
+
end
|
23
|
+
|
24
|
+
def verb
|
25
|
+
@request.verb
|
26
|
+
end
|
27
|
+
|
8
28
|
end
|
9
29
|
end
|
@@ -1,27 +1,7 @@
|
|
1
1
|
module Restfulie
|
2
2
|
module Client
|
3
3
|
module HTTP#:nodoc:
|
4
|
-
autoload
|
5
|
-
autoload :Response, 'restfulie/client/http/response'
|
6
|
-
autoload :ResponseHandler, 'restfulie/client/http/response_handler'
|
7
|
-
autoload :RequestAdapter, 'restfulie/client/http/request_adapter'
|
8
|
-
autoload :RequestBuilder, 'restfulie/client/http/request_builder'
|
9
|
-
autoload :RequestFollow, 'restfulie/client/http/request_follow'
|
10
|
-
autoload :RequestHistory, 'restfulie/client/http/request_history'
|
11
|
-
autoload :RequestExecutor, 'restfulie/client/http/request_executor'
|
12
|
-
autoload :RequestBuilderExecutor, 'restfulie/client/http/request_builder_executor'
|
13
|
-
autoload :RequestFollowExecutor, 'restfulie/client/http/request_follow_executor'
|
14
|
-
autoload :RequestHistoryExecutor, 'restfulie/client/http/request_history_executor'
|
15
|
-
autoload :Cache, 'restfulie/client/http/cache'
|
16
|
-
autoload :ResponseHolder, 'restfulie/client/http/response_holder'
|
17
|
-
autoload :RequestMarshaller, 'restfulie/client/http/request_marshaller'
|
18
|
-
autoload :LinkRequestBuilder, 'restfulie/client/http/link_request_builder'
|
19
|
-
autoload :RequestMarshallerExecutor, 'restfulie/client/http/request_marshaller_executor'
|
4
|
+
Dir["#{File.dirname(__FILE__)}/http/*.rb"].each {|f| autoload File.basename(f)[0..-4].camelize.to_sym, f }
|
20
5
|
end
|
21
6
|
end
|
22
7
|
end
|
23
|
-
|
24
|
-
require 'restfulie/client/ext/atom_ext'
|
25
|
-
require 'restfulie/client/ext/xml_ext'
|
26
|
-
require 'restfulie/client/ext/http_ext'
|
27
|
-
require 'restfulie/client/ext/json_ext'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class MasterDelegator
|
2
|
+
|
3
|
+
alias_method :original_respond_to?, :respond_to?
|
4
|
+
|
5
|
+
def respond_to?(sym)
|
6
|
+
original_respond_to?(sym) || @requester.respond_to?(sym)
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(sym, *args, &block)
|
10
|
+
if original_respond_to?(sym)
|
11
|
+
result = super(sym, *args, &block)
|
12
|
+
elsif @requester.respond_to?(sym)
|
13
|
+
result = @requester.send(sym, *args, &block)
|
14
|
+
else
|
15
|
+
# let it go
|
16
|
+
return super(sym, *args, &block)
|
17
|
+
end
|
18
|
+
delegate_parse result
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def delegate(what, *args, &block)
|
24
|
+
delegate_parse @requester.send(what, *args, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def delegate_parse(result)
|
28
|
+
(result == @requester) ? self : result
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -42,6 +42,11 @@ module Restfulie
|
|
42
42
|
|
43
43
|
# keeps changing from a steady state to another until its goal has been achieved
|
44
44
|
def run
|
45
|
+
|
46
|
+
# load the steps and scenario
|
47
|
+
@goal.steps
|
48
|
+
@goal.scenario
|
49
|
+
|
45
50
|
if @start.kind_of? String
|
46
51
|
client = Restfulie.at(@start)
|
47
52
|
client = client.follow if @follow
|
@@ -52,10 +57,6 @@ module Restfulie
|
|
52
57
|
@start = current = @goal.class.get_restfulie.get
|
53
58
|
end
|
54
59
|
|
55
|
-
# load the steps and scenario
|
56
|
-
@goal.steps
|
57
|
-
@goal.scenario
|
58
|
-
|
59
60
|
while(!@goal.completed?(current))
|
60
61
|
current = @walker.move(@goal, current, self)
|
61
62
|
end
|
@@ -14,7 +14,7 @@ module Restfulie
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def try_to_execute(step, current, max_attempts, mikyung)
|
17
|
-
raise "Unable to proceed when trying to #{step}" if max_attempts == 0
|
17
|
+
raise "Unable to proceed when trying to analyze #{step.body}" if max_attempts == 0
|
18
18
|
|
19
19
|
resource = step
|
20
20
|
raise "Step returned 'give up'" if resource.nil?
|
@@ -1,13 +1,7 @@
|
|
1
1
|
module Restfulie
|
2
2
|
module Client
|
3
3
|
module Mikyung
|
4
|
-
autoload
|
5
|
-
autoload :ThenCondition, 'restfulie/client/mikyung/then_condition'
|
6
|
-
autoload :RestProcessModel, 'restfulie/client/mikyung/rest_process_model'
|
7
|
-
autoload :Concatenator, 'restfulie/client/mikyung/concatenator'
|
8
|
-
autoload :Core, 'restfulie/client/mikyung/core'
|
9
|
-
autoload :SteadyStateWalker, 'restfulie/client/mikyung/steady_state_walker'
|
10
|
-
autoload :Languages, 'restfulie/client/mikyung/languages'
|
4
|
+
Dir["#{File.dirname(__FILE__)}/mikyung/*.rb"].each {|f| autoload File.basename(f)[0..-4].camelize.to_sym, f }
|
11
5
|
end
|
12
6
|
end
|
13
7
|
end
|
@@ -17,6 +11,5 @@ end
|
|
17
11
|
module Restfulie
|
18
12
|
class Mikyung < Restfulie::Client::Mikyung::Core
|
19
13
|
Restfulie::Common::Logger.logger.level = Logger::INFO
|
20
|
-
# empty class
|
21
14
|
end
|
22
15
|
end
|
data/lib/restfulie/client.rb
CHANGED
@@ -2,12 +2,15 @@ require 'restfulie/common'
|
|
2
2
|
|
3
3
|
module Restfulie
|
4
4
|
module Client
|
5
|
+
autoload :MasterDelegator, 'restfulie/client/master_delegator'
|
5
6
|
autoload :HTTP, 'restfulie/client/http'
|
6
7
|
autoload :Configuration, 'restfulie/client/configuration'
|
7
8
|
autoload :EntryPoint, 'restfulie/client/entry_point'
|
8
9
|
autoload :Base, 'restfulie/client/base'
|
9
10
|
autoload :Mikyung, 'restfulie/client/mikyung'
|
10
11
|
autoload :Cache, 'restfulie/client/cache'
|
12
|
+
autoload :Feature, 'restfulie/client/feature'
|
13
|
+
autoload :Dsl, 'restfulie/client/dsl'
|
11
14
|
|
12
15
|
mattr_accessor :cache_provider, :cache_store
|
13
16
|
|
@@ -20,5 +23,4 @@ end
|
|
20
23
|
require 'restfulie/client/ext/http_ext'
|
21
24
|
require 'restfulie/client/ext/atom_ext'
|
22
25
|
require 'restfulie/client/ext/json_ext'
|
23
|
-
require 'restfulie/client/ext/xml_ext'
|
24
26
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Restfulie::Common::Converter::FormUrlEncoded < Restfulie::Common::Representation::Generic
|
2
|
+
def self.marshal(content, rel)
|
3
|
+
if content.kind_of? Hash
|
4
|
+
content.map { |key, value| "#{key}=#{value}" }.join("&")
|
5
|
+
else
|
6
|
+
content
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.unmarshal(content)
|
11
|
+
def content.links
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
content
|
15
|
+
end
|
16
|
+
end
|
@@ -34,8 +34,11 @@ module Restfulie
|
|
34
34
|
|
35
35
|
# Check if the object is already an json
|
36
36
|
unless recipe
|
37
|
-
|
38
|
-
|
37
|
+
if obj.kind_of?(Hash) || obj.kind_of?(Array)
|
38
|
+
return Restfulie::Common::Representation::Json.create(obj)
|
39
|
+
else
|
40
|
+
raise Restfulie::Common::Error::ConverterError.new("Recipe required")
|
41
|
+
end
|
39
42
|
end
|
40
43
|
|
41
44
|
# Get recipe already described
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Restfulie::Common::Converter::OpenSearch::Descriptor
|
2
|
+
|
3
|
+
def initialize(hash)
|
4
|
+
@hash = hash["OpenSearchDescription"]
|
5
|
+
end
|
6
|
+
|
7
|
+
def urls
|
8
|
+
uris = @hash["Url"]
|
9
|
+
uris.kind_of?(Array) ? uris : [uris]
|
10
|
+
end
|
11
|
+
|
12
|
+
def use(content_type)
|
13
|
+
uri = urls.find do |url|
|
14
|
+
url["type"]==content_type
|
15
|
+
end
|
16
|
+
return nil if uri.nil?
|
17
|
+
|
18
|
+
base_uri, params_pattern = extract_uri(uri)
|
19
|
+
Restfulie.at(base_uri).accepts(content_type).open_search.with_pattern(params_pattern)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def extract_uri(uri)
|
24
|
+
uri = uri["template"]
|
25
|
+
interrogation = uri.index("?")
|
26
|
+
params = uri[interrogation+1..uri.size]
|
27
|
+
base_uri = uri[0..interrogation-1]
|
28
|
+
[base_uri, params]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Restfulie
|
2
|
+
module Common
|
3
|
+
class Converter::OpenSearch#:nodoc:
|
4
|
+
autoload :Descriptor, 'restfulie/common/converter/open_search/descriptor'
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Restfulie::Common::Converter::OpenSearch
|
10
|
+
|
11
|
+
def self.unmarshal(xml)
|
12
|
+
hash = Hash.from_xml(xml)
|
13
|
+
descriptor = Descriptor.new(hash)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/hash/conversions'
|
2
|
+
|
1
3
|
module Restfulie
|
2
4
|
module Common
|
3
5
|
module Converter
|
@@ -43,7 +45,7 @@ module Restfulie
|
|
43
45
|
end
|
44
46
|
|
45
47
|
# Create representation and proxy
|
46
|
-
builder = Builder.new(obj)
|
48
|
+
builder = Builder.new(obj, options)
|
47
49
|
|
48
50
|
# Check recipe arity size before calling it
|
49
51
|
recipe.call(*[builder, obj, options][0,recipe.arity])
|
@@ -42,11 +42,12 @@ module Restfulie
|
|
42
42
|
insert_value("link", nil, options)
|
43
43
|
end
|
44
44
|
|
45
|
-
def members(a_collection = nil, &block)
|
45
|
+
def members(a_collection = nil, options = {}, &block)
|
46
46
|
collection = a_collection || @obj
|
47
47
|
raise Error::BuilderError("Members method require a collection to execute") unless collection.respond_to?(:each)
|
48
48
|
collection.each do |member|
|
49
|
-
|
49
|
+
root = options[:root] || Restfulie::Common::Converter.root_element_for(member)
|
50
|
+
entry = @doc.create_element(root)
|
50
51
|
entry.parent = @parent
|
51
52
|
@parent = entry
|
52
53
|
block.call(self, member)
|
@@ -3,12 +3,12 @@ module Restfulie
|
|
3
3
|
module Converter
|
4
4
|
module Xml
|
5
5
|
module Helpers
|
6
|
-
def collection(obj,
|
7
|
-
Xml.to_xml(obj,
|
6
|
+
def collection(obj, opts = {}, &block)
|
7
|
+
Xml.to_xml(obj, opts, &block)
|
8
8
|
end
|
9
9
|
|
10
|
-
def member(obj,
|
11
|
-
Xml.to_xml(obj,
|
10
|
+
def member(obj, opts = {}, &block)
|
11
|
+
Xml.to_xml(obj, opts, &block)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -6,11 +6,7 @@ module Restfulie
|
|
6
6
|
def initialize(links)
|
7
7
|
links = [links] unless links.kind_of? Array
|
8
8
|
links = [] unless links
|
9
|
-
@links = links.map
|
10
|
-
link = Restfulie::Common::Converter::Xml::Link.new(l)
|
11
|
-
link.instance_eval { self.class.send :include, ::Restfulie::Client::HTTP::LinkRequestBuilder }
|
12
|
-
link
|
13
|
-
end
|
9
|
+
@links = links.map { |l| Restfulie::Common::Converter::Xml::Link.new(l) }
|
14
10
|
end
|
15
11
|
|
16
12
|
def method_missing(sym, *args)
|
@@ -1,10 +1,7 @@
|
|
1
1
|
module Restfulie
|
2
2
|
module Common
|
3
3
|
module Converter
|
4
|
-
autoload
|
5
|
-
autoload :Atom, 'restfulie/common/converter/atom'
|
6
|
-
autoload :Json, 'restfulie/common/converter/json'
|
7
|
-
autoload :Xml, 'restfulie/common/converter/xml'
|
4
|
+
Dir["#{File.dirname(__FILE__)}/converter/*.rb"].each {|f| autoload File.basename(f)[0..-4].camelize.to_sym, f }
|
8
5
|
|
9
6
|
# Returns the default root element name for an item or collection
|
10
7
|
def self.root_element_for(obj)
|
@@ -16,6 +13,30 @@ module Restfulie
|
|
16
13
|
obj.class.to_s.underscore
|
17
14
|
end
|
18
15
|
end
|
16
|
+
|
17
|
+
def self.register(media_type,representation)
|
18
|
+
representations[media_type] = representation
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.content_type_for(media_type)
|
22
|
+
return nil unless media_type
|
23
|
+
content_type = media_type.split(';')[0] # [/(.*?);/, 1]
|
24
|
+
representations[content_type]
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.representations
|
30
|
+
@representations ||= {}
|
31
|
+
end
|
32
|
+
|
33
|
+
register 'application/atom+xml' , ::Restfulie::Common::Converter::Atom
|
34
|
+
register 'application/xml' , ::Restfulie::Common::Converter::Xml
|
35
|
+
register 'text/xml' , ::Restfulie::Common::Converter::Xml
|
36
|
+
register 'application/json' , ::Restfulie::Common::Converter::Json
|
37
|
+
register 'application/opensearchdescription+xml' , ::Restfulie::Common::Converter::OpenSearch
|
38
|
+
register 'application/x-www-form-urlencoded', Restfulie::Common::Converter::FormUrlEncoded
|
39
|
+
|
19
40
|
end
|
20
41
|
end
|
21
42
|
end
|
@@ -1,12 +1,18 @@
|
|
1
1
|
class Hash
|
2
|
+
|
2
3
|
def links(*args)
|
3
4
|
links = fetch("link", [])
|
4
5
|
Restfulie::Common::Converter::Xml::Links.new(links)
|
5
6
|
end
|
7
|
+
|
8
|
+
include Restfulie::Common::Links
|
9
|
+
|
6
10
|
def method_missing(sym, *args)
|
7
11
|
self[sym.to_s].nil? ? super(sym, args) : self[sym.to_s]
|
8
12
|
end
|
13
|
+
|
9
14
|
def respond_to?(sym)
|
10
15
|
include?(sym.to_s) || super(sym)
|
11
16
|
end
|
17
|
+
|
12
18
|
end
|