X-Git-Url: http://gitweb.michael.orlitzky.com/?p=mailshears.git;a=blobdiff_plain;f=lib%2Fcommon%2Fplugin.rb;h=1178e2fb9a238293b22e72c3620d03b44b6e8782;hp=702b621ff5da9c1ee18ccbd0fd29352950a63386;hb=58849f9ba58bd0804ffe6c6d8248caf2ab66dc66;hpb=650e23790019880da91c7c7248a214a13763fd3e diff --git a/lib/common/plugin.rb b/lib/common/plugin.rb index 702b621..1178e2f 100644 --- a/lib/common/plugin.rb +++ b/lib/common/plugin.rb @@ -1,38 +1,77 @@ require 'common/domain' require 'common/user' -# All plugins should include this module. It defines the basic -# operations that all plugins are supposed to support. +# Methods that all plugins must provide. Certain operations -- for +# example, user listing -- must be supported by all plugins. These +# operations are defined here, often with naive default +# implementations, but it is up to each individual plugin to ensure +# that they are in fact implemented (well). +# module Plugin + # These are class methods for runnable plugins, meant to be + # _extended_. Those runnable plugins get a magic *run* method but + # need to define their own *runner* and *dummy_runner* to make it + # work. + # module Run - # Module methods, meant to be extended. Includers can explicitly - # extend this to get a run() method defined in terms of their own - # runner() and dummy_runner() methods. + # A callback function, called whenever another class or module + # includes this one. This is used to build a list of all things + # that inherited this class. Having such a list lets us run a + # collection of plugins without knowing in advance what they are. + # + # @param c [Class,Module] the name of the class or module that + # included us. + # def included(c) - # Callback, called whenever another class or module includes this - # one. The parameter given is the name of the class or module - # that included us. @includers ||= [] @includers << c end - def includers + + # Obtain the list of classes and modules that have included this one. + # + # @return [Array] the list of classes and modules + # that have included this one. + # + def includers() @includers ||= [] return @includers end + + # The runner class associated with this plugin. This method must + # be supplied by the child class, since they will all have + # different runners. + # + # @return [Class] the runner class associated with this plugin. + # def runner() - # The Runner associated with this plugin. raise NotImplementedError end + + # The "dummy" runner class associated with this plugin. This method + # must be supplied by the child class, since they will all have + # different dummy runners. + # + # @return [Class] the dummy runner class associated with this + # plugin. + # def dummy_runner() - # The DummyRunner associated with this plugin. raise NotImplementedError end + + # Run all of the plugins that have included this module. + # + # @param cfg [Configuration] the configuration options to pass to + # each of the plugins. + # + # @param args [Array] a variable number of additional + # arguments to be passed to the plugins we're running. + # def run(cfg, *args) includers().each do |includer| plugin = includer.new(cfg) @@ -46,14 +85,21 @@ module Plugin # The splat passes the correct (we hope) number of arguments to the # appropriate runner. The Rm(Dummy)Runner have splats on their # *target arguments as well, to turn ARGV back into an array. - runner.run(plugin, *args) + runner.run(cfg, plugin, *args) end end end + + # A generic version of {#describe_user}/{#describe_domain} that + # dispatches base on the class of the target. + # + # @param target [User,Domain] either a user or a domain to describe. + # + # @return [String] a string describing the *target*. The contents of + # the string depend on the plugin. + # def describe(target) - # A generic version of describe_user/describe_domain that - # dispatches base on the class of the target. if target.is_a?(User) if user_exists(target) then return describe_user(target) @@ -71,59 +117,110 @@ module Plugin end end + + # Provide a description of the given *domain*. This is output along + # with the domain name and can be anything of use to the system + # administrator. The default doesn't do anything useful and should + # be overridden if possible. + # + # @param domain [Domain] the domain to describe. + # + # @return [String] a string description of *domain*. + # def describe_domain(domain) - # Provide a "description" of the domain. This is output along with - # the domain name and can be anything of use to the system - # administrator. The default doesn't do anything useful and should - # be overridden. return domain.to_s() end + + # Provide a description of the given *user*. This is output along + # with the username and can be anything of use to the system + # administrator. The default doesn't do anything useful and should + # be overridden if possible. + # + # @param user [User] the domain to describe. + # + # @return [String] a string description of *user*. + # def describe_user(user) - # Provide a "description" of the user. This is output along - # with the domain name and can be anything of use to the system - # administrator. The default doesn't do anything useful and should - # be overridden. return user.to_s() end + + # Return a list of all users managed by this plugin. This must be + # supplied by the individual plugins (who know how to find their + # users). + # + # @return [Array] a list of the users that this plugin knows + # about. + # def list_users() - # Return a list of all users managed by this plugin. raise NotImplementedError end + + # Return a list of all domains managed by this plugin. This must be + # supplied by the individual plugins (who know how to find their + # domains). Many plugins will not have a separate concept of + # "domain", so the default implementation constructs a list of + # domains resulting from {#list_users}. + # + # For plugins that do know about domains, smarter implementations + # are surely possible. + # + # @return [Array] a list of the domains that this plugin knows + # about. + # def list_domains() - # Compute the domains from a list of users. Obviously much worse - # than getting the domains the "smart" way, if such a way exists. users = list_users() domains = users.map{ |u| u.domain() } return domains.uniq() end + + # Does the given *user* exist for this plugin? We use a naive + # implementation here based on {#list_users}. Plugins should override + # this with something faster. + # + # @param user [User] the user whose existence is in question. + # + # @return [Boolean] true if *user* exists for this plugin, and + # false otherwise. + # def user_exists(user) - # Does the given username exist for this plugin? We use a naive - # implementation here based on list_users() which is required to - # exist above. Plugins can override this with something fast. users = list_users() return users.include?(user) end + + # Does the given *domain* exist for this plugin? We use a naive + # implementation here based on {#list_domains}. Plugins that know + # about domains should override this with something fast. + # + # @param domain [Domain] the domain whose existence is in question. + # + # @return [Boolean] true if *domain* exists for this plugin, and + # false otherwise. + # def domain_exists(domain) - # Does the given domain exist for this plugin? We use a naive - # implementation here based on list_domains() which is required to - # exist above. Plugins can override this with something fast. domains = list_domains() return domains.include?(domain) end + + # List all users belonging to the given domains. We say that a user + # belongs to a domain "example.com" if the domain part of the user's + # email address is "example.com". + # + # This uses a naive loop, but relies only on the existence of + # {#list_users}. Plugins that know about domains should provide a + # more efficient implementation. + # + # @param domains [Array] the domains whose users we want. + # + # @return [Array] a list of {User} objects belonging to + # *domains* for this plugin. + # def list_domains_users(domains) - # Get all users belonging to the given domains. If a user has - # domainpart "example.com" then it belongs to the domain - # "example.com". - # - # This uses a naive loop, but relies only on the existence of a - # list_users() method which is guaranteed above. More efficient - # implementations can usually be made within the plugin. domains_users = [] users = list_users();