From 7a67d0f617db7d2962b6c3b80466e21570b244bf Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 18 Feb 2005 23:43:09 +0000 Subject: Renamed Action Service to Action Web Service git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@669 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionservice/ChangeLog | 44 - actionservice/HACKING | 44 - actionservice/MIT-LICENSE | 21 - actionservice/README | 238 ---- actionservice/Rakefile | 144 --- actionservice/TODO | 38 - actionservice/examples/googlesearch/README | 143 -- .../googlesearch/autoloading/google_search_api.rb | 50 - .../autoloading/google_search_controller.rb | 57 - .../delegated/google_search_service.rb | 108 -- .../googlesearch/delegated/search_controller.rb | 7 - .../googlesearch/direct/google_search_api.rb | 50 - .../googlesearch/direct/search_controller.rb | 58 - actionservice/examples/metaWeblog/README | 28 - .../examples/metaWeblog/blog_controller.rb | 127 -- actionservice/lib/action_service.rb | 60 - actionservice/lib/action_service/api.rb | 2 - actionservice/lib/action_service/api/abstract.rb | 192 --- .../lib/action_service/api/action_controller.rb | 92 -- actionservice/lib/action_service/base.rb | 41 - actionservice/lib/action_service/client.rb | 3 - actionservice/lib/action_service/client/base.rb | 35 - actionservice/lib/action_service/client/soap.rb | 87 -- actionservice/lib/action_service/client/xmlrpc.rb | 76 -- actionservice/lib/action_service/container.rb | 232 ---- actionservice/lib/action_service/invocation.rb | 252 ---- actionservice/lib/action_service/protocol.rb | 4 - .../lib/action_service/protocol/abstract.rb | 128 -- .../lib/action_service/protocol/registry.rb | 55 - actionservice/lib/action_service/protocol/soap.rb | 484 ------- .../lib/action_service/protocol/xmlrpc.rb | 183 --- actionservice/lib/action_service/router.rb | 2 - .../lib/action_service/router/action_controller.rb | 99 -- actionservice/lib/action_service/router/wsdl.rb | 210 --- actionservice/lib/action_service/struct.rb | 55 - .../support/class_inheritable_options.rb | 26 - .../lib/action_service/support/signature.rb | 100 -- actionservice/setup.rb | 1360 -------------------- actionservice/test/abstract_client.rb | 124 -- actionservice/test/abstract_soap.rb | 58 - actionservice/test/abstract_unit.rb | 9 - actionservice/test/api_test.rb | 52 - actionservice/test/base_test.rb | 42 - actionservice/test/client_soap_test.rb | 87 -- actionservice/test/client_xmlrpc_test.rb | 86 -- actionservice/test/container_test.rb | 53 - actionservice/test/invocation_test.rb | 158 --- actionservice/test/protocol_registry_test.rb | 53 - actionservice/test/protocol_soap_test.rb | 226 ---- actionservice/test/protocol_xmlrpc_test.rb | 157 --- .../test/router_action_controller_test.rb | 139 -- actionservice/test/router_wsdl_test.rb | 100 -- actionservice/test/struct_test.rb | 40 - 53 files changed, 6319 deletions(-) delete mode 100644 actionservice/ChangeLog delete mode 100644 actionservice/HACKING delete mode 100644 actionservice/MIT-LICENSE delete mode 100644 actionservice/README delete mode 100644 actionservice/Rakefile delete mode 100644 actionservice/TODO delete mode 100644 actionservice/examples/googlesearch/README delete mode 100644 actionservice/examples/googlesearch/autoloading/google_search_api.rb delete mode 100644 actionservice/examples/googlesearch/autoloading/google_search_controller.rb delete mode 100644 actionservice/examples/googlesearch/delegated/google_search_service.rb delete mode 100644 actionservice/examples/googlesearch/delegated/search_controller.rb delete mode 100644 actionservice/examples/googlesearch/direct/google_search_api.rb delete mode 100644 actionservice/examples/googlesearch/direct/search_controller.rb delete mode 100644 actionservice/examples/metaWeblog/README delete mode 100644 actionservice/examples/metaWeblog/blog_controller.rb delete mode 100644 actionservice/lib/action_service.rb delete mode 100644 actionservice/lib/action_service/api.rb delete mode 100644 actionservice/lib/action_service/api/abstract.rb delete mode 100644 actionservice/lib/action_service/api/action_controller.rb delete mode 100644 actionservice/lib/action_service/base.rb delete mode 100644 actionservice/lib/action_service/client.rb delete mode 100644 actionservice/lib/action_service/client/base.rb delete mode 100644 actionservice/lib/action_service/client/soap.rb delete mode 100644 actionservice/lib/action_service/client/xmlrpc.rb delete mode 100644 actionservice/lib/action_service/container.rb delete mode 100644 actionservice/lib/action_service/invocation.rb delete mode 100644 actionservice/lib/action_service/protocol.rb delete mode 100644 actionservice/lib/action_service/protocol/abstract.rb delete mode 100644 actionservice/lib/action_service/protocol/registry.rb delete mode 100644 actionservice/lib/action_service/protocol/soap.rb delete mode 100644 actionservice/lib/action_service/protocol/xmlrpc.rb delete mode 100644 actionservice/lib/action_service/router.rb delete mode 100644 actionservice/lib/action_service/router/action_controller.rb delete mode 100644 actionservice/lib/action_service/router/wsdl.rb delete mode 100644 actionservice/lib/action_service/struct.rb delete mode 100644 actionservice/lib/action_service/support/class_inheritable_options.rb delete mode 100644 actionservice/lib/action_service/support/signature.rb delete mode 100644 actionservice/setup.rb delete mode 100644 actionservice/test/abstract_client.rb delete mode 100644 actionservice/test/abstract_soap.rb delete mode 100644 actionservice/test/abstract_unit.rb delete mode 100644 actionservice/test/api_test.rb delete mode 100644 actionservice/test/base_test.rb delete mode 100644 actionservice/test/client_soap_test.rb delete mode 100644 actionservice/test/client_xmlrpc_test.rb delete mode 100644 actionservice/test/container_test.rb delete mode 100644 actionservice/test/invocation_test.rb delete mode 100644 actionservice/test/protocol_registry_test.rb delete mode 100644 actionservice/test/protocol_soap_test.rb delete mode 100644 actionservice/test/protocol_xmlrpc_test.rb delete mode 100644 actionservice/test/router_action_controller_test.rb delete mode 100644 actionservice/test/router_wsdl_test.rb delete mode 100644 actionservice/test/struct_test.rb (limited to 'actionservice') diff --git a/actionservice/ChangeLog b/actionservice/ChangeLog deleted file mode 100644 index 010c4f638a..0000000000 --- a/actionservice/ChangeLog +++ /dev/null @@ -1,44 +0,0 @@ -UNRELEASED - - * lib/*,test/*,examples/*: prefix all generic "service" - type names with web_. update all using code as well as - the RDoc. - * lib/action_service/router/wsdl.rb: ensure that #wsdl is - defined in the final container class, or the new ActionPack - filtering will exclude it - * lib/action_service/struct.rb,test/struct_test.rb: create a - default #initialize on inherit that accepts a Hash containing - the default member values - * lib/action_service/api/action_controller.rb: add support and - tests for #client_api in controller - * test/router_wsdl_test.rb: add tests to ensure declared - service names don't contain ':', as ':' causes interoperability - issues - * lib/*, test/*: rename "interface" concept to "api", and change all - related uses to reflect this change. update all uses of Inflector - to call the method on String instead. - * test/api_test.rb: add test to ensure API definition not - instantiatable - * lib/action_service/invocation.rb: change @invocation_params to - @method_params - * lib/*: update RDoc - * lib/action_service/struct.rb: update to support base types - * lib/action_service/support/signature.rb: support the notion of - "base types" in signatures, with well-known unambiguous names such as :int, - :bool, etc, which map to the correct Ruby class. accept the same names - used by ActiveRecord as well as longer versions of each, as aliases. - * examples/*: update for seperate API definition updates - * lib/action_service/*, test/*: extensive refactoring: define API methods in - a seperate class, and specify it wherever used with 'service_api'. - this makes writing a client API for accessing defined API methods - with ActionService really easy. - * lib/action_service/container.rb: fix a bug in default call - handling for direct dispatching, and add ActionController filter - support for direct dispatching. - * test/router_action_controller_test.rb: add tests to ensure - ActionController filters are actually called. - * test/protocol_soap_test.rb: add more tests for direct dispatching. - -0.3.0 - - * First public release diff --git a/actionservice/HACKING b/actionservice/HACKING deleted file mode 100644 index 9c0cde6313..0000000000 --- a/actionservice/HACKING +++ /dev/null @@ -1,44 +0,0 @@ -== Coding Style - -Please try to follow Rails conventions and idioms. - - -== Concepts - - * Service - A service has an associated API definition, and - implements the methods defined in the API definition - - * Container - A container contains zero or more services - - * API - An API definition defines a list of methods implemented by - a service - - * Router - A router takes raw wire requests, decodes them, performs the invocation on - the service, and generates raw wire responses from the invocation result. - A router is mixed into a container class. - - * Protocol - A protocol implementation implements the unmarshaling and marshaling of - raw wire requests and responses. Registers with router. - - -== Action Pack Integration - -For Action Pack, the ActionController is both container and router, and also contains -the protocol implementations. - - -== Adding support for a new protocol - - 1. Add an ActionService::Protocol::YourProtocol module and any classes you need to - perform unmarshaling/marshaling of protocol requests. See the SOAP implementation - for an example of a complex mapping, and also see - ActionService::Protocol::AbstractProtocol for the methods you need to implement. - - 2. Add unit tests for your new protocol. Be sure to test using a Action Pack test request - duplicating how the real requests will arrive and verify that mapping to and from Ruby - types works correctly. diff --git a/actionservice/MIT-LICENSE b/actionservice/MIT-LICENSE deleted file mode 100644 index 528941e849..0000000000 --- a/actionservice/MIT-LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (C) 2005 Leon Breedt - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/actionservice/README b/actionservice/README deleted file mode 100644 index c011b9c537..0000000000 --- a/actionservice/README +++ /dev/null @@ -1,238 +0,0 @@ -= Action Service -- Serving APIs on rails - -Action Service provides a way to publish interoperable web service APIs with -Rails without spending a lot of time delving into protocol details. - - -== Features - -* SOAP RPC protocol support -* Dynamic WSDL generation for APIs -* XML-RPC protocol support -* Clients that use the same API definitions as the server for - easy interoperability with other Action Service based applications -* Type signature hints to improve interoperability with static languages -* Active Record model class support in signatures - - -== Defining your APIs - -You specify the methods you want to make available as API methods in an -ActionService::API::Base derivative, and then specify this API -definition class wherever you want to use that API. - -The implementation of the methods is done seperately to the API -specification. - - -==== Method name inflection - -Action Service will camelcase the method names according to Rails Inflector -rules for the API visible to public callers. What this means, for example -is that the method names in generated WSDL will be camelcased, and callers will -have to supply the camelcased name in their requests for the request to -succeed. - -If you do not desire this behaviour, you can turn it off with the -ActionService::API::Base +inflect_names+ option. - - -==== Inflection examples - - :add => Add - :find_all => FindAll - - -==== Disabling inflection - - class PersonAPI < ActionService::API::Base - inflect_names false - end - - -==== API definition example - - class PersonAPI < ActionService::API::Base - api_method :add, :expects => [:string, :string, :bool], :returns => [:int] - api_method :remove, :expects => [:int], :returns => [:bool] - end - -==== API usage example - - class PersonController < ActionController::Base - web_service_api PersonAPI - - def add - end - - def remove - end - end - - -== Publishing your APIs - -Action Service uses Action Pack to process protocol requests. There are two -modes of dispatching protocol requests, _Direct_, and _Delegated_. - - -=== Direct dispatching - -This is the default mode. In this mode, controller actions implement the API -methods, and parameters for incoming method calls will be placed in -@params (keyed by name), and @method_params (ordered list). - -The return value of the action is sent back as the return value to the -caller. - -In this mode, a special api action is generated in the target -controller to unwrap the protocol request, forward it on to the relevant action -and send back the wrapped return value. This action must not be -overridden. - -==== Direct dispatching example - - class PersonController < ApplicationController - web_service_api PersonAPI - - def add - end - - def remove - end - end - - class PersonAPI < ActionService::API::Base - ... - end - - -For this example, protocol requests for +Add+ and +Remove+ methods sent to -/person/api will be routed to the actions +add+ and +remove+. - - -=== Delegated dispatching - -This mode can be turned on by setting the +web_service_dispatching_mode+ option -in a controller. - -In this mode, the controller contains one or more web service objects (objects -that implement an ActionService::API::Base definition). These web service -objects are each mapped onto one controller action only. - -==== Delegated dispatching example - - class ApiController < ApplicationController - web_service_dispatching_mode :delegated - - web_service :person, PersonService.new - end - - class PersonService < ActionService::Base - web_service_api PersonAPI - - def add - end - - def remove - end - end - - class PersonAPI < ActionService::API::Base - ... - end - - -For this example, all protocol requests for +PersonService+ are -sent to the /api/person action. - -The /api/person action is generated when the +web_service+ -method is called. This action must not be overridden. - -Other controller actions (actions that aren't the target of a +web_service+ call) -are ignored for ActionService purposes, and can do normal action tasks. - - -== Using the client support - -Action Service includes client classes that can use the same API -definition as the server. The advantage of this approach is that your client -will have the same support for Active Record and structured types as the -server, and can just use them directly, and rely on the marshaling to Do The -Right Thing. - -*Note*: The client support is intended for communication between Ruby on Rails -applications that both use Action Service. It may work with other servers, but -that is not its intended use, and interoperability can't be guaranteed, especially -not for .NET web services. - -Web services protocol specifications are complex, and Action Service client -support can only be guaranteed to work with a subset. - - -==== Factory created client example - - class BlogManagerController < ApplicationController - web_client_api :blogger, :xmlrpc, 'http://url/to/blog/api/RPC2', :handler_name => 'blogger' - end - - class SearchingController < ApplicationController - web_client_api :google, :soap, 'http://url/to/blog/api/beta', :service_name => 'GoogleSearch' - end - -See ActionService::API::ActionController::ClassMethods for more details. - -==== Manually created client example - - class PersonAPI < ActionService::API::Base - api_method :find_all, :returns => [[Person]] - end - - soap_client = ActionService::Client::Soap.new(PersonAPI, "http://...") - persons = soap_client.find_all - - class BloggerAPI < ActionService::API::Base - inflect_names false - api_method :getRecentPosts, :returns => [[Blog::Post]] - end - - blog = ActionService::Client::XmlRpc.new(BloggerAPI, "http://.../xmlrpc", :handler_name => "blogger") - posts = blog.getRecentPosts - - -See ActionService::Client::Soap and ActionService::Client::XmlRpc for more details. - -== Dependencies - -Action Service requires that the Action Pack and Active Record are either -available to be required immediately or are accessible as GEMs. - -It also requires a version of Ruby that includes SOAP support in the standard -library. At least version 1.8.2 final (2004-12-25) of Ruby is recommended, this -is the version tested against. - - -== Download - -The latest Action Service version can be downloaded from -http://rubyforge.org/projects/actionservice - - -== Installation - -You can install Action Service with the following command. - - % [sudo] ruby setup.rb - - -== License - -Action Service is released under the MIT license. - - -== Support - -The Ruby on Rails mailing list - -Or, to contact the author, send mail to bitserf@gmail.com - diff --git a/actionservice/Rakefile b/actionservice/Rakefile deleted file mode 100644 index f4ed2bdb31..0000000000 --- a/actionservice/Rakefile +++ /dev/null @@ -1,144 +0,0 @@ -require 'rubygems' -require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' -require 'rake/packagetask' -require 'rake/gempackagetask' -require 'rake/contrib/rubyforgepublisher' -require 'fileutils' - -PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : '' -PKG_NAME = 'actionservice' -PKG_VERSION = '0.4.0' + PKG_BUILD -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" -PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}" - -desc "Default Task" -task :default => [ :test ] - - -# Run the unit tests -Rake::TestTask.new { |t| - t.libs << "test" - t.pattern = 'test/*_test.rb' - t.verbose = true -} - - -# Generate the RDoc documentation -Rake::RDocTask.new { |rdoc| - rdoc.rdoc_dir = 'doc' - rdoc.title = "Action Service -- Web services for Action Pack" - rdoc.options << '--line-numbers --inline-source --main README --accessor class_inheritable_option=RW' - rdoc.rdoc_files.include('README') - rdoc.rdoc_files.include('lib/action_service.rb') - rdoc.rdoc_files.include('lib/action_service/*.rb') - rdoc.rdoc_files.include('lib/action_service/api/*.rb') - rdoc.rdoc_files.include('lib/action_service/client/*.rb') - rdoc.rdoc_files.include('lib/action_service/protocol/*.rb') - rdoc.rdoc_files.include('lib/action_service/router/*.rb') - rdoc.rdoc_files.include('lib/action_service/support/*.rb') -} - - -# Create compressed packages -spec = Gem::Specification.new do |s| - s.platform = Gem::Platform::RUBY - s.name = PKG_NAME - s.summary = "Web service support for Action Pack." - s.description = %q{Adds WSDL/SOAP and XML-RPC web service support to Action Pack} - s.version = PKG_VERSION - - s.author = "Leon Breedt" - s.email = "bitserf@gmail.com" - s.rubyforge_project = "actionservice" - s.homepage = "http://www.rubyonrails.com" - - s.add_dependency('actionpack', '>= 1.4.0') - s.add_dependency('activerecord', '>= 1.6.0') - s.add_dependency('activesupport', '>= 0.9.0') - - s.has_rdoc = true - s.requirements << 'none' - s.require_path = 'lib' - s.autorequire = 'action_service' - - s.files = [ "Rakefile", "setup.rb", "README", "TODO", "HACKING", "ChangeLog", "MIT-LICENSE" ] - s.files = s.files + Dir.glob( "examples/**/*" ).delete_if { |item| item.include?( "\.svn" ) } - s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) } - s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) } -end -Rake::GemPackageTask.new(spec) do |p| - p.gem_spec = spec - p.need_tar = true - p.need_zip = true -end - - -# Publish beta gem -desc "Publish the API documentation" -task :pgem => [:package] do - Rake::SshFilePublisher.new("davidhh@comox.textdrive.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload - `ssh davidhh@comox.textdrive.com './gemupdate.sh'` -end - -# Publish documentation -desc "Publish the API documentation" -task :pdoc => [:rdoc] do - Rake::SshDirPublisher.new("davidhh@comox.textdrive.com", "public_html/as", "doc").upload -end - - -def each_source_file(*args) - prefix, includes, excludes, open_file = args - prefix ||= File.dirname(__FILE__) - open_file = true if open_file.nil? - includes ||= %w[lib\/action_service\.rb$ lib\/action_service\/.*\.rb$] - excludes ||= %w[] - Find.find(prefix) do |file_name| - next if file_name =~ /\.svn/ - file_name.gsub!(/^\.\//, '') - continue = false - includes.each do |inc| - if file_name.match(/#{inc}/) - continue = true - break - end - end - next unless continue - excludes.each do |exc| - if file_name.match(/#{exc}/) - continue = false - break - end - end - next unless continue - if open_file - File.open(file_name) do |f| - yield file_name, f - end - else - yield file_name - end - end -end - -desc "Count lines of the source code" -task :lines do - total_lines = total_loc = 0 - puts "Per File:" - each_source_file do |file_name, f| - file_lines = file_loc = 0 - while line = f.gets - file_lines += 1 - next if line =~ /^\s*$/ - next if line =~ /^\s*#/ - file_loc += 1 - end - puts " #{file_name}: Lines #{file_lines}, LOC #{file_loc}" - total_lines += file_lines - total_loc += file_loc - end - puts "Total:" - puts " Lines #{total_lines}, LOC #{total_loc}" -end diff --git a/actionservice/TODO b/actionservice/TODO deleted file mode 100644 index 4ee7545de5..0000000000 --- a/actionservice/TODO +++ /dev/null @@ -1,38 +0,0 @@ -= 0.4.0 Tasks - - add ActiveRecord-like logging that includes timing information - - rename project to 'actionwebservice', Action Web Service - -= Post-0.4.0 Tasks - - relax type-checking for XML-RPC, and perform casts between base types if there - are mismatches (i.e. String received when Integer expected, or vice-versa) - - - support XML-RPC's "handler." method namespacing. perhaps something like: - - class BloggingServices < ActionService::LayeredService - def initialize(request) - @request = controller.request - end - - web_service :mt {MTService.new(@request)} - web_service :blogger {BloggerService.new(@request)} - web_service :metaWeblog {MetaWeblogService.new(@request)} - end - - class ApiController < ApplicationController - web_service_dispatching_mode :delegated - web_service :xmlrpc { BloggingServices.new(@request) } - end - -= Low priority tasks - - add better type mapping tests for XML-RPC - - add tests for ActiveRecord support (with mock objects?) - -= Refactoring - - Find an alternative way to map interesting types for SOAP (like ActiveRecord - model classes) that doesn't require creation of a sanitized copy object with data - copied from the real one. Ideally this would let us get rid of - ActionService::Struct altogether and provide a block that would yield the - attributes and values. "Filters" ? Not sure how to integrate with SOAP though. - - - Don't have clean way to go from SOAP Class object to the xsd:NAME type - string -- NaHi possibly looking at remedying this situation diff --git a/actionservice/examples/googlesearch/README b/actionservice/examples/googlesearch/README deleted file mode 100644 index 25ccbd2382..0000000000 --- a/actionservice/examples/googlesearch/README +++ /dev/null @@ -1,143 +0,0 @@ -= Google Service example - -This example shows how one would implement an API like Google -Search that uses lots of structured types. - -There are examples for "Direct" and "Delegated" dispatching -modes. - -There is also an example for API definition file autoloading. - - -= Running the examples - - 1. Add the files to an Action Web Service enabled Rails project. - - "Direct" example: - - * Copy direct/search_controller.rb to "app/controllers" - in a Rails project. - * Copy direct/google_search_api.rb to "app/apis" - in a Rails project - - "Delegated" example: - - * Copy delegated/search_controller.rb to "app/controllers" - in a Rails project. - * Copy delegated/google_search_service.rb to "lib" - in a Rails project. - - "Autoloading" example: - - * Copy autoloading/google_search_api.rb to "app/apis" (create the directory - if it doesn't exist) in a Rails project. - - * Copy autoloading/google_search_controller.rb "app/controllers" - in a Rails project. - - - 2. Go to the WSDL url in a browser, and check that it looks correct. - - "Direct" and "Delegated" examples: - http://url_to_project/search/wsdl - - "Autoloading" example: - http://url_to_project/google_search/wsdl - - You can compare it to Google's hand-coded WSDL at http://api.google.com/GoogleSearch.wsdl - and see how close (or not) the generated version is. - - Note that I used GoogleSearch as the canonical "best practice" - interoperable example when implementing WSDL/SOAP support, which might - explain extreme similarities :) - - - 3. Test that it works with .NET (Mono in this example): - - $ wget WSDL_URL - $ mv wsdl GoogleSearch.wsdl - $ wsdl -out:GoogleSearch.cs GoogleSearch.wsdl - - Add these lines to the GoogleSearchService class body (be mindful of the - wrapping): - - public static void Main(string[] args) - { - GoogleSearchResult result; - GoogleSearchService service; - - service = new GoogleSearchService(); - result = service.doGoogleSearch("myApiKey", "my query", 10, 30, true, "restrict", false, "lr", "ie", "oe"); - System.Console.WriteLine("documentFiltering: {0}", result.documentFiltering); - System.Console.WriteLine("searchComments: {0}", result.searchComments); - System.Console.WriteLine("estimatedTotalResultsCount: {0}", result.estimatedTotalResultsCount); - System.Console.WriteLine("estimateIsExact: {0}", result.estimateIsExact); - System.Console.WriteLine("resultElements:"); - foreach (ResultElement element in result.resultElements) { - System.Console.WriteLine("\tsummary: {0}", element.summary); - System.Console.WriteLine("\tURL: {0}", element.URL); - System.Console.WriteLine("\tsnippet: {0}", element.snippet); - System.Console.WriteLine("\ttitle: {0}", element.title); - System.Console.WriteLine("\tcachedSize: {0}", element.cachedSize); - System.Console.WriteLine("\trelatedInformationPresent: {0}", element.relatedInformationPresent); - System.Console.WriteLine("\thostName: {0}", element.hostName); - System.Console.WriteLine("\tdirectoryCategory: {0}", element.directoryCategory.fullViewableName); - System.Console.WriteLine("\tdirectoryTitle: {0}", element.directoryTitle); - } - System.Console.WriteLine("searchQuery: {0}", result.searchQuery); - System.Console.WriteLine("startIndex: {0}", result.startIndex); - System.Console.WriteLine("endIndex: {0}", result.endIndex); - System.Console.WriteLine("searchTips: {0}", result.searchTips); - System.Console.WriteLine("directoryCategories:"); - foreach (DirectoryCategory cat in result.directoryCategories) { - System.Console.WriteLine("\t{0} ({1})", cat.fullViewableName, cat.specialEncoding); - } - System.Console.WriteLine("searchTime: {0}", result.searchTime); - } - - Now compile and run: - - $ mcs -reference:System.Web.Services GoogleSearch.cs - $ mono GoogleSearch.exe - - - If you had the application running (on the same host you got - the WSDL from), you should see something like this: - - - documentFiltering: True - searchComments: - estimatedTotalResultsCount: 322000 - estimateIsExact: False - resultElements: - summary: ONlamp.com: Rolling with Ruby on Rails - URL: http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html - snippet: Curt Hibbs shows off Ruby on Rails by building a simple ... - title: Teh Railz0r - cachedSize: Almost no lines of code! - relatedInformationPresent: True - hostName: rubyonrails.com - directoryCategory: Web Development - directoryTitle: - searchQuery: http://www.google.com/search?q=ruby+on+rails - startIndex: 10 - endIndex: 40 - searchTips: "on" is a very common word and was not included in your search [details] - directoryCategories: - Web Development (UTF-8) - Programming (US-ASCII) - searchTime: 1E-06 - - - Also, if an API method throws an exception, it will be sent back to the - caller in the protocol's exception format, so they should get an exception - thrown on their side with a meaningful error message. - - If you don't like this behaviour, you can do: - - class MyController < ActionController::Base - web_service_exception_reporting false - end - - 4. Crack open a beer. Publishing APIs for working with the same model as - your Rails web app should be easy from now on :) diff --git a/actionservice/examples/googlesearch/autoloading/google_search_api.rb b/actionservice/examples/googlesearch/autoloading/google_search_api.rb deleted file mode 100644 index e7e33a1105..0000000000 --- a/actionservice/examples/googlesearch/autoloading/google_search_api.rb +++ /dev/null @@ -1,50 +0,0 @@ -class DirectoryCategory < ActionService::Struct - member :fullViewableName, :string - member :specialEncoding, :string -end - -class ResultElement < ActionService::Struct - member :summary, :string - member :URL, :string - member :snippet, :string - member :title, :string - member :cachedSize, :string - member :relatedInformationPresent, :bool - member :hostName, :string - member :directoryCategory, DirectoryCategory - member :directoryTitle, :string -end - -class GoogleSearchResult < ActionService::Struct - member :documentFiltering, :bool - member :searchComments, :string - member :estimatedTotalResultsCount, :int - member :estimateIsExact, :bool - member :resultElements, [ResultElement] - member :searchQuery, :string - member :startIndex, :int - member :endIndex, :int - member :searchTips, :string - member :directoryCategories, [DirectoryCategory] - member :searchTime, :float -end - -class GoogleSearchAPI < ActionService::API::Base - inflect_names false - - api_method :doGetCachedPage, :returns => [:string], :expects => [{:key=>:string}, {:url=>:string}] - api_method :doGetSpellingSuggestion, :returns => [:string], :expects => [{:key=>:string}, {:phrase=>:string}] - - api_method :doGoogleSearch, :returns => [GoogleSearchResult], :expects => [ - {:key=>:string}, - {:q=>:string}, - {:start=>:int}, - {:maxResults=>:int}, - {:filter=>:bool}, - {:restrict=>:string}, - {:safeSearch=>:bool}, - {:lr=>:string}, - {:ie=>:string}, - {:oe=>:string} - ] -end diff --git a/actionservice/examples/googlesearch/autoloading/google_search_controller.rb b/actionservice/examples/googlesearch/autoloading/google_search_controller.rb deleted file mode 100644 index c62e869df5..0000000000 --- a/actionservice/examples/googlesearch/autoloading/google_search_controller.rb +++ /dev/null @@ -1,57 +0,0 @@ -class GoogleSearchController < ApplicationController - wsdl_service_name 'GoogleSearch' - - def doGetCachedPage - "i am a cached page. my key was %s, url was %s" % [@params['key'], @params['url']] - end - - def doSpellingSuggestion - "%s: Did you mean '%s'?" % [@params['key'], @params['phrase']] - end - - def doGoogleSearch - resultElement = ResultElement.new - resultElement.summary = "ONlamp.com: Rolling with Ruby on Rails" - resultElement.URL = "http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html" - resultElement.snippet = "Curt Hibbs shows off Ruby on Rails by building a simple application that requires " + - "almost no Ruby experience. ... Rolling with Ruby on Rails. ..." - resultElement.title = "Teh Railz0r" - resultElement.cachedSize = "Almost no lines of code!" - resultElement.relatedInformationPresent = true - resultElement.hostName = "rubyonrails.com" - resultElement.directoryCategory = category("Web Development", "UTF-8") - - result = GoogleSearchResult.new - result.documentFiltering = @params['filter'] - result.searchComments = "" - result.estimatedTotalResultsCount = 322000 - result.estimateIsExact = false - result.resultElements = [resultElement] - result.searchQuery = "http://www.google.com/search?q=ruby+on+rails" - result.startIndex = @params['start'] - result.endIndex = @params['start'] + @params['maxResults'] - result.searchTips = "\"on\" is a very common word and was not included in your search [details]" - result.searchTime = 0.000001 - - # For Mono, we have to clone objects if they're referenced by more than one place, otherwise - # the Ruby SOAP collapses them into one instance and uses references all over the - # place, confusing Mono. - # - # This has recently been fixed: - # http://bugzilla.ximian.com/show_bug.cgi?id=72265 - result.directoryCategories = [ - category("Web Development", "UTF-8"), - category("Programming", "US-ASCII"), - ] - - result - end - - private - def category(name, encoding) - cat = DirectoryCategory.new - cat.fullViewableName = name.dup - cat.specialEncoding = encoding.dup - cat - end -end diff --git a/actionservice/examples/googlesearch/delegated/google_search_service.rb b/actionservice/examples/googlesearch/delegated/google_search_service.rb deleted file mode 100644 index da7f8f4529..0000000000 --- a/actionservice/examples/googlesearch/delegated/google_search_service.rb +++ /dev/null @@ -1,108 +0,0 @@ -class DirectoryCategory < ActionService::Struct - member :fullViewableName, :string - member :specialEncoding, :string -end - -class ResultElement < ActionService::Struct - member :summary, :string - member :URL, :string - member :snippet, :string - member :title, :string - member :cachedSize, :string - member :relatedInformationPresent, :bool - member :hostName, :string - member :directoryCategory, DirectoryCategory - member :directoryTitle, :string -end - -class GoogleSearchResult < ActionService::Struct - member :documentFiltering, :bool - member :searchComments, :string - member :estimatedTotalResultsCount, :int - member :estimateIsExact, :bool - member :resultElements, [ResultElement] - member :searchQuery, :string - member :startIndex, :int - member :endIndex, :int - member :searchTips, :string - member :directoryCategories, [DirectoryCategory] - member :searchTime, :float -end - -class GoogleSearchAPI < ActionService::API::Base - inflect_names false - - api_method :doGetCachedPage, :returns => [:string], :expects => [{:key=>:string}, {:url=>:string}] - api_method :doGetSpellingSuggestion, :returns => [:string], :expects => [{:key=>:string}, {:phrase=>:string}] - - api_method :doGoogleSearch, :returns => [GoogleSearchResult], :expects => [ - {:key=>:string}, - {:q=>:string}, - {:start=>:int}, - {:maxResults=>:int}, - {:filter=>:bool}, - {:restrict=>:string}, - {:safeSearch=>:bool}, - {:lr=>:string}, - {:ie=>:string}, - {:oe=>:string} - ] -end - -class GoogleSearchService < ActionService::Base - web_service_api GoogleSearchAPI - - def doGetCachedPage(key, url) - "i am a cached page" - end - - def doSpellingSuggestion(key, phrase) - "Did you mean 'teh'?" - end - - def doGoogleSearch(key, q, start, maxResults, filter, restrict, safeSearch, lr, ie, oe) - resultElement = ResultElement.new - resultElement.summary = "ONlamp.com: Rolling with Ruby on Rails" - resultElement.URL = "http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html" - resultElement.snippet = "Curt Hibbs shows off Ruby on Rails by building a simple application that requires " + - "almost no Ruby experience. ... Rolling with Ruby on Rails. ..." - resultElement.title = "Teh Railz0r" - resultElement.cachedSize = "Almost no lines of code!" - resultElement.relatedInformationPresent = true - resultElement.hostName = "rubyonrails.com" - resultElement.directoryCategory = category("Web Development", "UTF-8") - - result = GoogleSearchResult.new - result.documentFiltering = filter - result.searchComments = "" - result.estimatedTotalResultsCount = 322000 - result.estimateIsExact = false - result.resultElements = [resultElement] - result.searchQuery = "http://www.google.com/search?q=ruby+on+rails" - result.startIndex = start - result.endIndex = start + maxResults - result.searchTips = "\"on\" is a very common word and was not included in your search [details]" - result.searchTime = 0.000001 - - # For Mono, we have to clone objects if they're referenced by more than one place, otherwise - # the Ruby SOAP collapses them into one instance and uses references all over the - # place, confusing Mono. - # - # This has recently been fixed: - # http://bugzilla.ximian.com/show_bug.cgi?id=72265 - result.directoryCategories = [ - category("Web Development", "UTF-8"), - category("Programming", "US-ASCII"), - ] - - result - end - - private - def category(name, encoding) - cat = DirectoryCategory.new - cat.fullViewableName = name.dup - cat.specialEncoding = encoding.dup - cat - end -end diff --git a/actionservice/examples/googlesearch/delegated/search_controller.rb b/actionservice/examples/googlesearch/delegated/search_controller.rb deleted file mode 100644 index 6525921b5a..0000000000 --- a/actionservice/examples/googlesearch/delegated/search_controller.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'google_search_service' - -class SearchController < ApplicationController - wsdl_service_name 'GoogleSearch' - web_service_dispatching_mode :delegated - web_service :beta3, GoogleSearchService.new -end diff --git a/actionservice/examples/googlesearch/direct/google_search_api.rb b/actionservice/examples/googlesearch/direct/google_search_api.rb deleted file mode 100644 index e7e33a1105..0000000000 --- a/actionservice/examples/googlesearch/direct/google_search_api.rb +++ /dev/null @@ -1,50 +0,0 @@ -class DirectoryCategory < ActionService::Struct - member :fullViewableName, :string - member :specialEncoding, :string -end - -class ResultElement < ActionService::Struct - member :summary, :string - member :URL, :string - member :snippet, :string - member :title, :string - member :cachedSize, :string - member :relatedInformationPresent, :bool - member :hostName, :string - member :directoryCategory, DirectoryCategory - member :directoryTitle, :string -end - -class GoogleSearchResult < ActionService::Struct - member :documentFiltering, :bool - member :searchComments, :string - member :estimatedTotalResultsCount, :int - member :estimateIsExact, :bool - member :resultElements, [ResultElement] - member :searchQuery, :string - member :startIndex, :int - member :endIndex, :int - member :searchTips, :string - member :directoryCategories, [DirectoryCategory] - member :searchTime, :float -end - -class GoogleSearchAPI < ActionService::API::Base - inflect_names false - - api_method :doGetCachedPage, :returns => [:string], :expects => [{:key=>:string}, {:url=>:string}] - api_method :doGetSpellingSuggestion, :returns => [:string], :expects => [{:key=>:string}, {:phrase=>:string}] - - api_method :doGoogleSearch, :returns => [GoogleSearchResult], :expects => [ - {:key=>:string}, - {:q=>:string}, - {:start=>:int}, - {:maxResults=>:int}, - {:filter=>:bool}, - {:restrict=>:string}, - {:safeSearch=>:bool}, - {:lr=>:string}, - {:ie=>:string}, - {:oe=>:string} - ] -end diff --git a/actionservice/examples/googlesearch/direct/search_controller.rb b/actionservice/examples/googlesearch/direct/search_controller.rb deleted file mode 100644 index 7c69f0225e..0000000000 --- a/actionservice/examples/googlesearch/direct/search_controller.rb +++ /dev/null @@ -1,58 +0,0 @@ -class SearchController < ApplicationController - web_service_api :google_search - wsdl_service_name 'GoogleSearch' - - def doGetCachedPage - "i am a cached page. my key was %s, url was %s" % [@params['key'], @params['url']] - end - - def doSpellingSuggestion - "%s: Did you mean '%s'?" % [@params['key'], @params['phrase']] - end - - def doGoogleSearch - resultElement = ResultElement.new - resultElement.summary = "ONlamp.com: Rolling with Ruby on Rails" - resultElement.URL = "http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html" - resultElement.snippet = "Curt Hibbs shows off Ruby on Rails by building a simple application that requires " + - "almost no Ruby experience. ... Rolling with Ruby on Rails. ..." - resultElement.title = "Teh Railz0r" - resultElement.cachedSize = "Almost no lines of code!" - resultElement.relatedInformationPresent = true - resultElement.hostName = "rubyonrails.com" - resultElement.directoryCategory = category("Web Development", "UTF-8") - - result = GoogleSearchResult.new - result.documentFiltering = @params['filter'] - result.searchComments = "" - result.estimatedTotalResultsCount = 322000 - result.estimateIsExact = false - result.resultElements = [resultElement] - result.searchQuery = "http://www.google.com/search?q=ruby+on+rails" - result.startIndex = @params['start'] - result.endIndex = @params['start'] + @params['maxResults'] - result.searchTips = "\"on\" is a very common word and was not included in your search [details]" - result.searchTime = 0.000001 - - # For Mono, we have to clone objects if they're referenced by more than one place, otherwise - # the Ruby SOAP collapses them into one instance and uses references all over the - # place, confusing Mono. - # - # This has recently been fixed: - # http://bugzilla.ximian.com/show_bug.cgi?id=72265 - result.directoryCategories = [ - category("Web Development", "UTF-8"), - category("Programming", "US-ASCII"), - ] - - result - end - - private - def category(name, encoding) - cat = DirectoryCategory.new - cat.fullViewableName = name.dup - cat.specialEncoding = encoding.dup - cat - end -end diff --git a/actionservice/examples/metaWeblog/README b/actionservice/examples/metaWeblog/README deleted file mode 100644 index f8a56d7018..0000000000 --- a/actionservice/examples/metaWeblog/README +++ /dev/null @@ -1,28 +0,0 @@ -= metaWeblog example - - -This example shows how one might begin to go about adding metaWeblog -(http://www.xmlrpc.com/metaWeblogApi) API support to a Rails-based -blogging application. - - -= Running - - 1. Ensure you have the 'actionservice' Gem installed. You can generate it using - this command: - - $ rake package - - - 2. Edit config/environment.rb, and add the following line after the rest of the - require_gem statements: - - require_gem 'actionservice' - - - 3. Copy blog_controller.rb to "app/controllers" in a Rails project. - - - 4. Fire up a desktop blogging application (such as BloGTK on Linux), - point it at http://localhost:3000/blog/api, and try creating or - editing blog posts. diff --git a/actionservice/examples/metaWeblog/blog_controller.rb b/actionservice/examples/metaWeblog/blog_controller.rb deleted file mode 100644 index aff2e909ea..0000000000 --- a/actionservice/examples/metaWeblog/blog_controller.rb +++ /dev/null @@ -1,127 +0,0 @@ -# point your client at http://project_url/blog/api to test -# this - -# structures as defined by the metaWeblog/blogger -# specifications. -module Blog - class Enclosure < ActionService::Struct - member :url, :string - member :length, :int - member :type, :string - end - - class Source < ActionService::Struct - member :url, :string - member :name, :string - end - - class Post < ActionService::Struct - member :title, :string - member :link, :string - member :description, :string - member :author, :string - member :category, :string - member :comments, :string - member :enclosure, Enclosure - member :guid, :string - member :pubDate, :string - member :source, Source - end - - class Blog < ActionService::Struct - member :url, :string - member :blogid, :string - member :blogName, :string - end -end - -# skeleton metaWeblog API -class MetaWeblogAPI < ActionService::API::Base - inflect_names false - - api_method :newPost, :returns => [:string], :expects => [ - {:blogid=>:string}, - {:username=>:string}, - {:password=>:string}, - {:struct=>Blog::Post}, - {:publish=>:bool}, - ] - - api_method :editPost, :returns => [:bool], :expects => [ - {:postid=>:string}, - {:username=>:string}, - {:password=>:string}, - {:struct=>Blog::Post}, - {:publish=>:bool}, - ] - - api_method :getPost, :returns => [Blog::Post], :expects => [ - {:postid=>:string}, - {:username=>:string}, - {:password=>:string}, - ] - - api_method :getUsersBlogs, :returns => [[Blog::Blog]], :expects => [ - {:appkey=>:string}, - {:username=>:string}, - {:password=>:string}, - ] - - api_method :getRecentPosts, :returns => [[Blog::Post]], :expects => [ - {:blogid=>:string}, - {:username=>:string}, - {:password=>:string}, - {:numberOfPosts=>:int}, - ] -end - -class BlogController < ApplicationController - web_service_api MetaWeblogAPI - - def initialize - @postid = 0 - end - - def newPost - $stderr.puts 'Creating post: username=%s password=%s struct=%s' % [ - @params['username'], - @params['password'], - @params['struct'].inspect - ] - (@postid += 1).to_s - end - - def editPost - $stderr.puts 'Editing post: username=%s password=%s struct=%s' % [ - @params['username'], - @params['password'], - @params['struct'].inspect - ] - true - end - - def getUsersBlogs - $stderr.puts "Returning user %s's blogs" % @params['username'] - blog = Blog::Blog.new( - :url =>'http://blog.xeraph.org', - :blogid => 'sttm', - :blogName => 'slave to the machine' - ) - [blog] - end - - def getRecentPosts - $stderr.puts "Returning recent posts (%d requested)" % @params['numberOfPosts'] - post1 = Blog::Post.new( - :title => 'first post!', - :link => 'http://blog.xeraph.org/testOne.html', - :description => 'this is the first post' - ) - post2 = Blog::Post.new( - :title => 'second post!', - :link => 'http://blog.xeraph.org/testTwo.html', - :description => 'this is the second post' - ) - [post1, post2] - end -end diff --git a/actionservice/lib/action_service.rb b/actionservice/lib/action_service.rb deleted file mode 100644 index 005e829e7b..0000000000 --- a/actionservice/lib/action_service.rb +++ /dev/null @@ -1,60 +0,0 @@ -#-- -# Copyright (C) 2005 Leon Breedt -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -#++ - -begin - require 'active_support' - require 'action_controller' - require 'active_record' -rescue LoadError - require 'rubygems' - require_gem 'activesupport', '>= 0.9.0' - require_gem 'actionpack', '>= 1.4.0' - require_gem 'activerecord', '>= 1.6.0' -end - -$:.unshift(File.dirname(__FILE__)) - -require 'action_service/base' -require 'action_service/client' -require 'action_service/invocation' -require 'action_service/api' -require 'action_service/struct' -require 'action_service/container' -require 'action_service/protocol' -require 'action_service/router' - -ActionService::Base.class_eval do - include ActionService::API - include ActionService::Invocation -end - -ActionController::Base.class_eval do - include ActionService::Container - include ActionService::Protocol::Registry - include ActionService::Protocol::Soap - include ActionService::Protocol::XmlRpc - include ActionService::API - include ActionService::API::ActionController - include ActionService::Router::ActionController - include ActionService::Router::Wsdl -end diff --git a/actionservice/lib/action_service/api.rb b/actionservice/lib/action_service/api.rb deleted file mode 100644 index 61f36fff56..0000000000 --- a/actionservice/lib/action_service/api.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'action_service/api/abstract' -require 'action_service/api/action_controller' diff --git a/actionservice/lib/action_service/api/abstract.rb b/actionservice/lib/action_service/api/abstract.rb deleted file mode 100644 index aab37a285d..0000000000 --- a/actionservice/lib/action_service/api/abstract.rb +++ /dev/null @@ -1,192 +0,0 @@ -module ActionService # :nodoc: - module API # :nodoc: - class APIError < ActionService::ActionServiceError # :nodoc: - end - - def self.append_features(base) # :nodoc: - super - base.extend(ClassMethods) - end - - module ClassMethods - # Attaches ActionService API +definition+ to the calling class. - # - # Action Controllers can have a default associated API, removing the need - # to call this method if you follow the Action Service naming conventions. - # - # A controller with a class name of GoogleSearchController will - # implicitly load app/apis/google_search_api.rb, and expect the - # API definition class to be named GoogleSearchAPI or - # GoogleSearchApi. - # - # ==== Service class example - # - # class MyService < ActionService::Base - # web_service_api MyAPI - # end - # - # class MyAPI < ActionService::API::Base - # ... - # end - # - # ==== Controller class example - # - # class MyController < ActionController::Base - # web_service_api MyAPI - # end - # - # class MyAPI < ActionService::API::Base - # ... - # end - def web_service_api(definition=nil) - if definition.nil? - read_inheritable_attribute("web_service_api") - else - if definition.is_a?(Symbol) - raise(APIError, "symbols can only be used for #web_service_api inside of a controller") - end - unless definition.respond_to?(:ancestors) && definition.ancestors.include?(Base) - raise(APIError, "#{definition.to_s} is not a valid API definition") - end - write_inheritable_attribute("web_service_api", definition) - call_web_service_api_callbacks(self, definition) - end - end - - def add_web_service_api_callback(&block) # :nodoc: - write_inheritable_array("web_service_api_callbacks", [block]) - end - - private - def call_web_service_api_callbacks(container_class, definition) - (read_inheritable_attribute("web_service_api_callbacks") || []).each do |block| - block.call(container_class, definition) - end - end - end - - # A web service API class specifies the methods that will be available for - # invocation for an API. It also contains metadata such as the method type - # signature hints. - # - # It is not intended to be instantiated. - # - # It is attached to web service implementation classes like - # ActionService::Base and ActionController::Base derivatives by using - # ClassMethods#web_service_api. - class Base - # Whether to transform the public API method names into camel-cased names - class_inheritable_option :inflect_names, true - - # If present, the name of a method to call when the remote caller - # tried to call a nonexistent method. Semantically equivalent to - # +method_missing+. - class_inheritable_option :default_api_method - - # Disallow instantiation - private_class_method :new, :allocate - - class << self - include ActionService::Signature - - # API methods have a +name+, which must be the Ruby method name to use when - # performing the invocation on the web service object. - # - # The signatures for the method input parameters and return value can - # by specified in +options+. - # - # A signature is an array of one or more parameter specifiers. - # A parameter specifier can be one of the following: - # - # * A symbol or string of representing one of the Action Service base types. - # See ActionService::Signature for a canonical list of the base types. - # * The Class object of the parameter type - # * A single-element Array containing one of the two preceding items. This - # will cause Action Service to treat the parameter at that position - # as an array containing only values of the given type. - # * A Hash containing as key the name of the parameter, and as value - # one of the three preceding items - # - # If no method input parameter or method return value signatures are given, - # the method is assumed to take no parameters and/or return no values of - # interest, and any values that are received by the server will be - # discarded and ignored. - # - # Valid options: - # [:expects] Signature for the method input parameters - # [:returns] Signature for the method return value - # [:expects_and_returns] Signature for both input parameters and return value - def api_method(name, options={}) - validate_options([:expects, :returns, :expects_and_returns], options.keys) - if options[:expects_and_returns] - expects = options[:expects_and_returns] - returns = options[:expects_and_returns] - else - expects = options[:expects] - returns = options[:returns] - end - expects = canonical_signature(expects) if expects - returns = canonical_signature(returns) if returns - if expects - expects.each do |param| - klass = signature_parameter_class(param) - klass = klass[0] if klass.is_a?(Array) - if klass.ancestors.include?(ActiveRecord::Base) - raise(ActionServiceError, "ActiveRecord model classes not allowed in :expects") - end - end - end - name = name.to_sym - public_name = public_api_method_name(name) - info = { :expects => expects, :returns => returns } - write_inheritable_hash("api_methods", name => info) - write_inheritable_hash("api_public_method_names", public_name => name) - end - - # Whether the given method name is a service method on this API - def has_api_method?(name) - api_methods.has_key?(name) - end - - # Whether the given public method name has a corresponding service method - # on this API - def has_public_api_method?(public_name) - api_public_method_names.has_key?(public_name) - end - - # The corresponding public method name for the given service method name - def public_api_method_name(name) - if inflect_names - name.to_s.camelize - else - name.to_s - end - end - - # The corresponding service method name for the given public method name - def api_method_name(public_name) - api_public_method_names[public_name] - end - - # A Hash containing all service methods on this API, and their - # associated metadata. - def api_methods - read_inheritable_attribute("api_methods") || {} - end - - private - def api_public_method_names - read_inheritable_attribute("api_public_method_names") || {} - end - - def validate_options(valid_option_keys, supplied_option_keys) - unknown_option_keys = supplied_option_keys - valid_option_keys - unless unknown_option_keys.empty? - raise(ActionServiceError, "Unknown options: #{unknown_option_keys}") - end - end - - end - end - end -end diff --git a/actionservice/lib/action_service/api/action_controller.rb b/actionservice/lib/action_service/api/action_controller.rb deleted file mode 100644 index d603f3a570..0000000000 --- a/actionservice/lib/action_service/api/action_controller.rb +++ /dev/null @@ -1,92 +0,0 @@ -module ActionService # :nodoc: - module API # :nodoc: - module ActionController # :nodoc: - def self.append_features(base) # :nodoc: - base.class_eval do - class << self - alias_method :inherited_without_api, :inherited - alias_method :web_service_api_without_require, :web_service_api - end - end - base.extend(ClassMethods) - end - - module ClassMethods - # Creates a client for accessing remote web services, using the - # given +protocol+ to communicate with the +endpoint_uri+. - # - # ==== Example - # - # class MyController < ActionController::Base - # web_client_api :blogger, :xmlrpc, "http://blogger.com/myblog/api/RPC2", :handler_name => 'blogger' - # end - # - # In this example, a protected method named blogger will - # now exist on the controller, and calling it will return the - # XML-RPC client object for working with that remote service. - # - # +options+ is the set of protocol client specific options, - # see a protocol client class for details. - # - # If your API definition does not exist on the load path with the - # correct rules for it to be found using +name+, you can pass through - # the API definition class in +options+, using a key of :api - def web_client_api(name, protocol, endpoint_uri, options={}) - unless method_defined?(name) - api_klass = options.delete(:api) || require_web_service_api(name) - class_eval do - define_method(name) do - probe_protocol_client(api_klass, protocol, endpoint_uri, options) - end - protected name - end - end - end - - def web_service_api(definition=nil) # :nodoc: - return web_service_api_without_require if definition.nil? - case definition - when String, Symbol - klass = require_web_service_api(definition) - else - klass = definition - end - web_service_api_without_require(klass) - end - - def require_web_service_api(name) # :nodoc: - case name - when String, Symbol - file_name = name.to_s.underscore + "_api" - class_name = file_name.camelize - class_names = [class_name, class_name.sub(/Api$/, 'API')] - begin - require_dependency(file_name) - rescue LoadError => load_error - requiree = / -- (.*?)(\.rb)?$/.match(load_error).to_a[1] - raise LoadError, requiree == file_name ? "Missing API definition file in apis/#{file_name}.rb" : "Can't load file: #{requiree}" - end - klass = nil - class_names.each do |name| - klass = name.constantize rescue nil - break unless klass.nil? - end - unless klass - raise(NameError, "neither #{class_names[0]} or #{class_names[1]} found") - end - klass - else - raise(ArgumentError, "expected String or Symbol argument") - end - end - - private - def inherited(child) - inherited_without_api(child) - child.web_service_api(child.controller_path) - rescue Exception => e - end - end - end - end -end diff --git a/actionservice/lib/action_service/base.rb b/actionservice/lib/action_service/base.rb deleted file mode 100644 index 05fd2afd34..0000000000 --- a/actionservice/lib/action_service/base.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'action_service/support/class_inheritable_options' -require 'action_service/support/signature' - -module ActionService # :nodoc: - class ActionServiceError < StandardError # :nodoc: - end - - # An Action Service object implements a specified API. - # - # Used by controllers operating in _Delegated_ dispatching mode. - # - # ==== Example - # - # class PersonService < ActionService::Base - # web_service_api PersonAPI - # - # def find_person(criteria) - # Person.find_all [...] - # end - # - # def delete_person(id) - # Person.find_by_id(id).destroy - # end - # end - # - # class PersonAPI < ActionService::API::Base - # api_method :find_person, :expects => [SearchCriteria], :returns => [[Person]] - # api_method :delete_person, :expects => [:int] - # end - # - # class SearchCriteria < ActionStruct::Base - # member :firstname, :string - # member :lastname, :string - # member :email, :string - # end - class Base - # Whether to report exceptions back to the caller in the protocol's exception - # format - class_inheritable_option :web_service_exception_reporting, true - end -end diff --git a/actionservice/lib/action_service/client.rb b/actionservice/lib/action_service/client.rb deleted file mode 100644 index ce91529f20..0000000000 --- a/actionservice/lib/action_service/client.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'action_service/client/base' -require 'action_service/client/soap' -require 'action_service/client/xmlrpc' diff --git a/actionservice/lib/action_service/client/base.rb b/actionservice/lib/action_service/client/base.rb deleted file mode 100644 index 955887a4d8..0000000000 --- a/actionservice/lib/action_service/client/base.rb +++ /dev/null @@ -1,35 +0,0 @@ -module ActionService # :nodoc: - module Client # :nodoc: - class ClientError < StandardError # :nodoc: - end - - class Base # :nodoc: - def initialize(api, endpoint_uri) - @api = api - @endpoint_uri = endpoint_uri - end - - def method_missing(name, *args) # :nodoc: - call_name = method_name(name) - return super(name, *args) if call_name.nil? - perform_invocation(call_name, args) - end - - protected - def perform_invocation(method_name, args) # :nodoc: - raise NotImplementedError, "use a protocol-specific client" - end - - private - def method_name(name) - if @api.has_api_method?(name.to_sym) - name.to_s - elsif @api.has_public_api_method?(name.to_s) - @api.api_method_name(name.to_s).to_s - else - nil - end - end - end - end -end diff --git a/actionservice/lib/action_service/client/soap.rb b/actionservice/lib/action_service/client/soap.rb deleted file mode 100644 index c617f36589..0000000000 --- a/actionservice/lib/action_service/client/soap.rb +++ /dev/null @@ -1,87 +0,0 @@ -require 'soap/rpc/driver' -require 'uri' - -module ActionService # :nodoc: - module Client # :nodoc: - - # Implements SOAP client support (using RPC encoding for the messages). - # - # ==== Example Usage - # - # class PersonAPI < ActionService::API::Base - # api_method :find_all, :returns => [[Person]] - # end - # - # soap_client = ActionService::Client::Soap.new(PersonAPI, "http://...") - # persons = soap_client.find_all - # - class Soap < Base - - # Creates a new web service client using the SOAP RPC protocol. - # - # +api+ must be an ActionService::API::Base derivative, and - # +endpoint_uri+ must point at the relevant URL to which protocol requests - # will be sent with HTTP POST. - # - # Valid options: - # [:service_name] If the remote server has used a custom +wsdl_service_name+ - # option, you must specify it here - def initialize(api, endpoint_uri, options={}) - super(api, endpoint_uri) - @service_name = options[:service_name] || 'ActionService' - @namespace = "urn:#{@service_name}" - @mapper = ActionService::Protocol::Soap::SoapMapper.new(@namespace) - @protocol = ActionService::Protocol::Soap::SoapProtocol.new(@mapper) - @soap_action_base = options[:soap_action_base] - @soap_action_base ||= URI.parse(endpoint_uri).path - @driver = create_soap_rpc_driver(api, endpoint_uri) - end - - protected - def perform_invocation(method_name, args) - @driver.send(method_name, *args) - end - - def soap_action(method_name) - "#{@soap_action_base}/#{method_name}" - end - - private - def create_soap_rpc_driver(api, endpoint_uri) - @mapper.map_api(api) - driver = SoapDriver.new(endpoint_uri, nil) - driver.mapping_registry = @mapper.registry - api.api_methods.each do |name, info| - public_name = api.public_api_method_name(name) - qname = XSD::QName.new(@namespace, public_name) - action = soap_action(public_name) - expects = info[:expects] - returns = info[:returns] - param_def = [] - i = 1 - if expects - expects.each do |klass| - param_name = klass.is_a?(Hash) ? klass.keys[0] : "param#{i}" - mapping = @mapper.lookup(klass) - param_def << ['in', param_name, mapping.registry_mapping] - i += 1 - end - end - if returns - mapping = @mapper.lookup(returns[0]) - param_def << ['retval', 'return', mapping.registry_mapping] - end - driver.add_method(qname, action, name.to_s, param_def) - end - driver - end - - class SoapDriver < SOAP::RPC::Driver # :nodoc: - def add_method(qname, soapaction, name, param_def) - @proxy.add_rpc_method(qname, soapaction, name, param_def) - add_rpc_method_interface(name, param_def) - end - end - end - end -end diff --git a/actionservice/lib/action_service/client/xmlrpc.rb b/actionservice/lib/action_service/client/xmlrpc.rb deleted file mode 100644 index d0d007f871..0000000000 --- a/actionservice/lib/action_service/client/xmlrpc.rb +++ /dev/null @@ -1,76 +0,0 @@ -require 'uri' -require 'xmlrpc/client' - -module ActionService # :nodoc: - module Client # :nodoc: - - # Implements XML-RPC client support - # - # ==== Example Usage - # - # class BloggerAPI < ActionService::API::Base - # inflect_names false - # api_method :getRecentPosts, :returns => [[Blog::Post]] - # end - # - # blog = ActionService::Client::XmlRpc.new(BloggerAPI, "http://.../RPC", :handler_name => "blogger") - # posts = blog.getRecentPosts - class XmlRpc < Base - - # Creates a new web service client using the XML-RPC protocol. - # - # +api+ must be an ActionService::API::Base derivative, and - # +endpoint_uri+ must point at the relevant URL to which protocol requests - # will be sent with HTTP POST. - # - # Valid options: - # [:handler_name] If the remote server defines its services inside special - # handler (the Blogger API uses a "blogger" handler name for example), - # provide it here, or your method calls will fail - def initialize(api, endpoint_uri, options={}) - @api = api - @handler_name = options[:handler_name] - @client = XMLRPC::Client.new2(endpoint_uri, options[:proxy], options[:timeout]) - end - - protected - def perform_invocation(method_name, args) - args = transform_outgoing_method_params(method_name, args) - ok, return_value = @client.call2(public_name(method_name), *args) - return transform_return_value(method_name, return_value) if ok - raise(ClientError, "#{return_value.faultCode}: #{return_value.faultString}") - end - - def transform_outgoing_method_params(method_name, params) - info = @api.api_methods[method_name.to_sym] - signature = info[:expects] - signature_length = signature.nil?? 0 : signature.length - if signature_length != params.length - raise(ProtocolError, "API declares #{public_name(method_name)} to accept " + - "#{signature_length} parameters, but #{params.length} parameters " + - "were supplied") - end - if signature_length > 0 - signature = Protocol::XmlRpc::XmlRpcProtocol.transform_array_types(signature) - (1..signature.size).each do |i| - i -= 1 - params[i] = Protocol::XmlRpc::XmlRpcProtocol.ruby_to_xmlrpc(params[i], signature[i]) - end - end - params - end - - def transform_return_value(method_name, return_value) - info = @api.api_methods[method_name.to_sym] - return true unless signature = info[:returns] - signature = Protocol::XmlRpc::XmlRpcProtocol.transform_array_types(signature) - Protocol::XmlRpc::XmlRpcProtocol.xmlrpc_to_ruby(return_value, signature[0]) - end - - def public_name(method_name) - public_name = @api.public_api_method_name(method_name) - @handler_name ? "#{@handler_name}.#{public_name}" : public_name - end - end - end -end diff --git a/actionservice/lib/action_service/container.rb b/actionservice/lib/action_service/container.rb deleted file mode 100644 index 282e6ad928..0000000000 --- a/actionservice/lib/action_service/container.rb +++ /dev/null @@ -1,232 +0,0 @@ -module ActionService # :nodoc: - module Container # :nodoc: - class ContainerError < ActionService::ActionServiceError # :nodoc: - end - - def self.append_features(base) # :nodoc: - super - base.class_inheritable_option(:web_service_dispatching_mode, :direct) - base.class_inheritable_option(:web_service_exception_reporting, true) - base.extend(ClassMethods) - base.send(:include, ActionService::Container::InstanceMethods) - end - - module ClassMethods - # Declares a web service that will provides access to the API of the given - # +object+. +object+ must be an ActionService::Base derivative. - # - # Web service object creation can either be _immediate_, where the object - # instance is given at class definition time, or _deferred_, where - # object instantiation is delayed until request time. - # - # ==== Immediate web service object example - # - # class ApiController < ApplicationController - # web_service_dispatching_mode :delegated - # - # web_service :person, PersonService.new - # end - # - # For deferred instantiation, a block should be given instead of an - # object instance. This block will be executed in controller instance - # context, so it can rely on controller instance variables being present. - # - # ==== Deferred web service object example - # - # class ApiController < ApplicationController - # web_service_dispatching_mode :delegated - # - # web_service(:person) { PersonService.new(@request.env) } - # end - def web_service(name, object=nil, &block) - if (object && block_given?) || (object.nil? && block.nil?) - raise(ContainerError, "either service, or a block must be given") - end - name = name.to_sym - if block_given? - info = { name => { :block => block } } - else - info = { name => { :object => object } } - end - write_inheritable_hash("web_services", info) - call_web_service_definition_callbacks(self, name, info) - end - - # Whether this service contains a service with the given +name+ - def has_web_service?(name) - web_services.has_key?(name.to_sym) - end - - def web_services # :nodoc: - read_inheritable_attribute("web_services") || {} - end - - def add_web_service_definition_callback(&block) # :nodoc: - write_inheritable_array("web_service_definition_callbacks", [block]) - end - - private - def call_web_service_definition_callbacks(container_class, web_service_name, service_info) - (read_inheritable_attribute("web_service_definition_callbacks") || []).each do |block| - block.call(container_class, web_service_name, service_info) - end - end - end - - module InstanceMethods # :nodoc: - def web_service_object(web_service_name) - info = self.class.web_services[web_service_name.to_sym] - unless info - raise(ContainerError, "no such web service '#{web_service_name}'") - end - service = info[:block] - service ? instance_eval(&service) : info[:object] - end - - private - def dispatch_web_service_request(protocol_request) - case web_service_dispatching_mode - when :direct - dispatch_direct_web_service_request(protocol_request) - when :delegated - dispatch_delegated_web_service_request(protocol_request) - else - raise(ContainerError, "unsupported dispatching mode :#{web_service_dispatching_mode}") - end - end - - def dispatch_direct_web_service_request(protocol_request) - public_method_name = protocol_request.public_method_name - api = self.class.web_service_api - method_name = api.api_method_name(public_method_name) - block = nil - expects = nil - if method_name - signature = api.api_methods[method_name] - expects = signature[:expects] - protocol_request.type = Protocol::CheckedMessage - protocol_request.signature = expects - protocol_request.return_signature = signature[:returns] - else - protocol_request.type = Protocol::UncheckedMessage - system_methods = self.class.read_inheritable_attribute('default_system_methods') || {} - protocol = protocol_request.protocol - block = system_methods[protocol.class] - unless block - method_name = api.default_api_method - unless method_name && respond_to?(method_name) - raise(ContainerError, "no such method ##{public_method_name}") - end - end - end - - @method_params = protocol_request.unmarshal - @params ||= {} - if expects - (1..@method_params.size).each do |i| - i -= 1 - if expects[i].is_a?(Hash) - @params[expects[i].keys.shift.to_s] = @method_params[i] - else - @params["param#{i}"] = @method_params[i] - end - end - end - - if respond_to?(:before_action) - @params['action'] = method_name.to_s - return protocol_request.marshal(nil) if before_action == false - end - - perform_invoke = lambda do - if block - block.call(public_method_name, self.class, *@method_params) - else - send(method_name) - end - end - try_default = true - result = nil - catch(:try_default) do - result = perform_invoke.call - try_default = false - end - if try_default - method_name = api.default_api_method - if method_name - protocol_request.type = Protocol::UncheckedMessage - else - raise(ContainerError, "no such method ##{public_method_name}") - end - result = perform_invoke.call - end - after_action if respond_to?(:after_action) - protocol_request.marshal(result) - end - - def dispatch_delegated_web_service_request(protocol_request) - web_service_name = protocol_request.web_service_name - service = web_service_object(web_service_name) - api = service.class.web_service_api - public_method_name = protocol_request.public_method_name - method_name = api.api_method_name(public_method_name) - - invocation = ActionService::Invocation::InvocationRequest.new( - ActionService::Invocation::ConcreteInvocation, - public_method_name, - method_name) - - if method_name - protocol_request.type = Protocol::CheckedMessage - signature = api.api_methods[method_name] - protocol_request.signature = signature[:expects] - protocol_request.return_signature = signature[:returns] - invocation.params = protocol_request.unmarshal - else - protocol_request.type = Protocol::UncheckedMessage - invocation.type = ActionService::Invocation::VirtualInvocation - system_methods = self.class.read_inheritable_attribute('default_system_methods') || {} - protocol = protocol_request.protocol - block = system_methods[protocol.class] - if block - invocation.block = block - invocation.block_params << service.class - else - method_name = api.default_api_method - if method_name && service.respond_to?(method_name) - invocation.params = protocol_request.unmarshal - invocation.method_name = method_name.to_sym - else - raise(ContainerError, "no such method /#{web_service_name}##{public_method_name}") - end - end - end - - canceled_reason = nil - canceled_block = lambda{|r| canceled_reason = r} - perform_invoke = lambda do - service.perform_invocation(invocation, &canceled_block) - end - try_default = true - result = nil - catch(:try_default) do - result = perform_invoke.call - try_default = false - end - if try_default - method_name = api.default_api_method - if method_name - protocol_request.type = Protocol::UncheckedMessage - invocation.params = protocol_request.unmarshal - invocation.method_name = method_name.to_sym - invocation.type = ActionService::Invocation::UnpublishedConcreteInvocation - else - raise(ContainerError, "no such method /#{web_service_name}##{public_method_name}") - end - result = perform_invoke.call - end - protocol_request.marshal(result) - end - end - end -end diff --git a/actionservice/lib/action_service/invocation.rb b/actionservice/lib/action_service/invocation.rb deleted file mode 100644 index f35ab76386..0000000000 --- a/actionservice/lib/action_service/invocation.rb +++ /dev/null @@ -1,252 +0,0 @@ -module ActionService # :nodoc: - module Invocation # :nodoc: - ConcreteInvocation = :concrete - VirtualInvocation = :virtual - UnpublishedConcreteInvocation = :unpublished_concrete - - class InvocationError < ActionService::ActionServiceError # :nodoc: - end - - def self.append_features(base) # :nodoc: - super - base.extend(ClassMethods) - base.send(:include, ActionService::Invocation::InstanceMethods) - end - - # Invocation interceptors provide a means to execute custom code before - # and after method invocations on ActionService::Base objects. - # - # When running in _Direct_ dispatching mode, ActionController filters - # should be used for this functionality instead. - # - # The semantics of invocation interceptors are the same as ActionController - # filters, and accept the same parameters and options. - # - # A _before_ interceptor can also cancel execution by returning +false+, - # or returning a [false, "cancel reason"] array if it wishes to supply - # a reason for canceling the request. - # - # === Example - # - # class CustomService < ActionService::Base - # before_invocation :intercept_add, :only => [:add] - # - # def add(a, b) - # a + b - # end - # - # private - # def intercept_add - # return [false, "permission denied"] # cancel it - # end - # end - # - # Options: - # [:except] A list of methods for which the interceptor will NOT be called - # [:only] A list of methods for which the interceptor WILL be called - module ClassMethods - # Appends the given +interceptors+ to be called - # _before_ method invocation. - def append_before_invocation(*interceptors, &block) - conditions = extract_conditions!(interceptors) - interceptors << block if block_given? - add_interception_conditions(interceptors, conditions) - append_interceptors_to_chain("before", interceptors) - end - - # Prepends the given +interceptors+ to be called - # _before_ method invocation. - def prepend_before_invocation(*interceptors, &block) - conditions = extract_conditions!(interceptors) - interceptors << block if block_given? - add_interception_conditions(interceptors, conditions) - prepend_interceptors_to_chain("before", interceptors) - end - - alias :before_invocation :append_before_invocation - - # Appends the given +interceptors+ to be called - # _after_ method invocation. - def append_after_invocation(*interceptors, &block) - conditions = extract_conditions!(interceptors) - interceptors << block if block_given? - add_interception_conditions(interceptors, conditions) - append_interceptors_to_chain("after", interceptors) - end - - # Prepends the given +interceptors+ to be called - # _after_ method invocation. - def prepend_after_invocation(*interceptors, &block) - conditions = extract_conditions!(interceptors) - interceptors << block if block_given? - add_interception_conditions(interceptors, conditions) - prepend_interceptors_to_chain("after", interceptors) - end - - alias :after_invocation :append_after_invocation - - def before_invocation_interceptors # :nodoc: - read_inheritable_attribute("before_invocation_interceptors") - end - - def after_invocation_interceptors # :nodoc: - read_inheritable_attribute("after_invocation_interceptors") - end - - def included_intercepted_methods # :nodoc: - read_inheritable_attribute("included_intercepted_methods") || {} - end - - def excluded_intercepted_methods # :nodoc: - read_inheritable_attribute("excluded_intercepted_methods") || {} - end - - private - def append_interceptors_to_chain(condition, interceptors) - write_inheritable_array("#{condition}_invocation_interceptors", interceptors) - end - - def prepend_interceptors_to_chain(condition, interceptors) - interceptors = interceptors + read_inheritable_attribute("#{condition}_invocation_interceptors") - write_inheritable_attribute("#{condition}_invocation_interceptors", interceptors) - end - - def extract_conditions!(interceptors) - return nil unless interceptors.last.is_a? Hash - interceptors.pop - end - - def add_interception_conditions(interceptors, conditions) - return unless conditions - included, excluded = conditions[:only], conditions[:except] - write_inheritable_hash("included_intercepted_methods", condition_hash(interceptors, included)) && return if included - write_inheritable_hash("excluded_intercepted_methods", condition_hash(interceptors, excluded)) if excluded - end - - def condition_hash(interceptors, *methods) - interceptors.inject({}) {|hash, interceptor| hash.merge(interceptor => methods.flatten.map {|method| method.to_s})} - end - end - - module InstanceMethods # :nodoc: - def self.append_features(base) - super - base.class_eval do - alias_method :perform_invocation_without_interception, :perform_invocation - alias_method :perform_invocation, :perform_invocation_with_interception - end - end - - def perform_invocation_with_interception(invocation, &block) - return if before_invocation(invocation.method_name, invocation.params, &block) == false - result = perform_invocation_without_interception(invocation) - after_invocation(invocation.method_name, invocation.params, result) - result - end - - def perform_invocation(invocation) - if invocation.concrete? - unless self.respond_to?(invocation.method_name) && \ - self.class.web_service_api.has_api_method?(invocation.method_name) - raise InvocationError, "no such web service method '#{invocation.method_name}' on service object" - end - end - params = invocation.params - if invocation.concrete? || invocation.unpublished_concrete? - self.send(invocation.method_name, *params) - else - if invocation.block - params = invocation.block_params + params - invocation.block.call(invocation.public_method_name, *params) - else - self.send(invocation.method_name, *params) - end - end - end - - def before_invocation(name, args, &block) - call_interceptors(self.class.before_invocation_interceptors, [name, args], &block) - end - - def after_invocation(name, args, result) - call_interceptors(self.class.after_invocation_interceptors, [name, args, result]) - end - - private - - def call_interceptors(interceptors, interceptor_args, &block) - if interceptors and not interceptors.empty? - interceptors.each do |interceptor| - next if method_exempted?(interceptor, interceptor_args[0].to_s) - result = case - when interceptor.is_a?(Symbol) - self.send(interceptor, *interceptor_args) - when interceptor_block?(interceptor) - interceptor.call(self, *interceptor_args) - when interceptor_class?(interceptor) - interceptor.intercept(self, *interceptor_args) - else - raise( - InvocationError, - "Interceptors need to be either a symbol, proc/method, or a class implementing a static intercept method" - ) - end - reason = nil - if result.is_a?(Array) - reason = result[1] if result[1] - result = result[0] - end - if result == false - block.call(reason) if block && reason - return false - end - end - end - end - - def interceptor_block?(interceptor) - interceptor.respond_to?("call") && (interceptor.arity == 3 || interceptor.arity == -1) - end - - def interceptor_class?(interceptor) - interceptor.respond_to?("intercept") - end - - def method_exempted?(interceptor, method_name) - case - when self.class.included_intercepted_methods[interceptor] - !self.class.included_intercepted_methods[interceptor].include?(method_name) - when self.class.excluded_intercepted_methods[interceptor] - self.class.excluded_intercepted_methods[interceptor].include?(method_name) - end - end - end - - class InvocationRequest # :nodoc: - attr_accessor :type - attr :public_method_name - attr_accessor :method_name - attr_accessor :params - attr_accessor :block - attr :block_params - - def initialize(type, public_method_name, method_name, params=nil) - @type = type - @public_method_name = public_method_name - @method_name = method_name - @params = params || [] - @block = nil - @block_params = [] - end - - def concrete? - @type == ConcreteInvocation ? true : false - end - - def unpublished_concrete? - @type == UnpublishedConcreteInvocation ? true : false - end - end - - end -end diff --git a/actionservice/lib/action_service/protocol.rb b/actionservice/lib/action_service/protocol.rb deleted file mode 100644 index 5e71b2bcfd..0000000000 --- a/actionservice/lib/action_service/protocol.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'action_service/protocol/abstract' -require 'action_service/protocol/registry' -require 'action_service/protocol/soap' -require 'action_service/protocol/xmlrpc' diff --git a/actionservice/lib/action_service/protocol/abstract.rb b/actionservice/lib/action_service/protocol/abstract.rb deleted file mode 100644 index bd02b6e829..0000000000 --- a/actionservice/lib/action_service/protocol/abstract.rb +++ /dev/null @@ -1,128 +0,0 @@ -module ActionService # :nodoc: - module Protocol # :nodoc: - CheckedMessage = :checked - UncheckedMessage = :unchecked - - class ProtocolError < ActionService::ActionServiceError # :nodoc: - end - - class AbstractProtocol # :nodoc: - attr :container_class - - def initialize(container_class) - @container_class = container_class - end - - def unmarshal_request(protocol_request) - raise NotImplementedError - end - - def marshal_response(protocol_request, return_value) - raise NotImplementedError - end - - def marshal_exception(exception) - raise NotImplementedError - end - - def self.create_protocol_request(container_class, action_pack_request) - nil - end - - def self.create_protocol_client(api, protocol_name, endpoint_uri, options) - nil - end - end - - class AbstractProtocolMessage # :nodoc: - attr_accessor :signature - attr_accessor :return_signature - attr_accessor :type - attr :options - - def initialize(options={}) - @signature = @return_signature = nil - @options = options - @type = @options[:type] || CheckedMessage - end - - def signature=(value) - return if value.nil? - @signature = [] - value.each do |klass| - if klass.is_a?(Hash) - @signature << klass.values.shift - else - @signature << klass - end - end - @signature - end - - def checked? - @type == CheckedMessage - end - - def check_parameter_types(values, signature) - return unless checked? && signature - unless signature.length == values.length - raise(ProtocolError, "Signature and parameter lengths mismatch") - end - (1..signature.length).each do |i| - check_compatibility(signature[i-1], values[i-1].class) - end - end - - def check_compatibility(expected_class, received_class) - return if \ - (expected_class == TrueClass or expected_class == FalseClass) and \ - (received_class == TrueClass or received_class == FalseClass) - unless received_class.ancestors.include?(expected_class) or \ - expected_class.ancestors.include?(received_class) - raise(ProtocolError, "value of type #{received_class.name} is not " + - "compatible with expected type #{expected_class.name}") - end - end - end - - class ProtocolRequest < AbstractProtocolMessage # :nodoc: - attr :protocol - attr :raw_body - - attr_accessor :web_service_name - attr_accessor :public_method_name - attr_accessor :content_type - - def initialize(protocol, raw_body, web_service_name, public_method_name, content_type, options={}) - super(options) - @protocol = protocol - @raw_body = raw_body - @web_service_name = web_service_name - @public_method_name = public_method_name - @content_type = content_type - end - - def unmarshal - @protocol.unmarshal_request(self) - end - - def marshal(return_value) - @protocol.marshal_response(self, return_value) - end - end - - class ProtocolResponse < AbstractProtocolMessage # :nodoc: - attr :protocol - attr :raw_body - - attr_accessor :content_type - - def initialize(protocol, raw_body, content_type, options={}) - super(options) - @protocol = protocol - @raw_body = raw_body - @content_type = content_type - end - end - end -end diff --git a/actionservice/lib/action_service/protocol/registry.rb b/actionservice/lib/action_service/protocol/registry.rb deleted file mode 100644 index e06361f916..0000000000 --- a/actionservice/lib/action_service/protocol/registry.rb +++ /dev/null @@ -1,55 +0,0 @@ -module ActionService # :nodoc: - module Protocol # :nodoc: - HeaderAndBody = :header_and_body - BodyOnly = :body_only - - module Registry # :nodoc: - def self.append_features(base) # :nodoc: - super - base.extend(ClassMethods) - base.send(:include, ActionService::Protocol::Registry::InstanceMethods) - end - - module ClassMethods # :nodoc: - def register_protocol(type, klass) # :nodoc: - case type - when HeaderAndBody - write_inheritable_array("header_and_body_protocols", [klass]) - when BodyOnly - write_inheritable_array("body_only_protocols", [klass]) - else - raise(ProtocolError, "unknown protocol type #{type}") - end - end - end - - module InstanceMethods # :nodoc: - private - def probe_request_protocol(action_pack_request) - (header_and_body_protocols + body_only_protocols).each do |protocol| - protocol_request = protocol.create_protocol_request(self.class, action_pack_request) - return protocol_request if protocol_request - end - raise(ProtocolError, "unsupported request message format") - end - - def probe_protocol_client(api, protocol_name, endpoint_uri, options) - (header_and_body_protocols + body_only_protocols).each do |protocol| - protocol_client = protocol.create_protocol_client(api, protocol_name, endpoint_uri, options) - return protocol_client if protocol_client - end - raise(ProtocolError, "unsupported client protocol :#{protocol_name}") - end - - def header_and_body_protocols - self.class.read_inheritable_attribute("header_and_body_protocols") || [] - end - - def body_only_protocols - self.class.read_inheritable_attribute("body_only_protocols") || [] - end - end - - end - end -end diff --git a/actionservice/lib/action_service/protocol/soap.rb b/actionservice/lib/action_service/protocol/soap.rb deleted file mode 100644 index 993e174e52..0000000000 --- a/actionservice/lib/action_service/protocol/soap.rb +++ /dev/null @@ -1,484 +0,0 @@ -require 'soap/processor' -require 'soap/mapping' -require 'soap/rpc/element' -require 'xsd/datatypes' -require 'xsd/ns' -require 'singleton' - -module ActionService # :nodoc: - module Protocol # :nodoc: - module Soap # :nodoc: - class ProtocolError < ActionService::ActionServiceError # :nodoc: - end - - def self.append_features(base) # :nodoc: - super - base.register_protocol(HeaderAndBody, SoapProtocol) - base.extend(ClassMethods) - base.wsdl_service_name('ActionService') - end - - module ClassMethods - # Specifies the WSDL service name to use when generating WSDL. Highly - # recommended that you set this value, or code generators may generate - # classes with very generic names. - # - # === Example - # class MyController < ActionController::Base - # wsdl_service_name 'MyService' - # end - def wsdl_service_name(name) - write_inheritable_attribute("soap_mapper", SoapMapper.new("urn:#{name}")) - end - - def soap_mapper # :nodoc: - read_inheritable_attribute("soap_mapper") - end - end - - class SoapProtocol < AbstractProtocol # :nodoc: - attr :mapper - - def initialize(mapper) - @mapper = mapper - end - - def self.create_protocol_request(container_class, action_pack_request) - soap_action = extract_soap_action(action_pack_request) - return nil unless soap_action - service_name = action_pack_request.parameters['action'] - public_method_name = soap_action.gsub(/^[\/]+/, '').split(/[\/]+/)[-1] - content_type = action_pack_request.env['HTTP_CONTENT_TYPE'] - content_type ||= 'text/xml' - protocol = SoapProtocol.new(container_class.soap_mapper) - ProtocolRequest.new(protocol, - action_pack_request.raw_post, - service_name.to_sym, - public_method_name, - content_type) - end - - def self.create_protocol_client(api, protocol_name, endpoint_uri, options) - return nil unless protocol_name.to_s.downcase.to_sym == :soap - ActionService::Client::Soap.new(api, endpoint_uri, options) - end - - def unmarshal_request(protocol_request) - unmarshal = lambda do - envelope = SOAP::Processor.unmarshal(protocol_request.raw_body) - request = envelope.body.request - values = request.collect{|k, v| request[k]} - soap_to_ruby_array(values) - end - signature = protocol_request.signature - if signature - map_signature_types(signature) - values = unmarshal.call - signature = signature.map{|x|mapper.lookup(x).ruby_klass} - protocol_request.check_parameter_types(values, signature) - values - else - if protocol_request.checked? - [] - else - unmarshal.call - end - end - end - - def marshal_response(protocol_request, return_value) - marshal = lambda do |signature| - mapping = mapper.lookup(signature[0]) - return_value = fixup_array_types(mapping, return_value) - signature = signature.map{|x|mapper.lookup(x).ruby_klass} - protocol_request.check_parameter_types([return_value], signature) - param_def = [['retval', 'return', mapping.registry_mapping]] - [param_def, ruby_to_soap(return_value)] - end - signature = protocol_request.return_signature - param_def = nil - if signature - param_def, return_value = marshal.call(signature) - else - if protocol_request.checked? - param_def, return_value = nil, nil - else - param_def, return_value = marshal.call([return_value.class]) - end - end - qname = XSD::QName.new(mapper.custom_namespace, - protocol_request.public_method_name) - response = SOAP::RPC::SOAPMethodResponse.new(qname, param_def) - response.retval = return_value unless return_value.nil? - ProtocolResponse.new(self, create_response(response), 'text/xml') - end - - def marshal_exception(exc) - ProtocolResponse.new(self, create_exception_response(exc), 'text/xml') - end - - private - def self.extract_soap_action(request) - return nil unless request.method == :post - content_type = request.env['HTTP_CONTENT_TYPE'] || 'text/xml' - return nil unless content_type - soap_action = request.env['HTTP_SOAPACTION'] - return nil unless soap_action - soap_action.gsub!(/^"/, '') - soap_action.gsub!(/"$/, '') - soap_action.strip! - return nil if soap_action.empty? - soap_action - end - - def fixup_array_types(mapping, obj) - mapping.each_attribute do |name, type, attr_mapping| - if attr_mapping.custom_type? - attr_obj = obj.send(name) - new_obj = fixup_array_types(attr_mapping, attr_obj) - obj.send("#{name}=", new_obj) unless new_obj.equal?(attr_obj) - end - end - if mapping.is_a?(SoapArrayMapping) - obj = mapping.ruby_klass.new(obj) - # man, this is going to be slow for big arrays :( - (1..obj.size).each do |i| - i -= 1 - obj[i] = fixup_array_types(mapping.element_mapping, obj[i]) - end - else - if !mapping.generated_klass.nil? && mapping.generated_klass.respond_to?(:members) - # have to map the publically visible structure of the class - new_obj = mapping.generated_klass.new - mapping.generated_klass.members.each do |name, klass| - new_obj.send("#{name}=", obj.send(name)) - end - obj = new_obj - end - end - obj - end - - def map_signature_types(types) - types.collect{|type| mapper.map(type)} - end - - def create_response(body) - header = SOAP::SOAPHeader.new - body = SOAP::SOAPBody.new(body) - envelope = SOAP::SOAPEnvelope.new(header, body) - SOAP::Processor.marshal(envelope) - end - - def create_exception_response(exc) - detail = SOAP::Mapping::SOAPException.new(exc) - body = SOAP::SOAPFault.new( - SOAP::SOAPString.new('Server'), - SOAP::SOAPString.new(exc.to_s), - SOAP::SOAPString.new(self.class.name), - SOAP::Mapping.obj2soap(detail)) - create_response(body) - end - - def ruby_to_soap(obj) - SOAP::Mapping.obj2soap(obj, mapper.registry) - end - - def soap_to_ruby(obj) - SOAP::Mapping.soap2obj(obj, mapper.registry) - end - - def soap_to_ruby_array(array) - array.map{|x| soap_to_ruby(x)} - end - end - - class SoapMapper # :nodoc: - attr :registry - attr :custom_namespace - attr :custom_types - - def initialize(custom_namespace) - @custom_namespace = custom_namespace - @registry = SOAP::Mapping::Registry.new - @klass2map = {} - @custom_types = {} - @ar2klass = {} - end - - def lookup(klass) - lookup_klass = klass.is_a?(Array) ? klass[0] : klass - generated_klass = nil - unless lookup_klass.respond_to?(:ancestors) - raise(ProtocolError, "expected parameter type definition to be a Class") - end - if lookup_klass.ancestors.include?(ActiveRecord::Base) - generated_klass = @ar2klass.has_key?(klass) ? @ar2klass[klass] : nil - klass = generated_klass if generated_klass - end - return @klass2map[klass] if @klass2map.has_key?(klass) - - custom_type = false - - ruby_klass = select_class(lookup_klass) - generated_klass = @ar2klass[lookup_klass] if @ar2klass.has_key?(lookup_klass) - type_name = ruby_klass.name - - # Array signatures generate a double-mapping and require generation - # of an Array subclass to represent the mapping in the SOAP - # registry - array_klass = nil - if klass.is_a?(Array) - array_klass = Class.new(Array) do - module_eval <<-END - def self.name - "#{type_name}Array" - end - END - end - end - - mapping = @registry.find_mapped_soap_class(ruby_klass) rescue nil - unless mapping - # Custom structured type, generate a mapping - info = { :type => XSD::QName.new(@custom_namespace, type_name) } - @registry.add(ruby_klass, - SOAP::SOAPStruct, - SOAP::Mapping::Registry::TypedStructFactory, - info) - mapping = ensure_mapped(ruby_klass) - custom_type = true - end - - array_mapping = nil - if array_klass - # Typed array always requires a custom type. The info of the array - # is the info of its element type (in mapping[2]), falling back - # to SOAP base types. - info = mapping[2] - info ||= {} - info[:type] ||= soap_base_type_qname(mapping[0]) - @registry.add(array_klass, - SOAP::SOAPArray, - SOAP::Mapping::Registry::TypedArrayFactory, - info) - array_mapping = ensure_mapped(array_klass) - end - - if array_mapping - @klass2map[ruby_klass] = SoapMapping.new(self, - type_name, - ruby_klass, - generated_klass, - mapping[0], - mapping, - custom_type) - @klass2map[klass] = SoapArrayMapping.new(self, - type_name, - array_klass, - array_mapping[0], - array_mapping, - @klass2map[ruby_klass]) - @custom_types[klass] = @klass2map[klass] - @custom_types[ruby_klass] = @klass2map[ruby_klass] if custom_type - else - @klass2map[klass] = SoapMapping.new(self, - type_name, - ruby_klass, - generated_klass, - mapping[0], - mapping, - custom_type) - @custom_types[klass] = @klass2map[klass] if custom_type - end - - @klass2map[klass] - end - alias :map :lookup - - def map_container_services(container, &block) - dispatching_mode = container.web_service_dispatching_mode - web_services = nil - case dispatching_mode - when :direct - api = container.class.web_service_api - if container.respond_to?(:controller_class_name) - web_service_name = container.controller_class_name.sub(/Controller$/, '').underscore - else - web_service_name = container.class.name.demodulize.underscore - end - web_services = { web_service_name => api } - when :delegated - web_services = {} - container.class.web_services.each do |web_service_name, web_service_info| - begin - object = container.web_service_object(web_service_name) - rescue Exception => e - raise(ProtocolError, "failed to retrieve web service object for web service '#{web_service_name}': #{e.message}") - end - web_services[web_service_name] = object.class.web_service_api - end - end - web_services.each do |web_service_name, api| - if api.nil? - raise(ProtocolError, "no web service API set while in :#{dispatching_mode} mode") - end - map_api(api) do |api_methods| - yield web_service_name, api, api_methods if block_given? - end - end - end - - def map_api(api, &block) - lookup_proc = lambda do |klass| - mapping = lookup(klass) - custom_mapping = nil - if mapping.respond_to?(:element_mapping) - custom_mapping = mapping.element_mapping - else - custom_mapping = mapping - end - if custom_mapping && custom_mapping.custom_type? - # What gives? This is required so that structure types - # referenced only by structures (and not signatures) still - # have a custom type mapping in the registry (needed for WSDL - # generation). - custom_mapping.each_attribute{} - end - mapping - end - api_methods = block.nil?? nil : {} - api.api_methods.each do |method_name, method_info| - expects = method_info[:expects] - expects_signature = nil - if expects - expects_signature = block ? [] : nil - expects.each do |klass| - lookup_klass = nil - if klass.is_a?(Hash) - lookup_klass = lookup_proc.call(klass.values[0]) - expects_signature << {klass.keys[0]=>lookup_klass} if block - else - lookup_klass = lookup_proc.call(klass) - expects_signature << lookup_klass if block - end - end - end - returns = method_info[:returns] - returns_signature = returns ? returns.map{|klass| lookup_proc.call(klass)} : nil - if block - api_methods[method_name] = { - :expects => expects_signature, - :returns => returns_signature - } - end - end - yield api_methods if block - end - - private - def select_class(klass) - return Integer if klass == Fixnum - if klass.ancestors.include?(ActiveRecord::Base) - new_klass = Class.new(ActionService::Struct) - new_klass.class_eval <<-EOS - def self.name - "#{klass.name}" - end - EOS - klass.columns.each do |column| - next if column.klass.nil? - new_klass.send(:member, column.name.to_sym, column.klass) - end - @ar2klass[klass] = new_klass - return new_klass - end - klass - end - - def ensure_mapped(klass) - mapping = @registry.find_mapped_soap_class(klass) rescue nil - raise(ProtocolError, "failed to register #{klass.name}") unless mapping - mapping - end - - def soap_base_type_qname(base_type) - xsd_type = base_type.ancestors.find{|c| c.const_defined? 'Type'} - xsd_type ? xsd_type.const_get('Type') : XSD::XSDAnySimpleType::Type - end - end - - class SoapMapping # :nodoc: - attr :ruby_klass - attr :generated_klass - attr :soap_klass - attr :registry_mapping - - def initialize(mapper, type_name, ruby_klass, generated_klass, soap_klass, registry_mapping, - custom_type=false) - @mapper = mapper - @type_name = type_name - @ruby_klass = ruby_klass - @generated_klass = generated_klass - @soap_klass = soap_klass - @registry_mapping = registry_mapping - @custom_type = custom_type - end - - def type_name - @type_name - end - - def custom_type? - @custom_type - end - - def qualified_type_name - name = type_name - if custom_type? - "typens:#{name}" - else - xsd_type_for(@soap_klass) - end - end - - def each_attribute(&block) - if @ruby_klass.respond_to?(:members) - @ruby_klass.members.each do |name, klass| - name = name.to_s - mapping = @mapper.lookup(klass) - yield name, mapping.qualified_type_name, mapping - end - end - end - - def is_xsd_type?(klass) - klass.ancestors.include?(XSD::NSDBase) - end - - def xsd_type_for(klass) - ns = XSD::NS.new - ns.assign(XSD::Namespace, SOAP::XSDNamespaceTag) - xsd_klass = klass.ancestors.find{|c| c.const_defined?('Type')} - return ns.name(XSD::AnyTypeName) unless xsd_klass - ns.name(xsd_klass.const_get('Type')) - end - end - - class SoapArrayMapping < SoapMapping # :nodoc: - attr :element_mapping - - def initialize(mapper, type_name, ruby_klass, soap_klass, registry_mapping, element_mapping) - super(mapper, type_name, ruby_klass, nil, soap_klass, registry_mapping, true) - @element_mapping = element_mapping - end - - def type_name - super + "Array" - end - - def each_attribute(&block); end - end - end - end -end diff --git a/actionservice/lib/action_service/protocol/xmlrpc.rb b/actionservice/lib/action_service/protocol/xmlrpc.rb deleted file mode 100644 index 32b8e00327..0000000000 --- a/actionservice/lib/action_service/protocol/xmlrpc.rb +++ /dev/null @@ -1,183 +0,0 @@ -require 'xmlrpc/parser' -require 'xmlrpc/create' -require 'xmlrpc/config' -require 'xmlrpc/utils' -require 'singleton' - -module XMLRPC # :nodoc: - class XmlRpcHelper # :nodoc: - include Singleton - include ParserWriterChooseMixin - - def parse_method_call(message) - parser().parseMethodCall(message) - end - - def create_method_response(successful, return_value) - create().methodResponse(successful, return_value) - end - end -end - -module ActionService # :nodoc: - module Protocol # :nodoc: - module XmlRpc # :nodoc: - def self.append_features(base) # :nodoc: - super - base.register_protocol(BodyOnly, XmlRpcProtocol) - end - - class XmlRpcProtocol < AbstractProtocol # :nodoc: - def self.create_protocol_request(container_class, action_pack_request) - helper = XMLRPC::XmlRpcHelper.instance - service_name = action_pack_request.parameters['action'] - methodname, params = helper.parse_method_call(action_pack_request.raw_post) - methodname.gsub!(/^[^\.]+\./, '') unless methodname =~ /^system\./ # XXX - protocol = XmlRpcProtocol.new(container_class) - content_type = action_pack_request.env['HTTP_CONTENT_TYPE'] - content_type ||= 'text/xml' - request = ProtocolRequest.new(protocol, - action_pack_request.raw_post, - service_name.to_sym, - methodname, - content_type, - :xmlrpc_values => params) - request - rescue - nil - end - - def self.create_protocol_client(api, protocol_name, endpoint_uri, options) - return nil unless protocol_name.to_s.downcase.to_sym == :xmlrpc - ActionService::Client::XmlRpc.new(api, endpoint_uri, options) - end - - def initialize(container_class) - super(container_class) - container_class.write_inheritable_hash('default_system_methods', XmlRpcProtocol => method(:xmlrpc_default_system_handler)) - end - - def unmarshal_request(protocol_request) - values = protocol_request.options[:xmlrpc_values] - signature = protocol_request.signature - if signature - values = self.class.transform_incoming_method_params(self.class.transform_array_types(signature), values) - protocol_request.check_parameter_types(values, check_array_types(signature)) - values - else - protocol_request.checked? ? [] : values - end - end - - def marshal_response(protocol_request, return_value) - helper = XMLRPC::XmlRpcHelper.instance - signature = protocol_request.return_signature - if signature - protocol_request.check_parameter_types([return_value], check_array_types(signature)) - return_value = self.class.transform_return_value(self.class.transform_array_types(signature), return_value) - raw_response = helper.create_method_response(true, return_value) - else - # XML-RPC doesn't have the concept of a void method, nor does it - # support a nil return value, so return true if we would have returned - # nil - if protocol_request.checked? - raw_response = helper.create_method_response(true, true) - else - return_value = true if return_value.nil? - raw_response = helper.create_method_response(true, return_value) - end - end - ProtocolResponse.new(self, raw_response, 'text/xml') - end - - def marshal_exception(exception) - helper = XMLRPC::XmlRpcHelper.instance - exception = XMLRPC::FaultException.new(1, exception.message) - raw_response = helper.create_method_response(false, exception) - ProtocolResponse.new(self, raw_response, 'text/xml') - end - - class << self - def transform_incoming_method_params(signature, params) - (1..signature.size).each do |i| - i -= 1 - params[i] = xmlrpc_to_ruby(params[i], signature[i]) - end - params - end - - def transform_return_value(signature, return_value) - ruby_to_xmlrpc(return_value, signature[0]) - end - - def ruby_to_xmlrpc(param, param_class) - if param_class.is_a?(XmlRpcArray) - param.map{|p| ruby_to_xmlrpc(p, param_class.klass)} - elsif param_class.ancestors.include?(ActiveRecord::Base) - param.instance_variable_get('@attributes') - elsif param_class.ancestors.include?(ActionService::Struct) - struct = {} - param_class.members.each do |name, klass| - value = param.send(name) - next if value.nil? - struct[name.to_s] = value - end - struct - else - param - end - end - - def xmlrpc_to_ruby(param, param_class) - if param_class.is_a?(XmlRpcArray) - param.map{|p| xmlrpc_to_ruby(p, param_class.klass)} - elsif param_class.ancestors.include?(ActiveRecord::Base) - raise(ProtocolError, "incoming ActiveRecord::Base types are not allowed") - elsif param_class.ancestors.include?(ActionService::Struct) - unless param.is_a?(Hash) - raise(ProtocolError, "expected parameter to be a Hash") - end - new_param = param_class.new - param_class.members.each do |name, klass| - new_param.send('%s=' % name.to_s, param[name.to_s]) - end - new_param - else - param - end - end - - def transform_array_types(signature) - signature.map{|x| x.is_a?(Array) ? XmlRpcArray.new(x[0]) : x} - end - end - - private - def xmlrpc_default_system_handler(name, service_class, *args) - case name - when 'system.listMethods' - methods = [] - api = service_class.web_service_api - api.api_methods.each do |name, info| - methods << api.public_api_method_name(name) - end - methods.sort - else - throw :try_default - end - end - - def check_array_types(signature) - signature.map{|x| x.is_a?(Array) ? Array : x} - end - - class XmlRpcArray - attr :klass - def initialize(klass) - @klass = klass - end - end - end - end - end -end diff --git a/actionservice/lib/action_service/router.rb b/actionservice/lib/action_service/router.rb deleted file mode 100644 index 16f0ae4463..0000000000 --- a/actionservice/lib/action_service/router.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'action_service/router/action_controller' -require 'action_service/router/wsdl' diff --git a/actionservice/lib/action_service/router/action_controller.rb b/actionservice/lib/action_service/router/action_controller.rb deleted file mode 100644 index ca9c94e35c..0000000000 --- a/actionservice/lib/action_service/router/action_controller.rb +++ /dev/null @@ -1,99 +0,0 @@ -module ActionService # :nodoc: - module Router # :nodoc: - module ActionController # :nodoc: - def self.append_features(base) # :nodoc: - base.add_web_service_api_callback do |container_class, api| - if container_class.web_service_dispatching_mode == :direct - container_class.class_eval <<-EOS - def api - process_action_service_request - end - EOS - end - end - base.add_web_service_definition_callback do |klass, name, info| - if klass.web_service_dispatching_mode == :delegated - klass.class_eval <<-EOS - def #{name} - process_action_service_request - end - EOS - end - end - base.send(:include, ActionService::Router::ActionController::InstanceMethods) - end - - module InstanceMethods # :nodoc: - private - def process_action_service_request - protocol_request = nil - begin - begin - protocol_request = probe_request_protocol(self.request) - rescue Exception => e - unless logger.nil? - logger.error "Invalid request: #{e.message}" - logger.error self.request.raw_post - end - raise - end - if protocol_request - log_request(protocol_request) - protocol_response = dispatch_web_service_request(protocol_request) - log_response(protocol_response) - response_options = { - :type => protocol_response.content_type, - :disposition => 'inline' - } - send_data(protocol_response.raw_body, response_options) - else - logger.fatal "Invalid Action Service service or method requested" unless logger.nil? - render_text 'Internal protocol error', "500 Invalid service/method" - end - rescue Exception => e - log_error e unless logger.nil? - exc_response = nil - case web_service_dispatching_mode - when :direct - if self.class.web_service_exception_reporting - exc_response = protocol_request.protocol.marshal_exception(e) - end - when :delegated - web_service = web_service_object(protocol_request.service_name) rescue nil - if web_service && web_service.class.web_service_exception_reporting - exc_response = protocol_request.protocol.marshal_exception(e) rescue nil - end - end - if exc_response - response_options = { - :type => exc_response.content_type, - :disposition => 'inline' - } - log_response exc_response - send_data(exc_response.raw_body, response_options) - else - render_text 'Internal protocol error', "500 #{e.message}" - end - end - end - - def log_request(protocol_request) - unless logger.nil? - web_service_name = protocol_request.web_service_name - method_name = protocol_request.public_method_name - logger.info "\nProcessing Action Service Request: #{web_service_name}##{method_name}" - logger.info "Raw Request Body:" - logger.info protocol_request.raw_body - end - end - - def log_response(protocol_response) - unless logger.nil? - logger.info "\nRaw Response Body:" - logger.info protocol_response.raw_body - end - end - end - end - end -end diff --git a/actionservice/lib/action_service/router/wsdl.rb b/actionservice/lib/action_service/router/wsdl.rb deleted file mode 100644 index c2f29da0b0..0000000000 --- a/actionservice/lib/action_service/router/wsdl.rb +++ /dev/null @@ -1,210 +0,0 @@ -module ActionService # :nodoc: - module Router # :nodoc: - module Wsdl # :nodoc: - def self.append_features(base) # :nodoc: - base.class_eval do - class << self - alias_method :inherited_without_wsdl, :inherited - end - end - base.extend(ClassMethods) - end - - module ClassMethods - def inherited(child) - inherited_without_wsdl(child) - child.send(:include, ActionService::Router::Wsdl::InstanceMethods) - end - end - - module InstanceMethods # :nodoc: - XsdNs = 'http://www.w3.org/2001/XMLSchema' - WsdlNs = 'http://schemas.xmlsoap.org/wsdl/' - SoapNs = 'http://schemas.xmlsoap.org/wsdl/soap/' - SoapEncodingNs = 'http://schemas.xmlsoap.org/soap/encoding/' - SoapHttpTransport = 'http://schemas.xmlsoap.org/soap/http' - - def wsdl - case @request.method - when :get - begin - host_name = @request.env['HTTP_HOST']||@request.env['SERVER_NAME'] - uri = "http://#{host_name}/#{controller_name}/" - soap_action_base = "/#{controller_name}" - xml = to_wsdl(self, uri, soap_action_base) - send_data(xml, :type => 'text/xml', :disposition => 'inline') - rescue Exception => e - log_error e unless logger.nil? - render_text('', "500 #{e.message}") - end - when :post - render_text('', "500 POST not supported") - end - end - - private - def to_wsdl(container, uri, soap_action_base) - wsdl = "" - - web_service_dispatching_mode = container.web_service_dispatching_mode - mapper = container.class.soap_mapper - namespace = mapper.custom_namespace - wsdl_service_name = namespace.split(/:/)[1] - - services = {} - mapper.map_container_services(container) do |name, api, api_methods| - services[name] = [api, api_methods] - end - custom_types = mapper.custom_types - - - xm = Builder::XmlMarkup.new(:target => wsdl, :indent => 2) - xm.instruct! - - xm.definitions('name' => wsdl_service_name, - 'targetNamespace' => namespace, - 'xmlns:typens' => namespace, - 'xmlns:xsd' => XsdNs, - 'xmlns:soap' => SoapNs, - 'xmlns:soapenc' => SoapEncodingNs, - 'xmlns:wsdl' => WsdlNs, - 'xmlns' => WsdlNs) do - - # Custom type XSD generation - if custom_types.size > 0 - xm.types do - xm.xsd(:schema, 'xmlns' => XsdNs, 'targetNamespace' => namespace) do - custom_types.each do |klass, mapping| - case - when mapping.is_a?(ActionService::Protocol::Soap::SoapArrayMapping) - xm.xsd(:complexType, 'name' => mapping.type_name) do - xm.xsd(:complexContent) do - xm.xsd(:restriction, 'base' => 'soapenc:Array') do - xm.xsd(:attribute, 'ref' => 'soapenc:arrayType', - 'wsdl:arrayType' => mapping.element_mapping.qualified_type_name + '[]') - end - end - end - when mapping.is_a?(ActionService::Protocol::Soap::SoapMapping) - xm.xsd(:complexType, 'name' => mapping.type_name) do - xm.xsd(:all) do - mapping.each_attribute do |name, type_name| - xm.xsd(:element, 'name' => name, 'type' => type_name) - end - end - end - else - raise(WsdlError, "unsupported mapping type #{mapping.class.name}") - end - end - end - end - end - - services.each do |service_name, service_values| - service_api, api_methods = service_values - # Parameter list message definitions - api_methods.each do |method_name, method_signature| - gen = lambda do |msg_name, direction| - xm.message('name' => msg_name) do - sym = nil - if direction == :out - if method_signature[:returns] - xm.part('name' => 'return', 'type' => method_signature[:returns][0].qualified_type_name) - end - else - mapping_list = method_signature[:expects] - i = 1 - mapping_list.each do |mapping| - if mapping.is_a?(Hash) - param_name = mapping.keys.shift - mapping = mapping.values.shift - else - param_name = "param#{i}" - end - xm.part('name' => param_name, 'type' => mapping.qualified_type_name) - i += 1 - end if mapping_list - end - end - end - public_name = service_api.public_api_method_name(method_name) - gen.call(public_name, :in) - gen.call("#{public_name}Response", :out) - end - - # Declare the port - port_name = port_name_for(wsdl_service_name, service_name) - xm.portType('name' => port_name) do - api_methods.each do |method_name, method_signature| - public_name = service_api.public_api_method_name(method_name) - xm.operation('name' => public_name) do - xm.input('message' => "typens:#{public_name}") - xm.output('message' => "typens:#{public_name}Response") - end - end - end - - # Bind the port to SOAP - binding_name = binding_name_for(wsdl_service_name, service_name) - xm.binding('name' => binding_name, 'type' => "typens:#{port_name}") do - xm.soap(:binding, 'style' => 'rpc', 'transport' => SoapHttpTransport) - api_methods.each do |method_name, method_signature| - public_name = service_api.public_api_method_name(method_name) - xm.operation('name' => public_name) do - case web_service_dispatching_mode - when :direct - soap_action = soap_action_base + "/api/" + public_name - when :delegated - soap_action = soap_action_base \ - + "/" + service_name.to_s \ - + "/" + public_name - end - xm.soap(:operation, 'soapAction' => soap_action) - xm.input do - xm.soap(:body, - 'use' => 'encoded', - 'namespace' => namespace, - 'encodingStyle' => SoapEncodingNs) - end - xm.output do - xm.soap(:body, - 'use' => 'encoded', - 'namespace' => namespace, - 'encodingStyle' => SoapEncodingNs) - end - end - end - end - end - - # Define the service - xm.service('name' => "#{wsdl_service_name}Service") do - services.each do |service_name, service_values| - port_name = port_name_for(wsdl_service_name, service_name) - binding_name = binding_name_for(wsdl_service_name, service_name) - case web_service_dispatching_mode - when :direct - binding_target = 'api' - when :delegated - binding_target = service_name.to_s - end - xm.port('name' => port_name, 'binding' => "typens:#{binding_name}") do - xm.soap(:address, 'location' => "#{uri}#{binding_target}") - end - end - end - end - end - - def port_name_for(wsdl_service_name, service_name) - "#{wsdl_service_name}#{service_name.to_s.camelize}Port" - end - - def binding_name_for(wsdl_service_name, service_name) - "#{wsdl_service_name}#{service_name.to_s.camelize}Binding" - end - end - end - end -end diff --git a/actionservice/lib/action_service/struct.rb b/actionservice/lib/action_service/struct.rb deleted file mode 100644 index 142127b052..0000000000 --- a/actionservice/lib/action_service/struct.rb +++ /dev/null @@ -1,55 +0,0 @@ -module ActionService - # To send structured types across the wire, derive from ActionService::Struct, - # and use +member+ to declare structure members. - # - # ActionService::Struct should be used in method signatures when you want to accept or return - # structured types that have no Active Record model class representations, or you don't - # want to expose your entire Active Record model to remote callers. - # - # === Example - # - # class Person < ActionService::Struct - # member :id, :int - # member :firstnames, [:string] - # member :lastname, :string - # member :email, :string - # end - # person = Person.new(:id => 5, :firstname => 'john', :lastname => 'doe') - # - # Active Record model classes are already implicitly supported for method - # return signatures. A structure containing its columns as members will be - # automatically generated if its present in a signature. - class Struct - - # If a Hash is given as argument to an ActionService::Struct constructor, - # it can contain initial values for the structure member. - def initialize(values={}) - if values.is_a?(Hash) - values.map{|k,v| send('%s=' % k.to_s, v)} - end - end - - # The member with the given name - def [](name) - send(name.to_s) - end - - class << self - include ActionService::Signature - - # Creates a structure member with the specified +name+ and +type+. Generates - # accessor methods for reading and writing the member value. - def member(name, type) - write_inheritable_hash("struct_members", name => signature_parameter_class(type)) - class_eval <<-END - def #{name}; @#{name}; end - def #{name}=(value); @#{name} = value; end - END - end - - def members # :nodoc: - read_inheritable_attribute("struct_members") || {} - end - end - end -end diff --git a/actionservice/lib/action_service/support/class_inheritable_options.rb b/actionservice/lib/action_service/support/class_inheritable_options.rb deleted file mode 100644 index 4d1c2ed471..0000000000 --- a/actionservice/lib/action_service/support/class_inheritable_options.rb +++ /dev/null @@ -1,26 +0,0 @@ -class Class # :nodoc: - def class_inheritable_option(sym, default_value=nil) - write_inheritable_attribute sym, default_value - class_eval <<-EOS - def self.#{sym}(value=nil) - if !value.nil? - write_inheritable_attribute(:#{sym}, value) - else - read_inheritable_attribute(:#{sym}) - end - end - - def self.#{sym}=(value) - write_inheritable_attribute(:#{sym}, value) - end - - def #{sym} - self.class.#{sym} - end - - def #{sym}=(value) - self.class.#{sym} = value - end - EOS - end -end diff --git a/actionservice/lib/action_service/support/signature.rb b/actionservice/lib/action_service/support/signature.rb deleted file mode 100644 index 946118c523..0000000000 --- a/actionservice/lib/action_service/support/signature.rb +++ /dev/null @@ -1,100 +0,0 @@ -module ActionService # :nodoc: - # Action Service parameter specifiers may contain symbols or strings - # instead of Class objects, for a limited set of base types. - # - # This provides an unambiguous way to specify that a given parameter - # contains an integer or boolean value, for example. - # - # The allowed set of symbol/string aliases: - # - # [:int] any integer value - # [:float] any floating point value - # [:string] any string value - # [:bool] any boolean value - # [:time] any value containing both date and time - # [:date] any value containing only a date - module Signature - class SignatureError < StandardError # :nodoc: - end - - private - def canonical_signature(params) - return nil if params.nil? - params.map do |param| - klass = signature_parameter_class(param) - if param.is_a?(Hash) - param[param.keys[0]] = klass - param - else - klass - end - end - end - - def signature_parameter_class(param) - param = param.is_a?(Hash) ? param.values[0] : param - is_array = param.is_a?(Array) - param = is_array ? param[0] : param - param = param.is_a?(String) ? param.to_sym : param - param = param.is_a?(Symbol) ? signature_ruby_class(param) : param - is_array ? [param] : param - end - - - def canonical_signature_base_type(base_type) - base_type = base_type.to_sym - case base_type - when :int, :integer, :fixnum, :bignum - :int - when :string, :base64 - :string - when :bool, :boolean - :bool - when :float, :double - :float - when :time, :datetime, :timestamp - :time - when :date - :date - else - raise(SignatureError, ":#{base_type} is not an ActionService base type") - end - end - - def signature_ruby_class(base_type) - case canonical_signature_base_type(base_type) - when :int - Integer - when :string - String - when :bool - TrueClass - when :float - Float - when :time - Time - when :date - Date - end - end - - def signature_base_type(ruby_class) - case ruby_class - when Bignum, Integer, Fixnum - :int - when String - :string - when TrueClass, FalseClass - :bool - when Float, Numeric, Precision - :float - when Time, DateTime - :time - when Date - :date - else - raise(SignatureError, "#{ruby_class.name} is not an ActionService base type") - end - end - end -end diff --git a/actionservice/setup.rb b/actionservice/setup.rb deleted file mode 100644 index 0807023db2..0000000000 --- a/actionservice/setup.rb +++ /dev/null @@ -1,1360 +0,0 @@ -# -# setup.rb -# -# Copyright (c) 2000-2004 Minero Aoki -# -# This program is free software. -# You can distribute/modify this program under the terms of -# the GNU LGPL, Lesser General Public License version 2.1. -# - -unless Enumerable.method_defined?(:map) # Ruby 1.4.6 - module Enumerable - alias map collect - end -end - -unless File.respond_to?(:read) # Ruby 1.6 - def File.read(fname) - open(fname) {|f| - return f.read - } - end -end - -def File.binread(fname) - open(fname, 'rb') {|f| - return f.read - } -end - -# for corrupted windows stat(2) -def File.dir?(path) - File.directory?((path[-1,1] == '/') ? path : path + '/') -end - - -class SetupError < StandardError; end - -def setup_rb_error(msg) - raise SetupError, msg -end - -# -# Config -# - -if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg } - ARGV.delete(arg) - require arg.split(/=/, 2)[1] - $".push 'rbconfig.rb' -else - require 'rbconfig' -end - -def multipackage_install? - FileTest.directory?(File.dirname($0) + '/packages') -end - - -class ConfigItem - def initialize(name, template, default, desc) - @name = name.freeze - @template = template - @value = default - @default = default.dup.freeze - @description = desc - end - - attr_reader :name - attr_reader :description - - attr_accessor :default - alias help_default default - - def help_opt - "--#{@name}=#{@template}" - end - - def value - @value - end - - def eval(table) - @value.gsub(%r<\$([^/]+)>) { table[$1] } - end - - def set(val) - @value = check(val) - end - - private - - def check(val) - setup_rb_error "config: --#{name} requires argument" unless val - val - end -end - -class BoolItem < ConfigItem - def config_type - 'bool' - end - - def help_opt - "--#{@name}" - end - - private - - def check(val) - return 'yes' unless val - unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ val - setup_rb_error "config: --#{@name} accepts only yes/no for argument" - end - (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no' - end -end - -class PathItem < ConfigItem - def config_type - 'path' - end - - private - - def check(path) - setup_rb_error "config: --#{@name} requires argument" unless path - path[0,1] == '$' ? path : File.expand_path(path) - end -end - -class ProgramItem < ConfigItem - def config_type - 'program' - end -end - -class SelectItem < ConfigItem - def initialize(name, template, default, desc) - super - @ok = template.split('/') - end - - def config_type - 'select' - end - - private - - def check(val) - unless @ok.include?(val.strip) - setup_rb_error "config: use --#{@name}=#{@template} (#{val})" - end - val.strip - end -end - -class PackageSelectionItem < ConfigItem - def initialize(name, template, default, help_default, desc) - super name, template, default, desc - @help_default = help_default - end - - attr_reader :help_default - - def config_type - 'package' - end - - private - - def check(val) - unless File.dir?("packages/#{val}") - setup_rb_error "config: no such package: #{val}" - end - val - end -end - -class ConfigTable_class - - def initialize(items) - @items = items - @table = {} - items.each do |i| - @table[i.name] = i - end - ALIASES.each do |ali, name| - @table[ali] = @table[name] - end - end - - include Enumerable - - def each(&block) - @items.each(&block) - end - - def key?(name) - @table.key?(name) - end - - def lookup(name) - @table[name] or raise ArgumentError, "no such config item: #{name}" - end - - def add(item) - @items.push item - @table[item.name] = item - end - - def remove(name) - item = lookup(name) - @items.delete_if {|i| i.name == name } - @table.delete_if {|name, i| i.name == name } - item - end - - def new - dup() - end - - def savefile - '.config' - end - - def load - begin - t = dup() - File.foreach(savefile()) do |line| - k, v = *line.split(/=/, 2) - t[k] = v.strip - end - t - rescue Errno::ENOENT - setup_rb_error $!.message + "#{File.basename($0)} config first" - end - end - - def save - @items.each {|i| i.value } - File.open(savefile(), 'w') {|f| - @items.each do |i| - f.printf "%s=%s\n", i.name, i.value if i.value - end - } - end - - def [](key) - lookup(key).eval(self) - end - - def []=(key, val) - lookup(key).set val - end - -end - -c = ::Config::CONFIG - -rubypath = c['bindir'] + '/' + c['ruby_install_name'] - -major = c['MAJOR'].to_i -minor = c['MINOR'].to_i -teeny = c['TEENY'].to_i -version = "#{major}.#{minor}" - -# ruby ver. >= 1.4.4? -newpath_p = ((major >= 2) or - ((major == 1) and - ((minor >= 5) or - ((minor == 4) and (teeny >= 4))))) - -if c['rubylibdir'] - # V < 1.6.3 - _stdruby = c['rubylibdir'] - _siteruby = c['sitedir'] - _siterubyver = c['sitelibdir'] - _siterubyverarch = c['sitearchdir'] -elsif newpath_p - # 1.4.4 <= V <= 1.6.3 - _stdruby = "$prefix/lib/ruby/#{version}" - _siteruby = c['sitedir'] - _siterubyver = "$siteruby/#{version}" - _siterubyverarch = "$siterubyver/#{c['arch']}" -else - # V < 1.4.4 - _stdruby = "$prefix/lib/ruby/#{version}" - _siteruby = "$prefix/lib/ruby/#{version}/site_ruby" - _siterubyver = _siteruby - _siterubyverarch = "$siterubyver/#{c['arch']}" -end -libdir = '-* dummy libdir *-' -stdruby = '-* dummy rubylibdir *-' -siteruby = '-* dummy site_ruby *-' -siterubyver = '-* dummy site_ruby version *-' -parameterize = lambda {|path| - path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')\ - .sub(/\A#{Regexp.quote(libdir)}/, '$libdir')\ - .sub(/\A#{Regexp.quote(stdruby)}/, '$stdruby')\ - .sub(/\A#{Regexp.quote(siteruby)}/, '$siteruby')\ - .sub(/\A#{Regexp.quote(siterubyver)}/, '$siterubyver') -} -libdir = parameterize.call(c['libdir']) -stdruby = parameterize.call(_stdruby) -siteruby = parameterize.call(_siteruby) -siterubyver = parameterize.call(_siterubyver) -siterubyverarch = parameterize.call(_siterubyverarch) - -if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } - makeprog = arg.sub(/'/, '').split(/=/, 2)[1] -else - makeprog = 'make' -end - -common_conf = [ - PathItem.new('prefix', 'path', c['prefix'], - 'path prefix of target environment'), - PathItem.new('bindir', 'path', parameterize.call(c['bindir']), - 'the directory for commands'), - PathItem.new('libdir', 'path', libdir, - 'the directory for libraries'), - PathItem.new('datadir', 'path', parameterize.call(c['datadir']), - 'the directory for shared data'), - PathItem.new('mandir', 'path', parameterize.call(c['mandir']), - 'the directory for man pages'), - PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']), - 'the directory for man pages'), - PathItem.new('stdruby', 'path', stdruby, - 'the directory for standard ruby libraries'), - PathItem.new('siteruby', 'path', siteruby, - 'the directory for version-independent aux ruby libraries'), - PathItem.new('siterubyver', 'path', siterubyver, - 'the directory for aux ruby libraries'), - PathItem.new('siterubyverarch', 'path', siterubyverarch, - 'the directory for aux ruby binaries'), - PathItem.new('rbdir', 'path', '$siterubyver', - 'the directory for ruby scripts'), - PathItem.new('sodir', 'path', '$siterubyverarch', - 'the directory for ruby extentions'), - PathItem.new('rubypath', 'path', rubypath, - 'the path to set to #! line'), - ProgramItem.new('rubyprog', 'name', rubypath, - 'the ruby program using for installation'), - ProgramItem.new('makeprog', 'name', makeprog, - 'the make program to compile ruby extentions'), - SelectItem.new('shebang', 'all/ruby/never', 'ruby', - 'shebang line (#!) editing mode'), - BoolItem.new('without-ext', 'yes/no', 'no', - 'does not compile/install ruby extentions') -] -class ConfigTable_class # open again - ALIASES = { - 'std-ruby' => 'stdruby', - 'site-ruby-common' => 'siteruby', # For backward compatibility - 'site-ruby' => 'siterubyver', # For backward compatibility - 'bin-dir' => 'bindir', - 'bin-dir' => 'bindir', - 'rb-dir' => 'rbdir', - 'so-dir' => 'sodir', - 'data-dir' => 'datadir', - 'ruby-path' => 'rubypath', - 'ruby-prog' => 'rubyprog', - 'ruby' => 'rubyprog', - 'make-prog' => 'makeprog', - 'make' => 'makeprog' - } -end -multipackage_conf = [ - PackageSelectionItem.new('with', 'name,name...', '', 'ALL', - 'package names that you want to install'), - PackageSelectionItem.new('without', 'name,name...', '', 'NONE', - 'package names that you do not want to install') -] -if multipackage_install? - ConfigTable = ConfigTable_class.new(common_conf + multipackage_conf) -else - ConfigTable = ConfigTable_class.new(common_conf) -end - - -module MetaConfigAPI - - def eval_file_ifexist(fname) - instance_eval File.read(fname), fname, 1 if File.file?(fname) - end - - def config_names - ConfigTable.map {|i| i.name } - end - - def config?(name) - ConfigTable.key?(name) - end - - def bool_config?(name) - ConfigTable.lookup(name).config_type == 'bool' - end - - def path_config?(name) - ConfigTable.lookup(name).config_type == 'path' - end - - def value_config?(name) - case ConfigTable.lookup(name).config_type - when 'bool', 'path' - true - else - false - end - end - - def add_config(item) - ConfigTable.add item - end - - def add_bool_config(name, default, desc) - ConfigTable.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc) - end - - def add_path_config(name, default, desc) - ConfigTable.add PathItem.new(name, 'path', default, desc) - end - - def set_config_default(name, default) - ConfigTable.lookup(name).default = default - end - - def remove_config(name) - ConfigTable.remove(name) - end - -end - - -# -# File Operations -# - -module FileOperations - - def mkdir_p(dirname, prefix = nil) - dirname = prefix + File.expand_path(dirname) if prefix - $stderr.puts "mkdir -p #{dirname}" if verbose? - return if no_harm? - - # does not check '/'... it's too abnormal case - dirs = File.expand_path(dirname).split(%r<(?=/)>) - if /\A[a-z]:\z/i =~ dirs[0] - disk = dirs.shift - dirs[0] = disk + dirs[0] - end - dirs.each_index do |idx| - path = dirs[0..idx].join('') - Dir.mkdir path unless File.dir?(path) - end - end - - def rm_f(fname) - $stderr.puts "rm -f #{fname}" if verbose? - return if no_harm? - - if File.exist?(fname) or File.symlink?(fname) - File.chmod 0777, fname - File.unlink fname - end - end - - def rm_rf(dn) - $stderr.puts "rm -rf #{dn}" if verbose? - return if no_harm? - - Dir.chdir dn - Dir.foreach('.') do |fn| - next if fn == '.' - next if fn == '..' - if File.dir?(fn) - verbose_off { - rm_rf fn - } - else - verbose_off { - rm_f fn - } - end - end - Dir.chdir '..' - Dir.rmdir dn - end - - def move_file(src, dest) - File.unlink dest if File.exist?(dest) - begin - File.rename src, dest - rescue - File.open(dest, 'wb') {|f| f.write File.binread(src) } - File.chmod File.stat(src).mode, dest - File.unlink src - end - end - - def install(from, dest, mode, prefix = nil) - $stderr.puts "install #{from} #{dest}" if verbose? - return if no_harm? - - realdest = prefix ? prefix + File.expand_path(dest) : dest - realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) - str = File.binread(from) - if diff?(str, realdest) - verbose_off { - rm_f realdest if File.exist?(realdest) - } - File.open(realdest, 'wb') {|f| - f.write str - } - File.chmod mode, realdest - - File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| - if prefix - f.puts realdest.sub(prefix, '') - else - f.puts realdest - end - } - end - end - - def diff?(new_content, path) - return true unless File.exist?(path) - new_content != File.binread(path) - end - - def command(str) - $stderr.puts str if verbose? - system str or raise RuntimeError, "'system #{str}' failed" - end - - def ruby(str) - command config('rubyprog') + ' ' + str - end - - def make(task = '') - command config('makeprog') + ' ' + task - end - - def extdir?(dir) - File.exist?(dir + '/MANIFEST') - end - - def all_files_in(dirname) - Dir.open(dirname) {|d| - return d.select {|ent| File.file?("#{dirname}/#{ent}") } - } - end - - REJECT_DIRS = %w( - CVS SCCS RCS CVS.adm .svn - ) - - def all_dirs_in(dirname) - Dir.open(dirname) {|d| - return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS - } - end - -end - - -# -# Main Installer -# - -module HookUtils - - def run_hook(name) - try_run_hook "#{curr_srcdir()}/#{name}" or - try_run_hook "#{curr_srcdir()}/#{name}.rb" - end - - def try_run_hook(fname) - return false unless File.file?(fname) - begin - instance_eval File.read(fname), fname, 1 - rescue - setup_rb_error "hook #{fname} failed:\n" + $!.message - end - true - end - -end - - -module HookScriptAPI - - def get_config(key) - @config[key] - end - - alias config get_config - - def set_config(key, val) - @config[key] = val - end - - # - # srcdir/objdir (works only in the package directory) - # - - #abstract srcdir_root - #abstract objdir_root - #abstract relpath - - def curr_srcdir - "#{srcdir_root()}/#{relpath()}" - end - - def curr_objdir - "#{objdir_root()}/#{relpath()}" - end - - def srcfile(path) - "#{curr_srcdir()}/#{path}" - end - - def srcexist?(path) - File.exist?(srcfile(path)) - end - - def srcdirectory?(path) - File.dir?(srcfile(path)) - end - - def srcfile?(path) - File.file? srcfile(path) - end - - def srcentries(path = '.') - Dir.open("#{curr_srcdir()}/#{path}") {|d| - return d.to_a - %w(. ..) - } - end - - def srcfiles(path = '.') - srcentries(path).select {|fname| - File.file?(File.join(curr_srcdir(), path, fname)) - } - end - - def srcdirectories(path = '.') - srcentries(path).select {|fname| - File.dir?(File.join(curr_srcdir(), path, fname)) - } - end - -end - - -class ToplevelInstaller - - Version = '3.3.1' - Copyright = 'Copyright (c) 2000-2004 Minero Aoki' - - TASKS = [ - [ 'all', 'do config, setup, then install' ], - [ 'config', 'saves your configurations' ], - [ 'show', 'shows current configuration' ], - [ 'setup', 'compiles ruby extentions and others' ], - [ 'install', 'installs files' ], - [ 'clean', "does `make clean' for each extention" ], - [ 'distclean',"does `make distclean' for each extention" ] - ] - - def ToplevelInstaller.invoke - instance().invoke - end - - @singleton = nil - - def ToplevelInstaller.instance - @singleton ||= new(File.dirname($0)) - @singleton - end - - include MetaConfigAPI - - def initialize(ardir_root) - @config = nil - @options = { 'verbose' => true } - @ardir = File.expand_path(ardir_root) - end - - def inspect - "#<#{self.class} #{__id__()}>" - end - - def invoke - run_metaconfigs - case task = parsearg_global() - when nil, 'all' - @config = load_config('config') - parsearg_config - init_installers - exec_config - exec_setup - exec_install - else - @config = load_config(task) - __send__ "parsearg_#{task}" - init_installers - __send__ "exec_#{task}" - end - end - - def run_metaconfigs - eval_file_ifexist "#{@ardir}/metaconfig" - end - - def load_config(task) - case task - when 'config' - ConfigTable.new - when 'clean', 'distclean' - if File.exist?(ConfigTable.savefile) - then ConfigTable.load - else ConfigTable.new - end - else - ConfigTable.load - end - end - - def init_installers - @installer = Installer.new(@config, @options, @ardir, File.expand_path('.')) - end - - # - # Hook Script API bases - # - - def srcdir_root - @ardir - end - - def objdir_root - '.' - end - - def relpath - '.' - end - - # - # Option Parsing - # - - def parsearg_global - valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/ - - while arg = ARGV.shift - case arg - when /\A\w+\z/ - setup_rb_error "invalid task: #{arg}" unless valid_task =~ arg - return arg - - when '-q', '--quiet' - @options['verbose'] = false - - when '--verbose' - @options['verbose'] = true - - when '-h', '--help' - print_usage $stdout - exit 0 - - when '-v', '--version' - puts "#{File.basename($0)} version #{Version}" - exit 0 - - when '--copyright' - puts Copyright - exit 0 - - else - setup_rb_error "unknown global option '#{arg}'" - end - end - - nil - end - - - def parsearg_no_options - unless ARGV.empty? - setup_rb_error "#{task}: unknown options: #{ARGV.join ' '}" - end - end - - alias parsearg_show parsearg_no_options - alias parsearg_setup parsearg_no_options - alias parsearg_clean parsearg_no_options - alias parsearg_distclean parsearg_no_options - - def parsearg_config - re = /\A--(#{ConfigTable.map {|i| i.name }.join('|')})(?:=(.*))?\z/ - @options['config-opt'] = [] - - while i = ARGV.shift - if /\A--?\z/ =~ i - @options['config-opt'] = ARGV.dup - break - end - m = re.match(i) or setup_rb_error "config: unknown option #{i}" - name, value = *m.to_a[1,2] - @config[name] = value - end - end - - def parsearg_install - @options['no-harm'] = false - @options['install-prefix'] = '' - while a = ARGV.shift - case a - when /\A--no-harm\z/ - @options['no-harm'] = true - when /\A--prefix=(.*)\z/ - path = $1 - path = File.expand_path(path) unless path[0,1] == '/' - @options['install-prefix'] = path - else - setup_rb_error "install: unknown option #{a}" - end - end - end - - def print_usage(out) - out.puts 'Typical Installation Procedure:' - out.puts " $ ruby #{File.basename $0} config" - out.puts " $ ruby #{File.basename $0} setup" - out.puts " # ruby #{File.basename $0} install (may require root privilege)" - out.puts - out.puts 'Detailed Usage:' - out.puts " ruby #{File.basename $0} " - out.puts " ruby #{File.basename $0} [] []" - - fmt = " %-24s %s\n" - out.puts - out.puts 'Global options:' - out.printf fmt, '-q,--quiet', 'suppress message outputs' - out.printf fmt, ' --verbose', 'output messages verbosely' - out.printf fmt, '-h,--help', 'print this message' - out.printf fmt, '-v,--version', 'print version and quit' - out.printf fmt, ' --copyright', 'print copyright and quit' - out.puts - out.puts 'Tasks:' - TASKS.each do |name, desc| - out.printf fmt, name, desc - end - - fmt = " %-24s %s [%s]\n" - out.puts - out.puts 'Options for CONFIG or ALL:' - ConfigTable.each do |item| - out.printf fmt, item.help_opt, item.description, item.help_default - end - out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's" - out.puts - out.puts 'Options for INSTALL:' - out.printf fmt, '--no-harm', 'only display what to do if given', 'off' - out.printf fmt, '--prefix=path', 'install path prefix', '$prefix' - out.puts - end - - # - # Task Handlers - # - - def exec_config - @installer.exec_config - @config.save # must be final - end - - def exec_setup - @installer.exec_setup - end - - def exec_install - @installer.exec_install - end - - def exec_show - ConfigTable.each do |i| - printf "%-20s %s\n", i.name, i.value - end - end - - def exec_clean - @installer.exec_clean - end - - def exec_distclean - @installer.exec_distclean - end - -end - - -class ToplevelInstallerMulti < ToplevelInstaller - - include HookUtils - include HookScriptAPI - include FileOperations - - def initialize(ardir) - super - @packages = all_dirs_in("#{@ardir}/packages") - raise 'no package exists' if @packages.empty? - end - - def run_metaconfigs - eval_file_ifexist "#{@ardir}/metaconfig" - @packages.each do |name| - eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig" - end - end - - def init_installers - @installers = {} - @packages.each do |pack| - @installers[pack] = Installer.new(@config, @options, - "#{@ardir}/packages/#{pack}", - "packages/#{pack}") - end - - with = extract_selection(config('with')) - without = extract_selection(config('without')) - @selected = @installers.keys.select {|name| - (with.empty? or with.include?(name)) \ - and not without.include?(name) - } - end - - def extract_selection(list) - a = list.split(/,/) - a.each do |name| - setup_rb_error "no such package: #{name}" unless @installers.key?(name) - end - a - end - - def print_usage(f) - super - f.puts 'Inluded packages:' - f.puts ' ' + @packages.sort.join(' ') - f.puts - end - - # - # multi-package metaconfig API - # - - attr_reader :packages - - def declare_packages(list) - raise 'package list is empty' if list.empty? - list.each do |name| - raise "directory packages/#{name} does not exist"\ - unless File.dir?("#{@ardir}/packages/#{name}") - end - @packages = list - end - - # - # Task Handlers - # - - def exec_config - run_hook 'pre-config' - each_selected_installers {|inst| inst.exec_config } - run_hook 'post-config' - @config.save # must be final - end - - def exec_setup - run_hook 'pre-setup' - each_selected_installers {|inst| inst.exec_setup } - run_hook 'post-setup' - end - - def exec_install - run_hook 'pre-install' - each_selected_installers {|inst| inst.exec_install } - run_hook 'post-install' - end - - def exec_clean - rm_f ConfigTable.savefile - run_hook 'pre-clean' - each_selected_installers {|inst| inst.exec_clean } - run_hook 'post-clean' - end - - def exec_distclean - rm_f ConfigTable.savefile - run_hook 'pre-distclean' - each_selected_installers {|inst| inst.exec_distclean } - run_hook 'post-distclean' - end - - # - # lib - # - - def each_selected_installers - Dir.mkdir 'packages' unless File.dir?('packages') - @selected.each do |pack| - $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose'] - Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") - Dir.chdir "packages/#{pack}" - yield @installers[pack] - Dir.chdir '../..' - end - end - - def verbose? - @options['verbose'] - end - - def no_harm? - @options['no-harm'] - end - -end - - -class Installer - - FILETYPES = %w( bin lib ext data ) - - include HookScriptAPI - include HookUtils - include FileOperations - - def initialize(config, opt, srcroot, objroot) - @config = config - @options = opt - @srcdir = File.expand_path(srcroot) - @objdir = File.expand_path(objroot) - @currdir = '.' - end - - def inspect - "#<#{self.class} #{File.basename(@srcdir)}>" - end - - # - # Hook Script API base methods - # - - def srcdir_root - @srcdir - end - - def objdir_root - @objdir - end - - def relpath - @currdir - end - - # - # configs/options - # - - def no_harm? - @options['no-harm'] - end - - def verbose? - @options['verbose'] - end - - def verbose_off - begin - save, @options['verbose'] = @options['verbose'], false - yield - ensure - @options['verbose'] = save - end - end - - # - # TASK config - # - - def exec_config - exec_task_traverse 'config' - end - - def config_dir_bin(rel) - end - - def config_dir_lib(rel) - end - - def config_dir_ext(rel) - extconf if extdir?(curr_srcdir()) - end - - def extconf - opt = @options['config-opt'].join(' ') - command "#{config('rubyprog')} #{curr_srcdir()}/extconf.rb #{opt}" - end - - def config_dir_data(rel) - end - - # - # TASK setup - # - - def exec_setup - exec_task_traverse 'setup' - end - - def setup_dir_bin(rel) - all_files_in(curr_srcdir()).each do |fname| - adjust_shebang "#{curr_srcdir()}/#{fname}" - end - end - - def adjust_shebang(path) - return if no_harm? - tmpfile = File.basename(path) + '.tmp' - begin - File.open(path, 'rb') {|r| - first = r.gets - return unless File.basename(config('rubypath')) == 'ruby' - return unless File.basename(first.sub(/\A\#!/, '').split[0]) == 'ruby' - $stderr.puts "adjusting shebang: #{File.basename(path)}" if verbose? - File.open(tmpfile, 'wb') {|w| - w.print first.sub(/\A\#!\s*\S+/, '#! ' + config('rubypath')) - w.write r.read - } - move_file tmpfile, File.basename(path) - } - ensure - File.unlink tmpfile if File.exist?(tmpfile) - end - end - - def setup_dir_lib(rel) - end - - def setup_dir_ext(rel) - make if extdir?(curr_srcdir()) - end - - def setup_dir_data(rel) - end - - # - # TASK install - # - - def exec_install - rm_f 'InstalledFiles' - exec_task_traverse 'install' - end - - def install_dir_bin(rel) - install_files collect_filenames_auto(), "#{config('bindir')}/#{rel}", 0755 - end - - def install_dir_lib(rel) - install_files ruby_scripts(), "#{config('rbdir')}/#{rel}", 0644 - end - - def install_dir_ext(rel) - return unless extdir?(curr_srcdir()) - install_files ruby_extentions('.'), - "#{config('sodir')}/#{File.dirname(rel)}", - 0555 - end - - def install_dir_data(rel) - install_files collect_filenames_auto(), "#{config('datadir')}/#{rel}", 0644 - end - - def install_files(list, dest, mode) - mkdir_p dest, @options['install-prefix'] - list.each do |fname| - install fname, dest, mode, @options['install-prefix'] - end - end - - def ruby_scripts - collect_filenames_auto().select {|n| /\.rb\z/ =~ n } - end - - # picked up many entries from cvs-1.11.1/src/ignore.c - reject_patterns = %w( - core RCSLOG tags TAGS .make.state - .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb - *~ *.old *.bak *.BAK *.orig *.rej _$* *$ - - *.org *.in .* - ) - mapping = { - '.' => '\.', - '$' => '\$', - '#' => '\#', - '*' => '.*' - } - REJECT_PATTERNS = Regexp.new('\A(?:' + - reject_patterns.map {|pat| - pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] } - }.join('|') + - ')\z') - - def collect_filenames_auto - mapdir((existfiles() - hookfiles()).reject {|fname| - REJECT_PATTERNS =~ fname - }) - end - - def existfiles - all_files_in(curr_srcdir()) | all_files_in('.') - end - - def hookfiles - %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| - %w( config setup install clean ).map {|t| sprintf(fmt, t) } - }.flatten - end - - def mapdir(filelist) - filelist.map {|fname| - if File.exist?(fname) # objdir - fname - else # srcdir - File.join(curr_srcdir(), fname) - end - } - end - - def ruby_extentions(dir) - Dir.open(dir) {|d| - ents = d.select {|fname| /\.#{::Config::CONFIG['DLEXT']}\z/ =~ fname } - if ents.empty? - setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first" - end - return ents - } - end - - # - # TASK clean - # - - def exec_clean - exec_task_traverse 'clean' - rm_f ConfigTable.savefile - rm_f 'InstalledFiles' - end - - def clean_dir_bin(rel) - end - - def clean_dir_lib(rel) - end - - def clean_dir_ext(rel) - return unless extdir?(curr_srcdir()) - make 'clean' if File.file?('Makefile') - end - - def clean_dir_data(rel) - end - - # - # TASK distclean - # - - def exec_distclean - exec_task_traverse 'distclean' - rm_f ConfigTable.savefile - rm_f 'InstalledFiles' - end - - def distclean_dir_bin(rel) - end - - def distclean_dir_lib(rel) - end - - def distclean_dir_ext(rel) - return unless extdir?(curr_srcdir()) - make 'distclean' if File.file?('Makefile') - end - - # - # lib - # - - def exec_task_traverse(task) - run_hook "pre-#{task}" - FILETYPES.each do |type| - if config('without-ext') == 'yes' and type == 'ext' - $stderr.puts 'skipping ext/* by user option' if verbose? - next - end - traverse task, type, "#{task}_dir_#{type}" - end - run_hook "post-#{task}" - end - - def traverse(task, rel, mid) - dive_into(rel) { - run_hook "pre-#{task}" - __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') - all_dirs_in(curr_srcdir()).each do |d| - traverse task, "#{rel}/#{d}", mid - end - run_hook "post-#{task}" - } - end - - def dive_into(rel) - return unless File.dir?("#{@srcdir}/#{rel}") - - dir = File.basename(rel) - Dir.mkdir dir unless File.dir?(dir) - prevdir = Dir.pwd - Dir.chdir dir - $stderr.puts '---> ' + rel if verbose? - @currdir = rel - yield - Dir.chdir prevdir - $stderr.puts '<--- ' + rel if verbose? - @currdir = File.dirname(rel) - end - -end - - -if $0 == __FILE__ - begin - if multipackage_install? - ToplevelInstallerMulti.invoke - else - ToplevelInstaller.invoke - end - rescue SetupError - raise if $DEBUG - $stderr.puts $!.message - $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." - exit 1 - end -end diff --git a/actionservice/test/abstract_client.rb b/actionservice/test/abstract_client.rb deleted file mode 100644 index 70d2d21124..0000000000 --- a/actionservice/test/abstract_client.rb +++ /dev/null @@ -1,124 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' -require 'webrick' -require 'webrick/log' -require 'singleton' - -module ClientTest - class Person < ActionService::Struct - member :firstnames, [:string] - member :lastname, :string - - def ==(other) - firstnames == other.firstnames && lastname == other.lastname - end - end - - class API < ActionService::API::Base - api_method :void - api_method :normal, :expects => [:int, :int], :returns => [:int] - api_method :array_return, :returns => [[Person]] - api_method :struct_pass, :expects => [[Person]], :returns => [:bool] - api_method :client_container, :returns => [:int] - end - - class NullLogOut - def <<(*args); end - end - - class Container < ActionController::Base - web_service_api API - - attr :value_void - attr :value_normal - attr :value_array_return - attr :value_struct_pass - - def initialize - @session = @assigns = {} - @value_void = nil - @value_normal = nil - @value_array_return = nil - @value_struct_pass = nil - end - - def void - @value_void = @method_params - end - - def normal - @value_normal = @method_params - 5 - end - - def array_return - person = Person.new - person.firstnames = ["one", "two"] - person.lastname = "last" - @value_array_return = [person] - end - - def struct_pass - @value_struct_pass = @method_params - true - end - - def client_container - 50 - end - - def protocol_request(request) - probe_request_protocol(request) - end - - def dispatch_request(protocol_request) - dispatch_web_service_request(protocol_request) - end - end - - class AbstractClientLet < WEBrick::HTTPServlet::AbstractServlet - def initialize(controller) - @controller = controller - end - - def get_instance(*args) - self - end - - def require_path_info? - false - end - - def do_GET(req, res) - raise WEBrick::HTTPStatus::MethodNotAllowed, "GET request not allowed." - end - - def do_POST(req, res) - raise NotImplementedError - end - end - - class AbstractServer - include ClientTest - include Singleton - attr :container - def initialize - @container = Container.new - @clientlet = create_clientlet(@container) - log = WEBrick::BasicLog.new(NullLogOut.new) - @server = WEBrick::HTTPServer.new(:Port => server_port, :Logger => log, :AccessLog => log) - @server.mount('/', @clientlet) - @thr = Thread.new { @server.start } - until @server.status == :Running; end - at_exit { @server.stop; @thr.join } - end - - protected - def create_clientlet - raise NotImplementedError - end - - def server_port - raise NotImplementedError - end - end -end diff --git a/actionservice/test/abstract_soap.rb b/actionservice/test/abstract_soap.rb deleted file mode 100644 index 7454be9bdf..0000000000 --- a/actionservice/test/abstract_soap.rb +++ /dev/null @@ -1,58 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' -require 'soap/rpc/element' - -class SoapTestError < StandardError -end - -class AbstractSoapTest < Test::Unit::TestCase - def default_test - end - - protected - def service_name - raise NotImplementedError - end - - def do_soap_call(public_method_name, *args) - mapper = @container.class.soap_mapper - param_def = [] - i = 1 - args.each do |arg| - mapping = mapper.lookup(arg.class) - param_def << ["in", "param#{i}", mapping.registry_mapping] - i += 1 - end - qname = XSD::QName.new('urn:ActionService', public_method_name) - request = SOAP::RPC::SOAPMethodRequest.new(qname, param_def) - soap_args = [] - i = 1 - args.each do |arg| - soap_args << ["param#{i}", SOAP::Mapping.obj2soap(arg)] - i += 1 - end - request.set_param(soap_args) - header = SOAP::SOAPHeader.new - body = SOAP::SOAPBody.new(request) - envelope = SOAP::SOAPEnvelope.new(header, body) - raw_request = SOAP::Processor.marshal(envelope) - test_request = ActionController::TestRequest.new - test_request.request_parameters['action'] = service_name - test_request.env['REQUEST_METHOD'] = "POST" - test_request.env['HTTP_CONTENTTYPE'] = 'text/xml' - test_request.env['HTTP_SOAPACTION'] = "/soap/#{service_name}/#{public_method_name}" - test_request.env['RAW_POST_DATA'] = raw_request - test_response = ActionController::TestResponse.new - response = yield test_request, test_response - raw_body = response.respond_to?(:body) ? response.body : response.raw_body - envelope = SOAP::Processor.unmarshal(raw_body) - if envelope - if envelope.body.response - SOAP::Mapping.soap2obj(envelope.body.response) - else - nil - end - else - raise(SoapTestError, "empty/invalid body from server") - end - end -end diff --git a/actionservice/test/abstract_unit.rb b/actionservice/test/abstract_unit.rb deleted file mode 100644 index 54ca73b35c..0000000000 --- a/actionservice/test/abstract_unit.rb +++ /dev/null @@ -1,9 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + '/../lib') - -require 'test/unit' -require 'action_service' -require 'action_controller' -require 'action_controller/test_process' - -ActionController::Base.logger = nil -ActionController::Base.ignore_missing_templates = true diff --git a/actionservice/test/api_test.rb b/actionservice/test/api_test.rb deleted file mode 100644 index 2ef5cc7bda..0000000000 --- a/actionservice/test/api_test.rb +++ /dev/null @@ -1,52 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module APITest - class API < ActionService::API::Base - api_method :void - api_method :expects_and_returns, :expects_and_returns => [:string] - api_method :expects, :expects => [:int, :bool] - api_method :returns, :returns => [:int, [:string]] - api_method :named_signature, :expects => [{:appkey=>:int}, {:publish=>:bool}] - api_method :string_types, :expects => ['int', 'string', 'bool'] - api_method :class_types, :expects => [TrueClass, Bignum, String] - end -end - -class TC_API < Test::Unit::TestCase - API = APITest::API - - def test_api_method_declaration - %w( - void - expects_and_returns - expects - returns - named_signature - string_types - class_types - ).each do |name| - name = name.to_sym - public_name = API.public_api_method_name(name) - assert(API.has_api_method?(name)) - assert(API.has_public_api_method?(public_name)) - assert(API.api_method_name(public_name) == name) - assert(API.api_methods.has_key?(name)) - end - end - - def test_signature_canonicalization - assert_equal({:expects=>nil, :returns=>nil}, API.api_methods[:void]) - assert_equal({:expects=>[String], :returns=>[String]}, API.api_methods[:expects_and_returns]) - assert_equal({:expects=>[Integer, TrueClass], :returns=>nil}, API.api_methods[:expects]) - assert_equal({:expects=>nil, :returns=>[Integer, [String]]}, API.api_methods[:returns]) - assert_equal({:expects=>[{:appkey=>Integer}, {:publish=>TrueClass}], :returns=>nil}, API.api_methods[:named_signature]) - assert_equal({:expects=>[Integer, String, TrueClass], :returns=>nil}, API.api_methods[:string_types]) - assert_equal({:expects=>[TrueClass, Bignum, String], :returns=>nil}, API.api_methods[:class_types]) - end - - def test_not_instantiable - assert_raises(NoMethodError) do - API.new - end - end -end diff --git a/actionservice/test/base_test.rb b/actionservice/test/base_test.rb deleted file mode 100644 index a9fbdd1a8b..0000000000 --- a/actionservice/test/base_test.rb +++ /dev/null @@ -1,42 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module BaseTest - class API < ActionService::API::Base - api_method :add, :expects => [:int, :int], :returns => [:int] - api_method :void - end - - class PristineAPI < ActionService::API::Base - inflect_names false - - api_method :add - api_method :under_score - end - - class Service < ActionService::Base - web_service_api API - - def add(a, b) - end - - def void - end - end - - class PristineService < ActionService::Base - web_service_api PristineAPI - - def add - end - - def under_score - end - end -end - -class TC_Base < Test::Unit::TestCase - def test_options - assert(BaseTest::PristineService.web_service_api.inflect_names == false) - assert(BaseTest::Service.web_service_api.inflect_names == true) - end -end diff --git a/actionservice/test/client_soap_test.rb b/actionservice/test/client_soap_test.rb deleted file mode 100644 index 80fae90543..0000000000 --- a/actionservice/test/client_soap_test.rb +++ /dev/null @@ -1,87 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_client' - - -module ClientSoapTest - PORT = 8998 - - class SoapClientLet < ClientTest::AbstractClientLet - def do_POST(req, res) - test_request = ActionController::TestRequest.new - test_request.request_parameters['action'] = req.path.gsub(/^\//, '').split(/\//)[1] - test_request.env['REQUEST_METHOD'] = "POST" - test_request.env['HTTP_CONTENTTYPE'] = 'text/xml' - test_request.env['HTTP_SOAPACTION'] = req.header['soapaction'][0] - test_request.env['RAW_POST_DATA'] = req.body - protocol_request = @controller.protocol_request(test_request) - response = @controller.dispatch_request(protocol_request) - res.header['content-type'] = 'text/xml' - res.body = response.raw_body - rescue Exception => e - $stderr.puts e.message - $stderr.puts e.backtrace.join("\n") - end - end - - class ClientContainer < ActionController::Base - web_client_api :client, :soap, "http://localhost:#{PORT}/client/api", :api => ClientTest::API - - def get_client - client - end - end - - class SoapServer < ClientTest::AbstractServer - def create_clientlet(controller) - SoapClientLet.new(controller) - end - - def server_port - PORT - end - end -end - -class TC_ClientSoap < Test::Unit::TestCase - include ClientTest - include ClientSoapTest - - def setup - @server = SoapServer.instance - @container = @server.container - @client = ActionService::Client::Soap.new(API, "http://localhost:#{@server.server_port}/client/api") - end - - def test_void - assert(@container.value_void.nil?) - @client.void - assert(!@container.value_void.nil?) - end - - def test_normal - assert(@container.value_normal.nil?) - assert_equal(5, @client.normal(5, 6)) - assert_equal([5, 6], @container.value_normal) - end - - def test_array_return - assert(@container.value_array_return.nil?) - new_person = Person.new - new_person.firstnames = ["one", "two"] - new_person.lastname = "last" - assert_equal([new_person], @client.array_return) - assert_equal([new_person], @container.value_array_return) - end - - def test_struct_pass - assert(@container.value_struct_pass.nil?) - new_person = Person.new - new_person.firstnames = ["one", "two"] - new_person.lastname = "last" - assert_equal(true, @client.struct_pass([new_person])) - assert_equal([[new_person]], @container.value_struct_pass) - end - - def test_client_container - assert_equal(50, ClientContainer.new.get_client.client_container) - end -end diff --git a/actionservice/test/client_xmlrpc_test.rb b/actionservice/test/client_xmlrpc_test.rb deleted file mode 100644 index 35768adf32..0000000000 --- a/actionservice/test/client_xmlrpc_test.rb +++ /dev/null @@ -1,86 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_client' - - -module ClientXmlRpcTest - PORT = 8999 - - class XmlRpcClientLet < ClientTest::AbstractClientLet - def do_POST(req, res) - test_request = ActionController::TestRequest.new - test_request.request_parameters['action'] = req.path.gsub(/^\//, '').split(/\//)[1] - test_request.env['REQUEST_METHOD'] = "POST" - test_request.env['HTTP_CONTENTTYPE'] = 'text/xml' - test_request.env['RAW_POST_DATA'] = req.body - protocol_request = @controller.protocol_request(test_request) - response = @controller.dispatch_request(protocol_request) - res.header['content-type'] = 'text/xml' - res.body = response.raw_body - rescue Exception => e - $stderr.puts e.message - $stderr.puts e.backtrace.join("\n") - end - end - - class ClientContainer < ActionController::Base - web_client_api :client, :xmlrpc, "http://localhost:#{PORT}/client/api", :api => ClientTest::API - - def get_client - client - end - end - - class XmlRpcServer < ClientTest::AbstractServer - def create_clientlet(controller) - XmlRpcClientLet.new(controller) - end - - def server_port - PORT - end - end -end - -class TC_ClientXmlRpc < Test::Unit::TestCase - include ClientTest - include ClientXmlRpcTest - - def setup - @server = XmlRpcServer.instance - @container = @server.container - @client = ActionService::Client::XmlRpc.new(API, "http://localhost:#{@server.server_port}/client/api") - end - - def test_void - assert(@container.value_void.nil?) - @client.void - assert(!@container.value_void.nil?) - end - - def test_normal - assert(@container.value_normal.nil?) - assert_equal(5, @client.normal(5, 6)) - assert_equal([5, 6], @container.value_normal) - end - - def test_array_return - assert(@container.value_array_return.nil?) - new_person = Person.new - new_person.firstnames = ["one", "two"] - new_person.lastname = "last" - assert_equal([new_person], @client.array_return) - assert_equal([new_person], @container.value_array_return) - end - - def test_struct_pass - assert(@container.value_struct_pass.nil?) - new_person = Person.new - new_person.firstnames = ["one", "two"] - new_person.lastname = "last" - assert_equal(true, @client.struct_pass([new_person])) - assert_equal([[new_person]], @container.value_struct_pass) - end - - def test_client_container - assert_equal(50, ClientContainer.new.get_client.client_container) - end -end diff --git a/actionservice/test/container_test.rb b/actionservice/test/container_test.rb deleted file mode 100644 index 8c66651b64..0000000000 --- a/actionservice/test/container_test.rb +++ /dev/null @@ -1,53 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module ContainerTest - - $immediate_service = Object.new - $deferred_service = Object.new - - class DelegateContainer < ActionController::Base - web_service_dispatching_mode :delegated - - attr :flag - attr :previous_flag - - def initialize - @previous_flag = nil - @flag = true - end - - web_service :immediate_service, $immediate_service - web_service(:deferred_service) { @previous_flag = @flag; @flag = false; $deferred_service } - end - - class DirectContainer < ActionController::Base - web_service_dispatching_mode :direct - end -end - -class TC_Container < Test::Unit::TestCase - def setup - @delegate_container = ContainerTest::DelegateContainer.new - @direct_container = ContainerTest::DirectContainer.new - end - - def test_registration - assert(ContainerTest::DelegateContainer.has_web_service?(:immediate_service)) - assert(ContainerTest::DelegateContainer.has_web_service?(:deferred_service)) - assert(!ContainerTest::DelegateContainer.has_web_service?(:fake_service)) - end - - def test_service_object - assert(@delegate_container.flag == true) - assert(@delegate_container.web_service_object(:immediate_service) == $immediate_service) - assert(@delegate_container.previous_flag.nil?) - assert(@delegate_container.flag == true) - assert(@delegate_container.web_service_object(:deferred_service) == $deferred_service) - assert(@delegate_container.previous_flag == true) - assert(@delegate_container.flag == false) - end - - def test_direct_container - assert(ContainerTest::DirectContainer.web_service_dispatching_mode == :direct) - end -end diff --git a/actionservice/test/invocation_test.rb b/actionservice/test/invocation_test.rb deleted file mode 100644 index e4c82a35f8..0000000000 --- a/actionservice/test/invocation_test.rb +++ /dev/null @@ -1,158 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module InvocationTest - class API < ActionService::API::Base - api_method :add, :expects => [:int, :int], :returns => [:int] - api_method :transmogrify, :expects_and_returns => [:string] - api_method :fail_with_reason - api_method :fail_generic - api_method :no_before - api_method :no_after - api_method :only_one - api_method :only_two - end - - class Service < ActionService::Base - web_service_api API - - before_invocation :intercept_before, :except => [:no_before] - after_invocation :intercept_after, :except => [:no_after] - before_invocation :intercept_only, :only => [:only_one, :only_two] - - attr_accessor :before_invoked - attr_accessor :after_invoked - attr_accessor :only_invoked - attr_accessor :invocation_result - - def initialize - @before_invoked = nil - @after_invoked = nil - @only_invoked = nil - @invocation_result = nil - end - - def add(a, b) - a + b - end - - def transmogrify(str) - str.upcase - end - - def fail_with_reason - end - - def fail_generic - end - - def no_before - 5 - end - - def no_after - end - - def only_one - end - - def only_two - end - - def not_public - end - - protected - def intercept_before(name, args) - @before_invoked = name - return [false, "permission denied"] if name == :fail_with_reason - return false if name == :fail_generic - end - - def intercept_after(name, args, result) - @after_invoked = name - @invocation_result = result - end - - def intercept_only(name, args) - raise "Interception error" unless name == :only_one || name == :only_two - @only_invoked = name - end - end -end - -class TC_Invocation < Test::Unit::TestCase - include ActionService::Invocation - - def setup - @service = InvocationTest::Service.new - end - - def test_invocation - assert(perform_invocation(:add, 5, 10) == 15) - assert(perform_invocation(:transmogrify, "hello") == "HELLO") - assert_raises(InvocationError) do - perform_invocation(:not_public) - end - assert_raises(InvocationError) do - perform_invocation(:nonexistent_method_xyzzy) - end - end - - def test_interceptor_registration - assert(InvocationTest::Service.before_invocation_interceptors.length == 2) - assert(InvocationTest::Service.after_invocation_interceptors.length == 1) - end - - def test_interception - assert(@service.before_invoked.nil? && @service.after_invoked.nil? && @service.only_invoked.nil? && @service.invocation_result.nil?) - perform_invocation(:add, 20, 50) - assert(@service.before_invoked == :add) - assert(@service.after_invoked == :add) - assert(@service.invocation_result == 70) - end - - def test_interception_canceling - reason = nil - perform_invocation(:fail_with_reason){|r| reason = r} - assert(@service.before_invoked == :fail_with_reason) - assert(@service.after_invoked.nil?) - assert(@service.invocation_result.nil?) - assert(reason == "permission denied") - reason = true - @service.before_invoked = @service.after_invoked = @service.invocation_result = nil - perform_invocation(:fail_generic){|r| reason = r} - assert(@service.before_invoked == :fail_generic) - assert(@service.after_invoked.nil?) - assert(@service.invocation_result.nil?) - assert(reason == true) - end - - def test_interception_except_conditions - perform_invocation(:no_before) - assert(@service.before_invoked.nil?) - assert(@service.after_invoked == :no_before) - assert(@service.invocation_result == 5) - @service.before_invoked = @service.after_invoked = @service.invocation_result = nil - perform_invocation(:no_after) - assert(@service.before_invoked == :no_after) - assert(@service.after_invoked.nil?) - assert(@service.invocation_result.nil?) - end - - def test_interception_only_conditions - assert(@service.only_invoked.nil?) - perform_invocation(:only_one) - assert(@service.only_invoked == :only_one) - @service.only_invoked = nil - perform_invocation(:only_two) - assert(@service.only_invoked == :only_two) - end - - private - def perform_invocation(method_name, *args, &block) - public_method_name = @service.class.web_service_api.public_api_method_name(method_name) - args ||= [] - request = InvocationRequest.new(ConcreteInvocation, public_method_name, method_name, args) - @service.perform_invocation(request, &block) - end -end diff --git a/actionservice/test/protocol_registry_test.rb b/actionservice/test/protocol_registry_test.rb deleted file mode 100644 index 8e2b9659a6..0000000000 --- a/actionservice/test/protocol_registry_test.rb +++ /dev/null @@ -1,53 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - - -module Foo - include ActionService::Protocol - - def self.append_features(base) - super - base.register_protocol(BodyOnly, FooMinimalProtocol) - base.register_protocol(HeaderAndBody, FooMinimalProtocolTwo) - base.register_protocol(HeaderAndBody, FooMinimalProtocolTwo) - base.register_protocol(HeaderAndBody, FooFullProtocol) - end - - class FooFullProtocol < AbstractProtocol - def self.create_protocol_request(klass, request) - protocol = FooFullProtocol.new klass - ActionService::Protocol::ProtocolRequest.new(protocol, '', '', '', '') - end - end - - class FooMinimalProtocol < AbstractProtocol - def self.create_protocol_request(klass, request) - protocol = FooMinimalProtocol.new klass - ActionService::Protocol::ProtocolRequest.new(protocol, '', '', '', '') - end - end - - class FooMinimalProtocolTwo < AbstractProtocol - end -end - -class ProtocolRegistry - include ActionService::Protocol::Registry - include Foo - - def all_protocols - header_and_body_protocols + body_only_protocols - end - - def protocol_request - probe_request_protocol(nil) - end -end - - -class TC_ProtocolRegistry < Test::Unit::TestCase - def test_registration - registry = ProtocolRegistry.new - assert(registry.all_protocols.length == 4) - assert(registry.protocol_request.protocol.is_a?(Foo::FooFullProtocol)) - end -end diff --git a/actionservice/test/protocol_soap_test.rb b/actionservice/test/protocol_soap_test.rb deleted file mode 100644 index 164d06bbd6..0000000000 --- a/actionservice/test/protocol_soap_test.rb +++ /dev/null @@ -1,226 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_soap' - -module ProtocolSoapTest - class Person < ActionService::Struct - member :id, Integer - member :names, [String] - member :lastname, String - member :deleted, TrueClass - - def ==(other) - id == other.id && names == other.names && lastname == other.lastname && deleted == other.deleted - end - end - - class API < ActionService::API::Base - api_method :argument_passing, :expects => [{:int=>:int}, {:string=>:string}, {:array=>[:int]}], :returns => [:bool] - api_method :array_returner, :returns => [[:int]] - api_method :nil_returner - api_method :struct_array_returner, :returns => [[Person]] - api_method :exception_thrower - - default_api_method :default - end - - class Service < ActionService::Base - web_service_api API - - attr :int - attr :string - attr :array - attr :values - attr :person - attr :default_args - - def initialize - @int = 20 - @string = "wrong string value" - @default_args = nil - end - - def argument_passing(int, string, array) - @int = int - @string = string - @array = array - true - end - - def array_returner - @values = [1, 2, 3] - end - - def nil_returner - nil - end - - def struct_array_returner - @person = Person.new - @person.id = 5 - @person.names = ["one", "two"] - @person.lastname = "test" - @person.deleted = false - [@person] - end - - def exception_thrower - raise "Hi, I'm a SOAP error" - end - - def default(*args) - @default_args = args - nil - end - end - - class AbstractContainer - include ActionService::API - include ActionService::Container - include ActionService::Protocol::Registry - include ActionService::Protocol::Soap - - wsdl_service_name 'Test' - - def protocol_request(request) - probe_request_protocol(request) - end - - def dispatch_request(protocol_request) - dispatch_web_service_request(protocol_request) - end - end - - class DelegatedContainer < AbstractContainer - web_service_dispatching_mode :delegated - web_service :protocol_soap_service, Service.new - end - - class DirectContainer < AbstractContainer - web_service_api API - web_service_dispatching_mode :direct - - attr :int - attr :string - attr :array - attr :values - attr :person - attr :default_args - - def initialize - @int = 20 - @string = "wrong string value" - @default_args = nil - end - - def argument_passing - @int = @params['int'] - @string = @params['string'] - @array = @params['array'] - true - end - - def array_returner - @values = [1, 2, 3] - end - - def nil_returner - nil - end - - def struct_array_returner - @person = Person.new - @person.id = 5 - @person.names = ["one", "two"] - @person.lastname = "test" - @person.deleted = false - [@person] - end - - def exception_thrower - raise "Hi, I'm a SOAP error" - end - - def default - @default_args = @method_params - nil - end - end -end - -class TC_ProtocolSoap < AbstractSoapTest - def setup - @delegated_container = ProtocolSoapTest::DelegatedContainer.new - @direct_container = ProtocolSoapTest::DirectContainer.new - end - - def test_argument_passing - in_all_containers do - assert(do_soap_call('ArgumentPassing', 5, "test string", [true, false]) == true) - assert(service.int == 5) - assert(service.string == "test string") - assert(service.array == [true, false]) - end - end - - def test_array_returner - in_all_containers do - assert(do_soap_call('ArrayReturner') == [1, 2, 3]) - assert(service.values == [1, 2, 3]) - end - end - - def test_nil_returner - in_all_containers do - assert(do_soap_call('NilReturner') == nil) - end - end - - def test_struct_array_returner - in_all_containers do - assert(do_soap_call('StructArrayReturner') == [service.person]) - end - end - - def test_exception_thrower - in_all_containers do - assert_raises(RuntimeError) do - do_soap_call('ExceptionThrower') - end - end - end - - def test_default_api_method - in_all_containers do - assert(do_soap_call('NonExistentMethodName', 50, false).nil?) - assert(service.default_args == [50, false]) - end - end - - def test_service_name_setting - in_all_containers do - assert(ProtocolSoapTest::DelegatedContainer.soap_mapper.custom_namespace == 'urn:Test') - end - end - - protected - def service_name - @container == @direct_container ? 'api' : 'protocol_soap_service' - end - - def service - @container == @direct_container ? @container : @container.web_service_object(:protocol_soap_service) - end - - def in_all_containers(&block) - [@direct_container].each do |container| - @container = container - block.call - end - end - - def do_soap_call(public_method_name, *args) - super(public_method_name, *args) do |test_request, test_response| - protocol_request = @container.protocol_request(test_request) - @container.dispatch_request(protocol_request) - end - end -end diff --git a/actionservice/test/protocol_xmlrpc_test.rb b/actionservice/test/protocol_xmlrpc_test.rb deleted file mode 100644 index a8a6efc07e..0000000000 --- a/actionservice/test/protocol_xmlrpc_test.rb +++ /dev/null @@ -1,157 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' -require 'xmlrpc/parser' -require 'xmlrpc/create' -require 'xmlrpc/config' - -module XMLRPC - class XmlRpcTestHelper - include ParserWriterChooseMixin - - def create_request(methodName, *args) - create().methodCall(methodName, *args) - end - - def parse_response(response) - parser().parseMethodResponse(response) - end - end -end - -module ProtocolXmlRpcTest - class Person < ActionService::Struct - member :firstname, String - member :lastname, String - member :active, TrueClass - end - - class API < ActionService::API::Base - api_method :add, :expects => [Integer, Integer], :returns => [Integer] - api_method :hash_returner, :returns => [Hash] - api_method :array_returner, :returns => [[Integer]] - api_method :something_hash, :expects => [Hash] - api_method :struct_array_returner, :returns => [[Person]] - - default_api_method :default - end - - class Service < ActionService::Base - web_service_api API - - attr :result - attr :hashvalue - attr :default_args - - def initialize - @result = nil - @hashvalue = nil - @default_args = nil - end - - def add(a, b) - @result = a + b - end - - def something_hash(hash) - @hashvalue = hash - end - - def array_returner - [1, 2, 3] - end - - def hash_returner - {'name' => 1, 'value' => 2} - end - - def struct_array_returner - person = Person.new - person.firstname = "John" - person.lastname = "Doe" - person.active = true - [person] - end - - def default(*args) - @default_args = args - nil - end - end - - $service = Service.new - - class Container - include ActionService::Container - include ActionService::Protocol::Registry - include ActionService::Protocol::Soap - include ActionService::Protocol::XmlRpc - - def protocol_request(request) - probe_request_protocol(request) - end - - def dispatch_request(protocol_request) - dispatch_web_service_request(protocol_request) - end - - web_service :xmlrpc, $service - web_service_dispatching_mode :delegated - end -end - -class TC_ProtocolXmlRpc < Test::Unit::TestCase - def setup - @helper = XMLRPC::XmlRpcTestHelper.new - @container = ProtocolXmlRpcTest::Container.new - end - - def test_xmlrpc_request_dispatching - retval = do_xmlrpc_call('Add', 50, 30) - assert(retval == [true, 80]) - end - - def test_array_returning - retval = do_xmlrpc_call('ArrayReturner') - assert(retval == [true, [1, 2, 3]]) - end - - def test_hash_returning - retval = do_xmlrpc_call('HashReturner') - assert(retval == [true, {'name' => 1, 'value' => 2}]) - end - - def test_struct_array_returning - retval = do_xmlrpc_call('StructArrayReturner') - assert(retval == [true, [{"firstname"=>"John", "lastname"=>"Doe", "active"=>true}]]) - end - - def test_hash_parameter - retval = do_xmlrpc_call('SomethingHash', {'name' => 1, 'value' => 2}) - assert(retval == [true, true]) - assert($service.hashvalue == {'name' => 1, 'value' => 2}) - end - - def test_default_api_method - retval = do_xmlrpc_call('SomeNonexistentMethod', 'test', [1, 2], {'name'=>'value'}) - assert(retval == [true, true]) - assert($service.default_args == ['test', [1, 2], {'name'=>'value'}]) - end - - def test_xmlrpc_introspection - retval = do_xmlrpc_call('system.listMethods', 'test', [1, 2], {'name'=>'value'}) - assert(retval == [true, ["Add", "ArrayReturner", "HashReturner", "SomethingHash", "StructArrayReturner"]]) - end - - private - def do_xmlrpc_call(public_method_name, *args) - service_name = 'xmlrpc' - raw_request = @helper.create_request(public_method_name, *args) - test_request = ActionController::TestRequest.new - test_request.request_parameters['action'] = service_name - test_request.env['REQUEST_METHOD'] = "POST" - test_request.env['HTTP_CONTENTTYPE'] = 'text/xml' - test_request.env['RAW_POST_DATA'] = raw_request - protocol_request = @container.protocol_request(test_request) - response = @container.dispatch_request(protocol_request) - @helper.parse_response(response.raw_body) - end -end diff --git a/actionservice/test/router_action_controller_test.rb b/actionservice/test/router_action_controller_test.rb deleted file mode 100644 index e26d67c194..0000000000 --- a/actionservice/test/router_action_controller_test.rb +++ /dev/null @@ -1,139 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_soap' -require 'wsdl/parser' - -module RouterActionControllerTest - class API < ActionService::API::Base - api_method :add, :expects => [:int, :int], :returns => [:int] - end - - class Service < ActionService::Base - web_service_api API - - attr :added - - def add(a, b) - @added = a + b - end - end - - class DelegatedController < ActionController::Base - web_service_dispatching_mode :delegated - - web_service(:test_service) { @service ||= Service.new; @service } - end - - class DirectAPI < ActionService::API::Base - api_method :add, :expects => [{:a=>:int}, {:b=>:int}], :returns => [:int] - api_method :before_filtered - api_method :after_filtered, :returns => [:int] - api_method :thrower - end - - class DirectController < ActionController::Base - web_service_api DirectAPI - web_service_dispatching_mode :direct - - before_filter :alwaysfail, :only => [:before_filtered] - after_filter :alwaysok, :only => [:after_filtered] - - attr :added - attr :before_filter_called - attr :before_filter_target_called - attr :after_filter_called - attr :after_filter_target_called - - def initialize - @before_filter_called = false - @before_filter_target_called = false - @after_filter_called = false - @after_filter_target_called = false - end - - def add - @added = @params['a'] + @params['b'] - end - - def before_filtered - @before_filter_target_called = true - end - - def after_filtered - @after_filter_target_called = true - 5 - end - - def thrower - raise "Hi, I'm a SOAP exception" - end - - protected - def alwaysfail - @before_filter_called = true - false - end - - def alwaysok - @after_filter_called = true - end - end -end - -class TC_RouterActionController < AbstractSoapTest - def test_direct_routing - @container = RouterActionControllerTest::DirectController.new - assert(do_soap_call('Add', 20, 50) == 70) - assert(@container.added == 70) - end - - def test_direct_entrypoint - @container = RouterActionControllerTest::DirectController.new - assert(@container.respond_to?(:api)) - end - - def test_direct_filtering - @container = RouterActionControllerTest::DirectController.new - assert(@container.before_filter_called == false) - assert(@container.before_filter_target_called == false) - assert(do_soap_call('BeforeFiltered').nil?) - assert(@container.before_filter_called == true) - assert(@container.before_filter_target_called == false) - assert(@container.after_filter_called == false) - assert(@container.after_filter_target_called == false) - assert(do_soap_call('AfterFiltered') == 5) - assert(@container.after_filter_called == true) - assert(@container.after_filter_target_called == true) - end - - def test_delegated_routing - @container = RouterActionControllerTest::DelegatedController.new - assert(do_soap_call('Add', 50, 80) == 130) - assert(service.added == 130) - end - - def test_exception_marshaling - @container = RouterActionControllerTest::DirectController.new - result = do_soap_call('Thrower') - exception = result.detail - assert(exception.cause.is_a?(RuntimeError)) - assert_equal("Hi, I'm a SOAP exception", exception.cause.message) - @container.web_service_exception_reporting = false - assert_raises(SoapTestError) do - do_soap_call('Thrower') - end - end - - protected - def service_name - @container.is_a?(RouterActionControllerTest::DelegatedController) ? 'test_service' : 'api' - end - - def service - @container.web_service_object(:test_service) - end - - def do_soap_call(public_method_name, *args) - super(public_method_name, *args) do |test_request, test_response| - response = @container.process(test_request, test_response) - end - end -end diff --git a/actionservice/test/router_wsdl_test.rb b/actionservice/test/router_wsdl_test.rb deleted file mode 100644 index 6812d25579..0000000000 --- a/actionservice/test/router_wsdl_test.rb +++ /dev/null @@ -1,100 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' -require 'wsdl/parser' - -module RouterWsdlTest - class Person < ActionService::Struct - member :id, Integer - member :names, [String] - member :lastname, String - member :deleted, TrueClass - end - - class API < ActionService::API::Base - api_method :add, :expects => [{:a=>:int}, {:b=>:int}], :returns => [:int] - api_method :find_people, :returns => [[Person]] - api_method :nil_returner - end - - class Service < ActionService::Base - web_service_api API - - def add(a, b) - a + b - end - - def find_people - [] - end - - def nil_returner - end - end - - class AbstractController < ActionController::Base - def generate_wsdl(container, uri, soap_action_base) - to_wsdl(container, uri, soap_action_base) - end - end - - class DirectController < AbstractController - web_service_api API - - def add - end - - def find_people - end - - def nil_returner - end - end - - class DelegatedController < AbstractController - web_service_dispatching_mode :delegated - web_service(:test_service) { Service.new } - end -end - -class TC_RouterWsdl < Test::Unit::TestCase - include RouterWsdlTest - - def test_wsdl_generation - ensure_valid_generation DelegatedController.new - ensure_valid_generation DirectController.new - end - - def - - def test_wsdl_action - ensure_valid_wsdl_action DelegatedController.new - ensure_valid_wsdl_action DirectController.new - end - - protected - def ensure_valid_generation(controller) - wsdl = controller.generate_wsdl(controller, 'http://localhost:3000/test/', '/test') - ensure_valid_wsdl(wsdl) - end - - def ensure_valid_wsdl(wsdl) - definitions = WSDL::Parser.new.parse(wsdl) - assert(definitions.is_a?(WSDL::Definitions)) - definitions.bindings.each do |binding| - assert(binding.name.name.index(':').nil?) - end - definitions.services.each do |service| - service.ports.each do |port| - assert(port.name.name.index(':').nil?) - end - end - end - - def ensure_valid_wsdl_action(controller) - test_request = ActionController::TestRequest.new({ 'action' => 'wsdl' }) - test_request.env['REQUEST_METHOD'] = 'GET' - test_request.env['HTTP_HOST'] = 'localhost:3000' - test_response = ActionController::TestResponse.new - wsdl = controller.process(test_request, test_response).body - ensure_valid_wsdl(wsdl) - end -end diff --git a/actionservice/test/struct_test.rb b/actionservice/test/struct_test.rb deleted file mode 100644 index b883c6d991..0000000000 --- a/actionservice/test/struct_test.rb +++ /dev/null @@ -1,40 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' - -module StructTest - class Struct < ActionService::Struct - member :id, Integer - member :name, String - member :items, [String] - member :deleted, :bool - member :emails, [:string] - end -end - -class TC_Struct < Test::Unit::TestCase - def test_members - assert_equal(5, StructTest::Struct.members.size) - assert_equal(Integer, StructTest::Struct.members[:id]) - assert_equal(String, StructTest::Struct.members[:name]) - assert_equal([String], StructTest::Struct.members[:items]) - assert_equal(TrueClass, StructTest::Struct.members[:deleted]) - assert_equal([String], StructTest::Struct.members[:emails]) - end - - def test_initializer_and_lookup - s = StructTest::Struct.new(:id => 5, - :name => 'hello', - :items => ['one', 'two'], - :deleted => true, - :emails => ['test@test.com']) - assert_equal(5, s.id) - assert_equal('hello', s.name) - assert_equal(['one', 'two'], s.items) - assert_equal(true, s.deleted) - assert_equal(['test@test.com'], s.emails) - assert_equal(5, s['id']) - assert_equal('hello', s['name']) - assert_equal(['one', 'two'], s['items']) - assert_equal(true, s['deleted']) - assert_equal(['test@test.com'], s['emails']) - end -end -- cgit v1.2.3