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.
-
#visibility ⇒ Object
The visibility 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.
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/copland/service-point.rb', line 101 def initialize( owner, name, opts={} ) @owner = owner @name = name @visibility = :public 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 |
#visibility ⇒ Object
The visibility of this service point. If :public
(the default), the service point is accessible outside of its package. If it is :private
, then it is only directly accessible to other services within its package.
95 96 97 |
# File 'lib/copland/service-point.rb', line 95 def visibility @visibility end |
Instance Method Details
#add_event_producer(producer) ⇒ Object
Add the given service point as an event producer for this service point.
137 138 139 |
# File 'lib/copland/service-point.rb', line 137 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.
143 144 145 |
# File 'lib/copland/service-point.rb', line 143 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.
217 218 219 |
# File 'lib/copland/service-point.rb', line 217 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.
190 191 192 193 |
# File 'lib/copland/service-point.rb', line 190 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.
201 202 203 204 205 206 207 208 209 210 |
# File 'lib/copland/service-point.rb', line 201 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.
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/copland/service-point.rb', line 230 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).
260 261 262 |
# File 'lib/copland/service-point.rb', line 260 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.
115 116 117 |
# File 'lib/copland/service-point.rb', line 115 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.
153 154 155 |
# File 'lib/copland/service-point.rb', line 153 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.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/copland/service-point.rb', line 164 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.
121 122 123 |
# File 'lib/copland/service-point.rb', line 121 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.
128 129 130 131 132 133 134 |
# File 'lib/copland/service-point.rb', line 128 def use_service_model( service_model_name ) @model = Copland::ClassFactory.instance.get( Copland::ServiceModel::POOL_NAME, service_model_name, self ) end |