mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
6f5a7b2004
seperate out protocol marshaling into a small 'ws' library in vendor, so that AWS itself only does integration with ActionPack, and so we can keep protocol specific code in AWS proper to a minimum. refactor unit tests to get 95% code coverage (for a baseline). be far more relaxed about the types given to us by the remote side, don't do any poor man's type checking, just try to cast and marshal to the correct types if possible, and if not, return what they gave us anyway. this should make interoperating with fuzzy XML-RPC clients easier. if exception reporting is turned on, do best-effort error responses, so that we can avoid "Internal protocol error" with no details if there is a bug in AWS itself. also perform extensive cleanups on AWS proper. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@800 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
87 lines
3.2 KiB
Ruby
87 lines
3.2 KiB
Ruby
module ActionWebService # :nodoc:
|
|
module Container # :nodoc:
|
|
module Delegated # :nodoc:
|
|
class ContainerError < ActionWebServiceError # :nodoc:
|
|
end
|
|
|
|
def self.append_features(base) # :nodoc:
|
|
super
|
|
base.extend(ClassMethods)
|
|
base.send(:include, ActionWebService::Container::Delegated::InstanceMethods)
|
|
end
|
|
|
|
module ClassMethods
|
|
# Declares a web service that will provides 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 ? instance_eval(&service) : info[:object]
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|