restfulie 0.6.0 → 0.7.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.
Files changed (74) hide show
  1. data/README.textile +83 -7
  2. data/Rakefile +98 -13
  3. data/lib/restfulie/client/base.rb +48 -53
  4. data/lib/restfulie/client/configuration.rb +69 -0
  5. data/lib/restfulie/client/http/adapter.rb +487 -0
  6. data/lib/restfulie/client/http/atom_ext.rb +87 -0
  7. data/lib/restfulie/client/http/cache.rb +28 -0
  8. data/lib/restfulie/client/http/error.rb +80 -0
  9. data/lib/restfulie/client/http/marshal.rb +147 -0
  10. data/lib/restfulie/client/http.rb +13 -0
  11. data/lib/restfulie/client.rb +8 -56
  12. data/lib/restfulie/common/builder/builder_base.rb +58 -0
  13. data/lib/restfulie/common/builder/helpers.rb +22 -0
  14. data/lib/restfulie/common/builder/marshalling/atom.rb +197 -0
  15. data/lib/restfulie/common/builder/marshalling/base.rb +12 -0
  16. data/lib/restfulie/common/builder/marshalling/json.rb +2 -0
  17. data/lib/restfulie/common/builder/marshalling.rb +16 -0
  18. data/lib/restfulie/common/builder/rules/collection_rule.rb +10 -0
  19. data/lib/restfulie/common/builder/rules/link.rb +20 -0
  20. data/lib/restfulie/common/builder/rules/links.rb +9 -0
  21. data/lib/restfulie/common/builder/rules/member_rule.rb +8 -0
  22. data/lib/restfulie/common/builder/rules/namespace.rb +25 -0
  23. data/lib/restfulie/common/builder/rules/rules_base.rb +76 -0
  24. data/lib/restfulie/common/builder.rb +16 -0
  25. data/lib/restfulie/common/errors.rb +9 -0
  26. data/lib/restfulie/{logger.rb → common/logger.rb} +3 -5
  27. data/lib/restfulie/common/representation/atom.rb +48 -0
  28. data/lib/restfulie/common/representation/generic.rb +33 -0
  29. data/lib/restfulie/common/representation/xml.rb +24 -0
  30. data/lib/restfulie/common/representation.rb +10 -0
  31. data/lib/restfulie/common.rb +23 -0
  32. data/lib/restfulie/server/action_controller/base.rb +31 -0
  33. data/lib/restfulie/server/action_controller/params_parser.rb +62 -0
  34. data/lib/restfulie/server/action_controller/restful_responder.rb +39 -0
  35. data/lib/restfulie/server/action_controller/routing/restful_route.rb +14 -0
  36. data/lib/restfulie/server/action_controller/routing.rb +12 -0
  37. data/lib/restfulie/server/action_controller.rb +15 -0
  38. data/lib/restfulie/server/action_view/helpers.rb +45 -0
  39. data/lib/restfulie/server/action_view/template_handlers/tokamak.rb +15 -0
  40. data/lib/restfulie/server/action_view/template_handlers.rb +13 -0
  41. data/lib/restfulie/server/action_view.rb +8 -0
  42. data/lib/restfulie/server/configuration.rb +21 -0
  43. data/lib/restfulie/server/core_ext/array.rb +45 -0
  44. data/lib/restfulie/server/core_ext.rb +1 -0
  45. data/lib/restfulie/server/restfulie_controller.rb +1 -17
  46. data/lib/restfulie/server.rb +15 -0
  47. data/lib/restfulie.rb +4 -72
  48. data/lib/vendor/atom/configuration.rb +24 -0
  49. data/lib/vendor/atom/pub.rb +250 -0
  50. data/lib/vendor/atom/xml/parser.rb +373 -0
  51. data/lib/vendor/atom.rb +771 -0
  52. metadata +94 -33
  53. data/lib/restfulie/client/atom_media_type.rb +0 -75
  54. data/lib/restfulie/client/cache.rb +0 -103
  55. data/lib/restfulie/client/entry_point.rb +0 -94
  56. data/lib/restfulie/client/extensions/http.rb +0 -116
  57. data/lib/restfulie/client/helper.rb +0 -28
  58. data/lib/restfulie/client/instance.rb +0 -158
  59. data/lib/restfulie/client/request_execution.rb +0 -321
  60. data/lib/restfulie/client/state.rb +0 -36
  61. data/lib/restfulie/media_type.rb +0 -143
  62. data/lib/restfulie/media_type_control.rb +0 -115
  63. data/lib/restfulie/media_type_defaults.rb +0 -51
  64. data/lib/restfulie/server/atom_media_type.rb +0 -115
  65. data/lib/restfulie/server/base.rb +0 -91
  66. data/lib/restfulie/server/controller.rb +0 -122
  67. data/lib/restfulie/server/instance.rb +0 -102
  68. data/lib/restfulie/server/marshalling.rb +0 -47
  69. data/lib/restfulie/server/opensearch/description.rb +0 -54
  70. data/lib/restfulie/server/opensearch.rb +0 -18
  71. data/lib/restfulie/server/transition.rb +0 -93
  72. data/lib/restfulie/unmarshalling.rb +0 -131
  73. data/lib/vendor/jeokkarak/hashi.rb +0 -65
  74. data/lib/vendor/jeokkarak/jeokkarak.rb +0 -81
@@ -1,158 +0,0 @@
1
- #
2
- # Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
3
- # All rights reserved.
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- module Restfulie::Client::Instance
19
-
20
- # list of possible states to access
21
- def existing_relations
22
- @existing_relations ||= {}
23
- end
24
-
25
- # which content-type generated this data
26
- attr_reader :_came_from
27
-
28
- # prepares a new request
29
- def request
30
- Restfulie::Client::RequestExecution.new(self.class, self)
31
- end
32
-
33
- # parse arguments from a transition invocation (or relation)
34
- # it will receive either zero, one or two args, if there are two args, return them
35
- # if there is one hash arg, its the options, add a data = nil
36
- # if there is one arg (not a hash), its the data, add a options = {}
37
- # if there are no args, data is nil and options = {}
38
- def parse_args_from_transition(args)
39
- data = nil
40
- if args.nil? || args.size==0
41
- options = {}
42
- elsif args.size==1
43
- if args[0].kind_of?(Hash)
44
- options = args[0]
45
- else
46
- data = args[0]
47
- options = {}
48
- end
49
- elsif args.size==2
50
- data = args[0]
51
- options = args[1] || {}
52
- end
53
- [data, options]
54
- end
55
-
56
- def invoke_remote_transition(name, args, block = nil)
57
-
58
- data, options = parse_args_from_transition(args)
59
-
60
- method = Restfulie::Client::Config.requisition_method_for options[:method], name
61
- state = self.existing_relations[name]
62
-
63
- request = Restfulie::Client::RequestExecution.new(self.class, self).at(state["href"] || state[:href]).with(options[:headers])
64
- request.do method, name, data
65
-
66
- end
67
-
68
- # inserts all links from this object as can_xxx and xxx methods
69
- def add_transitions(links)
70
- links.each do |t|
71
- self.existing_relations[t["rel"] || t[:rel]] = t
72
- self.add_state(t)
73
- end
74
- self.extend Restfulie::Client::State
75
- end
76
-
77
- # adds the specific information for one state change or related resource
78
- def add_state(transition)
79
- name = transition["rel"] || transition[:rel]
80
-
81
- # TODO: wrong, should be instance_eval
82
- self.class.module_eval do
83
-
84
- def temp_method(*args, &block)
85
- self.invoke_remote_transition(Restfulie::Client::Helper.current_method, args, block)
86
- end
87
-
88
- alias_method name, :temp_method
89
- undef :temp_method
90
- end
91
- end
92
-
93
- # returns a list of extended fields for this instance.
94
- # extended fields are those unknown to this model but kept in a hash
95
- # to allow forward-compatibility.
96
- def extended_fields
97
- @extended_fields ||= {}
98
- @extended_fields
99
- end
100
-
101
- def method_missing(name, *args)
102
- name = name.to_s if name.kind_of? Symbol
103
-
104
- if name[-1,1] == "="
105
- extended_fields[name.chop] = args[0]
106
- elsif name[-1,1] == "?"
107
- found = extended_fields[name.chop]
108
- return super(name,args) if found.nil?
109
- parse(found)
110
- else
111
- found = extended_fields[name]
112
- return super(name,args) if found.nil?
113
- parse(transform(found))
114
- end
115
-
116
- end
117
-
118
- def respond_to?(sym)
119
- extended_fields[sym.to_s].nil? ? super(sym) : true
120
- end
121
-
122
- # redefines attribute definition allowing the invocation of method_missing
123
- # when an attribute does not exist
124
- def attributes=(values)
125
- values.each do |key, value|
126
- unless attributes.include? key
127
- method_missing("#{key}=", value)
128
- values.delete key
129
- end
130
- end
131
- super(values)
132
- end
133
-
134
-
135
- # serializes the extended fields with the existing fields
136
- def to_xml(options={})
137
- super(options) do |xml|
138
- extended_fields.each do |key,value|
139
- xml.tag! key, value
140
- end
141
- end
142
- end
143
-
144
- private
145
-
146
- # transforms a value in a custom hash
147
- def transform(value)
148
- return CustomHash.new(value) if value.kind_of?(Hash) || value.kind_of?(Array)
149
- value
150
- end
151
-
152
- def parse(val)
153
- raise "undefined method: '#{val}'" if val.nil?
154
- val
155
- end
156
-
157
-
158
- end
@@ -1,321 +0,0 @@
1
- #
2
- # Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
3
- # All rights reserved.
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require 'restfulie/client/extensions/http'
19
-
20
- module Restfulie
21
- module Client
22
-
23
- # extension to all answers that allows you to access the web response
24
- module WebResponse
25
- attr_accessor :web_response
26
- end
27
-
28
- # some error ocurred while processing the request
29
- class ResponseError < Exception
30
- end
31
-
32
- # Handles response answered by servers by accessing the specific callback for a http response code.
33
- module ResponseHandler
34
-
35
- class << self
36
-
37
- # registers a new callback for a specific range of response codes
38
- #
39
- # Restfulie::Client::ResponseHandler.register(400, 599) do |restfulie_response|
40
- # # returns the original reponse object
41
- # restfulie_response.response
42
- # end
43
- def register(min_code, max_code, &block)
44
- (min_code..max_code).each do |code|
45
- handlers[code] = block
46
- end
47
- end
48
-
49
- # callback that returns the http response object
50
- def pure_response_return(restfulie_response)
51
- restfulie_response.response
52
- end
53
-
54
- # callback that raises a ResponseError
55
- def raise_error(restfulie_response)
56
- raise Restfulie::Client::ResponseError.new(restfulie_response.response)
57
- end
58
-
59
- # callback that parses the response media type and body,
60
- # returning a deserialized representation of the resource.
61
- # note that this will also set the _came_from instance variable with the content type
62
- # this resource was represented, in order to allow further requests to prefer this content type.
63
- def parse_entity(restfulie_response)
64
- response = restfulie_response.response
65
- content_type = response.content_type
66
- type = Restfulie::MediaType.type_for(content_type)
67
- if content_type[-3,3]=="xml"
68
- result = type.from_xml response.body
69
- elsif content_type[-4,4]=="json"
70
- result = type.from_json response.body
71
- else
72
- result = generic_parse_entity restfulie_response
73
- end
74
- result.instance_variable_set :@_came_from, content_type
75
- result
76
- end
77
-
78
- # callback taht executes a GET request to the response Location header.
79
- # this is the typical callback for 200 response codes.
80
- def retrieve_resource_from_location(restfulie_response)
81
- restfulie_response.type.from_web restfulie_response.response["Location"]
82
- end
83
-
84
- # given a restfulie response, extracts the response code and invoke the registered callback.
85
- def handle(restfulie_response)
86
- handlers[restfulie_response.response.code.to_i].call(restfulie_response)
87
- end
88
-
89
- def generic_parse_entity(restfulie_response)
90
- response = restfulie_response.response
91
- content_type = response.content_type
92
- type = Restfulie::MediaType.type_for(content_type)
93
- method = "from_#{content_type}".to_sym
94
- raise Restfulie::UnsupportedContentType.new("unsupported content type '#{content_type}' because '#{type}.#{method.to_s}' was not found") unless type.respond_to? method
95
- type.send(method, response.body)
96
- end
97
-
98
- private
99
- def handlers
100
- @handlers ||= {}
101
- end
102
-
103
- def register_func(min, max, proc)
104
- register(min, max) { |r| proc.call(r) }
105
- end
106
-
107
- end
108
-
109
- register_func( 100, 599, Proc.new{ |r| pure_response_return r} )
110
- register_func( 200, 200, Proc.new{ |r| parse_entity r} )
111
- register_func( 301, 301, Proc.new{ |r| retrieve_resource_from_location r} )
112
-
113
- end
114
-
115
-
116
- # TODO there should be a response for each method type
117
- class Response
118
-
119
- attr_reader :type, :response
120
-
121
- def initialize(type, response)
122
- @type = type
123
- @response = response
124
- end
125
-
126
- # TODO remote_post can probably be moved, does not need to be on the object's class itself
127
- # the expected_content_type is used in case a redirection takes place
128
- def parse_post(expected_content_type)
129
- code = @response.code
130
- if code=="301" && @type.follows.moved_permanently? == :all
131
- result = @type.remote_post_to(@response["Location"], @response.body)
132
- enhance(result)
133
- elsif code=="201"
134
- Restfulie.at(@response["Location"]).accepts(expected_content_type).get
135
- else
136
- final_parse
137
- end
138
- end
139
-
140
- # gets a result object and enhances it with web response methods
141
- # by extending WebResponse and defining the attribute web_response
142
- def enhance(result)
143
- @response.previous = result.web_response if result.respond_to? :web_response
144
- result.extend Restfulie::Client::WebResponse
145
- result.web_response = @response
146
- result
147
- end
148
-
149
- # parses this response using the correct ResponseHandler and enhances it
150
- def final_parse
151
- enhance Restfulie::Client::ResponseHandler.handle(@response)
152
- end
153
-
154
- # detects which type of method invocation it was and act accordingly
155
- # TODO this should be called by RequestExcution, not instance
156
- def parse(method, invoking_object, content_type)
157
-
158
- return enhance(invoking_object) if @response.code == "304"
159
-
160
- # return block.call(@response) if block
161
-
162
- return final_parse if method == Net::HTTP::Get
163
- return parse_post(content_type) if method == Net::HTTP::Post
164
- final_parse
165
-
166
- end
167
-
168
- end
169
-
170
- class RequestExecution
171
-
172
- def initialize(type)
173
- initialize(type, nil)
174
- end
175
-
176
- def initialize(type, invoking_object)
177
- @type = type
178
- @content_type = "application/xml"
179
- @accepts = "application/xml"
180
- @invoking_object = invoking_object
181
- end
182
-
183
- def at(uri)
184
- @uri = uri
185
- self
186
- end
187
-
188
- # sets the Content-type AND Accept headers for this request
189
- def as(content_type)
190
- @content_type = content_type
191
- @accepts = content_type
192
- self
193
- end
194
-
195
- # sets the Accept header for this request
196
- def accepts(content_type)
197
- @accepts = content_type
198
- self
199
- end
200
-
201
- def with(headers)
202
- @headers = headers
203
- self
204
- end
205
-
206
- # asks to create this content on the server (post it)
207
- def create(content)
208
- post(content)
209
- end
210
-
211
- # executes an http request using the specified verb
212
- #
213
- # example:
214
- # do(Net::HTTP::Get, 'self', nil)
215
- # do(Net::HTTP::Post, 'payment', '<payment/>')
216
- def do(verb, relation_name, body = nil)
217
- url, http_request = prepare_request(verb, relation_name, body)
218
- response = execute_request(url, http_request)
219
- Restfulie::Client::Response.new(@type, response).parse(verb, @invoking_object, "application/xml")
220
- end
221
-
222
- private
223
- def execute_request(url, http_request)
224
- cached = Restfulie.cache_provider.get(url, http_request)
225
- return cached if cached
226
-
227
- response = Net::HTTP.new(url.host, url.port).request(http_request)
228
- Restfulie.cache_provider.put(url, http_request, response)
229
- end
230
-
231
- public
232
-
233
- def prepare_request(verb, relation_name, body = nil)
234
- url = URI.parse(@uri)
235
- req = verb.new(url.path)
236
- add_basic_request_headers(req, relation_name)
237
-
238
- if body
239
- req.body = body
240
- req.add_field("Content-type", "application/xml") if req.get_fields("Content-type").nil?
241
- end
242
- [url, req]
243
- end
244
-
245
- # post this content to the server
246
- def post(content)
247
- remote_post_to(@uri, content)
248
- end
249
-
250
- # retrieves information from the server using a GET request
251
- def get(options = {})
252
- from_web(@uri, options)
253
- end
254
-
255
- def add_headers_to(hash)
256
- hash[:headers] = {} unless hash[:headers]
257
- hash[:headers]["Content-type"] = @content_type
258
- hash[:headers]["Accept"] = @accepts
259
- hash
260
- end
261
-
262
- def change_to_state(name, args)
263
- if !args.empty? && args[args.size-1].kind_of?(Hash)
264
- add_headers_to(args[args.size-1])
265
- else
266
- args << add_headers_to({})
267
- end
268
- @invoking_object.invoke_remote_transition name, args
269
- end
270
-
271
- # invokes an existing relation or delegates to the existing definition of method_missing
272
- def method_missing(name, *args)
273
- if @invoking_object && @invoking_object.existing_relations[name.to_s]
274
- change_to_state(name.to_s, args)
275
- else
276
- super(name, args)
277
- end
278
- end
279
-
280
- def add_basic_request_headers(req, name = nil)
281
-
282
- req.add_field("Accept", @accepts) unless @accepts.nil?
283
-
284
- @headers.each do |key, value|
285
- req.add_field(key, value)
286
- end if @headers
287
-
288
- req.add_field("Accept", @invoking_object._came_from) if req.get_fields("Accept")==["*/*"]
289
-
290
- if @type && name && @type.is_self_retrieval?(name) && @invoking_object.respond_to?(:web_response)
291
- req.add_field("If-None-Match", @invoking_object.web_response.etag) if !@invoking_object.web_response.etag.nil?
292
- req.add_field("If-Modified-Since", @invoking_object.web_response.last_modified) if !@invoking_object.web_response.last_modified.nil?
293
- end
294
-
295
- end
296
-
297
- private
298
- def remote_post_to(uri, content)
299
-
300
- url = URI.parse(uri)
301
- req = Net::HTTP::Post.new(url.path)
302
- req.body = content
303
- add_basic_request_headers(req)
304
- req.add_field("Content-type", @content_type)
305
-
306
- response = Net::HTTP.new(url.host, url.port).request(req)
307
- Restfulie::Client::Response.new(@type, response).parse_post(@content_type)
308
- end
309
-
310
- def from_web(uri, options = {})
311
- uri = URI.parse(uri)
312
- req = Net::HTTP::Get.new(uri.path)
313
- options.each { |key,value| req[key] = value }
314
- add_basic_request_headers(req)
315
- res = Net::HTTP.new(uri.host, uri.port).request(req)
316
- Restfulie::Client::Response.new(@type, res).final_parse
317
- end
318
-
319
- end
320
- end
321
- end
@@ -1,36 +0,0 @@
1
- #
2
- # Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
3
- # All rights reserved.
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- module Restfulie
19
-
20
- module Client
21
-
22
- # adds respond_to and has_state methods to resources
23
- module State
24
-
25
- # overrides the respond_to? method to check if this method is contained or was defined by a state
26
- def respond_to?(sym)
27
- has_state(sym.to_s) || super(sym)
28
- end
29
-
30
- # returns true if this resource has a state named name
31
- def has_state(name)
32
- !@existing_relations[name].nil?
33
- end
34
- end
35
- end
36
- end
@@ -1,143 +0,0 @@
1
- #
2
- # Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
3
- # All rights reserved.
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require 'restfulie/media_type_control'
19
-
20
- module Restfulie
21
-
22
- # represents an error when we are unable to support the desired content type
23
- class UnsupportedContentType < Exception
24
-
25
- attr_reader :msg
26
- def initialize(msg)
27
- @msg = msg
28
- end
29
-
30
- def to_s
31
- @msg
32
- end
33
-
34
- end
35
-
36
- module MediaType
37
-
38
- # returns the decoder type for a specific content type
39
- def self.type_for(content_type)
40
- if Restfulie::MediaType.supports? content_type
41
- Restfulie::MediaType.media_type(content_type)
42
- else
43
- Restfulie::MediaType::DefaultMediaTypeDecoder
44
- end
45
- end
46
-
47
- # TODO removethis nasty method
48
- def self.rendering_type(name, type)
49
- Restfulie::MediaType.media_types[name] || Type.new(name,type)
50
- end
51
-
52
- # TODO remove this method
53
- def self.custom_type(name, type, l)
54
- Restfulie::MediaType.media_types[name] || CustomType.new(name, type, l)
55
- end
56
-
57
- class Type
58
- attr_reader :name, :type
59
- def initialize(name, type)
60
- @name = name
61
- @type = type
62
- end
63
- def short_name
64
- name.gsub(/\//,'_').gsub(/\+/,'_').gsub(/\./,'_')
65
- end
66
-
67
- def format_name
68
- name[/(.*[\+\/])?(.*)/,2]
69
- end
70
- def execute_for(controller, resource, options, render_options)
71
- response = ["xml", "json"].include?(format_name) ? resource.send(:"to_#{format_name}", options) : resource
72
- render(controller, response, render_options)
73
- end
74
- def render(controller, response, options)
75
- options[:text] = response
76
- options[:content_type] = name
77
- controller.render options
78
- end
79
- end
80
-
81
- class CustomType < Type
82
- def initialize(name, type, l)
83
- super(name, type)
84
- @lambda = l
85
- end
86
- def execute_for(controller, resource, options, render_options)
87
- @lambda.call
88
- end
89
- end
90
-
91
- # from rails source code
92
- def self.constantize(camel_cased_word)
93
- unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
94
- raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
95
- end
96
-
97
- Object.module_eval("::#{$1}", __FILE__, __LINE__)
98
- end
99
-
100
- module DefaultMediaTypeDecoder
101
-
102
- def self.from_xml(xml)
103
- hash = Hash.from_xml xml
104
- from_hash(hash)
105
- end
106
-
107
- def self.from_hash(hash)
108
-
109
- type = Restfulie::MediaType.constantize(hash.keys.first.camelize) rescue Hashi
110
-
111
- result = type.from_hash hash.values.first
112
- return nil if result.nil?
113
- result
114
-
115
- end
116
-
117
- def self.from_json(json)
118
- hash = safe_json_decode(json)
119
- type = hash.keys.first.camelize.constantize
120
- type.from_hash(hash.values.first)
121
- end
122
-
123
- def self.from_html(body)
124
- Hashi::CustomHash.new :body => body
125
- end
126
-
127
- def self.from_xhtml(body)
128
- Hashi::CustomHash.new :body => body
129
- end
130
-
131
- end
132
- end
133
-
134
- end
135
-
136
- def safe_json_decode(json)
137
- return {} if !json
138
- begin
139
- ActiveSupport::JSON.decode json
140
- rescue ; {} end
141
- end
142
-
143
- require 'restfulie/media_type_defaults'