package org.embulk.plugin;
import java.util.Collection;
import java.util.Properties;
import java.net.URL;
import java.io.InputStream;
import java.io.IOException;
import com.google.inject.Module;
import com.google.inject.Binder;
import com.google.inject.Scopes;
import com.google.inject.Provider;
import org.embulk.config.ConfigSource;
public class PluginClassLoaderModule
implements Module
{
public PluginClassLoaderModule(ConfigSource systemConfig)
{ }
@Override
public void configure(Binder binder)
{
binder.bind(PluginClassLoaderFactory.class).toProvider(new FactoryProvider()).in(Scopes.SINGLETON);;
}
private static class FactoryProvider
implements Provider<PluginClassLoaderFactory>
{
private final Collection<String> parentFirstPackages;
private final Collection<String> parentFirstResources;
private final PluginClassLoaderFactory factory;
public FactoryProvider()
{
// TODO make these paths customizable using ConfigSource
this.parentFirstPackages = readPropertyKeys("/embulk/parent_first_packages.properties");
this.parentFirstResources = readPropertyKeys("/embulk/parent_first_resources.properties");
this.factory = new Factory();
}
private static Collection<String> readPropertyKeys(String name)
{
try (InputStream in = PluginClassLoaderModule.class.getResourceAsStream(name)) {
if (in == null) {
throw new NullPointerException(String.format("Resource '%s' is not found in classpath. Jar file or classloader is broken.", name));
}
Properties prop = new Properties();
prop.load(in);
return prop.stringPropertyNames();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
@Override
public PluginClassLoaderFactory get()
{
return factory;
}
private class Factory implements PluginClassLoaderFactory
{
public PluginClassLoader create(Collection<URL> urls, ClassLoader parentClassLoader)
{
return new PluginClassLoader(urls, parentClassLoader,
parentFirstPackages, parentFirstResources);
}
}
}
}