package open.dolphin.plugin;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Kazushi Minagawa
* @param <S>
*/
public final class PluginLoader<S> {
private static final String PREFIX = "META-INF/plugins/";
private final Class<S> plugin;
private final ClassLoader loader;
private final List<String> providers;
public PluginLoader(Class<S> plugin, ClassLoader loader) {
this.plugin = plugin;
this.loader = loader;
providers = new ArrayList<>();
readAllEntries();
}
public Iterator<S> iterator() {
return new Iterator<S>() {
Iterator<String> iter = providers.iterator();
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public S next() {
if (iter.hasNext()) {
String clsName = iter.next();
try {
S p = plugin.cast(Class.forName(clsName, true, loader).newInstance());
return p;
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
Logger.getLogger(PluginLoader.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
} else {
throw new NoSuchElementException();
}
}
};
}
private void readAllEntries() {
try {
try (InputStream in = loader.getResourceAsStream(PREFIX+plugin.getName());
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"))) {
String line;
while ((line=reader.readLine())!=null) {
if (!line.startsWith("#")) {
String[] cmp = line.split("\\s* \\s*");
providers.add(cmp[0]);
}
}
}
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(PluginLoader.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(PluginLoader.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static <S> PluginLoader<S> load(Class<S> plugin, ClassLoader loader) {
return new PluginLoader<>(plugin, loader);
}
public static <S> PluginLoader<S> load(Class<S> plugin) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return PluginLoader.load(plugin, cl);
}
}