aboutsummaryrefslogtreecommitdiffstats
path: root/actionwebservice/lib/action_web_service/api/base.rb
diff options
context:
space:
mode:
authorLeon Breedt <bitserf@gmail.com>2005-04-02 21:03:36 +0000
committerLeon Breedt <bitserf@gmail.com>2005-04-02 21:03:36 +0000
commitaaea48fe9826b9e5d2d5b92795a297b8f238c58d (patch)
treee7c01c7f95d467f837c1f96d58dac74c3c902610 /actionwebservice/lib/action_web_service/api/base.rb
parentaa09c770e9b5400683be11952673017295246de7 (diff)
downloadrails-aaea48fe9826b9e5d2d5b92795a297b8f238c58d.tar.gz
rails-aaea48fe9826b9e5d2d5b92795a297b8f238c58d.tar.bz2
rails-aaea48fe9826b9e5d2d5b92795a297b8f238c58d.zip
* collapse 'ws' back into protocols, it just added complexity and indirection, and was hard to extend.
* extract casting into seperate support file * ensure casting always does the right thing for return values, should fix interoperability issues with Ecto and possibly other XML-RPC clients * add functional unit tests for scaffolding * represent signature items with classes instead of symbols/Class objects, much more flexible * tweak logging to always show casted versions of parameters and return values, if possible. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1072 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionwebservice/lib/action_web_service/api/base.rb')
-rw-r--r--actionwebservice/lib/action_web_service/api/base.rb146
1 files changed, 18 insertions, 128 deletions
diff --git a/actionwebservice/lib/action_web_service/api/base.rb b/actionwebservice/lib/action_web_service/api/base.rb
index 03e406cfc3..c9fb9f967f 100644
--- a/actionwebservice/lib/action_web_service/api/base.rb
+++ b/actionwebservice/lib/action_web_service/api/base.rb
@@ -1,8 +1,5 @@
module ActionWebService # :nodoc:
module API # :nodoc:
- class CastingError < ActionWebService::ActionWebServiceError
- end
-
# A web service API class specifies the methods that will be available for
# invocation for an API. It also contains metadata such as the method type
# signature hints.
@@ -31,6 +28,8 @@ module ActionWebService # :nodoc:
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.
#
@@ -70,10 +69,9 @@ module ActionWebService # :nodoc:
expects = canonical_signature(expects)
returns = canonical_signature(returns)
if expects
- expects.each do |param|
- klass = WS::BaseTypes.canonical_param_type_class(param)
- klass = klass[0] if klass.is_a?(Array)
- if klass.ancestors.include?(ActiveRecord::Base) && !allow_active_record_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
@@ -138,16 +136,6 @@ module ActionWebService # :nodoc:
instance
end
- # Creates a dummy API Method instance for the given public method name
- def dummy_public_api_method_instance(public_method_name)
- Method.new(public_method_name.underscore.to_sym, public_method_name, nil, nil)
- end
-
- # Creates a dummy API Method instance for the given method name
- def dummy_api_method_instance(method_name)
- Method.new(method_name, public_api_method_name(method_name), nil, nil)
- end
-
private
def api_public_method_names
read_inheritable_attribute("api_public_method_names") || {}
@@ -159,11 +147,6 @@ module ActionWebService # :nodoc:
raise(ActionWebServiceError, "Unknown options: #{unknown_option_keys}")
end
end
-
- def canonical_signature(signature)
- return nil if signature.nil?
- signature.map{|spec| WS::BaseTypes.canonical_param_type_spec(spec)}
- end
end
end
@@ -180,134 +163,41 @@ module ActionWebService # :nodoc:
@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
- i = 0
- @expects.map{ |spec| param_name(spec, i += 1) }
- end
-
- # The name for the given parameter
- def param_name(spec, i=1)
- spec.is_a?(Hash) ? spec.keys.first.to_s : "p#{i}"
- end
-
- # The type of the parameter declared in +spec+. Is either
- # the Class of the parameter, or its canonical name (if its a
- # base type). Typed array specifications will return the type of
- # their elements.
- def param_type(spec)
- spec = spec.values.first if spec.is_a?(Hash)
- param_type = spec.is_a?(Array) ? spec[0] : spec
- WS::BaseTypes::class_to_type_name(param_type) rescue param_type
- end
-
- # The Class of the parameter declared in +spec+.
- def param_class(spec)
- type = param_type(spec)
- type.is_a?(Symbol) ? WS::BaseTypes.type_name_to_class(type) : type
- end
-
- # Registers all types known to this method with the given marshaler
- def register_types(marshaler)
- @expects.each{ |x| marshaler.register_type(x) } if @expects
- @returns.each{ |x| marshaler.register_type(x) } if @returns
+ @expects.map{ |type| type.name }
end
- # Encodes an RPC call for this method. Casting is performed if
- # the <tt>:strict</tt> option is given.
- def encode_rpc_call(marshaler, encoder, params, options={})
- name = options[:method_name] || @public_name
- expects = @expects || []
- returns = @returns || []
- (expects + returns).each { |spec| marshaler.register_type spec }
- (0..(params.length-1)).each do |i|
- spec = expects[i] || params[i].class
- type_binding = marshaler.lookup_type(spec)
- param_info = WS::ParamInfo.create(spec, type_binding, i)
- if options[:strict]
- value = marshaler.cast_outbound_recursive(params[i], spec)
- else
- value = params[i]
- end
- param = WS::Param.new(value, param_info)
- params[i] = marshaler.marshal(param)
- end
- encoder.encode_rpc_call(name, params)
- end
-
- # Encodes an RPC response for this method. Casting is performed if
- # the <tt>:strict</tt> option is given.
- def encode_rpc_response(marshaler, encoder, return_value, options={})
- if !return_value.nil? && @returns
- return_type = @returns[0]
- type_binding = marshaler.register_type(return_type)
- param_info = WS::ParamInfo.create(return_type, type_binding, 0)
- if options[:strict]
- return_value = marshaler.cast_inbound_recursive(return_value, return_type)
- end
- return_value = marshaler.marshal(WS::Param.new(return_value, param_info))
- else
- return_value = nil
- end
- encoder.encode_rpc_response(response_name(encoder), return_value)
- end
-
- # Casts a set of WS::Param values into the appropriate
- # Ruby values
- def cast_expects_ws2ruby(marshaler, params)
- return [] if @expects.nil?
- i = 0
- @expects.map do |spec|
- value = marshaler.cast_inbound_recursive(params[i].value, spec)
- i += 1
- value
- end
- end
-
# Casts a set of Ruby values into the expected Ruby values
- def cast_expects(marshaler, params)
- return [] if @expects.nil?
- i = 0
- @expects.map do |spec|
- value = marshaler.cast_outbound_recursive(params[i], spec)
- i += 1
- value
- end
+ def cast_expects(params)
+ @caster.cast_expects(params)
end
# Cast a Ruby return value into the expected Ruby value
- def cast_returns(marshaler, return_value)
- return nil if @returns.nil?
- marshaler.cast_inbound_recursive(return_value, @returns[0])
+ def cast_returns(return_value)
+ @caster.cast_returns(return_value)
end
# String representation of this method
def to_s
fqn = ""
- fqn << (@returns ? (friendly_param(@returns[0], nil) + " ") : "void ")
+ fqn << (@returns ? (friendly_param(@returns[0], false) + " ") : "void ")
fqn << "#{@public_name}("
- if @expects
- i = 0
- fqn << @expects.map{ |p| friendly_param(p, i+= 1) }.join(", ")
- end
+ fqn << @expects.map{ |p| friendly_param(p) }.join(", ") if @expects
fqn << ")"
fqn
end
private
- def response_name(encoder)
- encoder.is_a?(WS::Encoding::SoapRpcEncoding) ? (@public_name + "Response") : @public_name
- end
-
- def friendly_param(spec, i)
- name = param_name(spec, i)
- type = param_type(spec)
- spec = spec.values.first if spec.is_a?(Hash)
- type = spec.is_a?(Array) ? (type.to_s + "[]") : type.to_s
- i ? (type + " " + name) : type
+ def friendly_param(type, show_name=true)
+ name = type.name.to_s
+ type_type = type.type.to_s
+ str = type.array?? (type_type + '[]') : type_type
+ show_name ? (str + " " + name) : str
end
end
end