aboutsummaryrefslogtreecommitdiffstats
path: root/actionwebservice/lib/action_web_service/api.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionwebservice/lib/action_web_service/api.rb')
-rw-r--r--actionwebservice/lib/action_web_service/api.rb297
1 files changed, 0 insertions, 297 deletions
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
- # <tt>container.web_service_api</tt>, where <tt>container</tt> 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 <tt>:expects</tt>.
- # 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:
- # [<tt>:expects</tt>] Signature for the method input parameters
- # [<tt>:returns</tt>] Signature for the method return value
- # [<tt>:expects_and_returns</tt>] 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=>#<ActionWebService::API::Method:0x24379d8 ...>,
- # :getCompletedCount=>#<ActionWebService::API::Method:0x2437794 ...>}
- # 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') #=> <#<ActionWebService::API::Method:0x24379d8 ...>
- # 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) #=> <ActionWebService::API::Method:0x24379d8 ...>
- # ProjectsApi.api_method_instance('GetCount') #=> <ActionWebService::API::Method:0x24379d8 ...>
- 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