/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2010.
*/
package x10.plugin;
import java.io.File;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import polyglot.ast.NodeFactory;
import polyglot.frontend.AbstractGoal_c;
import polyglot.frontend.FileSource;
import polyglot.frontend.Globals;
import polyglot.frontend.Parser;
import polyglot.frontend.ParserlessJLExtensionInfo;
import polyglot.frontend.Source;
import polyglot.frontend.SourceLoader;
import polyglot.types.QName;
import polyglot.types.TypeSystem;
import polyglot.util.ErrorInfo;
import polyglot.util.ErrorQueue;
import polyglot.util.InternalCompilerError;
import polyglot.util.QuotedStringTokenizer;
import x10.Configuration;
import x10.ExtensionInfo;
import x10.X10CompilerOptions;
public class LoadPlugins extends AbstractGoal_c {
private static final long serialVersionUID = -7328993239190636933L;
private final ExtensionInfo extInfo;
public LoadPlugins(ExtensionInfo extInfo) {
super("LoadPlugins");
this.extInfo = extInfo;
}
public boolean runTask() {
X10CompilerOptions opts = (X10CompilerOptions) extInfo.getOptions();
String compilerPlugins = opts.x10_config.PLUGINS;
if (compilerPlugins != null && ! compilerPlugins.equals("")) {
loadPluginsFromConfigString(compilerPlugins);
}
return true;
}
private void loadPluginsFromConfigString(String compilerPlugins) {
for (StringTokenizer st = new StringTokenizer(compilerPlugins, ",; \t\n"); st.hasMoreTokens(); ) {
String pluginName = st.nextToken();
if (pluginName.length() > 0) {
loadPlugin(extInfo, QName.make(pluginName));
}
}
}
private static URL[] parseClassPath(String classpath) {
StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
ArrayList<URL> cp = new ArrayList<URL>(st.countTokens());
for (; st.hasMoreTokens(); ) {
try {
File f = new File(st.nextToken());
if (f.exists()) {
cp.add(f.toURL());
}
} catch (MalformedURLException e) { }
}
return cp.toArray(new URL[cp.size()]);
}
/**
* Load a compiler plugin from the class file and register it with the given ExtensionInfo.
* @param extInfo the extension info to register the plugin with
* @param pluginName the name of the plugin to load
* TODO: add a separate plugin classpath to the compiler options
*/
public static void loadPlugin(ExtensionInfo extInfo, QName pluginName) {
loadPlugin(extInfo, pluginName, System.getProperty("java.class.path"));
}
/**
* Load a compiler plugin from the class file and register it with the given ExtensionInfo.
* @param extInfo the extension info to register the plugin with
* @param pluginName the name of the plugin to load
* @param classpath the classpath to use for looking up the plugin class
*/
public static void loadPlugin(ExtensionInfo extInfo, QName pluginName, String classpath) {
ErrorQueue eq = extInfo.compiler().errorQueue();
try {
// System.out.println("classpath = " + System.getProperty("java.class.path"));
ClassLoader cl = new URLClassLoader(parseClassPath(classpath), LoadPlugins.class.getClassLoader());
Class<?> c = Class.forName(pluginName.toString(), true, cl);
Object o = c.newInstance();
if (o instanceof CompilerPlugin) {
// OK, it's a plugin!
CompilerPlugin plugin = (CompilerPlugin) o;
extInfo.addPlugin(pluginName, plugin);
}
else {
eq.enqueue(ErrorInfo.WARNING, "Class " + pluginName + " does not implement CompilerPlugin. Skipping.");
}
}
catch (IllegalAccessException e) {
eq.enqueue(ErrorInfo.WARNING, "Plugin class " + pluginName + " could not be accessed. Skipping.");
}
catch (InstantiationException e) {
eq.enqueue(ErrorInfo.WARNING, "Plugin class " + pluginName + " could not be instantiated. Skipping.");
}
catch (ClassNotFoundException e) {
eq.enqueue(ErrorInfo.WARNING, "Plugin class " + pluginName + " not found. Skipping.");
}
}
}