More documentation for the MatchHandler class.
[kaya.git] / lib / plugins / loader.rb
blob0b8ff445363e859443db5699406b23f0b936fb7a
1 # Copyright (c) 2009 Paolo Capriotti <p.capriotti@gmail.com>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 require 'enumerator'
10 class PluginLoader
11   BASE_DIR = File.expand_path(File.dirname(__FILE__))
12   
13   NoPluginFound = Class.new(Exception)
14   include Enumerable
15   
16   def initialize
17     # load all ruby files in subdirectories
18     Dir[File.join(BASE_DIR, '*')].each do |f|
19       if File.directory?(f)
20         Dir[File.join(f, '*.rb')].each do |rb_file|
21           load(rb_file)
22         end
23       end
24     end
25     
26     @plugins = ObjectSpace.
27                to_enum(:each_object, Class).
28                select do |k|
29       k.include?(Plugin) and k.plugin_name
30     end
31   end
32   
33   def each(&blk)
34     @plugins.each(&blk)
35   end
36   
37   def get_matching(interface, keywords = [])
38     plugins = get_all_matching(interface).
39       sort_by {|x| x.score(keywords) }
40       
41     raise NoPluginFound.new("No plugins matching interface #{interface}") if plugins.empty?
42     plugins.last
43   end
44   
45   def get_all_matching(interface)
46     @plugins.reject {|x| not x.implements?(interface) }
47   end
48   
49    # singleton
50   class << self
51     alias :internal_new :new
52     
53     def new
54       @instance ||= PluginLoader.internal_new
55     end
56   end
57   
58   def self.base_dir
59     BASE_DIR
60   end
61 end