Permalink
Browse files

Fix a ton of issues with AWS (yes, Kent saved it from being unbundled…

… in 1.1) #4038 [Kent Sibilev]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3750 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
dhh committed Mar 3, 2006
1 parent 94725b0 commit 3d4965765cd47df7f3f9d3db4cbb117936b1c939
@@ -1,5 +1,19 @@
*SVN*

* Fix that marshaler couldn't handle ActiveRecord models defined in a different namespace (#2392).

* Fix that marshaler couldn't handle structs with members of ActiveRecord type (#1889).

* Fix that marshaler couldn't handle nil values for inner structs (#3576).

* Fix that changes to ActiveWebService::API::Base required restarting of the server (#2390).

* Fix scaffolding for signatures with :date, :time and :base64 types (#3321, #2769, #2078).

* Fix for incorrect casting of TrueClass/FalseClass instances (#2633, #3421).

* Fix for incompatibility problems with SOAP4R 1.5.5 (#2553) [Kent Sibilev]

* Update from LGPL to MIT license as per Minero Aoki's permission. [Marcel Molina Jr.]

* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.]
@@ -30,6 +30,14 @@ Rake::TestTask.new { |t|
t.verbose = true
}

SCHEMA_PATH = File.join(File.dirname(__FILE__), *%w(test fixtures db_definitions))

desc 'Build the MySQL test database'
task :build_database do
%x( mysqladmin create activewebservice_unittest )
%x( mysql activewebservice_unittest < #{File.join(SCHEMA_PATH, 'mysql.sql')} )
end


# Generate the RDoc documentation
Rake::RDocTask.new { |rdoc|
@@ -14,6 +14,10 @@ module API # :nodoc:
# See ActionWebService::Container::Direct::ClassMethods for an example
# of use.
class Base
# Action WebService API subclasses should be reloaded by the dispatcher in Rails
# when Dependencies.mechanism = :load.
include Reloadable::Subclasses

# Whether to transform the public API method names into camel-cased names
class_inheritable_option :inflect_names, true

@@ -25,12 +25,16 @@ class ActionWebServiceError < StandardError # :nodoc:
# api_method :delete_person, :expects => [:int]
# end
#
# class SearchCriteria < ActionStruct::Base
# class SearchCriteria < ActionWebService::Struct
# member :firstname, :string
# member :lastname, :string
# member :email, :string
# end
class Base
# Action WebService subclasses should be reloaded by the dispatcher in Rails
# when Dependencies.mechanism = :load.
include Reloadable::Subclasses

# Whether to report exceptions back to the caller in the protocol's exception
# format
class_inheritable_option :web_service_exception_reporting, true
@@ -41,6 +41,11 @@ def cast_returns(api_method, return_value) # :nodoc:
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
@@ -108,6 +113,8 @@ def cast_to_structured_type(value, signature_type) # :nodoc:
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)
@@ -80,12 +80,20 @@ def create_soap_rpc_driver(api, endpoint_uri)
if expects
expects.each do |type|
type_binding = @protocol.marshaler.lookup_type(type)
param_def << ['in', type.name, type_binding.mapping]
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])
param_def << ['retval', 'return', type_binding.mapping]
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
@@ -32,7 +32,9 @@ def soap_to_ruby(obj)
end

def ruby_to_soap(obj)
SOAP::Mapping.obj2soap(obj, @registry)
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)
@@ -63,12 +65,21 @@ def register_type(type)
end

@type2binding[type] = array_binding ? array_binding : type_binding

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 binding.type.array?
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|
@@ -50,10 +50,10 @@ def decode_response(raw_response)
end

def encode_response(method_name, return_value, return_type, protocol_options={})
return_value = true if return_value.nil?
if return_type
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
@@ -65,14 +65,23 @@ def #{action_name}_submit
when :xmlrpc
@protocol = Protocol::XmlRpc::XmlRpcProtocol.create(self)
end
@invocation_cgi = request.respond_to?(:cgi) ? request.cgi : nil
bm = Benchmark.measure do
@protocol.register_api(@scaffold_service.api)
post_params = params['method_params'] ? params['method_params'].dup : nil
params = []
if @scaffold_method.expects
@scaffold_method.expects.length.times do |i|
params << post_params[i.to_s]
@scaffold_method.expects.each_with_index do |spec, i|
case spec.type
when :date
date = post_params[i.to_s]
params << (date['2'] + '/' + date['3'] + '/' + date['1'])
when :datetime, :time
date = post_params[i.to_s]
params << (date['2'] + '/' + date['3'] + '/' + date['1'] + ' ' +
date['4'] + ':' + date['5'] + ':' + date['6'])
else
params << post_params[i.to_s]
end
end
end
params = @scaffold_method.cast_expects(params)
@@ -130,14 +139,8 @@ def scaffold_path(template_name)
end
def reset_invocation_response
template = response.template
if @invocation_cgi
@response = ::ActionController::CgiResponse.new(@invocation_cgi)
else
@response = ::ActionController::TestResponse.new
end
response.template = template
@performed_render = false
erase_render_results
@response.headers = ::ActionController::AbstractResponse::DEFAULT_HEADERS.merge("cookie" => [])
end
def public_method_name(service_name, method_name)
@@ -173,7 +176,7 @@ def handle_invocation_exception(obj)
end

module Helpers # :nodoc:
def method_parameter_input_fields(method, type, field_name_base)
def method_parameter_input_fields(method, type, field_name_base, idx)
if type.array?
return content_tag('em', "Typed array input fields not supported yet (#{type.name})")
end
@@ -184,7 +187,7 @@ def method_parameter_input_fields(method, type, field_name_base)
nested_content = method_parameter_input_fields(
method,
member_type,
field_name_base + '[' + member_name.to_s + ']')
"#{field_name_base}[#{idx}][#{member_name}]")
if member_type.custom?
parameters << content_tag('li', label)
parameters << content_tag('ul', nested_content)
@@ -196,18 +199,30 @@ def method_parameter_input_fields(method, type, field_name_base)
else
case type.type
when :int
text_field_tag field_name_base
text_field_tag "#{field_name_base}[#{idx}]"
when :string
text_field_tag field_name_base
text_field_tag "#{field_name_base}[#{idx}]"
when :base64
text_area_tag "#{field_name_base}[#{idx}]", nil, :size => "40x5"
when :bool
radio_button_tag(field_name_base, "true") + " True" +
radio_button_tag(field_name_base, "false") + "False"
radio_button_tag("#{field_name_base}[#{idx}]", "true") + " True" +
radio_button_tag("#{field_name_base}[#{idx}]", "false") + "False"
when :float
text_field_tag field_name_base
when :time
select_datetime Time.now, 'name' => field_name_base
text_field_tag "#{field_name_base}[#{idx}]"
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}[#{idx}][#{i}]", :discard_type => true)
end.join
when :date
select_date Date.today, 'name' => field_name_base
date = Date.today
i = 0
%w|year month day|.map do |name|
i += 1
send("select_#{name}", date, :prefix => "#{field_name_base}[#{idx}][#{i}]", :discard_type => true)
end.join
end
end
end
@@ -53,9 +53,9 @@ def canonical_type_name(name) # :nodoc:
case name
when :int, :integer, :fixnum, :bignum
:int
when :string
when :string, :text
:string
when :base64
when :base64, :binary
:base64
when :bool, :boolean
:bool
@@ -203,7 +203,7 @@ def each_member
elsif @type_class.respond_to?(:columns)
i = -1
@type_class.columns.each do |column|
yield column.name, canonical_signature_entry(column.klass, i += 1)
yield column.name, canonical_signature_entry(column.type, i += 1)
end
end
end
@@ -10,20 +10,19 @@
</p>

<% if @scaffold_method.expects %>
<% i = 0 %>

<strong>Method Parameters:</strong><br />
<% @scaffold_method.expects.each do |type| %>
<% @scaffold_method.expects.each_with_index do |type, i| %>
<p>
<label for="method_params[<%= i %>]"><%= method_parameter_label(type.name, type) %> </label><br />
<%= method_parameter_input_fields(@scaffold_method, type, "method_params[#{i}]") %>
<%= method_parameter_input_fields(@scaffold_method, type, "method_params", i) %>
</p>
<% i += 1 %>
<% end %>

<% end %>

<%= submit_tag "Invoke" %>
<%= end_form_tag %>

<p>
<%= link_to "Back", :action => @scaffold_action_name %>
@@ -12,17 +12,44 @@ def ==(other)
firstnames == other.firstnames && lastname == other.lastname
end
end

class Inner < ActionWebService::Struct
member :name, :string
end

class Outer < ActionWebService::Struct
member :name, :string
member :inner, Inner
end

class User < ActiveRecord::Base
end

module Accounting
class User < ActiveRecord::Base
end
end

class WithModel < ActionWebService::Struct
member :user, User
member :users, [User]
end

class API < ActionWebService::API::Base
api_method :void
api_method :normal, :expects => [:int, :int], :returns => [:int]
api_method :array_return, :returns => [[Person]]
api_method :struct_pass, :expects => [[Person]], :returns => [:bool]
api_method :client_container, :returns => [:int]
api_method :named_parameters, :expects => [{:key=>:string}, {:id=>:int}]
api_method :normal, :expects => [:int, :int], :returns => [:int]
api_method :array_return, :returns => [[Person]]
api_method :struct_pass, :expects => [[Person]], :returns => [:bool]
api_method :nil_struct_return, :returns => [Person]
api_method :inner_nil, :returns => [Outer]
api_method :client_container, :returns => [:int]
api_method :named_parameters, :expects => [{:key=>:string}, {:id=>:int}]
api_method :thrower
api_method :user_return, :returns => [User]
api_method :with_model_return, :returns => [WithModel]
api_method :scoped_model_return, :returns => [Accounting::User]
end

class NullLogOut
def <<(*args); end
end
@@ -65,6 +92,14 @@ def struct_pass
@value_struct_pass = @method_params
true
end

def nil_struct_return
nil
end

def inner_nil
Outer.new :name => 'outer', :inner => nil
end

def client_container
50
@@ -77,6 +112,18 @@ def named_parameters
def thrower
raise "Hi"
end

def user_return
User.find(1)
end

def with_model_return
WithModel.new :user => User.find(1), :users => User.find(:all)
end

def scoped_model_return
Accounting::User.find(1)
end
end

class AbstractClientLet < WEBrick::HTTPServlet::AbstractServlet
Oops, something went wrong.

0 comments on commit 3d49657

Please sign in to comment.