Plugins: Allow for plugins to implement onModule method that will be automatically injected with the relevant module type, closes #1613.
This commit is contained in:
parent
e37c0904f0
commit
1d35e27b3b
|
@ -30,8 +30,10 @@ import java.util.Collection;
|
|||
|
||||
/**
|
||||
* A base class for a plugin.
|
||||
*
|
||||
*
|
||||
* <p/>
|
||||
* A plugin can be dynamically injected with {@link Module} by implementing <tt>onModule(AnyModule)</tt> method
|
||||
* removing the need to override {@link #processModule(org.elasticsearch.common.inject.Module)} and check using
|
||||
* instanceof.
|
||||
*/
|
||||
public abstract class AbstractPlugin implements Plugin {
|
||||
|
||||
|
|
|
@ -28,8 +28,10 @@ import java.util.Collection;
|
|||
|
||||
/**
|
||||
* An extension point allowing to plug in custom functionality.
|
||||
*
|
||||
*
|
||||
* <p/>
|
||||
* A plugin can be dynamically injected with {@link Module} by implementing <tt>onModule(AnyModule)</tt> method
|
||||
* removing the need to override {@link #processModule(org.elasticsearch.common.inject.Module)} and check using
|
||||
* instanceof.
|
||||
*/
|
||||
public interface Plugin {
|
||||
|
||||
|
@ -73,6 +75,10 @@ public interface Plugin {
|
|||
*/
|
||||
Collection<Class<? extends CloseableIndexComponent>> shardServices();
|
||||
|
||||
/**
|
||||
* Process a specific module. Note, its simpler to implement a custom <tt>onModule(AnyModule module)</tt>
|
||||
* method, which will be automatically be called by the relevant type.
|
||||
*/
|
||||
void processModule(Module module);
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.google.common.collect.Lists;
|
|||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.elasticsearch.ElasticSearchException;
|
||||
import org.elasticsearch.common.collect.MapBuilder;
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.component.LifecycleComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
|
@ -51,6 +52,18 @@ public class PluginsService extends AbstractComponent {
|
|||
|
||||
private final ImmutableMap<String, Plugin> plugins;
|
||||
|
||||
private final ImmutableMap<Plugin, List<OnModuleReference>> onModuleReferences;
|
||||
|
||||
static class OnModuleReference {
|
||||
public final Class<? extends Module> moduleClass;
|
||||
public final Method onModuleMethod;
|
||||
|
||||
OnModuleReference(Class<? extends Module> moduleClass, Method onModuleMethod) {
|
||||
this.moduleClass = moduleClass;
|
||||
this.onModuleMethod = onModuleMethod;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
public PluginsService(Settings settings, Environment environment) {
|
||||
super(settings);
|
||||
|
@ -65,6 +78,31 @@ public class PluginsService extends AbstractComponent {
|
|||
logger.info("loaded {}, sites {}", plugins.keySet(), sitePlugins());
|
||||
|
||||
this.plugins = ImmutableMap.copyOf(plugins);
|
||||
|
||||
MapBuilder<Plugin, List<OnModuleReference>> onModuleReferences = MapBuilder.newMapBuilder();
|
||||
for (Plugin plugin : plugins.values()) {
|
||||
List<OnModuleReference> list = Lists.newArrayList();
|
||||
for (Method method : plugin.getClass().getDeclaredMethods()) {
|
||||
if (!method.getName().equals("onModule")) {
|
||||
continue;
|
||||
}
|
||||
if (method.getParameterTypes().length == 0 || method.getParameterTypes().length > 1) {
|
||||
logger.warn("Plugin: {} implementing onModule with no parameters or more than one parameter", plugin.name());
|
||||
continue;
|
||||
}
|
||||
Class moduleClass = method.getParameterTypes()[0];
|
||||
if (!Module.class.isAssignableFrom(moduleClass)) {
|
||||
logger.warn("Plugin: {} implementing onModule by the type is not of Module type {}", plugin.name(), moduleClass);
|
||||
continue;
|
||||
}
|
||||
method.setAccessible(true);
|
||||
list.add(new OnModuleReference(moduleClass, method));
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
onModuleReferences.put(plugin, list);
|
||||
}
|
||||
}
|
||||
this.onModuleReferences = onModuleReferences.immutableMap();
|
||||
}
|
||||
|
||||
public ImmutableMap<String, Plugin> plugins() {
|
||||
|
@ -80,6 +118,19 @@ public class PluginsService extends AbstractComponent {
|
|||
public void processModule(Module module) {
|
||||
for (Plugin plugin : plugins().values()) {
|
||||
plugin.processModule(module);
|
||||
// see if there are onModule references
|
||||
List<OnModuleReference> references = onModuleReferences.get(plugin);
|
||||
if (references != null) {
|
||||
for (OnModuleReference reference : references) {
|
||||
if (reference.moduleClass.isAssignableFrom(module.getClass())) {
|
||||
try {
|
||||
reference.onModuleMethod.invoke(plugin, module);
|
||||
} catch (Exception e) {
|
||||
logger.warn("plugin {}, failed to invoke custom onModule method", e, plugin.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue