axtro-actionwebservice 2.3.5.1.20101118142125

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 (85) hide show
  1. data/CHANGELOG +335 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +381 -0
  4. data/Rakefile +184 -0
  5. data/TODO +32 -0
  6. data/examples/googlesearch/README +143 -0
  7. data/examples/googlesearch/autoloading/google_search_api.rb +51 -0
  8. data/examples/googlesearch/autoloading/google_search_controller.rb +58 -0
  9. data/examples/googlesearch/delegated/google_search_service.rb +109 -0
  10. data/examples/googlesearch/delegated/search_controller.rb +8 -0
  11. data/examples/googlesearch/direct/google_search_api.rb +51 -0
  12. data/examples/googlesearch/direct/search_controller.rb +59 -0
  13. data/examples/metaWeblog/README +17 -0
  14. data/examples/metaWeblog/apis/blogger_api.rb +61 -0
  15. data/examples/metaWeblog/apis/blogger_service.rb +35 -0
  16. data/examples/metaWeblog/apis/meta_weblog_api.rb +68 -0
  17. data/examples/metaWeblog/apis/meta_weblog_service.rb +49 -0
  18. data/examples/metaWeblog/controllers/xmlrpc_controller.rb +17 -0
  19. data/generators/web_service/USAGE +28 -0
  20. data/generators/web_service/templates/api_definition.rb +6 -0
  21. data/generators/web_service/templates/controller.rb +9 -0
  22. data/generators/web_service/templates/functional_test.rb +20 -0
  23. data/generators/web_service/web_service_generator.rb +30 -0
  24. data/lib/action_web_service.rb +61 -0
  25. data/lib/action_web_service/acts_as_web_service.rb +26 -0
  26. data/lib/action_web_service/api.rb +298 -0
  27. data/lib/action_web_service/base.rb +39 -0
  28. data/lib/action_web_service/casting.rb +160 -0
  29. data/lib/action_web_service/client.rb +4 -0
  30. data/lib/action_web_service/client/base.rb +29 -0
  31. data/lib/action_web_service/client/soap_client.rb +114 -0
  32. data/lib/action_web_service/client/xmlrpc_client.rb +59 -0
  33. data/lib/action_web_service/container.rb +4 -0
  34. data/lib/action_web_service/container/action_controller_container.rb +94 -0
  35. data/lib/action_web_service/container/delegated_container.rb +87 -0
  36. data/lib/action_web_service/container/direct_container.rb +70 -0
  37. data/lib/action_web_service/dispatcher.rb +3 -0
  38. data/lib/action_web_service/dispatcher/abstract.rb +209 -0
  39. data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +397 -0
  40. data/lib/action_web_service/invocation.rb +203 -0
  41. data/lib/action_web_service/protocol.rb +5 -0
  42. data/lib/action_web_service/protocol/abstract.rb +113 -0
  43. data/lib/action_web_service/protocol/discovery.rb +38 -0
  44. data/lib/action_web_service/protocol/soap_protocol.rb +177 -0
  45. data/lib/action_web_service/protocol/soap_protocol/marshaler.rb +243 -0
  46. data/lib/action_web_service/protocol/soap_protocol/marshaler.rb~ +243 -0
  47. data/lib/action_web_service/protocol/xmlrpc_protocol.rb +124 -0
  48. data/lib/action_web_service/scaffolding.rb +282 -0
  49. data/lib/action_web_service/simple.rb +54 -0
  50. data/lib/action_web_service/string_to_datetime_for_soap.rb +17 -0
  51. data/lib/action_web_service/struct.rb +69 -0
  52. data/lib/action_web_service/support/class_inheritable_options.rb +27 -0
  53. data/lib/action_web_service/support/signature_types.rb +262 -0
  54. data/lib/action_web_service/templates/scaffolds/layout.html.erb +65 -0
  55. data/lib/action_web_service/templates/scaffolds/methods.html.erb +6 -0
  56. data/lib/action_web_service/templates/scaffolds/parameters.html.erb +29 -0
  57. data/lib/action_web_service/templates/scaffolds/result.html.erb +30 -0
  58. data/lib/action_web_service/test_invoke.rb +111 -0
  59. data/lib/action_web_service/version.rb +11 -0
  60. data/lib/action_web_service/version.rb~ +10 -0
  61. data/lib/actionwebservice.rb +2 -0
  62. data/setup.rb +1380 -0
  63. data/test/abstract_client.rb +185 -0
  64. data/test/abstract_dispatcher.rb +550 -0
  65. data/test/abstract_unit.rb +44 -0
  66. data/test/api_test.rb +103 -0
  67. data/test/apis/auto_load_api.rb +4 -0
  68. data/test/apis/broken_auto_load_api.rb +3 -0
  69. data/test/base_test.rb +43 -0
  70. data/test/casting_test.rb +96 -0
  71. data/test/client_soap_test.rb +157 -0
  72. data/test/client_xmlrpc_test.rb +155 -0
  73. data/test/container_test.rb +76 -0
  74. data/test/dispatcher_action_controller_soap_test.rb +147 -0
  75. data/test/dispatcher_action_controller_xmlrpc_test.rb +60 -0
  76. data/test/fixtures/db_definitions/mysql.sql +8 -0
  77. data/test/fixtures/db_definitions/sqlite3.sql +8 -0
  78. data/test/fixtures/users.yml +12 -0
  79. data/test/gencov +3 -0
  80. data/test/invocation_test.rb +187 -0
  81. data/test/run +6 -0
  82. data/test/scaffolded_controller_test.rb +148 -0
  83. data/test/struct_test.rb +85 -0
  84. data/test/test_invoke_test.rb +114 -0
  85. metadata +167 -0
@@ -0,0 +1,184 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+ require 'fileutils'
9
+ require File.join(File.dirname(__FILE__), 'lib', 'action_web_service', 'version')
10
+
11
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ".#{Time.now.strftime('%Y%m%d%H%M%S')}"
12
+ PKG_NAME = 'axtro-actionwebservice'
13
+ PKG_VERSION = ActionWebService::VERSION::STRING + PKG_BUILD
14
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
15
+ PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}"
16
+
17
+ RELEASE_NAME = "REL #{PKG_VERSION}"
18
+
19
+ RUBY_FORGE_PROJECT = "aws"
20
+ RUBY_FORGE_USER = "webster132"
21
+
22
+ desc "Default Task"
23
+ task :default => [ :test ]
24
+
25
+
26
+ # Run the unit tests
27
+ Rake::TestTask.new { |t|
28
+ test_scope = ENV['SCOPE'] || '*'
29
+ t.test_files = FileList[ test_scope.split(',').collect{|scope| "test/#{scope}_test.rb"} ]
30
+
31
+ t.warning = !!ENV['WARNINGS']
32
+ t.verbose = !!ENV['VERBOSE']
33
+
34
+ t.libs << "test"
35
+ }
36
+
37
+ SCHEMA_PATH = File.join(File.dirname(__FILE__), *%w(test fixtures db_definitions))
38
+
39
+ desc 'Build the MySQL test database'
40
+ task :build_database do
41
+ %x( mysql -u root -p --execute='CREATE DATABASE actionwebservice_unittest; CREATE USER unit_tester@localhost; GRANT ALL PRIVILEGES ON actionwebservice_unittest.* TO unit_tester;' )
42
+ %x( mysql -uunit_tester -p actionwebservice_unittest < #{File.join(SCHEMA_PATH, 'mysql.sql')} )
43
+ end
44
+
45
+ desc 'Build the sqlite3 test database'
46
+ task :build_sqlite3_database do
47
+ filename = 'actionwebservice_unittest.db'
48
+ File.delete filename if File.exist? filename
49
+ %x(sqlite3 #{filename} < #{File.join(SCHEMA_PATH, 'sqlite3.sql')})
50
+ end
51
+
52
+
53
+ # Generate the RDoc documentation
54
+ Rake::RDocTask.new { |rdoc|
55
+ rdoc.rdoc_dir = 'doc'
56
+ rdoc.title = "Action Web Service -- Web services for Action Pack"
57
+ rdoc.options << '--line-numbers' << '--inline-source'
58
+ rdoc.options << '--charset' << 'utf-8'
59
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
60
+ rdoc.rdoc_files.include('README')
61
+ rdoc.rdoc_files.include('CHANGELOG')
62
+ rdoc.rdoc_files.include('lib/action_web_service.rb')
63
+ rdoc.rdoc_files.include('lib/action_web_service/*.rb')
64
+ rdoc.rdoc_files.include('lib/action_web_service/api/*.rb')
65
+ rdoc.rdoc_files.include('lib/action_web_service/client/*.rb')
66
+ rdoc.rdoc_files.include('lib/action_web_service/container/*.rb')
67
+ rdoc.rdoc_files.include('lib/action_web_service/dispatcher/*.rb')
68
+ rdoc.rdoc_files.include('lib/action_web_service/protocol/*.rb')
69
+ rdoc.rdoc_files.include('lib/action_web_service/support/*.rb')
70
+ }
71
+
72
+
73
+ # Create compressed packages
74
+ spec = Gem::Specification.new do |s|
75
+ s.platform = Gem::Platform::RUBY
76
+ s.name = PKG_NAME
77
+ s.summary = "Web service support for Action Pack."
78
+ s.description = %q{Adds WSDL/SOAP and XML-RPC web service support to Action Pack}
79
+ s.version = PKG_VERSION
80
+
81
+ s.author = "Laurence A. Lee, Leon Breedt, Kent Sibilev"
82
+ s.email = "rubyjedi@gmail.com, bitserf@gmail.com, ksibilev@yahoo.com"
83
+ s.homepage = "http://wiki.github.com/rubyjedi/actionwebservice/"
84
+
85
+ s.add_dependency('activesupport', '~> 2.3.0')
86
+ s.add_dependency('actionpack', '~> 2.3.0')
87
+ s.add_dependency('activerecord', '~> 2.3.0')
88
+
89
+ s.has_rdoc = true
90
+ s.requirements << 'none'
91
+ s.require_path = 'lib'
92
+ s.autorequire = 'actionwebservice'
93
+
94
+ s.files = [ "Rakefile", "setup.rb", "README", "TODO", "CHANGELOG", "MIT-LICENSE" ]
95
+ s.files = s.files + Dir.glob( "examples/**/*" ).delete_if { |item| item.match( /\.(svn|git)/ ) }
96
+ s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.match( /\.(svn|git)/ ) }
97
+ s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.match( /\.(svn|git)/ ) }
98
+ s.files = s.files + Dir.glob( "generators/**/*" ).delete_if { |item| item.match( /\.(svn|git)/ ) }
99
+ end
100
+ Rake::GemPackageTask.new(spec) do |p|
101
+ p.gem_spec = spec
102
+ p.need_tar = true
103
+ p.need_zip = true
104
+ end
105
+
106
+
107
+ # Publish beta gem
108
+ desc "Publish the API documentation"
109
+ task :pgem => [:package] do
110
+ Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
111
+ `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
112
+ end
113
+
114
+ # Publish documentation
115
+ desc "Publish the API documentation"
116
+ task :pdoc => [:rdoc] do
117
+ Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/aws", "doc").upload
118
+ end
119
+
120
+
121
+ def each_source_file(*args)
122
+ prefix, includes, excludes, open_file = args
123
+ prefix ||= File.dirname(__FILE__)
124
+ open_file = true if open_file.nil?
125
+ includes ||= %w[lib\/action_web_service\.rb$ lib\/action_web_service\/.*\.rb$]
126
+ excludes ||= %w[lib\/action_web_service\/vendor]
127
+ Find.find(prefix) do |file_name|
128
+ next if file_name =~ /\.svn/
129
+ file_name.gsub!(/^\.\//, '')
130
+ continue = false
131
+ includes.each do |inc|
132
+ if file_name.match(/#{inc}/)
133
+ continue = true
134
+ break
135
+ end
136
+ end
137
+ next unless continue
138
+ excludes.each do |exc|
139
+ if file_name.match(/#{exc}/)
140
+ continue = false
141
+ break
142
+ end
143
+ end
144
+ next unless continue
145
+ if open_file
146
+ File.open(file_name) do |f|
147
+ yield file_name, f
148
+ end
149
+ else
150
+ yield file_name
151
+ end
152
+ end
153
+ end
154
+
155
+ desc "Count lines of the AWS source code"
156
+ task :lines do
157
+ total_lines = total_loc = 0
158
+ puts "Per File:"
159
+ each_source_file do |file_name, f|
160
+ file_lines = file_loc = 0
161
+ while line = f.gets
162
+ file_lines += 1
163
+ next if line =~ /^\s*$/
164
+ next if line =~ /^\s*#/
165
+ file_loc += 1
166
+ end
167
+ puts " #{file_name}: Lines #{file_lines}, LOC #{file_loc}"
168
+ total_lines += file_lines
169
+ total_loc += file_loc
170
+ end
171
+ puts "Total:"
172
+ puts " Lines #{total_lines}, LOC #{total_loc}"
173
+ end
174
+
175
+ desc "Publish the release files to RubyForge."
176
+ task :release => [ :package ] do
177
+ require 'rubyforge'
178
+
179
+ packages = %w( gem tgz zip ).collect{ |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" }
180
+
181
+ rubyforge = RubyForge.new
182
+ rubyforge.login
183
+ rubyforge.add_release(PKG_NAME, PKG_NAME, "REL #{PKG_VERSION}", *packages)
184
+ end
data/TODO ADDED
@@ -0,0 +1,32 @@
1
+ = Post-1.0
2
+ - Document/Literal SOAP support
3
+ - URL-based dispatching, URL identifies method
4
+
5
+ - Add :rest dispatching mode, a.l.a. Backpack API. Clean up dispatching
6
+ in general. Support vanilla XML-format as a "Rails" protocol?
7
+ XML::Simple deserialization into params?
8
+
9
+ web_service_dispatching_mode :rest
10
+
11
+ def method1(params)
12
+ end
13
+
14
+ def method2(params)
15
+ end
16
+
17
+
18
+ /ws/method1
19
+ <xml>
20
+ /ws/method2
21
+ <yaml>
22
+
23
+ - Allow locking down a controller to only accept messages for a particular
24
+ protocol. This will allow us to generate fully conformant error messages
25
+ in cases where we currently fudge it if we don't know the protocol.
26
+
27
+ - Allow AWS user to participate in typecasting, so they can centralize
28
+ workarounds for buggy input in one place
29
+
30
+ = Refactoring
31
+ - Don't have clean way to go from SOAP Class object to the xsd:NAME type
32
+ string -- NaHi possibly looking at remedying this situation
@@ -0,0 +1,143 @@
1
+ = Google Service example
2
+
3
+ This example shows how one would implement an API like Google
4
+ Search that uses lots of structured types.
5
+
6
+ There are examples for "Direct" and "Delegated" dispatching
7
+ modes.
8
+
9
+ There is also an example for API definition file autoloading.
10
+
11
+
12
+ = Running the examples
13
+
14
+ 1. Add the files to an Action Web Service enabled Rails project.
15
+
16
+ "Direct" example:
17
+
18
+ * Copy direct/search_controller.rb to "app/controllers"
19
+ in a Rails project.
20
+ * Copy direct/google_search_api.rb to "app/apis"
21
+ in a Rails project
22
+
23
+ "Delegated" example:
24
+
25
+ * Copy delegated/search_controller.rb to "app/controllers"
26
+ in a Rails project.
27
+ * Copy delegated/google_search_service.rb to "lib"
28
+ in a Rails project.
29
+
30
+ "Autoloading" example:
31
+
32
+ * Copy autoloading/google_search_api.rb to "app/apis" (create the directory
33
+ if it doesn't exist) in a Rails project.
34
+
35
+ * Copy autoloading/google_search_controller.rb "app/controllers"
36
+ in a Rails project.
37
+
38
+
39
+ 2. Go to the WSDL url in a browser, and check that it looks correct.
40
+
41
+ "Direct" and "Delegated" examples:
42
+ http://url_to_project/search/wsdl
43
+
44
+ "Autoloading" example:
45
+ http://url_to_project/google_search/wsdl
46
+
47
+ You can compare it to Google's hand-coded WSDL at http://api.google.com/GoogleSearch.wsdl
48
+ and see how close (or not) the generated version is.
49
+
50
+ Note that I used GoogleSearch as the canonical "best practice"
51
+ interoperable example when implementing WSDL/SOAP support, which might
52
+ explain extreme similarities :)
53
+
54
+
55
+ 3. Test that it works with .NET (Mono in this example):
56
+
57
+ $ wget WSDL_URL
58
+ $ mv wsdl GoogleSearch.wsdl
59
+ $ wsdl -out:GoogleSearch.cs GoogleSearch.wsdl
60
+
61
+ Add these lines to the GoogleSearchService class body (be mindful of the
62
+ wrapping):
63
+
64
+ public static void Main(string[] args)
65
+ {
66
+ GoogleSearchResult result;
67
+ GoogleSearchService service;
68
+
69
+ service = new GoogleSearchService();
70
+ result = service.doGoogleSearch("myApiKey", "my query", 10, 30, true, "restrict", false, "lr", "ie", "oe");
71
+ System.Console.WriteLine("documentFiltering: {0}", result.documentFiltering);
72
+ System.Console.WriteLine("searchComments: {0}", result.searchComments);
73
+ System.Console.WriteLine("estimatedTotalResultsCount: {0}", result.estimatedTotalResultsCount);
74
+ System.Console.WriteLine("estimateIsExact: {0}", result.estimateIsExact);
75
+ System.Console.WriteLine("resultElements:");
76
+ foreach (ResultElement element in result.resultElements) {
77
+ System.Console.WriteLine("\tsummary: {0}", element.summary);
78
+ System.Console.WriteLine("\tURL: {0}", element.URL);
79
+ System.Console.WriteLine("\tsnippet: {0}", element.snippet);
80
+ System.Console.WriteLine("\ttitle: {0}", element.title);
81
+ System.Console.WriteLine("\tcachedSize: {0}", element.cachedSize);
82
+ System.Console.WriteLine("\trelatedInformationPresent: {0}", element.relatedInformationPresent);
83
+ System.Console.WriteLine("\thostName: {0}", element.hostName);
84
+ System.Console.WriteLine("\tdirectoryCategory: {0}", element.directoryCategory.fullViewableName);
85
+ System.Console.WriteLine("\tdirectoryTitle: {0}", element.directoryTitle);
86
+ }
87
+ System.Console.WriteLine("searchQuery: {0}", result.searchQuery);
88
+ System.Console.WriteLine("startIndex: {0}", result.startIndex);
89
+ System.Console.WriteLine("endIndex: {0}", result.endIndex);
90
+ System.Console.WriteLine("searchTips: {0}", result.searchTips);
91
+ System.Console.WriteLine("directoryCategories:");
92
+ foreach (DirectoryCategory cat in result.directoryCategories) {
93
+ System.Console.WriteLine("\t{0} ({1})", cat.fullViewableName, cat.specialEncoding);
94
+ }
95
+ System.Console.WriteLine("searchTime: {0}", result.searchTime);
96
+ }
97
+
98
+ Now compile and run:
99
+
100
+ $ mcs -reference:System.Web.Services GoogleSearch.cs
101
+ $ mono GoogleSearch.exe
102
+
103
+
104
+ If you had the application running (on the same host you got
105
+ the WSDL from), you should see something like this:
106
+
107
+
108
+ documentFiltering: True
109
+ searchComments:
110
+ estimatedTotalResultsCount: 322000
111
+ estimateIsExact: False
112
+ resultElements:
113
+ summary: ONlamp.com: Rolling with Ruby on Rails
114
+ URL: http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html
115
+ snippet: Curt Hibbs shows off Ruby on Rails by building a simple ...
116
+ title: Teh Railz0r
117
+ cachedSize: Almost no lines of code!
118
+ relatedInformationPresent: True
119
+ hostName: rubyonrails.com
120
+ directoryCategory: Web Development
121
+ directoryTitle:
122
+ searchQuery: http://www.google.com/search?q=ruby+on+rails
123
+ startIndex: 10
124
+ endIndex: 40
125
+ searchTips: "on" is a very common word and was not included in your search [details]
126
+ directoryCategories:
127
+ Web Development (UTF-8)
128
+ Programming (US-ASCII)
129
+ searchTime: 1E-06
130
+
131
+
132
+ Also, if an API method throws an exception, it will be sent back to the
133
+ caller in the protocol's exception format, so they should get an exception
134
+ thrown on their side with a meaningful error message.
135
+
136
+ If you don't like this behaviour, you can do:
137
+
138
+ class MyController < ActionController::Base
139
+ web_service_exception_reporting false
140
+ end
141
+
142
+ 4. Crack open a beer. Publishing APIs for working with the same model as
143
+ your Rails web app should be easy from now on :)
@@ -0,0 +1,51 @@
1
+ # encoding: UTF-8
2
+ class DirectoryCategory < ActionWebService::Struct
3
+ member :fullViewableName, :string
4
+ member :specialEncoding, :string
5
+ end
6
+
7
+ class ResultElement < ActionWebService::Struct
8
+ member :summary, :string
9
+ member :URL, :string
10
+ member :snippet, :string
11
+ member :title, :string
12
+ member :cachedSize, :string
13
+ member :relatedInformationPresent, :bool
14
+ member :hostName, :string
15
+ member :directoryCategory, DirectoryCategory
16
+ member :directoryTitle, :string
17
+ end
18
+
19
+ class GoogleSearchResult < ActionWebService::Struct
20
+ member :documentFiltering, :bool
21
+ member :searchComments, :string
22
+ member :estimatedTotalResultsCount, :int
23
+ member :estimateIsExact, :bool
24
+ member :resultElements, [ResultElement]
25
+ member :searchQuery, :string
26
+ member :startIndex, :int
27
+ member :endIndex, :int
28
+ member :searchTips, :string
29
+ member :directoryCategories, [DirectoryCategory]
30
+ member :searchTime, :float
31
+ end
32
+
33
+ class GoogleSearchAPI < ActionWebService::API::Base
34
+ inflect_names false
35
+
36
+ api_method :doGetCachedPage, :returns => [:string], :expects => [{:key=>:string}, {:url=>:string}]
37
+ api_method :doGetSpellingSuggestion, :returns => [:string], :expects => [{:key=>:string}, {:phrase=>:string}]
38
+
39
+ api_method :doGoogleSearch, :returns => [GoogleSearchResult], :expects => [
40
+ {:key=>:string},
41
+ {:q=>:string},
42
+ {:start=>:int},
43
+ {:maxResults=>:int},
44
+ {:filter=>:bool},
45
+ {:restrict=>:string},
46
+ {:safeSearch=>:bool},
47
+ {:lr=>:string},
48
+ {:ie=>:string},
49
+ {:oe=>:string}
50
+ ]
51
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: UTF-8
2
+ class GoogleSearchController < ApplicationController
3
+ wsdl_service_name 'GoogleSearch'
4
+
5
+ def doGetCachedPage
6
+ "<html><body>i am a cached page. my key was %s, url was %s</body></html>" % [@params['key'], @params['url']]
7
+ end
8
+
9
+ def doSpellingSuggestion
10
+ "%s: Did you mean '%s'?" % [@params['key'], @params['phrase']]
11
+ end
12
+
13
+ def doGoogleSearch
14
+ resultElement = ResultElement.new
15
+ resultElement.summary = "ONlamp.com: Rolling with Ruby on Rails"
16
+ resultElement.URL = "http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html"
17
+ resultElement.snippet = "Curt Hibbs shows off Ruby on Rails by building a simple application that requires " +
18
+ "almost no Ruby experience. ... Rolling with Ruby on Rails. ..."
19
+ resultElement.title = "Teh Railz0r"
20
+ resultElement.cachedSize = "Almost no lines of code!"
21
+ resultElement.relatedInformationPresent = true
22
+ resultElement.hostName = "rubyonrails.com"
23
+ resultElement.directoryCategory = category("Web Development", "UTF-8")
24
+
25
+ result = GoogleSearchResult.new
26
+ result.documentFiltering = @params['filter']
27
+ result.searchComments = ""
28
+ result.estimatedTotalResultsCount = 322000
29
+ result.estimateIsExact = false
30
+ result.resultElements = [resultElement]
31
+ result.searchQuery = "http://www.google.com/search?q=ruby+on+rails"
32
+ result.startIndex = @params['start']
33
+ result.endIndex = @params['start'] + @params['maxResults']
34
+ result.searchTips = "\"on\" is a very common word and was not included in your search [details]"
35
+ result.searchTime = 0.000001
36
+
37
+ # For Mono, we have to clone objects if they're referenced by more than one place, otherwise
38
+ # the Ruby SOAP collapses them into one instance and uses references all over the
39
+ # place, confusing Mono.
40
+ #
41
+ # This has recently been fixed:
42
+ # http://bugzilla.ximian.com/show_bug.cgi?id=72265
43
+ result.directoryCategories = [
44
+ category("Web Development", "UTF-8"),
45
+ category("Programming", "US-ASCII"),
46
+ ]
47
+
48
+ result
49
+ end
50
+
51
+ private
52
+ def category(name, encoding)
53
+ cat = DirectoryCategory.new
54
+ cat.fullViewableName = name.dup
55
+ cat.specialEncoding = encoding.dup
56
+ cat
57
+ end
58
+ end