What is a plugin?
A plugin is a software component that can be integrated into an
application even at runtime. Thus composition takes place just-in-time and
is usually initiated by the end user who installs the plugin.
How do I develop a plugin-based application?
You have to follow only some simple steps to develop and use plugins:
- Firstly, you need a plugin interface. This interface must be a sub-type of
de.uulm.plugin.Plugin in order that the plugin framework recognized it
as a plugin type. Furthermore, you can extend the interface
de.uulm.plugin.Singleton in case you want to assure that there is
at most one instance of each plugin of this type.
A sample plugin interface could be like:
public interface MyPlugin extends Plugin {
// the functionality implemented by each plugin
void doXY();
}
- Secondly, you can write your application using plugins of type MyPlugin.
Therefore, you'll firstly get an instance of de.uulm.plugin.PluginRegistry which
provides access to instances of all plugins:
PluginRegistry reg = PluginRegistry.getInstance();
Thereafter, you'll retrieve all plugins of your own plugin type from the
plugin registry:
MyPlugin[] ps = (MyPlugin[]) reg.getPlugins(MyPlugin.class);
Although that static return type is Plugin[], the dynamic type is
an array whose elements have the provided type. The parameter to the getPlugins()
method must be a Class object of an interface being a sub-type of
the Plugin interface.
Finally, you can work with your plugins, e.g.
for (MyPlugin p : ps)
p.doXY();
- Now, we have got a plugin-based application that is minimal and ready to run.
However, at present, there will be no iteration of the above for loop, since
there is no concrete plugin yet. Thus, we'll develop a plugin:
public class ConcretePluginA implements MyPlugin {
public void doXY() {
System.out.println("Hi folks!");
}
}
With the above steps, you'll get an application that uses plugins. Please be aware that
all plugins can be developed independently of the application using the plugins. They
also can be compiled independently and be composed as late as at runtime.
How can I invoke plugins conditionally?
If we plan to conditionally invoke plugins, we need a so-called voting method
that votes for or against the invocation of a plugin. Thus the plugin interface has
to look like this:
public interface MyPlugin extends Plugin {
// voting method that checks whether this plugin
// can handle this object
boolean canHandle(Object o);
// ... and handle object o (if it can be handled
// which has to be checked in advance!)
void handle(Object o);
}
With the method
canHandle() it has to be checked whether a plugin is able
to handle a certain object before the method
handle() is called with this
object.
Thus, the main application looks like this:
MyPlugin[] ps = (MyPlugin[]) reg.getPlugins(MyPlugin.class);
// object o should be handled by a suitable plugin
Object o = ...;
for (MyPlugin p : ps)
if (p.canHandle(o))
p.handle(o);