From 9b83e3396180d0dbcb23ec3d71adb198eae7629b Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 21 Nov 2007 15:17:04 +0000 Subject: Ousted ActionWebService from Rails 2.0 git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8180 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionwebservice/lib/action_web_service.rb | 66 ---- actionwebservice/lib/action_web_service/api.rb | 297 ---------------- actionwebservice/lib/action_web_service/base.rb | 38 --- actionwebservice/lib/action_web_service/casting.rb | 138 -------- actionwebservice/lib/action_web_service/client.rb | 3 - .../lib/action_web_service/client/base.rb | 28 -- .../lib/action_web_service/client/soap_client.rb | 113 ------ .../lib/action_web_service/client/xmlrpc_client.rb | 58 ---- .../lib/action_web_service/container.rb | 3 - .../container/action_controller_container.rb | 93 ----- .../container/delegated_container.rb | 86 ----- .../container/direct_container.rb | 69 ---- .../lib/action_web_service/dispatcher.rb | 2 - .../lib/action_web_service/dispatcher/abstract.rb | 207 ----------- .../dispatcher/action_controller_dispatcher.rb | 379 --------------------- .../lib/action_web_service/invocation.rb | 202 ----------- .../lib/action_web_service/protocol.rb | 4 - .../lib/action_web_service/protocol/abstract.rb | 112 ------ .../lib/action_web_service/protocol/discovery.rb | 37 -- .../action_web_service/protocol/soap_protocol.rb | 176 ---------- .../protocol/soap_protocol/marshaler.rb | 235 ------------- .../action_web_service/protocol/xmlrpc_protocol.rb | 122 ------- .../lib/action_web_service/scaffolding.rb | 283 --------------- actionwebservice/lib/action_web_service/struct.rb | 64 ---- .../support/class_inheritable_options.rb | 26 -- .../action_web_service/support/signature_types.rb | 226 ------------ .../templates/scaffolds/layout.erb | 65 ---- .../templates/scaffolds/layout.rhtml | 0 .../templates/scaffolds/methods.erb | 6 - .../templates/scaffolds/methods.rhtml | 0 .../templates/scaffolds/parameters.erb | 29 -- .../templates/scaffolds/parameters.rhtml | 0 .../templates/scaffolds/result.erb | 30 -- .../templates/scaffolds/result.rhtml | 0 .../lib/action_web_service/test_invoke.rb | 110 ------ actionwebservice/lib/action_web_service/version.rb | 9 - actionwebservice/lib/actionwebservice.rb | 1 - 37 files changed, 3317 deletions(-) delete mode 100644 actionwebservice/lib/action_web_service.rb delete mode 100644 actionwebservice/lib/action_web_service/api.rb delete mode 100644 actionwebservice/lib/action_web_service/base.rb delete mode 100644 actionwebservice/lib/action_web_service/casting.rb delete mode 100644 actionwebservice/lib/action_web_service/client.rb delete mode 100644 actionwebservice/lib/action_web_service/client/base.rb delete mode 100644 actionwebservice/lib/action_web_service/client/soap_client.rb delete mode 100644 actionwebservice/lib/action_web_service/client/xmlrpc_client.rb delete mode 100644 actionwebservice/lib/action_web_service/container.rb delete mode 100644 actionwebservice/lib/action_web_service/container/action_controller_container.rb delete mode 100644 actionwebservice/lib/action_web_service/container/delegated_container.rb delete mode 100644 actionwebservice/lib/action_web_service/container/direct_container.rb delete mode 100644 actionwebservice/lib/action_web_service/dispatcher.rb delete mode 100644 actionwebservice/lib/action_web_service/dispatcher/abstract.rb delete mode 100644 actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb delete mode 100644 actionwebservice/lib/action_web_service/invocation.rb delete mode 100644 actionwebservice/lib/action_web_service/protocol.rb delete mode 100644 actionwebservice/lib/action_web_service/protocol/abstract.rb delete mode 100644 actionwebservice/lib/action_web_service/protocol/discovery.rb delete mode 100644 actionwebservice/lib/action_web_service/protocol/soap_protocol.rb delete mode 100644 actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb delete mode 100644 actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb delete mode 100644 actionwebservice/lib/action_web_service/scaffolding.rb delete mode 100644 actionwebservice/lib/action_web_service/struct.rb delete mode 100644 actionwebservice/lib/action_web_service/support/class_inheritable_options.rb delete mode 100644 actionwebservice/lib/action_web_service/support/signature_types.rb delete mode 100644 actionwebservice/lib/action_web_service/templates/scaffolds/layout.erb delete mode 100644 actionwebservice/lib/action_web_service/templates/scaffolds/layout.rhtml delete mode 100644 actionwebservice/lib/action_web_service/templates/scaffolds/methods.erb delete mode 100644 actionwebservice/lib/action_web_service/templates/scaffolds/methods.rhtml delete mode 100644 actionwebservice/lib/action_web_service/templates/scaffolds/parameters.erb delete mode 100644 actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml delete mode 100644 actionwebservice/lib/action_web_service/templates/scaffolds/result.erb delete mode 100644 actionwebservice/lib/action_web_service/templates/scaffolds/result.rhtml delete mode 100644 actionwebservice/lib/action_web_service/test_invoke.rb delete mode 100644 actionwebservice/lib/action_web_service/version.rb delete mode 100644 actionwebservice/lib/actionwebservice.rb (limited to 'actionwebservice/lib') diff --git a/actionwebservice/lib/action_web_service.rb b/actionwebservice/lib/action_web_service.rb deleted file mode 100644 index 0632dd1ec0..0000000000 --- a/actionwebservice/lib/action_web_service.rb +++ /dev/null @@ -1,66 +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' - gem 'activesupport', '>= 1.0.2' - gem 'actionpack', '>= 1.6.0' - gem 'activerecord', '>= 1.9.0' -end - -$:.unshift(File.dirname(__FILE__) + "/action_web_service/vendor/") - -require 'action_web_service/support/class_inheritable_options' -require 'action_web_service/support/signature_types' -require 'action_web_service/base' -require 'action_web_service/client' -require 'action_web_service/invocation' -require 'action_web_service/api' -require 'action_web_service/casting' -require 'action_web_service/struct' -require 'action_web_service/container' -require 'action_web_service/protocol' -require 'action_web_service/dispatcher' -require 'action_web_service/scaffolding' - -ActionWebService::Base.class_eval do - include ActionWebService::Container::Direct - include ActionWebService::Invocation -end - -ActionController::Base.class_eval do - include ActionWebService::Protocol::Discovery - include ActionWebService::Protocol::Soap - include ActionWebService::Protocol::XmlRpc - include ActionWebService::Container::Direct - include ActionWebService::Container::Delegated - include ActionWebService::Container::ActionController - include ActionWebService::Invocation - include ActionWebService::Dispatcher - include ActionWebService::Dispatcher::ActionController - include ActionWebService::Scaffolding -end diff --git a/actionwebservice/lib/action_web_service/api.rb b/actionwebservice/lib/action_web_service/api.rb deleted file mode 100644 index d16dc420d3..0000000000 --- a/actionwebservice/lib/action_web_service/api.rb +++ /dev/null @@ -1,297 +0,0 @@ -module ActionWebService # :nodoc: - module API # :nodoc: - # 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 - # ActionWebService::Base and ActionController::Base derivatives by using - # container.web_service_api, where container is an - # ActionController::Base or a ActionWebService::Base. - # - # See ActionWebService::Container::Direct::ClassMethods for an example - # of use. - class Base - # Whether to transform the public API method names into camel-cased names - class_inheritable_option :inflect_names, true - - # By default only HTTP POST requests are processed - class_inheritable_option :allowed_http_methods, [ :post ] - - # Whether to allow ActiveRecord::Base models in :expects. - # The default is +false+; you should be aware of the security implications - # of allowing this, and ensure that you don't allow remote callers to - # easily overwrite data they should not have access to. - class_inheritable_option :allow_active_record_expects, false - - # 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 ActionWebService::SignatureTypes - - # 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 representing one of the Action Web Service base types. - # See ActionWebService::SignatureTypes 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 Web 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={}) - unless options.is_a?(Hash) - raise(ActionWebServiceError, "Expected a Hash for options") - end - 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) - returns = canonical_signature(returns) - if expects - expects.each do |type| - type = type.element_type if type.is_a?(ArrayType) - if type.type_class.ancestors.include?(ActiveRecord::Base) && !allow_active_record_expects - raise(ActionWebServiceError, "ActiveRecord model classes not allowed in :expects") - end - end - end - name = name.to_sym - public_name = public_api_method_name(name) - method = Method.new(name, public_name, expects, returns) - write_inheritable_hash("api_methods", name => method) - write_inheritable_hash("api_public_method_names", public_name => name) - end - - # Whether the given method name is a service method on this API - # - # class ProjectsApi < ActionWebService::API::Base - # api_method :getCount, :returns => [:int] - # end - # - # ProjectsApi.has_api_method?('GetCount') #=> false - # ProjectsApi.has_api_method?(:getCount) #=> true - 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 - # - # class ProjectsApi < ActionWebService::API::Base - # api_method :getCount, :returns => [:int] - # end - # - # ProjectsApi.has_api_method?(:getCount) #=> false - # ProjectsApi.has_api_method?('GetCount') #=> true - 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 - # - # ProjectsApi.public_api_method_name('GetCount') #=> "GetCount" - # ProjectsApi.public_api_method_name(:getCount) #=> "GetCount" - 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 - # - # class ProjectsApi < ActionWebService::API::Base - # api_method :getCount, :returns => [:int] - # end - # - # ProjectsApi.api_method_name('GetCount') #=> :getCount - 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. - # - # class ProjectsApi < ActionWebService::API::Base - # api_method :getCount, :returns => [:int] - # api_method :getCompletedCount, :returns => [:int] - # end - # - # ProjectsApi.api_methods #=> - # {:getCount=>#, - # :getCompletedCount=>#} - # ProjectsApi.api_methods[:getCount].public_name #=> "GetCount" - def api_methods - read_inheritable_attribute("api_methods") || {} - end - - # The Method instance for the given public API method name, if any - # - # class ProjectsApi < ActionWebService::API::Base - # api_method :getCount, :returns => [:int] - # api_method :getCompletedCount, :returns => [:int] - # end - # - # ProjectsApi.public_api_method_instance('GetCount') #=> <# - # ProjectsApi.public_api_method_instance(:getCount) #=> nil - def public_api_method_instance(public_method_name) - api_method_instance(api_method_name(public_method_name)) - end - - # The Method instance for the given API method name, if any - # - # class ProjectsApi < ActionWebService::API::Base - # api_method :getCount, :returns => [:int] - # api_method :getCompletedCount, :returns => [:int] - # end - # - # ProjectsApi.api_method_instance(:getCount) #=> - # ProjectsApi.api_method_instance('GetCount') #=> - def api_method_instance(method_name) - api_methods[method_name] - end - - # The Method instance for the default API method, if any - def default_api_method_instance - return nil unless name = default_api_method - instance = read_inheritable_attribute("default_api_method_instance") - if instance && instance.name == name - return instance - end - instance = Method.new(name, public_api_method_name(name), nil, nil) - write_inheritable_attribute("default_api_method_instance", instance) - instance - 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(ActionWebServiceError, "Unknown options: #{unknown_option_keys}") - end - end - end - end - - # Represents an API method and its associated metadata, and provides functionality - # to assist in commonly performed API method tasks. - class Method - attr :name - attr :public_name - attr :expects - attr :returns - - def initialize(name, public_name, expects, returns) - @name = name - @public_name = public_name - @expects = expects - @returns = returns - @caster = ActionWebService::Casting::BaseCaster.new(self) - end - - # The list of parameter names for this method - def param_names - return [] unless @expects - @expects.map{ |type| type.name } - end - - # Casts a set of Ruby values into the expected Ruby values - def cast_expects(params) - @caster.cast_expects(params) - end - - # Cast a Ruby return value into the expected Ruby value - def cast_returns(return_value) - @caster.cast_returns(return_value) - end - - # Returns the index of the first expected parameter - # with the given name - def expects_index_of(param_name) - return -1 if @expects.nil? - (0..(@expects.length-1)).each do |i| - return i if @expects[i].name.to_s == param_name.to_s - end - -1 - end - - # Returns a hash keyed by parameter name for the given - # parameter list - def expects_to_hash(params) - return {} if @expects.nil? - h = {} - @expects.zip(params){ |type, param| h[type.name] = param } - h - end - - # Backwards compatibility with previous API - def [](sig_type) - case sig_type - when :expects - @expects.map{|x| compat_signature_entry(x)} - when :returns - @returns.map{|x| compat_signature_entry(x)} - end - end - - # String representation of this method - def to_s - fqn = "" - fqn << (@returns ? (@returns[0].human_name(false) + " ") : "void ") - fqn << "#{@public_name}(" - fqn << @expects.map{ |p| p.human_name }.join(", ") if @expects - fqn << ")" - fqn - end - - private - def compat_signature_entry(entry) - if entry.array? - [compat_signature_entry(entry.element_type)] - else - if entry.spec.is_a?(Hash) - {entry.spec.keys.first => entry.type_class} - else - entry.type_class - end - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/base.rb b/actionwebservice/lib/action_web_service/base.rb deleted file mode 100644 index 6282061d87..0000000000 --- a/actionwebservice/lib/action_web_service/base.rb +++ /dev/null @@ -1,38 +0,0 @@ -module ActionWebService # :nodoc: - class ActionWebServiceError < StandardError # :nodoc: - end - - # An Action Web Service object implements a specified API. - # - # Used by controllers operating in _Delegated_ dispatching mode. - # - # ==== Example - # - # class PersonService < ActionWebService::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 < ActionWebService::API::Base - # api_method :find_person, :expects => [SearchCriteria], :returns => [[Person]] - # api_method :delete_person, :expects => [:int] - # end - # - # class SearchCriteria < ActionWebService::Struct - # 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/actionwebservice/lib/action_web_service/casting.rb b/actionwebservice/lib/action_web_service/casting.rb deleted file mode 100644 index 71f422eaea..0000000000 --- a/actionwebservice/lib/action_web_service/casting.rb +++ /dev/null @@ -1,138 +0,0 @@ -require 'time' -require 'date' -require 'xmlrpc/datetime' - -module ActionWebService # :nodoc: - module Casting # :nodoc: - class CastingError < ActionWebServiceError # :nodoc: - end - - # Performs casting of arbitrary values into the correct types for the signature - class BaseCaster # :nodoc: - def initialize(api_method) - @api_method = api_method - end - - # Coerces the parameters in +params+ (an Enumerable) into the types - # this method expects - def cast_expects(params) - self.class.cast_expects(@api_method, params) - end - - # Coerces the given +return_value+ into the type returned by this - # method - def cast_returns(return_value) - self.class.cast_returns(@api_method, return_value) - end - - class << self - include ActionWebService::SignatureTypes - - def cast_expects(api_method, params) # :nodoc: - return [] if api_method.expects.nil? - api_method.expects.zip(params).map{ |type, param| cast(param, type) } - end - - def cast_returns(api_method, return_value) # :nodoc: - return nil if api_method.returns.nil? - cast(return_value, api_method.returns[0]) - end - - def cast(value, signature_type) # :nodoc: - return value if signature_type.nil? # signature.length != params.length - return nil if value.nil? - # XMLRPC protocol doesn't support nil values. It uses false instead. - # It should never happen for SOAP. - if signature_type.structured? && value.equal?(false) - return nil - end - unless signature_type.array? || signature_type.structured? - return value if canonical_type(value.class) == signature_type.type - end - if signature_type.array? - unless value.respond_to?(:entries) && !value.is_a?(String) - raise CastingError, "Don't know how to cast #{value.class} into #{signature_type.type.inspect}" - end - value.entries.map do |entry| - cast(entry, signature_type.element_type) - end - elsif signature_type.structured? - cast_to_structured_type(value, signature_type) - elsif !signature_type.custom? - cast_base_type(value, signature_type) - end - end - - def cast_base_type(value, signature_type) # :nodoc: - # This is a work-around for the fact that XML-RPC special-cases DateTime values into its own DateTime type - # in order to support iso8601 dates. This doesn't work too well for us, so we'll convert it into a Time, - # with the caveat that we won't be able to handle pre-1970 dates that are sent to us. - # - # See http://dev.rubyonrails.com/ticket/2516 - value = value.to_time if value.is_a?(XMLRPC::DateTime) - - case signature_type.type - when :int - Integer(value) - when :string - value.to_s - when :base64 - if value.is_a?(ActionWebService::Base64) - value - else - ActionWebService::Base64.new(value.to_s) - end - when :bool - return false if value.nil? - return value if value == true || value == false - case value.to_s.downcase - when '1', 'true', 'y', 'yes' - true - when '0', 'false', 'n', 'no' - false - else - raise CastingError, "Don't know how to cast #{value.class} into Boolean" - end - when :float - Float(value) - when :decimal - BigDecimal(value.to_s) - when :time - value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) if value.kind_of?(Hash) - value.kind_of?(Time) ? value : Time.parse(value.to_s) - when :date - value = "%s/%s/%s" % value.values_at(*%w[2 3 1]) if value.kind_of?(Hash) - value.kind_of?(Date) ? value : Date.parse(value.to_s) - when :datetime - value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) if value.kind_of?(Hash) - value.kind_of?(DateTime) ? value : DateTime.parse(value.to_s) - end - end - - def cast_to_structured_type(value, signature_type) # :nodoc: - obj = nil - obj = value if canonical_type(value.class) == canonical_type(signature_type.type) - obj ||= signature_type.type_class.new - if value.respond_to?(:each_pair) - klass = signature_type.type_class - value.each_pair do |name, val| - type = klass.respond_to?(:member_type) ? klass.member_type(name) : nil - val = cast(val, type) if type - # See http://dev.rubyonrails.com/ticket/3567 - val = val.to_time if val.is_a?(XMLRPC::DateTime) - obj.__send__("#{name}=", val) if obj.respond_to?(name) - end - elsif value.respond_to?(:attributes) - signature_type.each_member do |name, type| - val = value.__send__(name) - obj.__send__("#{name}=", cast(val, type)) if obj.respond_to?(name) - end - else - raise CastingError, "Don't know how to cast #{value.class} to #{signature_type.type_class}" - end - obj - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/client.rb b/actionwebservice/lib/action_web_service/client.rb deleted file mode 100644 index 2a1e33054d..0000000000 --- a/actionwebservice/lib/action_web_service/client.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'action_web_service/client/base' -require 'action_web_service/client/soap_client' -require 'action_web_service/client/xmlrpc_client' diff --git a/actionwebservice/lib/action_web_service/client/base.rb b/actionwebservice/lib/action_web_service/client/base.rb deleted file mode 100644 index 9dada7bf98..0000000000 --- a/actionwebservice/lib/action_web_service/client/base.rb +++ /dev/null @@ -1,28 +0,0 @@ -module ActionWebService # :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? - self.perform_invocation(call_name, args) - 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 - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/client/soap_client.rb b/actionwebservice/lib/action_web_service/client/soap_client.rb deleted file mode 100644 index ebabd8ea82..0000000000 --- a/actionwebservice/lib/action_web_service/client/soap_client.rb +++ /dev/null @@ -1,113 +0,0 @@ -require 'soap/rpc/driver' -require 'uri' - -module ActionWebService # :nodoc: - module Client # :nodoc: - - # Implements SOAP client support (using RPC encoding for the messages). - # - # ==== Example Usage - # - # class PersonAPI < ActionWebService::API::Base - # api_method :find_all, :returns => [[Person]] - # end - # - # soap_client = ActionWebService::Client::Soap.new(PersonAPI, "http://...") - # persons = soap_client.find_all - # - class Soap < Base - # provides access to the underlying soap driver - attr_reader :driver - - # Creates a new web service client using the SOAP RPC protocol. - # - # +api+ must be an ActionWebService::API::Base derivative, and - # +endpoint_uri+ must point at the relevant URL to which protocol requests - # will be sent with HTTP POST. - # - # Valid options: - # [:namespace] If the remote server has used a custom namespace to - # declare its custom types, you can specify it here. This would - # be the namespace declared with a [WebService(Namespace = "http://namespace")] attribute - # in .NET, for example. - # [:driver_options] If you want to supply any custom SOAP RPC driver - # options, you can provide them as a Hash here - # - # The :driver_options option can be used to configure the backend SOAP - # RPC driver. An example of configuring the SOAP backend to do - # client-certificate authenticated SSL connections to the server: - # - # opts = {} - # opts['protocol.http.ssl_config.verify_mode'] = 'OpenSSL::SSL::VERIFY_PEER' - # opts['protocol.http.ssl_config.client_cert'] = client_cert_file_path - # opts['protocol.http.ssl_config.client_key'] = client_key_file_path - # opts['protocol.http.ssl_config.ca_file'] = ca_cert_file_path - # client = ActionWebService::Client::Soap.new(api, 'https://some/service', :driver_options => opts) - def initialize(api, endpoint_uri, options={}) - super(api, endpoint_uri) - @namespace = options[:namespace] || 'urn:ActionWebService' - @driver_options = options[:driver_options] || {} - @protocol = ActionWebService::Protocol::Soap::SoapProtocol.new @namespace - @soap_action_base = options[:soap_action_base] - @soap_action_base ||= URI.parse(endpoint_uri).path - @driver = create_soap_rpc_driver(api, endpoint_uri) - @driver_options.each do |name, value| - @driver.options[name.to_s] = value - end - end - - protected - def perform_invocation(method_name, args) - method = @api.api_methods[method_name.to_sym] - args = method.cast_expects(args.dup) rescue args - return_value = @driver.send(method_name, *args) - method.cast_returns(return_value.dup) rescue return_value - end - - def soap_action(method_name) - "#{@soap_action_base}/#{method_name}" - end - - private - def create_soap_rpc_driver(api, endpoint_uri) - @protocol.register_api(api) - driver = SoapDriver.new(endpoint_uri, nil) - driver.mapping_registry = @protocol.marshaler.registry - api.api_methods.each do |name, method| - qname = XSD::QName.new(@namespace, method.public_name) - action = soap_action(method.public_name) - expects = method.expects - returns = method.returns - param_def = [] - if expects - expects.each do |type| - type_binding = @protocol.marshaler.lookup_type(type) - if SOAP::Version >= "1.5.5" - param_def << ['in', type.name.to_s, [type_binding.type.type_class.to_s]] - else - param_def << ['in', type.name, type_binding.mapping] - end - end - end - if returns - type_binding = @protocol.marshaler.lookup_type(returns[0]) - if SOAP::Version >= "1.5.5" - param_def << ['retval', 'return', [type_binding.type.type_class.to_s]] - else - param_def << ['retval', 'return', type_binding.mapping] - end - end - driver.add_method(qname, action, method.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/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb b/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb deleted file mode 100644 index 42b5c5d4f9..0000000000 --- a/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'uri' -require 'xmlrpc/client' - -module ActionWebService # :nodoc: - module Client # :nodoc: - - # Implements XML-RPC client support - # - # ==== Example Usage - # - # class BloggerAPI < ActionWebService::API::Base - # inflect_names false - # api_method :getRecentPosts, :returns => [[Blog::Post]] - # end - # - # blog = ActionWebService::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 ActionWebService::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] - @protocol = ActionWebService::Protocol::XmlRpc::XmlRpcProtocol.new - @client = XMLRPC::Client.new2(endpoint_uri, options[:proxy], options[:timeout]) - end - - protected - def perform_invocation(method_name, args) - method = @api.api_methods[method_name.to_sym] - if method.expects && method.expects.length != args.length - raise(ArgumentError, "#{method.public_name}: wrong number of arguments (#{args.length} for #{method.expects.length})") - end - args = method.cast_expects(args.dup) rescue args - if method.expects - method.expects.each_with_index{ |type, i| args[i] = @protocol.value_to_xmlrpc_wire_format(args[i], type) } - end - ok, return_value = @client.call2(public_name(method_name), *args) - return (method.cast_returns(return_value.dup) rescue return_value) if ok - raise(ClientError, "#{return_value.faultCode}: #{return_value.faultString}") - 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/actionwebservice/lib/action_web_service/container.rb b/actionwebservice/lib/action_web_service/container.rb deleted file mode 100644 index 13d9d8ab56..0000000000 --- a/actionwebservice/lib/action_web_service/container.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'action_web_service/container/direct_container' -require 'action_web_service/container/delegated_container' -require 'action_web_service/container/action_controller_container' diff --git a/actionwebservice/lib/action_web_service/container/action_controller_container.rb b/actionwebservice/lib/action_web_service/container/action_controller_container.rb deleted file mode 100644 index bbc28083c3..0000000000 --- a/actionwebservice/lib/action_web_service/container/action_controller_container.rb +++ /dev/null @@ -1,93 +0,0 @@ -module ActionWebService # :nodoc: - module Container # :nodoc: - module ActionController # :nodoc: - def self.included(base) # :nodoc: - class << base - include ClassMethods - alias_method_chain :inherited, :api - alias_method_chain :web_service_api, :require - end - 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 in - # the API definition class via +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 - create_web_service_client(api_klass, protocol, endpoint_uri, options) - end - protected name - end - end - end - - def web_service_api_with_require(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] - msg = requiree == file_name ? "Missing API definition file in apis/#{file_name}.rb" : "Can't load file: #{requiree}" - raise LoadError.new(msg).copy_blame!(load_error) - 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_with_api(child) - inherited_without_api(child) - begin child.web_service_api(child.controller_path) - rescue MissingSourceFile => e - raise unless e.is_missing?("apis/#{child.controller_path}_api") - end - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/container/delegated_container.rb b/actionwebservice/lib/action_web_service/container/delegated_container.rb deleted file mode 100644 index 5477f8d103..0000000000 --- a/actionwebservice/lib/action_web_service/container/delegated_container.rb +++ /dev/null @@ -1,86 +0,0 @@ -module ActionWebService # :nodoc: - module Container # :nodoc: - module Delegated # :nodoc: - class ContainerError < ActionWebServiceError # :nodoc: - end - - def self.included(base) # :nodoc: - base.extend(ClassMethods) - base.send(:include, ActionWebService::Container::Delegated::InstanceMethods) - end - - module ClassMethods - # Declares a web service that will provide access to the API of the given - # +object+. +object+ must be an ActionWebService::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 ? self.instance_eval(&service) : info[:object] - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/container/direct_container.rb b/actionwebservice/lib/action_web_service/container/direct_container.rb deleted file mode 100644 index 8818d8f459..0000000000 --- a/actionwebservice/lib/action_web_service/container/direct_container.rb +++ /dev/null @@ -1,69 +0,0 @@ -module ActionWebService # :nodoc: - module Container # :nodoc: - module Direct # :nodoc: - class ContainerError < ActionWebServiceError # :nodoc: - end - - def self.included(base) # :nodoc: - base.extend(ClassMethods) - end - - module ClassMethods - # Attaches ActionWebService 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 Web 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 < ActionWebService::Base - # web_service_api MyAPI - # end - # - # class MyAPI < ActionWebService::API::Base - # ... - # end - # - # ==== Controller class example - # - # class MyController < ActionController::Base - # web_service_api MyAPI - # end - # - # class MyAPI < ActionWebService::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(ContainerError, "symbols can only be used for #web_service_api inside of a controller") - end - unless definition.respond_to?(:ancestors) && definition.ancestors.include?(ActionWebService::API::Base) - raise(ContainerError, "#{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 - end - end -end diff --git a/actionwebservice/lib/action_web_service/dispatcher.rb b/actionwebservice/lib/action_web_service/dispatcher.rb deleted file mode 100644 index 601d831373..0000000000 --- a/actionwebservice/lib/action_web_service/dispatcher.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'action_web_service/dispatcher/abstract' -require 'action_web_service/dispatcher/action_controller_dispatcher' diff --git a/actionwebservice/lib/action_web_service/dispatcher/abstract.rb b/actionwebservice/lib/action_web_service/dispatcher/abstract.rb deleted file mode 100644 index cb94d649e7..0000000000 --- a/actionwebservice/lib/action_web_service/dispatcher/abstract.rb +++ /dev/null @@ -1,207 +0,0 @@ -require 'benchmark' - -module ActionWebService # :nodoc: - module Dispatcher # :nodoc: - class DispatcherError < ActionWebService::ActionWebServiceError # :nodoc: - def initialize(*args) - super - set_backtrace(caller) - end - end - - def self.included(base) # :nodoc: - base.class_inheritable_option(:web_service_dispatching_mode, :direct) - base.class_inheritable_option(:web_service_exception_reporting, true) - base.send(:include, ActionWebService::Dispatcher::InstanceMethods) - end - - module InstanceMethods # :nodoc: - private - def invoke_web_service_request(protocol_request) - invocation = web_service_invocation(protocol_request) - if invocation.is_a?(Array) && protocol_request.protocol.is_a?(Protocol::XmlRpc::XmlRpcProtocol) - xmlrpc_multicall_invoke(invocation) - else - web_service_invoke(invocation) - end - end - - def web_service_direct_invoke(invocation) - @method_params = invocation.method_ordered_params - arity = method(invocation.api_method.name).arity rescue 0 - if arity < 0 || arity > 0 - params = @method_params - else - params = [] - end - web_service_filtered_invoke(invocation, params) - end - - def web_service_delegated_invoke(invocation) - web_service_filtered_invoke(invocation, invocation.method_ordered_params) - end - - def web_service_filtered_invoke(invocation, params) - cancellation_reason = nil - return_value = invocation.service.perform_invocation(invocation.api_method.name, params) do |x| - cancellation_reason = x - end - if cancellation_reason - raise(DispatcherError, "request canceled: #{cancellation_reason}") - end - return_value - end - - def web_service_invoke(invocation) - case web_service_dispatching_mode - when :direct - return_value = web_service_direct_invoke(invocation) - when :delegated, :layered - return_value = web_service_delegated_invoke(invocation) - end - web_service_create_response(invocation.protocol, invocation.protocol_options, invocation.api, invocation.api_method, return_value) - end - - def xmlrpc_multicall_invoke(invocations) - responses = [] - invocations.each do |invocation| - if invocation.is_a?(Hash) - responses << [invocation, nil] - next - end - begin - case web_service_dispatching_mode - when :direct - return_value = web_service_direct_invoke(invocation) - when :delegated, :layered - return_value = web_service_delegated_invoke(invocation) - end - api_method = invocation.api_method - if invocation.api.has_api_method?(api_method.name) - response_type = (api_method.returns ? api_method.returns[0] : nil) - return_value = api_method.cast_returns(return_value) - else - response_type = ActionWebService::SignatureTypes.canonical_signature_entry(return_value.class, 0) - end - responses << [return_value, response_type] - rescue Exception => e - responses << [{ 'faultCode' => 3, 'faultString' => e.message }, nil] - end - end - invocation = invocations[0] - invocation.protocol.encode_multicall_response(responses, invocation.protocol_options) - end - - def web_service_invocation(request, level = 0) - public_method_name = request.method_name - invocation = Invocation.new - invocation.protocol = request.protocol - invocation.protocol_options = request.protocol_options - invocation.service_name = request.service_name - if web_service_dispatching_mode == :layered - case invocation.protocol - when Protocol::Soap::SoapProtocol - soap_action = request.protocol_options[:soap_action] - if soap_action && soap_action =~ /^\/\w+\/(\w+)\// - invocation.service_name = $1 - end - when Protocol::XmlRpc::XmlRpcProtocol - if request.method_name =~ /^([^\.]+)\.(.*)$/ - public_method_name = $2 - invocation.service_name = $1 - end - end - end - if invocation.protocol.is_a? Protocol::XmlRpc::XmlRpcProtocol - if public_method_name == 'multicall' && invocation.service_name == 'system' - if level > 0 - raise(DispatcherError, "Recursive system.multicall invocations not allowed") - end - multicall = request.method_params.dup - unless multicall.is_a?(Array) && multicall[0].is_a?(Array) - raise(DispatcherError, "Malformed multicall (expected array of Hash elements)") - end - multicall = multicall[0] - return multicall.map do |item| - raise(DispatcherError, "Multicall elements must be Hash") unless item.is_a?(Hash) - raise(DispatcherError, "Multicall elements must contain a 'methodName' key") unless item.has_key?('methodName') - method_name = item['methodName'] - params = item.has_key?('params') ? item['params'] : [] - multicall_request = request.dup - multicall_request.method_name = method_name - multicall_request.method_params = params - begin - web_service_invocation(multicall_request, level + 1) - rescue Exception => e - {'faultCode' => 4, 'faultMessage' => e.message} - end - end - end - end - case web_service_dispatching_mode - when :direct - invocation.api = self.class.web_service_api - invocation.service = self - when :delegated, :layered - invocation.service = web_service_object(invocation.service_name) - invocation.api = invocation.service.class.web_service_api - end - if invocation.api.nil? - raise(DispatcherError, "no API attached to #{invocation.service.class}") - end - invocation.protocol.register_api(invocation.api) - request.api = invocation.api - if invocation.api.has_public_api_method?(public_method_name) - invocation.api_method = invocation.api.public_api_method_instance(public_method_name) - else - if invocation.api.default_api_method.nil? - raise(DispatcherError, "no such method '#{public_method_name}' on API #{invocation.api}") - else - invocation.api_method = invocation.api.default_api_method_instance - end - end - if invocation.service.nil? - raise(DispatcherError, "no service available for service name #{invocation.service_name}") - end - unless invocation.service.respond_to?(invocation.api_method.name) - raise(DispatcherError, "no such method '#{public_method_name}' on API #{invocation.api} (#{invocation.api_method.name})") - end - request.api_method = invocation.api_method - begin - invocation.method_ordered_params = invocation.api_method.cast_expects(request.method_params.dup) - rescue - logger.warn "Casting of method parameters failed" unless logger.nil? - invocation.method_ordered_params = request.method_params - end - request.method_params = invocation.method_ordered_params - invocation.method_named_params = {} - invocation.api_method.param_names.inject(0) do |m, n| - invocation.method_named_params[n] = invocation.method_ordered_params[m] - m + 1 - end - invocation - end - - def web_service_create_response(protocol, protocol_options, api, api_method, return_value) - if api.has_api_method?(api_method.name) - return_type = api_method.returns ? api_method.returns[0] : nil - return_value = api_method.cast_returns(return_value) - else - return_type = ActionWebService::SignatureTypes.canonical_signature_entry(return_value.class, 0) - end - protocol.encode_response(api_method.public_name + 'Response', return_value, return_type, protocol_options) - end - - class Invocation # :nodoc: - attr_accessor :protocol - attr_accessor :protocol_options - attr_accessor :service_name - attr_accessor :api - attr_accessor :api_method - attr_accessor :method_ordered_params - attr_accessor :method_named_params - attr_accessor :service - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb b/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb deleted file mode 100644 index f9995197a0..0000000000 --- a/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +++ /dev/null @@ -1,379 +0,0 @@ -require 'benchmark' -require 'builder/xmlmarkup' - -module ActionWebService # :nodoc: - module Dispatcher # :nodoc: - module ActionController # :nodoc: - def self.included(base) # :nodoc: - class << base - include ClassMethods - alias_method_chain :inherited, :action_controller - end - base.class_eval do - alias_method :web_service_direct_invoke_without_controller, :web_service_direct_invoke - end - base.add_web_service_api_callback do |klass, api| - if klass.web_service_dispatching_mode == :direct - klass.class_eval 'def api; dispatch_web_service_request; end' - end - end - base.add_web_service_definition_callback do |klass, name, info| - if klass.web_service_dispatching_mode == :delegated - klass.class_eval "def #{name}; dispatch_web_service_request; end" - elsif klass.web_service_dispatching_mode == :layered - klass.class_eval 'def api; dispatch_web_service_request; end' - end - end - base.send(:include, ActionWebService::Dispatcher::ActionController::InstanceMethods) - end - - module ClassMethods # :nodoc: - def inherited_with_action_controller(child) - inherited_without_action_controller(child) - child.send(:include, ActionWebService::Dispatcher::ActionController::WsdlAction) - end - end - - module InstanceMethods # :nodoc: - private - def dispatch_web_service_request - method = request.method.to_s.upcase - allowed_methods = self.class.web_service_api ? (self.class.web_service_api.allowed_http_methods || []) : [ :post ] - allowed_methods = allowed_methods.map{|m| m.to_s.upcase } - if !allowed_methods.include?(method) - render :text => "#{method} not supported", :status=>500 - return - end - exception = nil - begin - ws_request = discover_web_service_request(request) - rescue Exception => e - exception = e - end - if ws_request - ws_response = nil - exception = nil - bm = Benchmark.measure do - begin - ws_response = invoke_web_service_request(ws_request) - rescue Exception => e - exception = e - end - end - log_request(ws_request, request.raw_post) - if exception - log_error(exception) unless logger.nil? - send_web_service_error_response(ws_request, exception) - else - send_web_service_response(ws_response, bm.real) - end - else - exception ||= DispatcherError.new("Malformed SOAP or XML-RPC protocol message") - log_error(exception) unless logger.nil? - send_web_service_error_response(ws_request, exception) - end - rescue Exception => e - log_error(e) unless logger.nil? - send_web_service_error_response(ws_request, e) - end - - def send_web_service_response(ws_response, elapsed=nil) - log_response(ws_response, elapsed) - options = { :type => ws_response.content_type, :disposition => 'inline' } - send_data(ws_response.body, options) - end - - def send_web_service_error_response(ws_request, exception) - if ws_request - unless self.class.web_service_exception_reporting - exception = DispatcherError.new("Internal server error (exception raised)") - end - api_method = ws_request.api_method - public_method_name = api_method ? api_method.public_name : ws_request.method_name - return_type = ActionWebService::SignatureTypes.canonical_signature_entry(Exception, 0) - ws_response = ws_request.protocol.encode_response(public_method_name + 'Response', exception, return_type, ws_request.protocol_options) - send_web_service_response(ws_response) - else - if self.class.web_service_exception_reporting - message = exception.message - backtrace = "\nBacktrace:\n#{exception.backtrace.join("\n")}" - else - message = "Exception raised" - backtrace = "" - end - render :text => "Internal protocol error: #{message}#{backtrace}", :status => 500 - end - end - - def web_service_direct_invoke(invocation) - invocation.method_named_params.each do |name, value| - params[name] = value - end - web_service_direct_invoke_without_controller(invocation) - end - - def log_request(ws_request, body) - unless logger.nil? - name = ws_request.method_name - api_method = ws_request.api_method - params = ws_request.method_params - if api_method && api_method.expects - params = api_method.expects.zip(params).map{ |type, param| "#{type.name}=>#{param.inspect}" } - else - params = params.map{ |param| param.inspect } - end - service = ws_request.service_name - logger.debug("\nWeb Service Request: #{name}(#{params.join(", ")}) Entrypoint: #{service}") - logger.debug(indent(body)) - end - end - - def log_response(ws_response, elapsed=nil) - unless logger.nil? - elapsed = (elapsed ? " (%f):" % elapsed : ":") - logger.debug("\nWeb Service Response" + elapsed + " => #{ws_response.return_value.inspect}") - logger.debug(indent(ws_response.body)) - end - end - - def indent(body) - body.split(/\n/).map{|x| " #{x}"}.join("\n") - end - end - - module WsdlAction # :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 - options = { :type => 'text/xml', :disposition => 'inline' } - send_data(to_wsdl, options) - rescue Exception => e - log_error(e) unless logger.nil? - end - when :post - render :text => 'POST not supported', :status => 500 - end - end - - private - def base_uri - host = request.host_with_port - relative_url_root = request.relative_url_root - scheme = request.ssl? ? 'https' : 'http' - '%s://%s%s/%s/' % [scheme, host, relative_url_root, self.class.controller_path] - end - - def to_wsdl - xml = '' - dispatching_mode = web_service_dispatching_mode - global_service_name = wsdl_service_name - namespace = wsdl_namespace || 'urn:ActionWebService' - soap_action_base = "/#{controller_name}" - - marshaler = ActionWebService::Protocol::Soap::SoapMarshaler.new(namespace) - apis = {} - case dispatching_mode - when :direct - api = self.class.web_service_api - web_service_name = controller_class_name.sub(/Controller$/, '').underscore - apis[web_service_name] = [api, register_api(api, marshaler)] - when :delegated, :layered - self.class.web_services.each do |web_service_name, info| - service = web_service_object(web_service_name) - api = service.class.web_service_api - apis[web_service_name] = [api, register_api(api, marshaler)] - end - end - custom_types = [] - apis.values.each do |api, bindings| - bindings.each do |b| - custom_types << b unless custom_types.include?(b) - end - end - - xm = Builder::XmlMarkup.new(:target => xml, :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 - # Generate XSD - if custom_types.size > 0 - xm.types do - xm.xsd(:schema, 'xmlns' => XsdNs, 'targetNamespace' => namespace) do - custom_types.each do |binding| - case - when binding.type.array? - xm.xsd(:complexType, 'name' => binding.type_name) do - xm.xsd(:complexContent) do - xm.xsd(:restriction, 'base' => 'soapenc:Array') do - xm.xsd(:attribute, 'ref' => 'soapenc:arrayType', - 'wsdl:arrayType' => binding.element_binding.qualified_type_name('typens') + '[]') - end - end - end - when binding.type.structured? - xm.xsd(:complexType, 'name' => binding.type_name) do - xm.xsd(:all) do - binding.type.each_member do |name, type| - b = marshaler.register_type(type) - xm.xsd(:element, 'name' => name, 'type' => b.qualified_type_name('typens')) - end - end - end - end - end - end - end - end - - # APIs - apis.each do |api_name, values| - api = values[0] - api.api_methods.each do |name, method| - gen = lambda do |msg_name, direction| - xm.message('name' => message_name_for(api_name, msg_name)) do - sym = nil - if direction == :out - returns = method.returns - if returns - binding = marshaler.register_type(returns[0]) - xm.part('name' => 'return', 'type' => binding.qualified_type_name('typens')) - end - else - expects = method.expects - expects.each do |type| - binding = marshaler.register_type(type) - xm.part('name' => type.name, 'type' => binding.qualified_type_name('typens')) - end if expects - end - end - end - public_name = method.public_name - gen.call(public_name, :in) - gen.call("#{public_name}Response", :out) - end - - # Port - port_name = port_name_for(global_service_name, api_name) - xm.portType('name' => port_name) do - api.api_methods.each do |name, method| - xm.operation('name' => method.public_name) do - xm.input('message' => "typens:" + message_name_for(api_name, method.public_name)) - xm.output('message' => "typens:" + message_name_for(api_name, "#{method.public_name}Response")) - end - end - end - - # Bind it - binding_name = binding_name_for(global_service_name, api_name) - xm.binding('name' => binding_name, 'type' => "typens:#{port_name}") do - xm.soap(:binding, 'style' => 'rpc', 'transport' => SoapHttpTransport) - api.api_methods.each do |name, method| - xm.operation('name' => method.public_name) do - case web_service_dispatching_mode - when :direct - soap_action = soap_action_base + "/api/" + method.public_name - when :delegated, :layered - soap_action = soap_action_base \ - + "/" + api_name.to_s \ - + "/" + method.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 it - xm.service('name' => "#{global_service_name}Service") do - apis.each do |api_name, values| - port_name = port_name_for(global_service_name, api_name) - binding_name = binding_name_for(global_service_name, api_name) - case web_service_dispatching_mode - when :direct, :layered - binding_target = 'api' - when :delegated - binding_target = api_name.to_s - end - xm.port('name' => port_name, 'binding' => "typens:#{binding_name}") do - xm.soap(:address, 'location' => "#{base_uri}#{binding_target}") - end - end - end - end - end - - def port_name_for(global_service, service) - "#{global_service}#{service.to_s.camelize}Port" - end - - def binding_name_for(global_service, service) - "#{global_service}#{service.to_s.camelize}Binding" - end - - def message_name_for(api_name, message_name) - mode = web_service_dispatching_mode - if mode == :layered || mode == :delegated - api_name.to_s + '-' + message_name - else - message_name - end - end - - def register_api(api, marshaler) - bindings = {} - traverse_custom_types(api, marshaler, bindings) do |binding| - bindings[binding] = nil unless bindings.has_key?(binding) - element_binding = binding.element_binding - bindings[element_binding] = nil if element_binding && !bindings.has_key?(element_binding) - end - bindings.keys - end - - def traverse_custom_types(api, marshaler, bindings, &block) - api.api_methods.each do |name, method| - expects, returns = method.expects, method.returns - expects.each{ |type| traverse_type(marshaler, type, bindings, &block) if type.custom? } if expects - returns.each{ |type| traverse_type(marshaler, type, bindings, &block) if type.custom? } if returns - end - end - - def traverse_type(marshaler, type, bindings, &block) - binding = marshaler.register_type(type) - return if bindings.has_key?(binding) - bindings[binding] = nil - yield binding - if type.array? - yield marshaler.register_type(type.element_type) - type = type.element_type - end - type.each_member{ |name, type| traverse_type(marshaler, type, bindings, &block) } if type.structured? - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/invocation.rb b/actionwebservice/lib/action_web_service/invocation.rb deleted file mode 100644 index 2a9121ee26..0000000000 --- a/actionwebservice/lib/action_web_service/invocation.rb +++ /dev/null @@ -1,202 +0,0 @@ -module ActionWebService # :nodoc: - module Invocation # :nodoc: - class InvocationError < ActionWebService::ActionWebServiceError # :nodoc: - end - - def self.included(base) # :nodoc: - base.extend(ClassMethods) - base.send(:include, ActionWebService::Invocation::InstanceMethods) - end - - # Invocation interceptors provide a means to execute custom code before - # and after method invocations on ActionWebService::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 < ActionWebService::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.included(base) - base.class_eval do - alias_method_chain :perform_invocation, :interception - end - end - - def perform_invocation_with_interception(method_name, params, &block) - return if before_invocation(method_name, params, &block) == false - return_value = perform_invocation_without_interception(method_name, params) - after_invocation(method_name, params, return_value) - return_value - end - - def perform_invocation(method_name, params) - send(method_name, *params) - 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 - end -end diff --git a/actionwebservice/lib/action_web_service/protocol.rb b/actionwebservice/lib/action_web_service/protocol.rb deleted file mode 100644 index 053e9cb4be..0000000000 --- a/actionwebservice/lib/action_web_service/protocol.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'action_web_service/protocol/abstract' -require 'action_web_service/protocol/discovery' -require 'action_web_service/protocol/soap_protocol' -require 'action_web_service/protocol/xmlrpc_protocol' diff --git a/actionwebservice/lib/action_web_service/protocol/abstract.rb b/actionwebservice/lib/action_web_service/protocol/abstract.rb deleted file mode 100644 index fff5f622c9..0000000000 --- a/actionwebservice/lib/action_web_service/protocol/abstract.rb +++ /dev/null @@ -1,112 +0,0 @@ -module ActionWebService # :nodoc: - module Protocol # :nodoc: - class ProtocolError < ActionWebServiceError # :nodoc: - end - - class AbstractProtocol # :nodoc: - def setup(controller) - end - - def decode_action_pack_request(action_pack_request) - end - - def encode_action_pack_request(service_name, public_method_name, raw_body, options={}) - klass = options[:request_class] || SimpleActionPackRequest - request = klass.new - request.request_parameters['action'] = service_name.to_s - request.env['RAW_POST_DATA'] = raw_body - request.env['REQUEST_METHOD'] = 'POST' - request.env['HTTP_CONTENT_TYPE'] = 'text/xml' - request - end - - def decode_request(raw_request, service_name, protocol_options={}) - end - - def encode_request(method_name, params, param_types) - end - - def decode_response(raw_response) - end - - def encode_response(method_name, return_value, return_type, protocol_options={}) - end - - def protocol_client(api, protocol_name, endpoint_uri, options) - end - - def register_api(api) - end - end - - class Request # :nodoc: - attr :protocol - attr_accessor :method_name - attr_accessor :method_params - attr :service_name - attr_accessor :api - attr_accessor :api_method - attr :protocol_options - - def initialize(protocol, method_name, method_params, service_name, api=nil, api_method=nil, protocol_options=nil) - @protocol = protocol - @method_name = method_name - @method_params = method_params - @service_name = service_name - @api = api - @api_method = api_method - @protocol_options = protocol_options || {} - end - end - - class Response # :nodoc: - attr :body - attr :content_type - attr :return_value - - def initialize(body, content_type, return_value) - @body = body - @content_type = content_type - @return_value = return_value - end - end - - class SimpleActionPackRequest < ActionController::AbstractRequest # :nodoc: - def initialize - @env = {} - @qparams = {} - @rparams = {} - @cookies = {} - reset_session - end - - def query_parameters - @qparams - end - - def request_parameters - @rparams - end - - def env - @env - end - - def host - '' - end - - def cookies - @cookies - end - - def session - @session - end - - def reset_session - @session = {} - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/protocol/discovery.rb b/actionwebservice/lib/action_web_service/protocol/discovery.rb deleted file mode 100644 index 3d4e0818da..0000000000 --- a/actionwebservice/lib/action_web_service/protocol/discovery.rb +++ /dev/null @@ -1,37 +0,0 @@ -module ActionWebService # :nodoc: - module Protocol # :nodoc: - module Discovery # :nodoc: - def self.included(base) - base.extend(ClassMethods) - base.send(:include, ActionWebService::Protocol::Discovery::InstanceMethods) - end - - module ClassMethods # :nodoc: - def register_protocol(klass) - write_inheritable_array("web_service_protocols", [klass]) - end - end - - module InstanceMethods # :nodoc: - private - def discover_web_service_request(action_pack_request) - (self.class.read_inheritable_attribute("web_service_protocols") || []).each do |protocol| - protocol = protocol.create(self) - request = protocol.decode_action_pack_request(action_pack_request) - return request unless request.nil? - end - nil - end - - def create_web_service_client(api, protocol_name, endpoint_uri, options) - (self.class.read_inheritable_attribute("web_service_protocols") || []).each do |protocol| - protocol = protocol.create(self) - client = protocol.protocol_client(api, protocol_name, endpoint_uri, options) - return client unless client.nil? - end - nil - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb b/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb deleted file mode 100644 index 1bce496a7b..0000000000 --- a/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb +++ /dev/null @@ -1,176 +0,0 @@ -require 'action_web_service/protocol/soap_protocol/marshaler' -require 'soap/streamHandler' -require 'action_web_service/client/soap_client' - -module ActionWebService # :nodoc: - module API # :nodoc: - class Base # :nodoc: - def self.soap_client(endpoint_uri, options={}) - ActionWebService::Client::Soap.new self, endpoint_uri, options - end - end - end - - module Protocol # :nodoc: - module Soap # :nodoc: - def self.included(base) - base.register_protocol(SoapProtocol) - base.class_inheritable_option(:wsdl_service_name) - base.class_inheritable_option(:wsdl_namespace) - end - - class SoapProtocol < AbstractProtocol # :nodoc: - AWSEncoding = 'UTF-8' - XSDEncoding = 'UTF8' - - attr :marshaler - - def initialize(namespace=nil) - namespace ||= 'urn:ActionWebService' - @marshaler = SoapMarshaler.new namespace - end - - def self.create(controller) - SoapProtocol.new(controller.wsdl_namespace) - end - - def decode_action_pack_request(action_pack_request) - return nil unless soap_action = has_valid_soap_action?(action_pack_request) - service_name = action_pack_request.parameters['action'] - input_encoding = parse_charset(action_pack_request.env['HTTP_CONTENT_TYPE']) - protocol_options = { - :soap_action => soap_action, - :charset => input_encoding - } - decode_request(action_pack_request.raw_post, service_name, protocol_options) - end - - def encode_action_pack_request(service_name, public_method_name, raw_body, options={}) - request = super - request.env['HTTP_SOAPACTION'] = '/soap/%s/%s' % [service_name, public_method_name] - request - end - - def decode_request(raw_request, service_name, protocol_options={}) - envelope = SOAP::Processor.unmarshal(raw_request, :charset => protocol_options[:charset]) - unless envelope - raise ProtocolError, "Failed to parse SOAP request message" - end - request = envelope.body.request - method_name = request.elename.name - params = request.collect{ |k, v| marshaler.soap_to_ruby(request[k]) } - Request.new(self, method_name, params, service_name, nil, nil, protocol_options) - end - - def encode_request(method_name, params, param_types) - param_types.each{ |type| marshaler.register_type(type) } if param_types - qname = XSD::QName.new(marshaler.namespace, method_name) - param_def = [] - if param_types - params = param_types.zip(params).map do |type, param| - param_def << ['in', type.name, marshaler.lookup_type(type).mapping] - [type.name, marshaler.ruby_to_soap(param)] - end - else - params = [] - end - request = SOAP::RPC::SOAPMethodRequest.new(qname, param_def) - request.set_param(params) - envelope = create_soap_envelope(request) - SOAP::Processor.marshal(envelope) - end - - def decode_response(raw_response) - envelope = SOAP::Processor.unmarshal(raw_response) - unless envelope - raise ProtocolError, "Failed to parse SOAP request message" - end - method_name = envelope.body.request.elename.name - return_value = envelope.body.response - return_value = marshaler.soap_to_ruby(return_value) unless return_value.nil? - [method_name, return_value] - end - - def encode_response(method_name, return_value, return_type, protocol_options={}) - if return_type - return_binding = marshaler.register_type(return_type) - marshaler.annotate_arrays(return_binding, return_value) - end - qname = XSD::QName.new(marshaler.namespace, method_name) - if return_value.nil? - response = SOAP::RPC::SOAPMethodResponse.new(qname, nil) - else - if return_value.is_a?(Exception) - detail = SOAP::Mapping::SOAPException.new(return_value) - response = SOAP::SOAPFault.new( - SOAP::SOAPQName.new('%s:%s' % [SOAP::SOAPNamespaceTag, 'Server']), - SOAP::SOAPString.new(return_value.to_s), - SOAP::SOAPString.new(self.class.name), - marshaler.ruby_to_soap(detail)) - else - if return_type - param_def = [['retval', 'return', marshaler.lookup_type(return_type).mapping]] - response = SOAP::RPC::SOAPMethodResponse.new(qname, param_def) - response.retval = marshaler.ruby_to_soap(return_value) - else - response = SOAP::RPC::SOAPMethodResponse.new(qname, nil) - end - end - end - envelope = create_soap_envelope(response) - - # FIXME: This is not thread-safe, but StringFactory_ in SOAP4R only - # reads target encoding from the XSD::Charset.encoding variable. - # This is required to ensure $KCODE strings are converted - # correctly to UTF-8 for any values of $KCODE. - previous_encoding = XSD::Charset.encoding - XSD::Charset.encoding = XSDEncoding - response_body = SOAP::Processor.marshal(envelope, :charset => AWSEncoding) - XSD::Charset.encoding = previous_encoding - - Response.new(response_body, "text/xml; charset=#{AWSEncoding}", return_value) - end - - def protocol_client(api, protocol_name, endpoint_uri, options={}) - return nil unless protocol_name == :soap - ActionWebService::Client::Soap.new(api, endpoint_uri, options) - end - - def register_api(api) - api.api_methods.each do |name, method| - method.expects.each{ |type| marshaler.register_type(type) } if method.expects - method.returns.each{ |type| marshaler.register_type(type) } if method.returns - end - end - - private - def has_valid_soap_action?(request) - return nil unless request.method == :post - soap_action = request.env['HTTP_SOAPACTION'] - return nil unless soap_action - soap_action = soap_action.dup - soap_action.gsub!(/^"/, '') - soap_action.gsub!(/"$/, '') - soap_action.strip! - return nil if soap_action.empty? - soap_action - end - - def create_soap_envelope(body) - header = SOAP::SOAPHeader.new - body = SOAP::SOAPBody.new(body) - SOAP::SOAPEnvelope.new(header, body) - end - - def parse_charset(content_type) - return AWSEncoding if content_type.nil? - if /^text\/xml(?:\s*;\s*charset=([^"]+|"[^"]+"))$/i =~ content_type - $1 - else - AWSEncoding - end - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb b/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb deleted file mode 100644 index 1873396277..0000000000 --- a/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb +++ /dev/null @@ -1,235 +0,0 @@ -require 'soap/mapping' - -module ActionWebService - module Protocol - module Soap - # Workaround for SOAP4R return values changing - class Registry < SOAP::Mapping::Registry - if SOAP::Version >= "1.5.4" - def find_mapped_soap_class(obj_class) - return @map.instance_eval { @obj2soap[obj_class][0] } - end - - def find_mapped_obj_class(soap_class) - return @map.instance_eval { @soap2obj[soap_class][0] } - end - end - end - - class SoapMarshaler - attr :namespace - attr :registry - - def initialize(namespace=nil) - @namespace = namespace || 'urn:ActionWebService' - @registry = Registry.new - @type2binding = {} - register_static_factories - end - - def soap_to_ruby(obj) - SOAP::Mapping.soap2obj(obj, @registry) - end - - def ruby_to_soap(obj) - soap = SOAP::Mapping.obj2soap(obj, @registry) - soap.elename = XSD::QName.new if SOAP::Version >= "1.5.5" && soap.elename == XSD::QName::EMPTY - soap - end - - def register_type(type) - return @type2binding[type] if @type2binding.has_key?(type) - - if type.array? - array_mapping = @registry.find_mapped_soap_class(Array) - qname = XSD::QName.new(@namespace, soap_type_name(type.element_type.type_class.name) + 'Array') - element_type_binding = register_type(type.element_type) - @type2binding[type] = SoapBinding.new(self, qname, type, array_mapping, element_type_binding) - elsif (mapping = @registry.find_mapped_soap_class(type.type_class) rescue nil) - qname = mapping[2] ? mapping[2][:type] : nil - qname ||= soap_base_type_name(mapping[0]) - @type2binding[type] = SoapBinding.new(self, qname, type, mapping) - else - qname = XSD::QName.new(@namespace, soap_type_name(type.type_class.name)) - @registry.add(type.type_class, - SOAP::SOAPStruct, - typed_struct_factory(type.type_class), - { :type => qname }) - mapping = @registry.find_mapped_soap_class(type.type_class) - @type2binding[type] = SoapBinding.new(self, qname, type, mapping) - end - - if type.structured? - type.each_member do |m_name, m_type| - register_type(m_type) - end - end - - @type2binding[type] - end - alias :lookup_type :register_type - - def annotate_arrays(binding, value) - if value.nil? - return - elsif binding.type.array? - mark_typed_array(value, binding.element_binding.qname) - if binding.element_binding.type.custom? - value.each do |element| - annotate_arrays(binding.element_binding, element) - end - end - elsif binding.type.structured? - binding.type.each_member do |name, type| - member_binding = register_type(type) - member_value = value.respond_to?('[]') ? value[name] : value.send(name) - annotate_arrays(member_binding, member_value) if type.custom? - end - end - end - - private - def typed_struct_factory(type_class) - if Object.const_defined?('ActiveRecord') - if type_class.ancestors.include?(ActiveRecord::Base) - qname = XSD::QName.new(@namespace, soap_type_name(type_class.name)) - type_class.instance_variable_set('@qname', qname) - return SoapActiveRecordStructFactory.new - end - end - SOAP::Mapping::Registry::TypedStructFactory - end - - def mark_typed_array(array, qname) - (class << array; self; end).class_eval do - define_method(:arytype) do - qname - end - end - end - - def soap_base_type_name(type) - xsd_type = type.ancestors.find{ |c| c.const_defined? 'Type' } - xsd_type ? xsd_type.const_get('Type') : XSD::XSDAnySimpleType::Type - end - - def soap_type_name(type_name) - type_name.gsub(/::/, '..') - end - - def register_static_factories - @registry.add(ActionWebService::Base64, SOAP::SOAPBase64, SoapBase64Factory.new, nil) - mapping = @registry.find_mapped_soap_class(ActionWebService::Base64) - @type2binding[ActionWebService::Base64] = - SoapBinding.new(self, SOAP::SOAPBase64::Type, ActionWebService::Base64, mapping) - @registry.add(Array, SOAP::SOAPArray, SoapTypedArrayFactory.new, nil) - @registry.add(::BigDecimal, SOAP::SOAPDouble, SOAP::Mapping::Registry::BasetypeFactory, {:derived_class => true}) - end - end - - class SoapBinding - attr :qname - attr :type - attr :mapping - attr :element_binding - - def initialize(marshaler, qname, type, mapping, element_binding=nil) - @marshaler = marshaler - @qname = qname - @type = type - @mapping = mapping - @element_binding = element_binding - end - - def type_name - @type.custom? ? @qname.name : nil - end - - def qualified_type_name(ns=nil) - if @type.custom? - "#{ns ? ns : @qname.namespace}:#{@qname.name}" - else - ns = XSD::NS.new - ns.assign(XSD::Namespace, SOAP::XSDNamespaceTag) - ns.assign(SOAP::EncodingNamespace, "soapenc") - xsd_klass = mapping[0].ancestors.find{|c| c.const_defined?('Type')} - return ns.name(XSD::AnyTypeName) unless xsd_klass - ns.name(xsd_klass.const_get('Type')) - end - end - - def eql?(other) - @qname == other.qname - end - alias :== :eql? - - def hash - @qname.hash - end - end - - class SoapActiveRecordStructFactory < SOAP::Mapping::Factory - def obj2soap(soap_class, obj, info, map) - unless obj.is_a?(ActiveRecord::Base) - return nil - end - soap_obj = soap_class.new(obj.class.instance_variable_get('@qname')) - obj.class.columns.each do |column| - key = column.name.to_s - value = obj.send(key) - soap_obj[key] = SOAP::Mapping._obj2soap(value, map) - end - soap_obj - end - - def soap2obj(obj_class, node, info, map) - unless node.type == obj_class.instance_variable_get('@qname') - return false - end - obj = obj_class.new - node.each do |key, value| - obj[key] = value.data - end - obj.instance_variable_set('@new_record', false) - return true, obj - end - end - - class SoapTypedArrayFactory < SOAP::Mapping::Factory - def obj2soap(soap_class, obj, info, map) - unless obj.respond_to?(:arytype) - return nil - end - soap_obj = soap_class.new(SOAP::ValueArrayName, 1, obj.arytype) - mark_marshalled_obj(obj, soap_obj) - obj.each do |item| - child = SOAP::Mapping._obj2soap(item, map) - soap_obj.add(child) - end - soap_obj - end - - def soap2obj(obj_class, node, info, map) - return false - end - end - - class SoapBase64Factory < SOAP::Mapping::Factory - def obj2soap(soap_class, obj, info, map) - unless obj.is_a?(ActionWebService::Base64) - return nil - end - return soap_class.new(obj) - end - - def soap2obj(obj_class, node, info, map) - unless node.type == SOAP::SOAPBase64::Type - return false - end - return true, obj_class.new(node.string) - end - end - - end - end -end diff --git a/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb b/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb deleted file mode 100644 index dfa4afc670..0000000000 --- a/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb +++ /dev/null @@ -1,122 +0,0 @@ -require 'xmlrpc/marshal' -require 'action_web_service/client/xmlrpc_client' - -module XMLRPC # :nodoc: - class FaultException # :nodoc: - alias :message :faultString - end - - class Create - def wrong_type(value) - if BigDecimal === value - [true, value.to_f] - else - false - end - end - end -end - -module ActionWebService # :nodoc: - module API # :nodoc: - class Base # :nodoc: - def self.xmlrpc_client(endpoint_uri, options={}) - ActionWebService::Client::XmlRpc.new self, endpoint_uri, options - end - end - end - - module Protocol # :nodoc: - module XmlRpc # :nodoc: - def self.included(base) - base.register_protocol(XmlRpcProtocol) - end - - class XmlRpcProtocol < AbstractProtocol # :nodoc: - def self.create(controller) - XmlRpcProtocol.new - end - - def decode_action_pack_request(action_pack_request) - service_name = action_pack_request.parameters['action'] - decode_request(action_pack_request.raw_post, service_name) - end - - def decode_request(raw_request, service_name) - method_name, params = XMLRPC::Marshal.load_call(raw_request) - Request.new(self, method_name, params, service_name) - rescue - return nil - end - - def encode_request(method_name, params, param_types) - if param_types - params = params.dup - param_types.each_with_index{ |type, i| params[i] = value_to_xmlrpc_wire_format(params[i], type) } - end - XMLRPC::Marshal.dump_call(method_name, *params) - end - - def decode_response(raw_response) - [nil, XMLRPC::Marshal.load_response(raw_response)] - end - - def encode_response(method_name, return_value, return_type, protocol_options={}) - if return_value && return_type - return_value = value_to_xmlrpc_wire_format(return_value, return_type) - end - return_value = false if return_value.nil? - raw_response = XMLRPC::Marshal.dump_response(return_value) - Response.new(raw_response, 'text/xml', return_value) - end - - def encode_multicall_response(responses, protocol_options={}) - result = responses.map do |return_value, return_type| - if return_value && return_type - return_value = value_to_xmlrpc_wire_format(return_value, return_type) - return_value = [return_value] unless return_value.nil? - end - return_value = false if return_value.nil? - return_value - end - raw_response = XMLRPC::Marshal.dump_response(result) - Response.new(raw_response, 'text/xml', result) - end - - def protocol_client(api, protocol_name, endpoint_uri, options={}) - return nil unless protocol_name == :xmlrpc - ActionWebService::Client::XmlRpc.new(api, endpoint_uri, options) - end - - def value_to_xmlrpc_wire_format(value, value_type) - if value_type.array? - value.map{ |val| value_to_xmlrpc_wire_format(val, value_type.element_type) } - else - if value.is_a?(ActionWebService::Struct) - struct = {} - value.class.members.each do |name, type| - member_value = value[name] - next if member_value.nil? - struct[name.to_s] = value_to_xmlrpc_wire_format(member_value, type) - end - struct - elsif value.is_a?(ActiveRecord::Base) - struct = {} - value.attributes.each do |key, member_value| - next if member_value.nil? - struct[key.to_s] = member_value - end - struct - elsif value.is_a?(ActionWebService::Base64) - XMLRPC::Base64.new(value) - elsif value.is_a?(Exception) && !value.is_a?(XMLRPC::FaultException) - XMLRPC::FaultException.new(2, value.message) - else - value - end - end - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/scaffolding.rb b/actionwebservice/lib/action_web_service/scaffolding.rb deleted file mode 100644 index f94a7ee916..0000000000 --- a/actionwebservice/lib/action_web_service/scaffolding.rb +++ /dev/null @@ -1,283 +0,0 @@ -require 'benchmark' -require 'pathname' - -module ActionWebService - module Scaffolding # :nodoc: - class ScaffoldingError < ActionWebServiceError # :nodoc: - end - - def self.included(base) - base.extend(ClassMethods) - end - - # Web service invocation scaffolding provides a way to quickly invoke web service methods in a controller. The - # generated scaffold actions have default views to let you enter the method parameters and view the - # results. - # - # Example: - # - # class ApiController < ActionController - # web_service_scaffold :invoke - # end - # - # This example generates an +invoke+ action in the +ApiController+ that you can navigate to from - # your browser, select the API method, enter its parameters, and perform the invocation. - # - # If you want to customize the default views, create the following views in "app/views": - # - # * action_name/methods.erb - # * action_name/parameters.erb - # * action_name/result.erb - # * action_name/layout.erb - # - # Where action_name is the name of the action you gave to ClassMethods#web_service_scaffold. - # - # You can use the default views in RAILS_DIR/lib/action_web_service/templates/scaffolds as - # a guide. - module ClassMethods - # Generates web service invocation scaffolding for the current controller. The given action name - # can then be used as the entry point for invoking API methods from a web browser. - def web_service_scaffold(action_name) - add_template_helper(Helpers) - module_eval <<-"end_eval", __FILE__, __LINE__ + 1 - def #{action_name} - if request.method == :get - setup_invocation_assigns - render_invocation_scaffold 'methods' - end - end - - def #{action_name}_method_params - if request.method == :get - setup_invocation_assigns - render_invocation_scaffold 'parameters' - end - end - - def #{action_name}_submit - if request.method == :post - setup_invocation_assigns - protocol_name = params['protocol'] ? params['protocol'].to_sym : :soap - case protocol_name - when :soap - @protocol = Protocol::Soap::SoapProtocol.create(self) - when :xmlrpc - @protocol = Protocol::XmlRpc::XmlRpcProtocol.create(self) - end - bm = Benchmark.measure do - @protocol.register_api(@scaffold_service.api) - post_params = params['method_params'] ? params['method_params'].dup : nil - params = [] - @scaffold_method.expects.each_with_index do |spec, i| - params << post_params[i.to_s] - end if @scaffold_method.expects - params = @scaffold_method.cast_expects(params) - method_name = public_method_name(@scaffold_service.name, @scaffold_method.public_name) - @method_request_xml = @protocol.encode_request(method_name, params, @scaffold_method.expects) - new_request = @protocol.encode_action_pack_request(@scaffold_service.name, @scaffold_method.public_name, @method_request_xml) - prepare_request(new_request, @scaffold_service.name, @scaffold_method.public_name) - self.request = new_request - if @scaffold_container.dispatching_mode != :direct - request.parameters['action'] = @scaffold_service.name - end - dispatch_web_service_request - @method_response_xml = response.body - method_name, obj = @protocol.decode_response(@method_response_xml) - return if handle_invocation_exception(obj) - @method_return_value = @scaffold_method.cast_returns(obj) - end - @method_elapsed = bm.real - add_instance_variables_to_assigns - reset_invocation_response - render_invocation_scaffold 'result' - end - end - - private - def setup_invocation_assigns - @scaffold_class = self.class - @scaffold_action_name = "#{action_name}" - @scaffold_container = WebServiceModel::Container.new(self) - if params['service'] && params['method'] - @scaffold_service = @scaffold_container.services.find{ |x| x.name == params['service'] } - @scaffold_method = @scaffold_service.api_methods[params['method']] - end - add_instance_variables_to_assigns - end - - def render_invocation_scaffold(action) - customized_template = "\#{self.class.controller_path}/#{action_name}/\#{action}" - default_template = scaffold_path(action) - if template_exists?(customized_template) - content = @template.render :file => customized_template - else - content = @template.render :file => default_template - end - @template.instance_variable_set("@content_for_layout", content) - if self.active_layout.nil? - render :file => scaffold_path("layout") - else - render :file => self.active_layout - end - end - - def scaffold_path(template_name) - File.dirname(__FILE__) + "/templates/scaffolds/" + template_name + ".erb" - end - - def reset_invocation_response - erase_render_results - response.headers = ::ActionController::AbstractResponse::DEFAULT_HEADERS.merge("cookie" => []) - end - - def public_method_name(service_name, method_name) - if web_service_dispatching_mode == :layered && @protocol.is_a?(ActionWebService::Protocol::XmlRpc::XmlRpcProtocol) - service_name + '.' + method_name - else - method_name - end - end - - def prepare_request(new_request, service_name, method_name) - new_request.parameters.update(request.parameters) - request.env.each{ |k, v| new_request.env[k] = v unless new_request.env.has_key?(k) } - if web_service_dispatching_mode == :layered && @protocol.is_a?(ActionWebService::Protocol::Soap::SoapProtocol) - new_request.env['HTTP_SOAPACTION'] = "/\#{controller_name()}/\#{service_name}/\#{method_name}" - end - end - - def handle_invocation_exception(obj) - exception = nil - if obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && obj.detail.cause.is_a?(Exception) - exception = obj.detail.cause - elsif obj.is_a?(XMLRPC::FaultException) - exception = obj - end - return unless exception - reset_invocation_response - rescue_action(exception) - true - end - end_eval - end - end - - module Helpers # :nodoc: - def method_parameter_input_fields(method, type, field_name_base, idx, was_structured=false) - if type.array? - return content_tag('em', "Typed array input fields not supported yet (#{type.name})") - end - if type.structured? - return content_tag('em', "Nested structural types not supported yet (#{type.name})") if was_structured - parameters = "" - type.each_member do |member_name, member_type| - label = method_parameter_label(member_name, member_type) - nested_content = method_parameter_input_fields( - method, - member_type, - "#{field_name_base}[#{idx}][#{member_name}]", - idx, - true) - if member_type.custom? - parameters << content_tag('li', label) - parameters << content_tag('ul', nested_content) - else - parameters << content_tag('li', label + ' ' + nested_content) - end - end - content_tag('ul', parameters) - else - # If the data source was structured previously we already have the index set - field_name_base = "#{field_name_base}[#{idx}]" unless was_structured - - case type.type - when :int - text_field_tag "#{field_name_base}" - when :string - text_field_tag "#{field_name_base}" - when :base64 - text_area_tag "#{field_name_base}", nil, :size => "40x5" - when :bool - radio_button_tag("#{field_name_base}", "true") + " True" + - radio_button_tag("#{field_name_base}", "false") + "False" - when :float - text_field_tag "#{field_name_base}" - when :time, :datetime - time = Time.now - i = 0 - %w|year month day hour minute second|.map do |name| - i += 1 - send("select_#{name}", time, :prefix => "#{field_name_base}[#{i}]", :discard_type => true) - end.join - when :date - date = Date.today - i = 0 - %w|year month day|.map do |name| - i += 1 - send("select_#{name}", date, :prefix => "#{field_name_base}[#{i}]", :discard_type => true) - end.join - end - end - end - - def method_parameter_label(name, type) - name.to_s.capitalize + ' (' + type.human_name(false) + ')' - end - - def service_method_list(service) - action = @scaffold_action_name + '_method_params' - methods = service.api_methods_full.map do |desc, name| - content_tag("li", link_to(desc, :action => action, :service => service.name, :method => name)) - end - content_tag("ul", methods.join("\n")) - end - end - - module WebServiceModel # :nodoc: - class Container # :nodoc: - attr :services - attr :dispatching_mode - - def initialize(real_container) - @real_container = real_container - @dispatching_mode = @real_container.class.web_service_dispatching_mode - @services = [] - if @dispatching_mode == :direct - @services << Service.new(@real_container.controller_name, @real_container) - else - @real_container.class.web_services.each do |name, obj| - @services << Service.new(name, @real_container.instance_eval{ web_service_object(name) }) - end - end - end - end - - class Service # :nodoc: - attr :name - attr :object - attr :api - attr :api_methods - attr :api_methods_full - - def initialize(name, real_service) - @name = name.to_s - @object = real_service - @api = @object.class.web_service_api - if @api.nil? - raise ScaffoldingError, "No web service API attached to #{object.class}" - end - @api_methods = {} - @api_methods_full = [] - @api.api_methods.each do |name, method| - @api_methods[method.public_name.to_s] = method - @api_methods_full << [method.to_s, method.public_name.to_s] - end - end - - def to_s - self.name.camelize - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/struct.rb b/actionwebservice/lib/action_web_service/struct.rb deleted file mode 100644 index 00eafc169f..0000000000 --- a/actionwebservice/lib/action_web_service/struct.rb +++ /dev/null @@ -1,64 +0,0 @@ -module ActionWebService - # To send structured types across the wire, derive from ActionWebService::Struct, - # and use +member+ to declare structure members. - # - # ActionWebService::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 < ActionWebService::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 in method - # signatures. - class Struct - # If a Hash is given as argument to an ActionWebService::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 - - # Iterates through each member - def each_pair(&block) - self.class.members.each do |name, type| - yield name, self.__send__(name) - end - end - - class << self - # Creates a structure member with the specified +name+ and +type+. Generates - # accessor methods for reading and writing the member value. - def member(name, type) - name = name.to_sym - type = ActionWebService::SignatureTypes.canonical_signature_entry({ name => type }, 0) - write_inheritable_hash("struct_members", name => 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 - - def member_type(name) # :nodoc: - members[name.to_sym] - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/support/class_inheritable_options.rb b/actionwebservice/lib/action_web_service/support/class_inheritable_options.rb deleted file mode 100644 index 4d1c2ed471..0000000000 --- a/actionwebservice/lib/action_web_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/actionwebservice/lib/action_web_service/support/signature_types.rb b/actionwebservice/lib/action_web_service/support/signature_types.rb deleted file mode 100644 index 66c86bf6da..0000000000 --- a/actionwebservice/lib/action_web_service/support/signature_types.rb +++ /dev/null @@ -1,226 +0,0 @@ -module ActionWebService # :nodoc: - # Action Web Service supports the following base types in a signature: - # - # [:int] Represents an integer value, will be cast to an integer using Integer(value) - # [:string] Represents a string value, will be cast to an string using the to_s method on an object - # [:base64] Represents a Base 64 value, will contain the binary bytes of a Base 64 value sent by the caller - # [:bool] Represents a boolean value, whatever is passed will be cast to boolean (true, '1', 'true', 'y', 'yes' are taken to represent true; false, '0', 'false', 'n', 'no' and nil represent false) - # [:float] Represents a floating point value, will be cast to a float using Float(value) - # [:time] Represents a timestamp, will be cast to a Time object - # [:datetime] Represents a timestamp, will be cast to a DateTime object - # [:date] Represents a date, will be cast to a Date object - # - # For structured types, you'll need to pass in the Class objects of - # ActionWebService::Struct and ActiveRecord::Base derivatives. - module SignatureTypes - def canonical_signature(signature) # :nodoc: - return nil if signature.nil? - unless signature.is_a?(Array) - raise(ActionWebServiceError, "Expected signature to be an Array") - end - i = -1 - signature.map{ |spec| canonical_signature_entry(spec, i += 1) } - end - - def canonical_signature_entry(spec, i) # :nodoc: - orig_spec = spec - name = "param#{i}" - if spec.is_a?(Hash) - name, spec = spec.keys.first, spec.values.first - end - type = spec - if spec.is_a?(Array) - ArrayType.new(orig_spec, canonical_signature_entry(spec[0], 0), name) - else - type = canonical_type(type) - if type.is_a?(Symbol) - BaseType.new(orig_spec, type, name) - else - StructuredType.new(orig_spec, type, name) - end - end - end - - def canonical_type(type) # :nodoc: - type_name = symbol_name(type) || class_to_type_name(type) - type = type_name || type - return canonical_type_name(type) if type.is_a?(Symbol) - type - end - - def canonical_type_name(name) # :nodoc: - name = name.to_sym - case name - when :int, :integer, :fixnum, :bignum - :int - when :string, :text - :string - when :base64, :binary - :base64 - when :bool, :boolean - :bool - when :float, :double - :float - when :decimal - :decimal - when :time, :timestamp - :time - when :datetime - :datetime - when :date - :date - else - raise(TypeError, "#{name} is not a valid base type") - end - end - - def canonical_type_class(type) # :nodoc: - type = canonical_type(type) - type.is_a?(Symbol) ? type_name_to_class(type) : type - end - - def symbol_name(name) # :nodoc: - return name.to_sym if name.is_a?(Symbol) || name.is_a?(String) - nil - end - - def class_to_type_name(klass) # :nodoc: - klass = klass.class unless klass.is_a?(Class) - if derived_from?(Integer, klass) || derived_from?(Fixnum, klass) || derived_from?(Bignum, klass) - :int - elsif klass == String - :string - elsif klass == Base64 - :base64 - elsif klass == TrueClass || klass == FalseClass - :bool - elsif derived_from?(Float, klass) || derived_from?(Precision, klass) || derived_from?(Numeric, klass) - :float - elsif klass == Time - :time - elsif klass == DateTime - :datetime - elsif klass == Date - :date - else - nil - end - end - - def type_name_to_class(name) # :nodoc: - case canonical_type_name(name) - when :int - Integer - when :string - String - when :base64 - Base64 - when :bool - TrueClass - when :float - Float - when :decimal - BigDecimal - when :time - Time - when :date - Date - when :datetime - DateTime - else - nil - end - end - - def derived_from?(ancestor, child) # :nodoc: - child.ancestors.include?(ancestor) - end - - module_function :type_name_to_class - module_function :class_to_type_name - module_function :symbol_name - module_function :canonical_type_class - module_function :canonical_type_name - module_function :canonical_type - module_function :canonical_signature_entry - module_function :canonical_signature - module_function :derived_from? - end - - class BaseType # :nodoc: - include SignatureTypes - - attr :spec - attr :type - attr :type_class - attr :name - - def initialize(spec, type, name) - @spec = spec - @type = canonical_type(type) - @type_class = canonical_type_class(@type) - @name = name - end - - def custom? - false - end - - def array? - false - end - - def structured? - false - end - - def human_name(show_name=true) - type_type = array? ? element_type.type.to_s : self.type.to_s - str = array? ? (type_type + '[]') : type_type - show_name ? (str + " " + name.to_s) : str - end - end - - class ArrayType < BaseType # :nodoc: - attr :element_type - - def initialize(spec, element_type, name) - super(spec, Array, name) - @element_type = element_type - end - - def custom? - true - end - - def array? - true - end - end - - class StructuredType < BaseType # :nodoc: - def each_member - if @type_class.respond_to?(:members) - @type_class.members.each do |name, type| - yield name, type - end - elsif @type_class.respond_to?(:columns) - i = -1 - @type_class.columns.each do |column| - yield column.name, canonical_signature_entry(column.type, i += 1) - end - end - end - - def custom? - true - end - - def structured? - true - end - end - - class Base64 < String # :nodoc: - end -end diff --git a/actionwebservice/lib/action_web_service/templates/scaffolds/layout.erb b/actionwebservice/lib/action_web_service/templates/scaffolds/layout.erb deleted file mode 100644 index 167613f681..0000000000 --- a/actionwebservice/lib/action_web_service/templates/scaffolds/layout.erb +++ /dev/null @@ -1,65 +0,0 @@ - - - <%= @scaffold_class.wsdl_service_name %> Web Service - - - - -<%= @content_for_layout %> - - - diff --git a/actionwebservice/lib/action_web_service/templates/scaffolds/layout.rhtml b/actionwebservice/lib/action_web_service/templates/scaffolds/layout.rhtml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionwebservice/lib/action_web_service/templates/scaffolds/methods.erb b/actionwebservice/lib/action_web_service/templates/scaffolds/methods.erb deleted file mode 100644 index 60dfe23f07..0000000000 --- a/actionwebservice/lib/action_web_service/templates/scaffolds/methods.erb +++ /dev/null @@ -1,6 +0,0 @@ -<% @scaffold_container.services.each do |service| %> - -

API Methods for <%= service %>

- <%= service_method_list(service) %> - -<% end %> diff --git a/actionwebservice/lib/action_web_service/templates/scaffolds/methods.rhtml b/actionwebservice/lib/action_web_service/templates/scaffolds/methods.rhtml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionwebservice/lib/action_web_service/templates/scaffolds/parameters.erb b/actionwebservice/lib/action_web_service/templates/scaffolds/parameters.erb deleted file mode 100644 index 767284e0d4..0000000000 --- a/actionwebservice/lib/action_web_service/templates/scaffolds/parameters.erb +++ /dev/null @@ -1,29 +0,0 @@ -

Method Invocation Details for <%= @scaffold_service %>#<%= @scaffold_method.public_name %>

- -<% form_tag(:action => @scaffold_action_name + '_submit') do -%> -<%= hidden_field_tag "service", @scaffold_service.name %> -<%= hidden_field_tag "method", @scaffold_method.public_name %> - -

-
-<%= select_tag 'protocol', options_for_select([['SOAP', 'soap'], ['XML-RPC', 'xmlrpc']], params['protocol']) %> -

- -<% if @scaffold_method.expects %> - -Method Parameters:
-<% @scaffold_method.expects.each_with_index do |type, i| %> -

-
- <%= method_parameter_input_fields(@scaffold_method, type, "method_params", i) %> -

-<% end %> - -<% end %> - -<%= submit_tag "Invoke" %> -<% end -%> - -

-<%= link_to "Back", :action => @scaffold_action_name %> -

diff --git a/actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml b/actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionwebservice/lib/action_web_service/templates/scaffolds/result.erb b/actionwebservice/lib/action_web_service/templates/scaffolds/result.erb deleted file mode 100644 index 5317688fcd..0000000000 --- a/actionwebservice/lib/action_web_service/templates/scaffolds/result.erb +++ /dev/null @@ -1,30 +0,0 @@ -

Method Invocation Result for <%= @scaffold_service %>#<%= @scaffold_method.public_name %>

- -

-Invocation took <%= '%f' % @method_elapsed %> seconds -

- -

-Return Value:
-

-<%= h @method_return_value.inspect %>
-
-

- -

-Request XML:
-

-<%= h @method_request_xml %>
-
-

- -

-Response XML:
-

-<%= h @method_response_xml %>
-
-

- -

-<%= link_to "Back", :action => @scaffold_action_name + '_method_params', :method => @scaffold_method.public_name, :service => @scaffold_service.name %> -

diff --git a/actionwebservice/lib/action_web_service/templates/scaffolds/result.rhtml b/actionwebservice/lib/action_web_service/templates/scaffolds/result.rhtml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/actionwebservice/lib/action_web_service/test_invoke.rb b/actionwebservice/lib/action_web_service/test_invoke.rb deleted file mode 100644 index 7e714c941c..0000000000 --- a/actionwebservice/lib/action_web_service/test_invoke.rb +++ /dev/null @@ -1,110 +0,0 @@ -require 'test/unit' - -module Test # :nodoc: - module Unit # :nodoc: - class TestCase # :nodoc: - private - # invoke the specified API method - def invoke_direct(method_name, *args) - prepare_request('api', 'api', method_name, *args) - @controller.process(@request, @response) - decode_rpc_response - end - alias_method :invoke, :invoke_direct - - # invoke the specified API method on the specified service - def invoke_delegated(service_name, method_name, *args) - prepare_request(service_name.to_s, service_name, method_name, *args) - @controller.process(@request, @response) - decode_rpc_response - end - - # invoke the specified layered API method on the correct service - def invoke_layered(service_name, method_name, *args) - prepare_request('api', service_name, method_name, *args) - @controller.process(@request, @response) - decode_rpc_response - end - - # ---------------------- internal --------------------------- - - def prepare_request(action, service_name, api_method_name, *args) - @request.recycle! - @request.request_parameters['action'] = action - @request.env['REQUEST_METHOD'] = 'POST' - @request.env['HTTP_CONTENT_TYPE'] = 'text/xml' - @request.env['RAW_POST_DATA'] = encode_rpc_call(service_name, api_method_name, *args) - case protocol - when ActionWebService::Protocol::Soap::SoapProtocol - soap_action = "/#{@controller.controller_name}/#{service_name}/#{public_method_name(service_name, api_method_name)}" - @request.env['HTTP_SOAPACTION'] = soap_action - when ActionWebService::Protocol::XmlRpc::XmlRpcProtocol - @request.env.delete('HTTP_SOAPACTION') - end - end - - def encode_rpc_call(service_name, api_method_name, *args) - case @controller.web_service_dispatching_mode - when :direct - api = @controller.class.web_service_api - when :delegated, :layered - api = @controller.web_service_object(service_name.to_sym).class.web_service_api - end - protocol.register_api(api) - method = api.api_methods[api_method_name.to_sym] - raise ArgumentError, "wrong number of arguments for rpc call (#{args.length} for #{method.expects.length})" if method && method.expects && args.length != method.expects.length - protocol.encode_request(public_method_name(service_name, api_method_name), args.dup, method.expects) - end - - def decode_rpc_response - public_method_name, return_value = protocol.decode_response(@response.body) - exception = is_exception?(return_value) - raise exception if exception - return_value - end - - def public_method_name(service_name, api_method_name) - public_name = service_api(service_name).public_api_method_name(api_method_name) - if @controller.web_service_dispatching_mode == :layered && protocol.is_a?(ActionWebService::Protocol::XmlRpc::XmlRpcProtocol) - '%s.%s' % [service_name.to_s, public_name] - else - public_name - end - end - - def service_api(service_name) - case @controller.web_service_dispatching_mode - when :direct - @controller.class.web_service_api - when :delegated, :layered - @controller.web_service_object(service_name.to_sym).class.web_service_api - end - end - - def protocol - if @protocol.nil? - @protocol ||= ActionWebService::Protocol::Soap::SoapProtocol.create(@controller) - else - case @protocol - when :xmlrpc - @protocol = ActionWebService::Protocol::XmlRpc::XmlRpcProtocol.create(@controller) - when :soap - @protocol = ActionWebService::Protocol::Soap::SoapProtocol.create(@controller) - else - @protocol - end - end - end - - def is_exception?(obj) - case protocol - when :soap, ActionWebService::Protocol::Soap::SoapProtocol - (obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && \ - obj.detail.cause.is_a?(Exception)) ? obj.detail.cause : nil - when :xmlrpc, ActionWebService::Protocol::XmlRpc::XmlRpcProtocol - obj.is_a?(XMLRPC::FaultException) ? obj : nil - end - end - end - end -end diff --git a/actionwebservice/lib/action_web_service/version.rb b/actionwebservice/lib/action_web_service/version.rb deleted file mode 100644 index a1b3d59297..0000000000 --- a/actionwebservice/lib/action_web_service/version.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ActionWebService - module VERSION #:nodoc: - MAJOR = 1 - MINOR = 2 - TINY = 5 - - STRING = [MAJOR, MINOR, TINY].join('.') - end -end diff --git a/actionwebservice/lib/actionwebservice.rb b/actionwebservice/lib/actionwebservice.rb deleted file mode 100644 index 25e3aa8e8e..0000000000 --- a/actionwebservice/lib/actionwebservice.rb +++ /dev/null @@ -1 +0,0 @@ -require 'action_web_service' -- cgit v1.2.3