Strelka::

PluginLoader

module
Extended With
Loggability

Module API for the plugin system. This mixin adds the ability to load and install plugins into the extended object.

Attributes

loaded_plugins[RW]

The Hash of loaded plugin modules, keyed by their downcased and symbolified name (e.g., Strelka::App::Templating => :templating)

plugin_path_prefix[RW]

The prefix path for loading plugins

plugins_installed_from[RW]

If plugins have already been installed, this will be the call frame they were first installed from. This is used to warn about installing plugins twice.

Public Class Methods

anchor
extended( mod )

Extension callback – initialize some data structures in the extended object.

# File lib/strelka/plugins.rb, line 123
def self::extended( mod )
        super
        mod.extend( Loggability )
        mod.log_to( :strelka )
        mod.loaded_plugins = Strelka::PluginRegistry.new
        mod.plugin_path_prefix = mod.name.downcase.gsub( /::/, File::SEPARATOR )
end

Public Instance Methods

anchor
application_stack()

Return the list of plugin modules that are in effect for the current app.

# File lib/strelka/plugins.rb, line 279
def application_stack
        self.log.debug "Ancestors are: %p" % [ self.class.ancestors ]
        return self.ancestors.select {|mod| mod.respond_to?(:plugin_name) }
end
anchor
dump_application_stack()

Output the application stack into the logfile.

# File lib/strelka/plugins.rb, line 286
def dump_application_stack
        stack = self.application_stack.map( &:plugin_name )
        self.log.info "Application stack: request -> %s" % [ stack.join(" -> ") ]
end
anchor
inherited( subclass )

Extension callback – add instance variables to extending objects.

# File lib/strelka/plugins.rb, line 157
def inherited( subclass )
        super
        @plugins ||= []

        subclass.loaded_plugins = self.loaded_plugins
        subclass.plugin_path_prefix = self.plugin_path_prefix
        subclass.plugins_installed_from = nil
        subclass.instance_variable_set( :@plugins, @plugins.dup )
end
anchor
install_plugins()

Install the mixin part of the plugin, in the order determined by the plugin registry based on the run_outside and run_inside specifications of the plugins themselves.

# File lib/strelka/plugins.rb, line 249
def install_plugins
        if self.plugins_installed?
                self.log.warn "Plugins were already installed for %p from %p" %
                        [ self, self.plugins_installed_from ]
                self.log.info "I'll attempt to install any new ones, but plugin ordering"
                self.log.info "and other functionality might exhibit strange behavior."
        else
                self.log.info "Installing plugins for %p." % [ self ]
        end

        sorted_plugins = self.loaded_plugins.tsort.reverse

        sorted_plugins.each do |name|
                mod = self.loaded_plugins[ name ]

                unless @plugins.include?( name ) || @plugins.include?( mod )
                        self.log.debug "  skipping %s" % [ name ]
                        next
                end

                self.log.info "  including %p in %p." % [ mod, self ]
                include( mod )
        end

        self.plugins_installed_from = caller( 1 ).first
end
anchor
load_plugin( name )

Load the plugin with the given name

# File lib/strelka/plugins.rb, line 196
def load_plugin( name )

        # Just return Modules as-is
        return name if name.is_a?( Strelka::Plugin )
        mod = self.loaded_plugins[ name.to_sym ]

        unless mod.is_a?( Module )
                pluginpath = File.join( self.plugin_path_prefix, name.to_s )
                require( pluginpath )
                mod = self.loaded_plugins[ name.to_sym ] or
                        raise "#{name} plugin didn't load correctly."
        end

        return mod
end
anchor
new( * )

Install the mixin part of plugins immediately before the first instance is created.

# File lib/strelka/plugins.rb, line 240
def new( * )
        self.install_plugins unless self.plugins_installed?
        super
end
anchor
plugin( *names )
Alias for: plugins
anchor
plugins( *names )

Load the plugins with the given names and install them.

# File lib/strelka/plugins.rb, line 169
def plugins( *names )
        self.log.info "Adding plugins: %s" % [ names.flatten.map(&:to_s).join(', ') ]

        # Load the associated Plugin Module objects
        names.flatten.each {|name| self.load_plugin(name) }

        # Add the name/s to the list of mixins to apply on startup
        @plugins |= names

        # Install the declarative half of the plugin immediately
        names.each do |name|
                plugin = nil

                if name.is_a?( Module )
                        plugin = name
                else
                        plugin = self.loaded_plugins[ name ]
                end

                self.log.debug "  registering %p" % [ name ]
                self.register_plugin( plugin )
        end
end
Also aliased as: plugin
anchor
plugins_installed?()

Returns true if the plugins for the extended app class have already been installed.

# File lib/strelka/plugins.rb, line 151
def plugins_installed?
        return !self.plugins_installed_from.nil?
end
anchor
register_plugin( mod )

Register the plugin mod in the receiving class. This adds any declaratives and class-level data necessary for configuring the plugin.

# File lib/strelka/plugins.rb, line 216
def register_plugin( mod )
        if mod.const_defined?( :ClassMethods )
                cm_mod = mod.const_get(:ClassMethods)
                self.log.debug "  adding class methods from %p" % [ cm_mod ]

                extend( cm_mod )
                cm_mod.instance_variables.each do |ivar|
                        next if instance_variable_defined?( ivar )

                        ival = cm_mod.instance_variable_get( ivar )
                        copy = Strelka::DataUtilities.deep_copy( ival )

                        self.log.debug "  copying class instance variable %s (%p)" % [ ivar, copy ]

                        instance_variable_set( ivar, copy )
                        self.log.debug "  instance variable %p set to %p in %p" %
                                [ ivar, self.instance_variable_get(ivar), self ]
                end
        end
end