So there is this requirements I was mentioning before about the fact that a plugin may have several implementations.
There are two kinds of plugin
1/ plugins which are their own implementation: class FooPlugin extends CRaSHPlugin<FooPlugin> { … }
2/ plugins implementing a common class interface such as the AuthenticationPlugin: class MyAuthenticationPlugin extends CRaSHPlugin<Authenticator> { … }
Now the choice of the plugin to use is not done via the plugin system but instead via the consumer of the plugin, for instance if you look at SSHPlugin you will see that it uses the configuration property crash.auth to browse all plugins providing the Authentication interface until it find one with the name of the property, for example in configuration.properties we do have:
crash.auth=simple
and if you change by
crash.auth=jaas
then it changes the plugin implementation used by SSHPlugin.
The effort about enabling / disabling the plugin system is a good opportunity to improve that and have the SSHPlugin not worry about determining which plugin to use. Instead it would only ask for a single plugin implementing the Authentication interface and simply get it.
So the convention to enable/disable a plugin based on property should handle more than just enable / disable, they need to provide a way to specify the plugin to use. Each plugin should have two values for identifying it:
1/ the plugin name like "auth" : the plugin that takes care of authentication
2/ the plugin qualifier like "simple" or "jaas" (as in IOC qualifier)
(note we're staying away from the notion of Java type (i.e the class name of the plugin) because sysadmin simply don't know Java class. So it is more convenient to work on identifiers.)
Each plugin should provide the name and the qualifier in the CRaSHPlugin interface via abstract methods getName() and getQualifier() that a plugin must implement. The "default" qualifier is a convention to say that the plugin is the default implementation and used mostly when there is a single plugin implementation possible or when a plugin should be used by default. In case of Authentication plugin we would not use "default" because it should the plugin to use should be explicitly specified (crash.auth=simple).
Then we need to find a way to use configuration properties to:
1/ enable / disable a plugin
2/ specify the plugin qualifier to use (not specified means "default" qualifier).
So I'm thinking about something along the lines you proposed with crash.plugins prefix :
1/ specify plugin implementation to use
- crash.plugins.$NAME=$QUALIFIER (not specified then implementation to use is "default")
2/ control activation of plugin
- crash.plugins.$NAME.$QUALIFIER.active = false | true
- crash.plugins.$NAME.active = false | true (same but for "default" qualifier)
This way we could have following configuration:
a/ Disable telnet plugin
crash.plugins.telnet.active=false
b/ Use simple authentication
crash.plugins.auth=simple
c/ Use jaas authenticaton and disable simple authentication plugin
crash.plugins.auth=jaas
crash.plugins.auth.simple.active=false
WDYT ?
(I encourage you to review and challenge what I wrote because I often miss some scenario that could contradict the general case).