restfulie 0.9.3 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|