Went through the specs and updated them to reflect the application
[lyrix.git] / vendor / rails / actionwebservice / lib / action_web_service / container / delegated_container.rb
blob5477f8d103fe2abb93a64296b21eed8b3e07e40a
1 module ActionWebService # :nodoc:
2   module Container # :nodoc:
3     module Delegated # :nodoc:
4       class ContainerError < ActionWebServiceError # :nodoc:
5       end
6   
7       def self.included(base) # :nodoc:
8         base.extend(ClassMethods)
9         base.send(:include, ActionWebService::Container::Delegated::InstanceMethods)
10       end
11   
12       module ClassMethods
13         # Declares a web service that will provide access to the API of the given
14         # +object+. +object+ must be an ActionWebService::Base derivative.
15         #
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.
19         #
20         # ==== Immediate web service object example
21         #
22         #   class ApiController < ApplicationController
23         #     web_service_dispatching_mode :delegated
24         #
25         #     web_service :person, PersonService.new
26         #   end
27         #
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.
31         #
32         # ==== Deferred web service object example
33         #
34         #   class ApiController < ApplicationController
35         #     web_service_dispatching_mode :delegated
36         #
37         #     web_service(:person) { PersonService.new(request.env) }
38         #   end
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")
42           end
43           name = name.to_sym
44           if block_given?
45             info = { name => { :block => block } }
46           else
47             info = { name => { :object => object } }
48           end
49           write_inheritable_hash("web_services", info)
50           call_web_service_definition_callbacks(self, name, info)
51         end
52   
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)
56         end
57   
58         def web_services # :nodoc:
59           read_inheritable_attribute("web_services") || {}
60         end
61   
62         def add_web_service_definition_callback(&block) # :nodoc:
63           write_inheritable_array("web_service_definition_callbacks", [block])
64         end
65   
66         private
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)
70             end
71           end
72       end
73   
74       module InstanceMethods # :nodoc:
75         def web_service_object(web_service_name)
76           info = self.class.web_services[web_service_name.to_sym]
77           unless info
78             raise(ContainerError, "no such web service '#{web_service_name}'")
79           end
80           service = info[:block]
81           service ? self.instance_eval(&service) : info[:object]
82         end
83       end
84     end
85   end
86 end