public <P extends Plugin> P getPlugin(final Class<P> requestedPlugin,
GetPluginOption... options) {
// Report our request.
if (this.diagnosis != null) {
String name = requestedPlugin == null ? "null" : requestedPlugin.getCanonicalName();
this.diagnosis.channel(PluginManagerTracer.class).status("get/start", new OptionInfo("plugin", name));
}
// We don't handle null values.
if (requestedPlugin == null) {
this.diagnosis.channel(PluginManagerTracer.class).status("get/end", new OptionInfo("return", null));
return null;
}
// Sanity check.
if (!requestedPlugin.isInterface()) {
this.diagnosis.channel(PluginManagerTracer.class).status("get/onlyinterface", new OptionInfo("plugin", requestedPlugin.getCanonicalName()));
this.diagnosis.channel(PluginManagerTracer.class).status("get/end", new OptionInfo("return", null));
System.err.println("YOU MUST NOT call getPlugin() with a concrete class; only interfaces are");
System.err.println("supported for lookup. This means do not call getPlugin(MyPluginImpl.class),");
System.err.println("but rather getPlugin(MyPlugin.class)!");
return null;
}
// Used to process the options
final OptionUtils<GetPluginOption> ou = new OptionUtils<GetPluginOption>(options);
// We use this one to select the plugin
PluginSelector<P> pluginSelector = null;
// Check our options. In case we have a plugin selector, only use the selector
if (ou.contains(OptionPluginSelector.class)) {
pluginSelector = ou.get(OptionPluginSelector.class).getSelector();
} else {
// Capabilites we require
final String capabilites[] = ou.get(OptionCapabilities.class, new OptionCapabilities()).getCapabilities();
// Get caps as list
final Collection<String> caps = Arrays.asList(capabilites);
// Create our own selector
pluginSelector = new PluginSelector<P>() {
public boolean selectPlugin(final Plugin plugin) {
// In case we have caps do special handling and don't return the next
// best plugin
if (caps.size() > 0) {
Collection<String> pcaps = PluginManagerImpl.this.information.getInformation(Information.CAPABILITIES, plugin);
// Check the plugin has them all
if (pcaps.containsAll(caps)) return true;
return false;
}
return true;
}
};
}
// Check for each plugin if it matches
for (final Plugin plugin : this.pluginRegistry.getAllPlugins()) {
if (this.diagnosis != null)
this.diagnosis.channel(PluginManagerTracer.class).status("get/considering", new OptionInfo("plugin", plugin.toString()));
// Check the meta information for this plugin. We only want active classes
final PluginMetaInformation metaInformation = this.pluginRegistry.getMetaInformationFor(plugin);
// Plugins not active are not considered
if (metaInformation.pluginStatus != PluginStatus.ACTIVE) continue;
// Check if the plugin can be assigned to the requested class
if (requestedPlugin.isAssignableFrom(plugin.getClass())) {
if (pluginSelector.selectPlugin((P) plugin)) {
if (this.diagnosis != null)
this.diagnosis.channel(PluginManagerTracer.class).status("get/end", new OptionInfo("return", plugin.toString()));
return (P) plugin;
}
}
}
if (this.diagnosis != null)
this.diagnosis.channel(PluginManagerTracer.class).status("get/end", new OptionInfo("return", null));
return null;
}