package org.embulk.plugin;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import com.google.inject.Injector;
import org.embulk.config.ConfigException;
import org.embulk.spi.InputPlugin;
import org.embulk.plugin.compat.PluginWrappers;
public class PluginManager
{
private final List<PluginSource> sources;
private final Injector injector;
// Set<PluginSource> is injected by BuiltinPluginSourceModule or extensions
// using Multibinder<PluginSource>.
@Inject
public PluginManager(Set<PluginSource> pluginSources, Injector injector)
{
this.sources = ImmutableList.copyOf(pluginSources);
this.injector = injector;
}
@SuppressWarnings("unchecked")
public <T> T newPlugin(Class<T> iface, PluginType type)
{
T t = newPluginWithoutWrapper(iface, type);
if (t instanceof InputPlugin) {
return (T) PluginWrappers.inputPlugin((InputPlugin) t);
}
return t;
}
private <T> T newPluginWithoutWrapper(Class<T> iface, PluginType type)
{
if (sources.isEmpty()) {
throw new ConfigException("No PluginSource is installed");
}
if (type == null) {
throw new ConfigException(String.format("%s type is not set (if you intend to use NullOutputPlugin, you should enclose null in quotes such as {type: \"null\"}.", iface.getSimpleName()));
}
List<PluginSourceNotMatchException> exceptions = new ArrayList<>();
for (PluginSource source : sources) {
try {
return source.newPlugin(iface, type);
}
catch (PluginSourceNotMatchException e) {
exceptions.add(e);
}
}
throw buildPluginNotFoundException(iface, type, exceptions);
}
private static ConfigException buildPluginNotFoundException(Class<?> iface, PluginType type,
List<PluginSourceNotMatchException> exceptions)
{
StringBuilder message = new StringBuilder();
message.append(String.format("%s '%s' is not found.", iface.getSimpleName(), type.getName()));
for (PluginSourceNotMatchException exception : exceptions) {
Throwable cause = (exception.getCause() == null ? exception : exception.getCause());
if (cause.getMessage() != null) {
message.append(String.format("%n"));
message.append(cause.getMessage());
}
}
ConfigException e = new ConfigException(message.toString());
for (PluginSourceNotMatchException exception : exceptions) {
e.addSuppressed(exception);
}
return e;
}
}