Class: Copland::ServicePoint
- Inherits:
-
Object
- Object
- Copland::ServicePoint
- Defined in:
- lib/copland/service-point.rb
Overview
A “service point” is the definition of a service. Just as a class describes an object, a service point describes a service. Just as an object is the instantiation of a class, so is a service the instantiation of a service point.
A service point consists of an “instantiator” (which describes how the service is to be instantiated) and a service model (which describes when the service is to be instantiated). Optionally, a service point may also have interceptors (which act as filters on the methods of a service), _event producers_ (which send events to the service) and a schema (which is only useful for factory services, and describes what the format of the parameters that the factory understands).
Defined Under Namespace
Modules: Fixated
Constant Summary collapse
- DEFAULT_SERVICE_MODEL =
This is the service model that will be used when no other has been specified, and no other default was given in the options when the service point was created.
"singleton-deferred"
Instance Attribute Summary collapse
-
#description ⇒ Object
An (optional) description of this service point.
-
#event_producers ⇒ Object
readonly
An array of service points that instances of this service point will listen to for events.
-
#instantiator ⇒ Object
The instantiator that will be used to instantiate this service point.
-
#interceptors ⇒ Object
readonly
An array of Interceptor objects that should be instantiated when this service is instantiated.
-
#name ⇒ Object
readonly
The unqualified name of this service point.
-
#owner ⇒ Object
readonly
The package the owns this service point.
-
#schema ⇒ Object
The (optional) schema specification that identifies the valid parameters that can be given to an instance of this service point.
Instance Method Summary collapse
-
#add_event_producer(producer) ⇒ Object
Add the given service point as an event producer for this service point.
-
#add_interceptor(interceptor) ⇒ Object
Add the given Interceptor object to this service point, to be instantiated and applied when a new service is created.
-
#add_pending_interceptor(definition) ⇒ Object
Adds a “pending” (i.e., unvalidated) interceptor definition to this service point.
-
#find_service(name, &block) ⇒ Object
Searches for (and instantiates) the service with the given name in the registry, giving preference to services in this service point’s package (i.e., when an unqualified service name is given).
-
#find_service_point(name) ⇒ Object
Searches for the service point with the given name, giving preference to service points within this service point’s package (i.e., when an unqualified service point name is given).
-
#fixate! ⇒ Object
Fixates the service point.
-
#fixated? ⇒ Boolean
Returns
false
. -
#full_name ⇒ Object
Returns the fully-qualified name of this service point, which will be the name of the package and the name of the service point, separated by a dot.
-
#initialize(owner, name, opts = {}) ⇒ ServicePoint
constructor
Create a new service point, contained by the
owner
package. -
#instance(&block) ⇒ Object
Returns the instance returned by the service model.
-
#instantiate(&init) ⇒ Object
Directly instantiates the service point.
-
#service_model ⇒ Object
Return the service model instance that will be used to regulate the instantiation of this service point.
-
#use_service_model(service_model_name) ⇒ Object
Specify the name of service model to use for this service point.
Constructor Details
#initialize(owner, name, opts = {}) ⇒ ServicePoint
Create a new service point, contained by the owner
package. The only recognized option currently is :default_service_model
, which is used to identify the service model to use when no other service model has been specified.
95 96 97 98 99 100 101 102 103 |
# File 'lib/copland/service-point.rb', line 95 def initialize( owner, name, opts={} ) @owner = owner @name = name use_service_model opts[ :default_service_model ] || DEFAULT_SERVICE_MODEL @event_producers = [] @interceptors = [] end |
Instance Attribute Details
#description ⇒ Object
An (optional) description of this service point.
77 78 79 |
# File 'lib/copland/service-point.rb', line 77 def description @description end |
#event_producers ⇒ Object (readonly)
An array of service points that instances of this service point will listen to for events.
70 71 72 |
# File 'lib/copland/service-point.rb', line 70 def event_producers @event_producers end |
#instantiator ⇒ Object
The instantiator that will be used to instantiate this service point. (When a service point is first created, this is nil
, and the service point cannot be instantiated until an instantiator is specified.)
82 83 84 |
# File 'lib/copland/service-point.rb', line 82 def instantiator @instantiator end |
#interceptors ⇒ Object (readonly)
An array of Interceptor objects that should be instantiated when this service is instantiated.
74 75 76 |
# File 'lib/copland/service-point.rb', line 74 def interceptors @interceptors end |
#name ⇒ Object (readonly)
The unqualified name of this service point.
66 67 68 |
# File 'lib/copland/service-point.rb', line 66 def name @name end |
#owner ⇒ Object (readonly)
The package the owns this service point.
63 64 65 |
# File 'lib/copland/service-point.rb', line 63 def owner @owner end |
#schema ⇒ Object
The (optional) schema specification that identifies the valid parameters that can be given to an instance of this service point. This only applies when the service point describes a factory service, in which case the schema will be used to validate and preprocess the parameters that are passed to the factory when a new instance is required.
89 90 91 |
# File 'lib/copland/service-point.rb', line 89 def schema @schema end |
Instance Method Details
#add_event_producer(producer) ⇒ Object
Add the given service point as an event producer for this service point.
130 131 132 |
# File 'lib/copland/service-point.rb', line 130 def add_event_producer( producer ) ( @event_producers << producer ).uniq! end |
#add_interceptor(interceptor) ⇒ Object
Add the given Interceptor object to this service point, to be instantiated and applied when a new service is created.
136 137 138 |
# File 'lib/copland/service-point.rb', line 136 def add_interceptor( interceptor ) ( @interceptors << interceptor ).uniq! end |
#add_pending_interceptor(definition) ⇒ Object
Adds a “pending” (i.e., unvalidated) interceptor definition to this service point. This method is only valid before the service point has been fixated (see #fixate!). The definition
parameter should be a hash that contains the definition of the interceptor. The Interceptor itself will be instantiated when the service point is fixated.
210 211 212 |
# File 'lib/copland/service-point.rb', line 210 def add_pending_interceptor( definition ) ( @pending_interceptors ||= [] ).push definition end |
#find_service(name, &block) ⇒ Object
Searches for (and instantiates) the service with the given name in the registry, giving preference to services in this service point’s package (i.e., when an unqualified service name is given). If a block is specified, it will be invoked when the package and service point name have been resolved, allowing more than just services to be returned by this method.
183 184 185 186 |
# File 'lib/copland/service-point.rb', line 183 def find_service( name, &block ) Copland::get_possibly_local_service( owner.registry, owner, name, &block ) end |
#find_service_point(name) ⇒ Object
Searches for the service point with the given name, giving preference to service points within this service point’s package (i.e., when an unqualified service point name is given). If an invalid package name is given, this will raise a PackageNotFound exception. If the named service point does not exist, this will raise a ServicePointNotFound exception. Otherwise, it will return the requested service point.
194 195 196 197 198 199 200 201 202 203 |
# File 'lib/copland/service-point.rb', line 194 def find_service_point( name ) point = find_service( name ) do |pkg, id| raise PackageNotFound, name unless pkg pkg.service_point( id ) end raise ServicePointNotFound, name unless point return point end |
#fixate! ⇒ Object
Fixates the service point. After calling this, #add_pending_interceptor becomes illegal to call.
Fixating a service point will cause its instantiator to be validated (via the #validate! method of the corresponding instantiator). Also, any pending interceptors will be processed and added to the service point. Then, if the schema value that was associated with this service point is a string value, then it is treated as a reference to an “external” schema, which is then looked up.
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/copland/service-point.rb', line 223 def fixate! extend Fixated if @schema.is_a?( String ) @schema = @owner.find_schema( @schema ) elsif !@schema.nil? @schema.fixate! end instantiator.validate! if @pending_interceptors @pending_interceptors.each do |definition| interceptor = Interceptor.new( self, definition ) add_interceptor interceptor end remove_instance_variable :@pending_interceptors end # do lazy evaluation of the actual event producer services, so that # no one is actually instantiated until needed. @event_producers.map! do |name| find_service_point( name ) end end |
#fixated? ⇒ Boolean
Returns false
. Once the service point has been fixated, this method will be overridden with a method that returns true
. (See the Fixated module).
253 254 255 |
# File 'lib/copland/service-point.rb', line 253 def fixated? false end |
#full_name ⇒ Object
Returns the fully-qualified name of this service point, which will be the name of the package and the name of the service point, separated by a dot.
108 109 110 |
# File 'lib/copland/service-point.rb', line 108 def full_name owner.name + "." + name end |
#instance(&block) ⇒ Object
Returns the instance returned by the service model. This is the preferred way of instantiating a service point, since it takes advantage of the regulatory services offered by the service model.
If a block is given, it will be used to do one-time initialization of the new service.
146 147 148 |
# File 'lib/copland/service-point.rb', line 146 def instance( &block ) @model.instance( &block ) end |
#instantiate(&init) ⇒ Object
Directly instantiates the service point. This also applies the interceptors and sends out notifications that the service has been instantiated.
This should never be called except by service model instances. If you need to programmatically instantiate a service point, you should use the #instance method; otherwise the service model will be bypassed.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/copland/service-point.rb', line 157 def instantiate( &init ) service = @instantiator.instantiate service.instance_eval &init if init # the service is registered with each of its event producers before # the interceptors are added, thus enabling the event notifications to # bypass the interceptor layer @event_producers.each do |producer| producer.instance.add_listener service end # Construct the interceptor layer around the service service = InterceptorChainBuilder.build( service, @interceptors ) # TODO: lifecycle notifications: "service_instantiated" return service end |
#service_model ⇒ Object
Return the service model instance that will be used to regulate the instantiation of this service point.
114 115 116 |
# File 'lib/copland/service-point.rb', line 114 def service_model @model end |
#use_service_model(service_model_name) ⇒ Object
Specify the name of service model to use for this service point. An instance of the corresponding service model will be looked up in the class factory.
121 122 123 124 125 126 127 |
# File 'lib/copland/service-point.rb', line 121 def use_service_model( service_model_name ) @model = Copland::ClassFactory.instance.get( Copland::ServiceModel::POOL_NAME, service_model_name, self ) end |