The Registry is the primary interface exported by Copland. Very rarely should client applications need to access any other interface directly.

The Registry can be constructed in two ways. The first (and most common) is to call the build method, which instantiates, initializes, and returns the new Registry instance in one step.

  registry = Registry.build

The second is the instantiate an empty Registry and initialize it yourself. This is a more arduous approach, but may be necessary for some more complex Registry requirements.

Methods
Attributes
[R] logs The LogFactory instance that will be employed by this registry for creating logger instances.
Classes and Modules
Module Copland::Registry::Fixated
Module Copland::Registry::Shutdown
Included Modules
Public Class methods
build( *args )

Instantiate, initialize, and return a new Registry instance. The accepted parameters are:

  • if the first parameter is a String, it is interpreted to be the "default" search path. (This defaults to ".".)
  • the other parameter (or the first parameter, if it is not a String) must be either absent, or it must be a Hash, in which case it specifies options that will be used to construct and initialize the Registry.

Valid options are:

  • :default_service_model: the default service model to use when creating service points, when an explicit service model has not been given.
  • :search_paths: an array of paths that should be searched for package descriptors.

Also, any option that LogFactory accepts is also valid, prefixed with "log_". (I.e., :log_device instead of :device.)

     # File lib/copland/registry.rb, line 83
 83:     def self.build( *args )
 84:       if args.length > 2
 85:         raise ArgumentError, "expected [0..2] arguments, got #{args.length}"
 86:       end
 87: 
 88:       default_search_path = "."
 89:       options = {}
 90: 
 91:       default_search_path = args.shift if args.first.is_a? String
 92:       options = args.shift if args.first.is_a? Hash
 93: 
 94:       unless args.empty?
 95:         raise ArgumentError, "unexpected argument type #{args.first.class}"
 96:       end
 97: 
 98:       ( options[:search_paths] ||= [] ).unshift( default_search_path ).uniq!
 99:       options[:search_paths].compact!
100: 
101:       search_paths = options[:search_paths]
102:       options.delete :search_paths
103: 
104:       registry = new( options )
105:       loader = Copland::Configuration::Loader.new( search_paths )
106:       loader.add_loader Copland::Configuration::YAML::Loader.new( registry,
107:         loader )
108:       loader.load( options )
109: 
110:       startup = registry.service( "copland.Startup" )
111:       startup.start
112: 
113:       return registry
114:     end
new( options={} )

Create a new, empty registry. The options hash accepts any value that LogFactory’s constructor accepts, with "log_" prefixed. (I.e., :log_device instead of :device.)

     # File lib/copland/registry.rb, line 123
123:     def initialize( options={} )
124:       @packages = Hash.new
125: 
126:       log_options = Hash.new
127:       options.each do |k,v|
128:         log_options[$1.intern] = v if k.to_s =~ /^log_(.*)/
129:       end
130: 
131:       @logs = LogFactory.new( log_options )
132:     end
Public Instance methods
add_identity_service( package_name, service_point_name, object, description=nil )

A convenience method for clients that wish to add a specific object to the registry as an "identity" service (that is, a singleton service point that always instantiates as the given object).

     # File lib/copland/registry.rb, line 206
206:     def add_identity_service( package_name,
207:                               service_point_name,
208:                               object,
209:                               description=nil )
210:     # begin
211:       owner = package( package_name )
212:       if owner.nil?
213:         owner = Package.new( self, package_name )
214:         add_package owner
215:       end
216: 
217:       service_point = ServicePoint.new( owner, service_point_name )
218:       service_point.use_service_model "singleton"
219: 
220:       service_point.description = description
221: 
222:       service_point.instantiator = ClassFactory.instance.get(
223:         Instantiator::POOL_NAME, "identity", service_point, object )
224:       owner.add_service_point( service_point )
225: 
226:       service_point
227:     end
add_package( pkg )

Adds the given package to the registry. If there is already a package in the registry by that name, a DuplicatePackageError will be raised.

     # File lib/copland/registry.rb, line 295
295:     def add_package( pkg )
296:       if @packages[ pkg.name ]
297:         raise DuplicatePackageError, pkg.name
298:       end
299: 
300:       @packages[ pkg.name ] = pkg
301:     end
configuration_point( name )

This returns the configuration point with the given name. If the package exists but no configuration point by that name can be found in it, this returns nil. If the package itself does not exist, then a ConfigurationPointNotFound exception is raised.

     # File lib/copland/registry.rb, line 281
281:     def configuration_point( name )
282:       Copland::get_possibly_local_service( self, nil, name ) do |pkg, id|
283:         unless pkg
284:           raise ConfigurationPointNotFound,
285:             "A fully-qualified configuration point name must be given " +
286:             "to Registry#service"
287:         else
288:           return pkg.configuration_point( id )
289:         end
290:       end
291:     end
define_log_factory_as_service()

This creates a new service point called "copland.LogFactory" and makes it so that it always returns the log factory instance owned by the active registry.

     # File lib/copland/registry.rb, line 191
191:     def define_log_factory_as_service
192:       description = "The LogFactory service provides log instances " +
193:         "on demand. It is always an identity for the log factory instance " +
194:         "owned by the registry."
195: 
196:       add_identity_service "copland",
197:                            "LogFactory",
198:                            logs,
199:                            description
200:     end
each_package( &block )

Iterates over each package in the registry.

     # File lib/copland/registry.rb, line 304
304:     def each_package( &block )
305:       @packages.each_value( &block )
306:       self
307:     end
fixate!()

Fixates the registry. This performs one-time operations on the registry, and then makes it illegal to perform those operations subsequently on the same registry instance.

This will create the "copland.Registry" service point, fixate each of the registry’s packages, and then register a finalizer in ObjectSpace that will cause the registry to always be gracefully shutdown.

     # File lib/copland/registry.rb, line 141
141:     def fixate!
142:       define_self_as_service
143:       define_log_factory_as_service
144:       @packages.each { |id, pkg| pkg.fixate! }
145:       ObjectSpace.define_finalizer( self, proc { shutdown } )
146:       extend Fixated
147:     end
fixated?()

Returns false. After the registry has been fixated (see fixate!), this will be overridden with a method that returns true.

     # File lib/copland/registry.rb, line 151
151:     def fixated?
152:       false
153:     end
package( name )

Returns the package with the given name. If there is no such package, this returns nil.

     # File lib/copland/registry.rb, line 231
231:     def package( name )
232:       @packages[ name ]
233:     end
package_count()

Returns the number of packages in the registry.

     # File lib/copland/registry.rb, line 310
310:     def package_count
311:       @packages.size
312:     end
service( name, &init )

Returns the service with the given name. If no such service point can be found, this raises the ServicePointNotFound exception. (See Package#service.)

If a block is given, it is passed to Package#service and is used to initialize the service.

     # File lib/copland/registry.rb, line 241
241:     def service( name, &init )
242:       Copland::get_possibly_local_service( self, nil, name ) do |pkg, id|
243:         unless pkg
244:           raise ServicePointNotFound,
245:             "A fully-qualified service name must be given to Registry#service"
246:         else
247:           return pkg.service( id, &init )
248:         end
249:       end
250:     end
service_exist?( name )

Returns true if the named service exists in this registry, and false otherwise.

     # File lib/copland/registry.rb, line 267
267:     def service_exist?( name )
268:       Copland::get_possibly_local_service( self, nil, name ) do |pkg, id|
269:         unless pkg
270:           return false
271:         else
272:           return pkg.service_exist?( id )
273:         end
274:       end
275:     end
service_point( name )

Returns the service point with the given name. If no such service point can be found, this nil.

     # File lib/copland/registry.rb, line 254
254:     def service_point( name )
255:       Copland::get_possibly_local_service( self, nil, name ) do |pkg, id|
256:         unless pkg
257:           raise ServicePointNotFound,
258:             "A fully-qualified service name must be given to Registry#service_point"
259:         else
260:           return pkg.service_point( id )
261:         end
262:       end
263:     end
shutdown()

Shuts down the registry by notifying any interested listeners (using the :registry_shutdown event), closing the logs, and then extending the Shutdown module.

     # File lib/copland/registry.rb, line 158
158:     def shutdown
159:       fire_event( :registry_shutdown )
160:       @logs.close
161:       extend Shutdown
162:     end
shutdown?()

Returns false. After the registry has been shutdown, this will be be overridden with a method that returns true.

     # File lib/copland/registry.rb, line 166
166:     def shutdown?
167:       false
168:     end