wrest 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/README.rdoc +104 -0
  2. data/Rakefile +230 -0
  3. data/VERSION.yml +4 -0
  4. data/bin/wrest +22 -0
  5. data/lib/wrest/core_ext/string/conversions.rb +23 -0
  6. data/lib/wrest/core_ext/string.rb +5 -0
  7. data/lib/wrest/exceptions/unsupported_content_type_exception.rb +15 -0
  8. data/lib/wrest/exceptions.rb +1 -0
  9. data/lib/wrest/mappers/attributes_container.rb +123 -0
  10. data/lib/wrest/mappers/resource/base.rb +69 -0
  11. data/lib/wrest/mappers/resource/collection.rb +12 -0
  12. data/lib/wrest/mappers/resource.rb +17 -0
  13. data/lib/wrest/mappers/simple_resource.rb +17 -0
  14. data/lib/wrest/mappers.rb +21 -0
  15. data/lib/wrest/response.rb +38 -0
  16. data/lib/wrest/translators/content_types.rb +20 -0
  17. data/lib/wrest/translators/json.rb +21 -0
  18. data/lib/wrest/translators/typed_hash.rb +4 -0
  19. data/lib/wrest/translators/xml.rb +24 -0
  20. data/lib/wrest/translators.rb +26 -0
  21. data/lib/wrest/uri.rb +74 -0
  22. data/lib/wrest/uri_template.rb +32 -0
  23. data/lib/wrest/version.rb +22 -0
  24. data/lib/wrest.rb +41 -0
  25. data/spec/custom_matchers/custom_matchers.rb +2 -0
  26. data/spec/rcov.opts +4 -0
  27. data/spec/spec.opts +6 -0
  28. data/spec/spec_helper.rb +18 -0
  29. data/spec/wrest/mappers/attributes_container_spec.rb +184 -0
  30. data/spec/wrest/mappers/resource/base_spec.rb +158 -0
  31. data/spec/wrest/mappers/simple_resource_spec.rb +7 -0
  32. data/spec/wrest/response_spec.rb +21 -0
  33. data/spec/wrest/translators/typed_hash_spec.rb +9 -0
  34. data/spec/wrest/translators/xml_spec.rb +12 -0
  35. data/spec/wrest/translators_spec.rb +9 -0
  36. data/spec/wrest/uri_spec.rb +131 -0
  37. data/spec/wrest/uri_template_spec.rb +28 -0
  38. metadata +130 -0
data/README.rdoc ADDED
@@ -0,0 +1,104 @@
1
+ = Wrest
2
+
3
+ (c) Copyright 2009 {Sidu Ponnappa}[http://blog.sidu.in]. All Rights Reserved.
4
+
5
+ Wrest is a ruby REST client library which allows you to quickly build object oriented wrappers around any web service. It has two components - Wrest Core and Wrest::Resource.
6
+
7
+ == Installation
8
+
9
+ The source is available at git://github.com/kaiwren/wrest.git
10
+
11
+ To install as a Rails plugin, do <tt>script/plugin install git://github.com/kaiwren/wrest.git</tt>
12
+
13
+ To install the Wrest gem, you'll need to add GitHub to you gem sources if you haven't already done so:
14
+
15
+ gem sources -a http://gems.github.com
16
+
17
+ Then to install Wrest and its dependencies:
18
+
19
+ sudo gem install kaiwren-wrest
20
+
21
+
22
+ == Wrest Core
23
+
24
+ * Designed to be used as a library, not just a command line REST client
25
+ * Provides basic infrastructure (including an interactive shell) and convenient HTTP wrappers
26
+ * Makes it easy to extend and modify both serialisation, deserialisation and object creation
27
+ * Isn't coupled to Rails (usable in a pure Ruby application to consume any REST api)
28
+ * Can be used both stand alone as well as to build object oriented abstractions around web services (Wrest::Resource is an example of the latter)
29
+
30
+ === Usage: Shell
31
+
32
+ You can launch the interactive Wrest shell by running bin/wrest if you have the source or invoking <tt>wrest</tt> from your prompt if you've installed the gem.
33
+ $ wrest
34
+ >> "http://search.yahooapis.com/NewsSearchService/V1/newsSearch?appid=YahooDemo&output=json&query=India&results=3&start=1".to_uri.get
35
+
36
+ === Usage: Library
37
+
38
+ require 'rubygems'
39
+ require 'wrest'
40
+ y "http://search.yahooapis.com/NewsSearchService/V1/newsSearch".to_uri.get(
41
+ :appid => 'YahooDemo',
42
+ :output => 'xml',
43
+ :query => 'India',
44
+ :results=> '3',
45
+ :start => '1'
46
+ )
47
+ === Basic Http Calls
48
+
49
+ ==== Get
50
+
51
+ A couple of ways to get the Yahoo news as hash map (needs the JSON gem - gem install json).
52
+
53
+ * This example simply does a get on a uri and figures out the appropriate deserialiser using the content-type (in this case 'text/javascript', which uses Wrest::Translators::Json). See content_types.rb under lib/wrest/mappers/translators.
54
+ "http://search.yahooapis.com/NewsSearchService/V1/newsSearch?appid=YahooDemo&output=json&query=India&results=3&start=1".to_uri.get.deserialise
55
+
56
+ * This example does a get on a base uri with several parameters passed to it, resulting in a uri essentially the same as the one above. It also shows how you can use a custom deserialiser to produce a hash-map from the response.
57
+ "http://search.yahooapis.com/NewsSearchService/V1/newsSearch".to_uri.get(
58
+ :appid => 'YahooDemo',
59
+ :output => 'xml',
60
+ :query => 'India',
61
+ :results=> '3',
62
+ :start => '1'
63
+ ).deserialise_using(Wrest::Translators::Xml)
64
+
65
+
66
+ === Logging
67
+
68
+ The Wrest logger can be set and accessed through Wrest.logger and is configured by default to log to STDOUT. If you're using Wrest in a Rails application, you can configure logging by placing the following line in your environment file:
69
+ Wrest.logger = ActiveRecord::Base.logger
70
+
71
+ === Build
72
+
73
+ Standard options are available and can be listed using <tt>rake -T</tt>. Use rake:rcov for coverage and rake:rdoc to generate documentation.
74
+
75
+ == Wrest::Resource
76
+
77
+ Wrest::Resource is an alternative to ActiveResource which targets Rails REST services; it is currently under development.
78
+
79
+ * Out of the box support for collections
80
+ * Out of the box support for collection pagination (including support for WillPaginate), both header based and xml attribute based
81
+ * Out of the box support for operations on all the records on the collection
82
+ * Out of the box support for nested resources
83
+ * Out of the box support for cached resources
84
+ * Out of the box support for type-casting data that comes in as parameter strings
85
+ * More natural mapping of deserialised entities to existing classes
86
+ * No communication via exceptions for http error status codes
87
+ * Better extensibility - allows access to request/response objects, avoids class variables, favours symbols over strings etc.
88
+
89
+ == Dependencies
90
+
91
+ * gems
92
+ * xmlsimple
93
+ * json
94
+ * rspec
95
+ * rcov
96
+ * active_support
97
+
98
+ == Support
99
+
100
+ This project uses Assembla for ticketing: http://www.assembla.com/spaces/wrest/tickets
101
+
102
+ == Licence
103
+
104
+ Wrest is released under the Apache 2.0 licence
data/Rakefile ADDED
@@ -0,0 +1,230 @@
1
+ # Copyright 2009 Sidu Ponnappa
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
7
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
+ # See the License for the specific language governing permissions and limitations under the License.
9
+
10
+ gem 'rspec'
11
+ require 'rake'
12
+ require 'rake/rdoctask'
13
+ require 'spec'
14
+ require 'spec/rake/spectask'
15
+ require 'rcov'
16
+ require 'rcov/rcovtask'
17
+
18
+ desc 'Default: run spec tests.'
19
+ task :default => :spec
20
+
21
+ desc "Run all specs"
22
+ Spec::Rake::SpecTask.new(:spec) do |task|
23
+ task.spec_files = FileList['spec/wrest/**/*_spec.rb']
24
+ task.spec_opts = ['--options', 'spec/spec.opts']
25
+ end
26
+
27
+ desc 'Generate documentation for Wrest'
28
+ Rake::RDocTask.new(:rdoc) do |rdoc|
29
+ rdoc.rdoc_dir = 'doc'
30
+ rdoc.title = 'WRest'
31
+ rdoc.options << '--line-numbers' << '--inline-source'
32
+ rdoc.rdoc_files.include('README.rdoc')
33
+ rdoc.rdoc_files.include('lib/**/*.rb')
34
+ end
35
+
36
+ desc "Run all specs in spec directory with RCov"
37
+ Spec::Rake::SpecTask.new(:rcov) do |t|
38
+ t.spec_opts = ['--options', "spec/spec.opts"]
39
+ t.spec_files = FileList["spec/wrest/**/*_spec.rb"]
40
+ t.rcov = true
41
+ t.rcov_opts = lambda do
42
+ IO.readlines("spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
43
+ end
44
+ # t.verbose = true
45
+ end
46
+
47
+ begin
48
+ require 'jeweler'
49
+ Jeweler::Tasks.new do |gemspec|
50
+ gemspec.name = "wrest"
51
+ gemspec.summary = "REST client library for Ruby."
52
+ gemspec.description = "Wrest is a REST client library which allows you to quickly build object oriented wrappers around any web service. It has two main components - Wrest Core and Wrest::Resource."
53
+ gemspec.authors = ["Sidu Ponnappa"]
54
+ gemspec.email = "ckponnappa@gmail.com"
55
+ gemspec.homepage = "http://github.com/kaiwren/wrest"
56
+ gemspec.has_rdoc = true
57
+ gemspec.rubyforge_project = 'wrest'
58
+ gemspec.platform = Gem::Platform::RUBY
59
+ gemspec.executables = ['wrest']
60
+ gemspec.require_path = "lib"
61
+ gemspec.files.exclude 'spec/wrest/meh_spec.rb'
62
+ gemspec.test_files.exclude 'spec/wrest/meh_spec.rb'
63
+ gemspec.add_dependency('activesupport', '>= 2.1.0')
64
+ gemspec.add_dependency('json', '>= 1.1.3')
65
+ gemspec.add_dependency('xml-simple', '>= 1.0.11')
66
+ end
67
+ rescue LoadError
68
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
69
+ end
70
+
71
+ begin
72
+ require 'rake/contrib/sshpublisher'
73
+ namespace :rubyforge do
74
+
75
+ desc "Release gem and RDoc documentation to RubyForge"
76
+ task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
77
+
78
+ namespace :release do
79
+ desc "Publish RDoc to RubyForge."
80
+ task :docs => [:rdoc] do
81
+ config = YAML.load(
82
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
83
+ )
84
+
85
+ host = "#{config['username']}@rubyforge.org"
86
+ remote_dir = "/var/www/gforge-projects/the-perfect-gem/"
87
+ local_dir = 'rdoc'
88
+
89
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
90
+ end
91
+ end
92
+ end
93
+ rescue LoadError
94
+ puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
95
+ end
96
+
97
+
98
+ namespace (:benchmark) do
99
+ desc "Create classes to be used in Wrest::Resource vs. ActiveResource"
100
+ task :setup_test_classes do
101
+ require 'active_resource'
102
+ require 'wrest'
103
+
104
+ class Ooga < Wrest::Mappers::Resource::Base;end
105
+ class Booga < ActiveResource::Base; self.site='';end
106
+ end
107
+
108
+ desc "Benchmark when objects are created each time before getting data; i.e there are few queries per instantiation"
109
+ task :create_and_get => :setup_test_classes do |t|
110
+
111
+ n = 10000
112
+ puts "Running #{n} times per report"
113
+ Benchmark.bmbm(10) do |rpt|
114
+ rpt.report("Wrest::Resource") do
115
+ n.times {
116
+ ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
117
+ ooga.profession
118
+ ooga.profession?
119
+ ooga.enhanced_by
120
+ ooga.enhanced_by?
121
+ }
122
+ end
123
+
124
+ rpt.report("ActiveResource") do
125
+ n.times {
126
+ booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
127
+ booga.profession
128
+ booga.profession?
129
+ booga.enhanced_by
130
+ booga.enhanced_by?
131
+ }
132
+ end
133
+ end
134
+ end
135
+
136
+ desc "Benchmark when objects are created beforehand; i.e there are many queries per instantiation"
137
+ task :create_once_and_get => :setup_test_classes do |t|
138
+
139
+ n = 10000
140
+ puts "Running #{n} times per report"
141
+
142
+ Benchmark.bmbm(10) do |rpt|
143
+ rpt.report("Wrest::Resource") do
144
+ ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
145
+
146
+ n.times {
147
+ ooga.profession
148
+ ooga.profession?
149
+ ooga.enhanced_by
150
+ ooga.enhanced_by?
151
+ }
152
+ end
153
+
154
+ rpt.report("ActiveResource") do
155
+ booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
156
+
157
+ n.times {
158
+ booga.profession
159
+ booga.profession?
160
+ booga.enhanced_by
161
+ booga.enhanced_by?
162
+ }
163
+ end
164
+ end
165
+ end
166
+
167
+ desc "Benchmark objects respond_to? performance without invocation"
168
+ task :responds_to_before => :setup_test_classes do |t|
169
+
170
+ n = 10000
171
+ puts "Running #{n} times per report"
172
+
173
+ Benchmark.bmbm(10) do |rpt|
174
+ rpt.report("Wrest::Resource") do
175
+ ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
176
+
177
+ n.times {
178
+ ooga.respond_to?(:profession)
179
+ ooga.respond_to?(:profession?)
180
+ ooga.respond_to?(:profession=)
181
+ }
182
+ end
183
+
184
+ rpt.report("ActiveResource") do
185
+ booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
186
+
187
+ n.times {
188
+ booga.respond_to?(:profession)
189
+ booga.respond_to?(:profession?)
190
+ booga.respond_to?(:profession=)
191
+ }
192
+ end
193
+ end
194
+ end
195
+
196
+ desc "Benchmark objects respond_to? performance after invocation"
197
+ task :responds_to_after => :setup_test_classes do |t|
198
+
199
+ n = 10000
200
+ puts "Running #{n} times per report"
201
+
202
+ Benchmark.bmbm(10) do |rpt|
203
+ rpt.report("Wrest::Resource") do
204
+ ooga = Ooga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
205
+ ooga.profession
206
+ ooga.profession?
207
+ ooga.profession = ''
208
+
209
+ n.times {
210
+ ooga.respond_to?(:profession)
211
+ ooga.respond_to?(:profession?)
212
+ ooga.respond_to?(:profession=)
213
+ }
214
+ end
215
+
216
+ rpt.report("ActiveResource") do
217
+ booga = Booga.new(:id => 5, :profession => 'Natural Magician', :enhanced_by => 'Kai Wren')
218
+ booga.profession
219
+ booga.profession?
220
+ booga.profession = ''
221
+
222
+ n.times {
223
+ booga.respond_to?(:profession)
224
+ booga.respond_to?(:profession?)
225
+ booga.respond_to?(:profession=)
226
+ }
227
+ end
228
+ end
229
+ end
230
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 4
3
+ :minor: 0
4
+ :major: 0
data/bin/wrest ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #!/usr/bin/env ruby
4
+ entry_point = "#{File.dirname(__FILE__)}/../lib/wrest.rb"
5
+ version = "#{File.dirname(__FILE__)}/../lib/wrest/version"
6
+
7
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
8
+
9
+ require 'optparse'
10
+ options = { :irb => irb }
11
+ OptionParser.new do |opt|
12
+ opt.banner = "Usage: console [options]"
13
+ opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |v| options[:irb] = v }
14
+ opt.parse!(ARGV)
15
+ end
16
+
17
+ libs = " -r irb/completion"
18
+ libs << " -r #{entry_point}"
19
+
20
+ require version
21
+ puts "Loading (Wrest #{Wrest::VERSION::STRING})"
22
+ exec "#{options[:irb]} #{libs} --simple-prompt"
@@ -0,0 +1,23 @@
1
+ # Copyright 2009 Sidu Ponnappa
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
7
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
+ # See the License for the specific language governing permissions and limitations under the License.
9
+
10
+ module Wrest
11
+ module CoreExt #:nodoc:
12
+ module String #:nodoc:
13
+ # Makes it easier to build other objects from a String
14
+ module Conversions
15
+
16
+ # A convenience method equivalent to Wrest::Uri.new(string)
17
+ def to_uri
18
+ Wrest::Uri.new(self)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ require "#{WREST_ROOT}/wrest/core_ext/string/conversions"
2
+
3
+ class String #:nodoc:
4
+ include Wrest::CoreExt::String::Conversions
5
+ end
@@ -0,0 +1,15 @@
1
+ # Copyright 2009 Sidu Ponnappa
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
7
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
+ # See the License for the specific language governing permissions and limitations under the License.
9
+
10
+ module Wrest
11
+ # Raised when a translator for an unregisterd response content type
12
+ # is requested. See Translators.
13
+ class UnsupportedContentTypeException < StandardError
14
+ end
15
+ end
@@ -0,0 +1 @@
1
+ require "#{WREST_ROOT}/wrest/exceptions/unsupported_content_type_exception"
@@ -0,0 +1,123 @@
1
+ # Copyright 2009 Sidu Ponnappa
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
7
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
+ # See the License for the specific language governing permissions and limitations under the License.
9
+
10
+ module Wrest::Mappers #:nodoc:
11
+
12
+ # Adds behaviour allowing a class to
13
+ # contain attributes and providing support
14
+ # for dynamic getters, setters and query methods.
15
+ # These methods are added at runtime, on the first
16
+ # invocation and on a per instance basis.
17
+ # <tt>respond_to?</tt> however will respond as though
18
+ # they are all already present.
19
+ # This means that two different instances of the same
20
+ # <tt>AttributesContainer</tt> could well have
21
+ # different attribute getters/setters/query methods.
22
+ #
23
+ # Note that this means the first call to a particular
24
+ # method will be slower because the method is defined
25
+ # at that point; subsequent calls will be much faster.
26
+ #
27
+ # If you're implementing your own initialize method
28
+ # remember to delegate to the default initialize
29
+ # of AttributesContainer by invoking <tt>super(attributes)</tt>
30
+ # Also keep in mind that attribute getter/setter/query methods
31
+ # will _not_ override any existing methods on the class.
32
+ #
33
+ # In situations where this is a problem, such as a client consuming Rails
34
+ # REST services where <tt>id</tt> is a common attribute and clashes with
35
+ # Object#id it is recommended to create getter/setter/query methods
36
+ # on the class (which affects all instances) using the <tt>has_attributes</tt> macro.
37
+ module AttributesContainer
38
+ def self.included(klass) #:nodoc:
39
+ klass.extend AttributesContainer::ClassMethods
40
+ klass.class_eval{ include AttributesContainer::InstanceMethods }
41
+ end
42
+
43
+ def self.build_attribute_getter(attribute_name) #:nodoc:
44
+ "def #{attribute_name};@attributes[:#{attribute_name}];end;"
45
+ end
46
+
47
+ def self.build_attribute_setter(attribute_name) #:nodoc:
48
+ "def #{attribute_name}=(value);@attributes[:#{attribute_name}] = value;end;"
49
+ end
50
+
51
+ def self.build_attribute_queryer(attribute_name) #:nodoc:
52
+ "def #{attribute_name}?;not @attributes[:#{attribute_name}].nil?;end;"
53
+ end
54
+
55
+ module ClassMethods
56
+ # This macro explicitly creates getter, setter and query methods on
57
+ # a class, overriding any exisiting methods with the same names.
58
+ # This can be used when attribute names clash with method names;
59
+ # an example would be Rails REST services which frequently make use
60
+ # an attribute named <tt>id</tt> which clashes with Object#id. Also,
61
+ # this can be used as a performance optimisation if the incoming
62
+ # attributes are known beforehand, as defining methods on the first
63
+ # invocation is no longer necessary.
64
+ def has_attributes(*attribute_names)
65
+ attribute_names.each do |attribute_name|
66
+ self.class_eval(
67
+ AttributesContainer.build_attribute_getter(attribute_name) +
68
+ AttributesContainer.build_attribute_setter(attribute_name) +
69
+ AttributesContainer.build_attribute_queryer(attribute_name)
70
+ )
71
+ end
72
+ end
73
+ end
74
+
75
+ module InstanceMethods
76
+ # Sets up any class to act like
77
+ # an attributes container by creating
78
+ # two variables, @attributes and @interface.
79
+ # Remember not to use these two variable names
80
+ # when using AttributesContainer in your
81
+ # own class.
82
+ def initialize(attributes = {})
83
+ @attributes = attributes.symbolize_keys
84
+ @interface = Module.new
85
+ self.extend @interface
86
+ end
87
+
88
+ def [](key)
89
+ @attributes[key.to_sym]
90
+ end
91
+
92
+ def []=(key, value)
93
+ @attributes[key.to_sym] = value
94
+ end
95
+
96
+ def respond_to?(method_name, include_private = false)
97
+ super(method_name, include_private) ? true : @attributes.include?(method_name.to_s.gsub(/(\?$)|(=$)/, '').to_sym)
98
+ end
99
+
100
+ # Creates getter, setter and query methods for
101
+ # attributes on the first call.
102
+ def method_missing(method_sym, *arguments)
103
+ method_name = method_sym.to_s
104
+ attribute_name = method_name.gsub(/(\?$)|(=$)/, '')
105
+
106
+ if @attributes.include?(attribute_name.to_sym) || method_name.last == '='
107
+ case method_name.last
108
+ when '='
109
+ @interface.module_eval AttributesContainer.build_attribute_setter(attribute_name)
110
+ when '?'
111
+ @interface.module_eval AttributesContainer.build_attribute_queryer(attribute_name)
112
+ else
113
+ @interface.module_eval AttributesContainer.build_attribute_getter(attribute_name)
114
+ end
115
+ send(method_sym, *arguments)
116
+ else
117
+ super(method_sym, *arguments)
118
+ end
119
+ end
120
+
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,69 @@
1
+ # Copyright 2009 Sidu Ponnappa
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
7
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
+ # See the License for the specific language governing permissions and limitations under the License.
9
+
10
+ module Wrest::Mappers::Resource #:nodoc:
11
+ # Resource::Base is the equivalent of ActiveResource::Base.
12
+ # It is a REST client targetted at Rails REST apps.
13
+ class Base
14
+ include Wrest::Mappers::AttributesContainer
15
+
16
+ has_attributes :id
17
+ attr_reader :attributes
18
+
19
+ class << self
20
+ def inherited(klass)
21
+ klass.set_resource_name klass.name
22
+ end
23
+
24
+ # Allows the resource name to be configured and creates
25
+ # a getter method for it.
26
+ # This is a useful feature when using anonymous classes like
27
+ # we often do while writing tests.
28
+ # By default, the resource name is set to the name of the class.
29
+ def set_resource_name(resource_name)
30
+ self.class_eval "def self.resource_name; '#{resource_name}';end"
31
+ end
32
+
33
+ # Allows the host url at which the resource is found to be configured
34
+ # and creates a getter method for it.
35
+ # For example in the url
36
+ # http://localhost:3000/users/1/settings
37
+ # you would set
38
+ # http://localhost:3000
39
+ # as the host url.
40
+ def set_host(host)
41
+ self.class_eval "def self.host; '#{host}';end"
42
+ end
43
+
44
+ def resource_path
45
+ @resource_path ||= "/#{resource_name.underscore.pluralize}"
46
+ end
47
+
48
+ def resource_url
49
+ "#{host}#{resource_path}"
50
+ end
51
+
52
+ def find_all
53
+ end
54
+
55
+ def find(id)
56
+ response_hash = "#{resource_url}/#{id}".to_uri.get.deserialise
57
+ resource_type = response_hash.keys.first
58
+ if(resource_type.underscore.camelize == self.name)
59
+ self.new(response_hash[resource_type].first)
60
+ else
61
+ response_hash
62
+ end
63
+ end
64
+
65
+ def objectify(hash)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,12 @@
1
+ # Copyright 2009 Sidu Ponnappa
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
7
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
+ # See the License for the specific language governing permissions and limitations under the License.
9
+
10
+ # Understands how to contain a collection of Wrest::Resources
11
+ class Wrest::Mappers::Resource::Collection
12
+ end
@@ -0,0 +1,17 @@
1
+ # Copyright 2009 Sidu Ponnappa
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
7
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
+ # See the License for the specific language governing permissions and limitations under the License.
9
+
10
+ module Wrest
11
+ module Mappers
12
+ module Resource
13
+ end
14
+ end
15
+ end
16
+
17
+ require "#{WREST_ROOT}/wrest/mappers/resource/base"
@@ -0,0 +1,17 @@
1
+ # Copyright 2009 Sidu Ponnappa
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
7
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
+ # See the License for the specific language governing permissions and limitations under the License.
9
+
10
+ module Wrest
11
+ module Mappers
12
+ class SimpleResource
13
+ include Wrest::Mappers::AttributesContainer
14
+ attr_reader :attributes
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # Copyright 2009 Sidu Ponnappa
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ # Unless required by applicable law or agreed to in writing, software distributed under the License
7
+ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
+ # See the License for the specific language governing permissions and limitations under the License.
9
+
10
+ module Wrest #:nodoc:
11
+ # A Mapper is anything that constructs an object
12
+ # or object graph from a hash map. This hash map
13
+ # is typically obtained by using a Translator to
14
+ # deserialise a Response.
15
+ module Mappers
16
+ end
17
+ end
18
+
19
+ require "#{WREST_ROOT}/wrest/mappers/attributes_container"
20
+ require "#{WREST_ROOT}/wrest/mappers/simple_resource"
21
+ require "#{WREST_ROOT}/wrest/mappers/resource"