1 module ActionWebService # :nodoc:
2 module Container # :nodoc:
3 module Delegated # :nodoc:
4 class ContainerError < ActionWebServiceError # :nodoc:
7 def self.included(base) # :nodoc:
8 base.extend(ClassMethods)
9 base.send(:include, ActionWebService::Container::Delegated::InstanceMethods)
13 # Declares a web service that will provide access to the API of the given
14 # +object+. +object+ must be an ActionWebService::Base derivative.
16 # Web service object creation can either be _immediate_, where the object
17 # instance is given at class definition time, or _deferred_, where
18 # object instantiation is delayed until request time.
20 # ==== Immediate web service object example
22 # class ApiController < ApplicationController
23 # web_service_dispatching_mode :delegated
25 # web_service :person, PersonService.new
28 # For deferred instantiation, a block should be given instead of an
29 # object instance. This block will be executed in controller instance
30 # context, so it can rely on controller instance variables being present.
32 # ==== Deferred web service object example
34 # class ApiController < ApplicationController
35 # web_service_dispatching_mode :delegated
37 # web_service(:person) { PersonService.new(request.env) }
39 def web_service(name, object=nil, &block)
40 if (object && block_given?) || (object.nil? && block.nil?)
41 raise(ContainerError, "either service, or a block must be given")
45 info = { name => { :block => block } }
47 info = { name => { :object => object } }
49 write_inheritable_hash("web_services", info)
50 call_web_service_definition_callbacks(self, name, info)
53 # Whether this service contains a service with the given +name+
54 def has_web_service?(name)
55 web_services.has_key?(name.to_sym)
58 def web_services # :nodoc:
59 read_inheritable_attribute("web_services") || {}
62 def add_web_service_definition_callback(&block) # :nodoc:
63 write_inheritable_array("web_service_definition_callbacks", [block])
67 def call_web_service_definition_callbacks(container_class, web_service_name, service_info)
68 (read_inheritable_attribute("web_service_definition_callbacks") || []).each do |block|
69 block.call(container_class, web_service_name, service_info)
74 module InstanceMethods # :nodoc:
75 def web_service_object(web_service_name)
76 info = self.class.web_services[web_service_name.to_sym]
78 raise(ContainerError, "no such web service '#{web_service_name}'")
80 service = info[:block]
81 service ? self.instance_eval(&service) : info[:object]