Class: Mongrel::PluginManager

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/mongrel/plugins.rb

Overview

Implements the main method of managing plugins for Mongrel. “Plugins” in this sense are any classes which get registered with Mongrel for possible use when it’s operating. These can be Handlers, Commands, or other classes. When you create a Plugin you register it into a URI-like namespace that makes it easy for you (and others) to reference it later during configuration.

PluginManager is used as nothing more than a holder of all the plugins that have registered themselves. Let’s say you have:

class StopNow < Plugin "/commands"
 ...
end

Then you can get at this plugin with:

cmd = PluginManager.create("/commands/stopnow")

The funky syntax for StopNow is a weird trick borrowed from the Camping framework. See the Mongrel::Plugin function (yes, function). What this basically does is register it into the namespace for plugins at /commands. You could go as arbitrarily nested as you like.

Why this strange almost second namespace? Why not just use the ObjectSpace and/or Modules? The main reason is speed and to avoid cluttering the Ruby namespace with what is really a configuration statement. This lets implementors put code into the Ruby structuring they need, and still have Plugins available to Mongrel via simple URI-like names.

The alternative (as pluginfactory does it) is to troll through ObjectSpace looking for stuff that might be plugins every time one is needed. This alternative also means that you are stuck naming your commands in specific ways and putting them in specific modules in order to configure how Mongrel should use them.

One downside to this is that you need to subclass plugin to make it work. In this case use mixins to add other functionality.

Instance Method Summary collapse

Constructor Details

#initializePluginManager

Returns a new instance of PluginManager.



48
49
50
# File 'lib/mongrel/plugins.rb', line 48

def initialize
  @plugins = URIClassifier.new
end

Instance Method Details

#availableObject

Returns a map of URIs-> that you can use to investigate available handlers.



96
97
98
99
100
101
102
103
104
105
# File 'lib/mongrel/plugins.rb', line 96

def available
  map = {}
  @plugins.uris.each do |u| 
    cat, name, plugins = @plugins.resolve(u)
    map[cat] ||= []
    map[cat] += plugins.keys
  end

  return map
end

#create(name, options = {}) ⇒ Object

Resolves the given name (should include /category/name) to find the plugin class and create an instance. It uses the same URIClassifier that the rest of Mongrel does so it is fast.



84
85
86
87
88
89
90
91
92
# File 'lib/mongrel/plugins.rb', line 84

def create(name, options = {})
  category, plugin, map = @plugins.resolve(name)

  if category and plugin and plugin.length > 0
    map[plugin].new(options)
  else
    raise "Plugin #{name} does not exist"
  end
end

#load(path) ⇒ Object

Tell the PluginManager to scan the given path (recursively) and load the *.rb files found there. This is how you’d setup your own plugin directory.



55
56
57
58
59
60
61
62
# File 'lib/mongrel/plugins.rb', line 55

def load(path)
  Dir.chdir(path) do
    Dir["**/*.rb"].each do |rbfile|
      STDERR.puts "Loading plugins from #{rbfile}"
      require rbfile
    end
  end
end

#register(category, name, klass) ⇒ Object

Not necessary for you to call directly, but this is how Mongrel::PluginBase.inherited actually adds a plugin to a category.



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/mongrel/plugins.rb', line 67

def register(category, name, klass)
  cat, ignored, map = @plugins.resolve(category)
  
  if not cat or ignored.length > 0
    map = {name => klass}
    @plugins.register(category, map)
  elsif not map
    raise "Unknown category #{category}"
  else
    map[name] = klass
  end
end