package org.embulk.jruby; import com.google.inject.Inject; import org.jruby.embed.ScriptingContainer; import org.jruby.embed.InvokeFailedException; import org.embulk.plugin.PluginType; import org.embulk.plugin.PluginSource; import org.embulk.plugin.PluginSourceNotMatchException; import org.embulk.spi.InputPlugin; import org.embulk.spi.OutputPlugin; import org.embulk.spi.ParserPlugin; import org.embulk.spi.FormatterPlugin; import org.embulk.spi.DecoderPlugin; import org.embulk.spi.EncoderPlugin; import org.embulk.spi.FilterPlugin; import org.embulk.spi.GuessPlugin; import org.embulk.spi.ExecutorPlugin; public class JRubyPluginSource implements PluginSource { private final ScriptingContainer jruby; private final Object rubyPluginManager; @Inject public JRubyPluginSource(ScriptingContainer jruby) { this.jruby = jruby; // get Embulk::Plugin //this.rubyPluginManager = ((RubyModule) jruby.get("Embulk")).const_get( // RubySymbol.newSymbol( // jruby.getProvider().getRuntime(), "Plugin")); this.rubyPluginManager = jruby.runScriptlet("Embulk::Plugin"); } public <T> T newPlugin(Class<T> iface, PluginType type) throws PluginSourceNotMatchException { String name = type.getName(); String category; if (InputPlugin.class.isAssignableFrom(iface)) { category = "input"; } else if (OutputPlugin.class.isAssignableFrom(iface)) { category = "output"; } else if (ParserPlugin.class.isAssignableFrom(iface)) { category = "parser"; } else if (FormatterPlugin.class.isAssignableFrom(iface)) { category = "formatter"; } else if (DecoderPlugin.class.isAssignableFrom(iface)) { category = "decoder"; } else if (EncoderPlugin.class.isAssignableFrom(iface)) { category = "encoder"; } else if (FilterPlugin.class.isAssignableFrom(iface)) { category = "filter"; } else if (GuessPlugin.class.isAssignableFrom(iface)) { category = "guess"; } else if (ExecutorPlugin.class.isAssignableFrom(iface)) { category = "executor"; } else { // unsupported plugin category throw new PluginSourceNotMatchException("Plugin interface "+iface+" is not supported in JRuby"); } String methodName = "new_java_" + category; try { return jruby.callMethod(rubyPluginManager, methodName, name, iface); } catch (InvokeFailedException ex) { throw new PluginSourceNotMatchException(ex.getCause()); } } }