class Nucleon::Environment
Plugin
environment¶ ↑
The Nucleon::Environment
class defines a container for registered plugins and autoloaded providers.
One of the primary functions of the Nucleon
library is to provide a very flexible extensible architectural base for Ruby applications needing ready made modularity. To fulfill our objectives, the Nucleon
library defines plugin managers managed as a global multition.
These managers should be able to fail gracefully and recover to the state they left off if a plugin provider crashes. To acomplish this, each manager is a Celluloid actor that manages a globally defined environment (also within a multition). This environment contains all of the plugins and providers that they manager has registered and loaded.
Three collections are managed:
-
Defined plugin types
The environment maintains a collection of registered plugin types with a default provider. Default providers can easily be changed in runtime as needs change.
-
Plugin
load infoWhenever a plugin is defined and initialized by the manager a specification is created and maintained that lets the manager know details about the plugin, such as where the base plugin resides, namespace, type, etc…
-
Active plugins
The environment maintains a registry of all of the plugin instances across the application. These active plugins are accessed by the manager, usually through the facade. When we work with plugins in the application, we are usually working with these instances.
See also:
Public Class Methods
Initialize a new Nucleon
environment
IMORTANT: The environment constructor should accept no parameters!
-
Parameters
-
Returns
- Void
-
This method does not return a value
-
Errors
See also:
Nucleon::Core::new
# File lib/core/environment.rb 64 def initialize 65 super({ 66 :plugin_types => {}, 67 :load_info => {}, 68 :active_info => {} 69 }, {}, true, true, false) 70 71 @instance_map = Config.new 72 end
Public Instance Methods
Return active plugins for namespaces, plugin types, providers if specified
-
Parameters
-
Returns
- nil,
Hash
<Symbol|Symbol|Symbol|Symbol|Nucleon::Plugin::Base> -
Returns all plugin instances if no parameters given
- nil,
- nil,
Hash
<Symbol|Symbol|Symbol|Nucleon::Plugin::Base> -
Returns namespace plugin instances if only namespace given
- nil,
- nil,
Hash
<Symbol|Symbol|Nucleon::Plugin::Base> -
Returns plugin type instances if namespace and plugin type given
- nil,
- nil,
Hash
<Symbol|Nucleon::Plugin::Base> -
Returns provider instances if namespace, plugin type, and provider given
- nil,
-
Errors
See:
See also:
# File lib/core/environment.rb 550 def active_plugins(namespace = nil, plugin_type = nil, provider = nil) 551 active_info = get_hash(:active_info) 552 553 namespace = namespace.to_sym if namespace 554 plugin_type = sanitize_id(plugin_type) if plugin_type 555 provider = sanitize_id(provider) if provider 556 results = {} 557 558 if namespace && active_info.has_key?(namespace) 559 if plugin_type && active_info[namespace].has_key?(plugin_type) 560 if provider && ! active_info[namespace][plugin_type].keys.empty? 561 active_info[namespace][plugin_type].each do |instance_name, plugin| 562 plugin = active_info[namespace][plugin_type][instance_name] 563 results[instance_name] = plugin if plugin.plugin_provider == provider 564 end 565 elsif ! provider 566 results = active_info[namespace][plugin_type] 567 end 568 elsif ! plugin_type 569 results = active_info[namespace] 570 end 571 elsif ! namespace 572 results = active_info 573 end 574 results 575 end
Autoload all of the defined plugins
-
Parameters
-
Returns
- Void
-
This method does not return a value
-
Errors
-
TODO
-
-
Yields
See:
# File lib/core/environment.rb 378 def autoload # :yields: namespace, plugin_type, provider, plugin 379 load_info = loaded_plugins 380 381 load_info.keys.each do |namespace| 382 load_info[namespace].keys.each do |plugin_type| 383 load_info[namespace][plugin_type].each do |provider, plugin| 384 require plugin[:file] 385 386 load_info[namespace][plugin_type][provider][:class] = class_const(plugin[:class_components]) 387 388 yield(namespace, plugin_type, provider, plugin) if block_given? 389 end 390 end 391 end 392 end
Return a fully formed class name as a machine usable constant
-
Parameters
- String, Symbol, Array
-
name Class name components
- String, Symbol
-
separator Class component separator (default ‘::’)
-
Returns
- Class Constant
-
Returns class constant for fully formed class name of given components
-
Errors
See also:
# File lib/core/environment.rb 629 def class_const(name, separator = '::') 630 components = class_name(name, separator, TRUE) 631 constant = Object 632 633 components.each do |component| 634 constant = constant.const_defined?(component) ? 635 constant.const_get(component) : 636 constant.const_missing(component) 637 end 638 constant 639 end
Return a fully formed class name as a string
-
Parameters
- String, Symbol, Array
-
name Class name components
- String, Symbol
-
separator Class component separator (default ‘::’)
- Boolean
-
want_array Whether or not to return array of final components or string version
-
Returns
- String
-
Returns fully rendered class name as string unless want_array is true
- Array
-
Returns array of final class components if want_array is true
-
Errors
# File lib/core/environment.rb 593 def class_name(name, separator = '::', want_array = false) 594 components = [] 595 596 case name 597 when String, Symbol 598 components = name.to_s.split(separator) 599 when Array 600 components = name.flatten 601 end 602 603 components.collect! do |value| 604 value = value.to_s.strip 605 value[0] = value.capitalize[0] if value =~ /^[a-z]/ 606 value 607 end 608 609 if want_array 610 return components 611 end 612 components.join(separator) 613 end
Create a new plugin instance of a specified provider
-
Parameters
-
Returns
- nil,
Nucleon::Plugin::Base
-
Returns plugin instance (inherited from
Nucleon::Plugin::Base
)
- nil,
-
Errors
-
Yields
See:
See also:
# File lib/core/environment.rb 429 def create_plugin(namespace, plugin_type, provider, options = {}, &code) # :yields: type_info, options 430 namespace = namespace.to_sym 431 plugin_type = sanitize_id(plugin_type) 432 provider = sanitize_id(provider) 433 options = Util::Data.clone(options) 434 plugin = nil 435 result = nil 436 437 unless plugin_type_defined?(namespace, plugin_type) 438 return plugin 439 end 440 441 if type_info = Util::Data.clone(loaded_plugin(namespace, plugin_type, provider)) 442 ids = array(type_info[:class].register_ids).flatten 443 instance_config = Config.new(options, {}, true, false) 444 ensure_new = instance_config.delete(:new, false) 445 446 instance_options = Util::Data.subset(instance_config.export, ids, true) 447 instance_name = "#{provider}_" + Nucleon.sha1(instance_options) 448 plugin = get([ :active_info, namespace, plugin_type, instance_name ]) 449 450 if ensure_new || ! ( instance_name && plugin ) 451 type_info[:instance_name] = instance_name 452 453 result = code.call(type_info, options) if code 454 options = result if result.is_a?(Hash) 455 456 options[:meta] = Config.new(type_info, {}, true, false).import(hash(options[:meta])) 457 458 options.delete(:new) 459 460 plugin = type_info[:class].new(namespace, plugin_type, provider, options) 461 set([ :active_info, namespace, plugin_type, instance_name ], plugin) 462 463 @instance_map.append([ namespace, plugin_type, plugin.plugin_name.to_sym ], instance_name.to_sym) 464 end 465 end 466 plugin 467 end
Define a new plugin provider of a specified plugin type.
-
Parameters
- String, Symbol
-
namespace Namespace that contains plugin types
- String, Symbol
-
plugin_type
Plugin
type name to fetch default provider
- String
-
base_path Base load path of the plugin provider
- String
-
file File that contains the provider definition
-
Returns
Nucleon::Environment
-
Returns reference to self for compound operations
-
Errors
-
Yields
See:
See also:
# File lib/core/environment.rb 225 def define_plugin(namespace, plugin_type, base_path, file, &code) # :yields: data 226 namespace = namespace.to_sym 227 plugin_type = sanitize_id(plugin_type) 228 plugin_info = parse_plugin_info(namespace, plugin_type, base_path, file) 229 230 unless get_hash([ :load_info, namespace, plugin_type ]).has_key?(plugin_info[:provider]) 231 data = { 232 :namespace => namespace, 233 :type => plugin_type, 234 :base_path => base_path, 235 :file => file, 236 :provider => plugin_info[:provider], 237 :directory => plugin_info[:directory], 238 :class_components => plugin_info[:class_components] 239 } 240 code.call(data) if code 241 242 set([ :load_info, namespace, plugin_type, plugin_info[:provider] ], data) 243 end 244 self 245 end
Define a new plugin type in a specified namespace.
-
Parameters
- String, Symbol
-
namespace Namespace that contains plugin types
- String, Symbol
-
plugin_type
Plugin
type name within namespace
- nil, String, Symbol
-
default_provider Default provider (defaults to none)
-
Returns
Nucleon::Environment
-
Returns reference to self for compound operations
-
Errors
See:
See also:
# File lib/core/environment.rb 128 def define_plugin_type(namespace, plugin_type, default_provider = nil) 129 set([ :plugin_types, namespace, sanitize_id(plugin_type) ], default_provider) 130 end
Define one or more new plugin types in a specified namespace.
-
Parameters
-
Returns
Nucleon::Environment
-
Returns reference to self for compound operations
-
Errors
See:
# File lib/core/environment.rb 146 def define_plugin_types(namespace, type_info) 147 if type_info.is_a?(Hash) 148 type_info.each do |plugin_type, default_provider| 149 define_plugin_type(namespace, plugin_type, default_provider) 150 end 151 end 152 self 153 end
Return a plugin instance by name if it exists
-
Parameters
-
Returns
- nil,
Nucleon::Plugin::Base
-
Returns a plugin instance of name specified if it exists
- nil,
-
Errors
See:
See also:
# File lib/core/environment.rb 488 def get_plugin(namespace, plugin_type, plugin_name) 489 namespace = namespace.to_sym 490 plugin_type = sanitize_id(plugin_type) 491 492 instances = get_hash([ :active_info, namespace, plugin_type ]) 493 instance_ids = array(@instance_map.get([ namespace, plugin_type, plugin_name.to_s.to_sym ])) 494 495 if instance_ids.size 496 return instances[instance_ids[0]] 497 end 498 nil 499 end
Return the load information for a specified plugin provider if it exists
-
Parameters
-
Returns
- nil,
Hash
<Symbol|ANY> -
Returns provider load information if provider exists, nil otherwise
- nil,
-
Errors
See:
See also:
# File lib/core/environment.rb 265 def loaded_plugin(namespace, plugin_type, provider) 266 get([ :load_info, namespace, sanitize_id(plugin_type), sanitize_id(provider) ], nil) 267 end
Return the load information for namespaces, plugin types, providers if it exists
-
Parameters
-
Returns
- nil,
Hash
<Symbol|Symbol|Symbol|Symbol|ANY> -
Returns all load information if no parameters given
- nil,
- nil,
Hash
<Symbol|Symbol|Symbol|ANY> -
Returns namespace load information if only namespace given
- nil,
- nil,
Hash
<Symbol|Symbol|ANY> -
Returns plugin type load information if namespace and plugin type given
- nil,
- nil,
Hash
<Symbol|ANY> -
Returns provider load information if namespace, plugin type, and provider given
- nil,
-
Errors
See:
See also:
# File lib/core/environment.rb 291 def loaded_plugins(namespace = nil, plugin_type = nil, provider = nil, default = {}) 292 load_info = get_hash(:load_info) 293 294 namespace = namespace.to_sym if namespace 295 plugin_type = sanitize_id(plugin_type) if plugin_type 296 provider = sanitize_id(provider) if provider 297 results = default 298 299 if namespace && load_info.has_key?(namespace) 300 if plugin_type && load_info[namespace].has_key?(plugin_type) 301 if provider && load_info[namespace][plugin_type].has_key?(provider) 302 results = load_info[namespace][plugin_type][provider] 303 elsif ! provider 304 results = load_info[namespace][plugin_type] 305 end 306 elsif ! plugin_type 307 results = load_info[namespace] 308 end 309 elsif ! namespace 310 results = load_info 311 end 312 results 313 end
Return all of the defined namespaces in the plugin environment.
-
Parameters
-
Returns
- Array<Symbol>
-
Array of defined plugin namespaces
-
Errors
See:
# File lib/core/environment.rb 89 def namespaces 90 get_hash(:plugin_types).keys 91 end
Return a class constant representing a base plugin class generated from namespace and plugin_type.
-
Parameters
-
Returns
- String
-
Returns a class constant representing the plugin namespace and type
-
Errors
See also:
# File lib/core/environment.rb 686 def plugin_class(namespace, plugin_type) 687 class_const([ sanitize_class(namespace), :plugin, sanitize_class(plugin_type) ]) 688 end
Check if a specified plugin provider has been loaded
-
Parameters
-
Returns
- Boolean
-
Returns true if plugin provider has been loaded, false otherwise
-
Errors
See:
See also:
# File lib/core/environment.rb 354 def plugin_has_provider?(namespace, plugin_type, provider) 355 get_hash([ :load_info, namespace, sanitize_id(plugin_type) ]).has_key?(sanitize_id(provider)) 356 end
Check if a specified plugin type has been loaded
-
Parameters
- String, Symbol
-
namespace Namespace that contains plugin types
- String, Symbol
-
plugin_type
Plugin
type name to check
-
Returns
- Boolean
-
Returns true if plugin type has been loaded, false otherwise
-
Errors
See:
See also:
# File lib/core/environment.rb 332 def plugin_has_type?(namespace, plugin_type) 333 get_hash([ :load_info, namespace ]).has_key?(sanitize_id(plugin_type)) 334 end
Return the default provider currently registered for a plugin type
-
Parameters
- String, Symbol
-
namespace Namespace that contains plugin types
- String, Symbol
-
plugin_type
Plugin
type name to fetch default provider
-
Returns
- nil, Symbol
-
Returns default provider if plugin type exists, nil otherwise
-
Errors
See:
See also:
# File lib/core/environment.rb 193 def plugin_type_default(namespace, plugin_type) 194 get([ :plugin_types, namespace, sanitize_id(plugin_type) ]) 195 end
Check if a specified plugin type has been defined
-
Parameters
- String, Symbol
-
namespace Namespace that contains plugin types
- String, Symbol
-
plugin_type
Plugin
type name to check within namespace
-
Returns
- Boolean
-
Returns true if plugin type exists, false otherwise
-
Errors
See:
See also:
# File lib/core/environment.rb 172 def plugin_type_defined?(namespace, plugin_type) 173 get_hash([ :plugin_types, namespace ]).has_key?(sanitize_id(plugin_type)) 174 end
Return all of the defined plugin types in a plugin namespace.
-
Parameters
- String, Symbol
-
namespace Namespace that contains plugin types
-
Returns
- Array<Symbol>
-
Array of defined plugin types
-
Errors
See:
# File lib/core/environment.rb 106 def plugin_types(namespace) 107 get_hash([ :plugin_types, namespace ]).keys 108 end
Return a class constant representing a plugin provider class generated from namespace, plugin_type, and provider name.
The provider name can be entered as an array if it is included in sub modules.
-
Parameters
-
Returns
- String
-
Returns a class constant representing the plugin provider
-
Errors
See also:
# File lib/core/environment.rb 709 def provider_class(namespace, plugin_type, provider) 710 class_const([ sanitize_class(namespace), sanitize_class(plugin_type), provider ]) 711 end
Remove a plugin instance from the environment
-
Parameters
-
Returns
- nil,
Nucleon::Plugin::Base
-
Returns the plugin instance that was removed from environment
- nil,
-
Errors
-
Yields
Nucleon::Plugin::Base
-
plugin
Plugin
object being removed (cleanup)
See:
See also:
# File lib/core/environment.rb 523 def remove_plugin(namespace, plugin_type, instance_name, &code) # :yields: plugin 524 plugin = delete([ :active_info, namespace, sanitize_id(plugin_type), instance_name ]) 525 code.call(plugin) if code && plugin 526 plugin 527 end
Protected Instance Methods
Parse plugin information for a specified namespace and plugin type.
-
Parameters
- String, Symbol
-
namespace Namespace that contains plugin types
- String, Symbol
-
plugin_type
Plugin
type name to fetch default provider
- String
-
base_path Base load path of the plugin provider
- String
-
file File that contains the provider definition
-
Returns
Hash
<Symbol|ANY>-
Returns a hash of the parsed plugin information
-
Errors
See also:
# File lib/core/environment.rb 730 def parse_plugin_info(namespace, plugin_type, base_path, file) 731 dir_components = base_path.split(File::SEPARATOR) 732 file_components = file.split(File::SEPARATOR) 733 734 file_name = file_components.pop.sub(/\.rb/, '') 735 directory = file_components.join(File::SEPARATOR) 736 737 file_class = sanitize_class(file_name) 738 group_components = directory.sub(/^#{base_path}#{File::SEPARATOR}?/, '').split(File::SEPARATOR) 739 740 class_components = [ sanitize_class(namespace), sanitize_class(plugin_type) ] 741 742 if ! group_components.empty? 743 group_name = group_components.collect {|elem| elem.downcase }.join('_') 744 provider = [ group_name, file_name ].join('_') 745 746 group_components = group_components.collect {|elem| sanitize_class(elem) } 747 class_components = [ class_components, group_components, file_class ].flatten 748 else 749 provider = file_name 750 class_components = [ class_components, file_class ].flatten 751 end 752 753 { 754 :directory => directory, 755 :provider => sanitize_id(provider), 756 :class_components => class_components 757 } 758 end
Sanitize a class identifier for internal use.
-
Parameters
- String, Symbol
-
class_component Class identifier to sanitize
-
Returns
- String
-
Returns a sanitized string representing the given class component
-
Errors
# File lib/core/environment.rb 666 def sanitize_class(class_component) 667 class_component.to_s.split('_').collect {|elem| elem.slice(0,1).capitalize + elem.slice(1..-1) }.join('') 668 end
Sanitize an identifier for internal plugin environment use.
-
Parameters
- String, Symbol
-
id_component Identifier to sanitize
-
Returns
- Symbol
-
Returns a sanitized symbol representing the given id component
-
Errors
# File lib/core/environment.rb 651 def sanitize_id(id_component) 652 id_component.to_s.gsub(/([a-z0-9])(?:\-|\_)?([A-Z])/, '\1_\2').downcase.to_sym 653 end