package net.jangaroo.ide.idea.jps.util;
import net.jangaroo.exml.api.Exmlc;
import net.jangaroo.jooc.api.Jooc;
import net.jangaroo.properties.api.Propc;
import java.io.File;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Load Jangaroo compilers of a specified version, using a custom class loader.
*/
public class CompilerLoader {
private static final Map<List<String>,ClassLoader> CLASS_LOADER_BY_JAR_FILES_CACHE = new HashMap<List<String>, ClassLoader>();
public static Jooc loadJooc(List<String> jarFileNames) throws FileNotFoundException, ClassNotFoundException, InstantiationException, IllegalAccessException {
return instantiateClass(Jooc.class, "net.jangaroo.jooc.Jooc", jarFileNames);
}
public static Exmlc loadExmlc(List<String> jarFileNames) throws FileNotFoundException, ClassNotFoundException, InstantiationException, IllegalAccessException {
return instantiateClass(Exmlc.class, "net.jangaroo.exml.compiler.Exmlc", jarFileNames);
}
public static Propc loadPropc(List<String> jarFileNames) throws FileNotFoundException, ClassNotFoundException, InstantiationException, IllegalAccessException {
return instantiateClass(Propc.class, "net.jangaroo.properties.PropertyClassGenerator", jarFileNames);
}
private static <T> T instantiateClass(Class<T> compilerInterface, String mainClassName, List<String> jarFileNames) throws FileNotFoundException, ClassNotFoundException, InstantiationException, IllegalAccessException {
ClassLoader jooClassLoader = getClassLoader(jarFileNames);
Class<?> joocClass = jooClassLoader.loadClass(mainClassName);
return compilerInterface.cast(joocClass.newInstance());
}
private static ClassLoader getClassLoader(List<String> jarFileNames) throws FileNotFoundException {
return anyEndsWith(jarFileNames, "-SNAPSHOT.jar")
? createClassLoader(jarFileNames)
: getCachedClassLoader(jarFileNames);
}
private static boolean anyEndsWith(List<String> strings, String suffix) {
for (String string : strings) {
if (string.endsWith(suffix)) {
return true;
}
}
return false;
}
private synchronized static ClassLoader getCachedClassLoader(List<String> jarFileNames) throws FileNotFoundException {
ClassLoader classLoader = CLASS_LOADER_BY_JAR_FILES_CACHE.get(jarFileNames);
if (classLoader == null) {
classLoader = createClassLoader(jarFileNames);
CLASS_LOADER_BY_JAR_FILES_CACHE.put(jarFileNames, classLoader);
}
return classLoader;
}
private static ClassLoader createClassLoader(List<String> jarFileNames) throws FileNotFoundException {
URL[] urls = new URL[jarFileNames.size()];
for (int i = 0; i < jarFileNames.size(); i++) {
urls[i] = toURL(jarFileNames.get(i));
}
return new URLClassLoader(urls, CompilerLoader.class.getClassLoader());
}
private static URL toURL(String jarFileName) throws FileNotFoundException {
File jarFile = new File(jarFileName);
if (!jarFile.exists()) {
throw new FileNotFoundException("JAR file not found: " + jarFile.getAbsolutePath());
}
try {
return jarFile.toURI().toURL();
} catch (MalformedURLException e) {
// should not happen:
throw new IllegalStateException(e);
}
}
}