package krasa.formatter.eclipse; import java.io.File; import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import java.util.List; import krasa.formatter.processor.Processor; import krasa.formatter.settings.Settings; import krasa.formatter.settings.provider.CppPropertiesProvider; import krasa.formatter.settings.provider.JSPropertiesProvider; import org.jetbrains.annotations.NotNull; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; public class Classloaders { private static final Logger LOG = Logger.getInstance(Classloaders.class.getName()); private static ClassLoader eclipse44; private static ClassLoader newEclipse; public static ClassLoader getEclipse44() { if (eclipse44 == null) { eclipse44 = classLoader(getPluginLibHomeEclipse44(), "adapter44.jar", "eclipse44.jar" ); } return eclipse44; } public static ClassLoader getEclipse() { if (newEclipse == null) { newEclipse = classLoader(getPluginLibHomeEclipse(), "adapter.jar", "eclipse.jar"); } return newEclipse; } public static ClassLoader getCustomClassloader(List<URL> jars) { try { jars.add(new File(getPluginLibHomeEclipse(), "adapter.jar").toURI().toURL()); for (URL jar : jars) { if (!new File(jar.toURI()).exists()) { throw new IllegalStateException("Plugin jar file not found: " + jar.toURI()); } } URL[] a = jars.toArray(new URL[jars.size()]); LOG.info("Creating classloader for " + Arrays.toString(a)); return new ParentLastURLClassLoader(Classloaders.class.getClassLoader(), a); } catch (Exception e) { throw new RuntimeException(e); } } @NotNull private static File getPluginLibHomeEclipse44() { return getPluginHome("eclipse44"); } @NotNull private static File getPluginLibHomeEclipse() { return getPluginHome("eclipse"); } @NotNull private static File getPluginHome(String eclipseVersion) { File pluginHome; if (isUnitTest()) { pluginHome = new File("../lib/" + eclipseVersion); } else { pluginHome = new File(PathManager.getPluginsPath(), "EclipseFormatter/lib/"); File preInstalled = new File(PathManager.getPreInstalledPluginsPath(), "EclipseFormatter/lib/"); if (!pluginHome.exists() && preInstalled.exists()) { pluginHome = preInstalled; } } return pluginHome; } private static boolean isUnitTest() { return ApplicationManager.getApplication() == null || ApplicationManager.getApplication().isUnitTestMode(); } @NotNull private static ClassLoader classLoader(File parent, String... jarFiles) { URL[] urls = new URL[jarFiles.length]; for (int i = 0; i < jarFiles.length; i++) { String jar = jarFiles[i]; File jarFile = new File(parent, jar); if (!jarFile.exists()) { throw new IllegalStateException("Plugin jar file not found: " + jarFile.getAbsolutePath()); } try { urls[i] = jarFile.toURI().toURL(); } catch (MalformedURLException e) { throw new RuntimeException(e); } } try { // return UrlClassLoader.classLoader().urls(jarFile).useCache().get(); LOG.info("Creating classloader for " + Arrays.toString(urls)); return new ParentLastURLClassLoader(Classloaders.class.getClassLoader(), urls); } catch (Exception e) { throw new RuntimeException(e); } } @NotNull public static CodeFormatterFacade getCppFormatter(CppPropertiesProvider cppProperties) { Object o = null; try { ClassLoader classLoader = getEclipse(); Class<?> aClass = Class.forName("krasa.formatter.adapter.CppCodeFormatterFacade", true, classLoader); Constructor<?> constructor = aClass.getConstructor(CppPropertiesProvider.class); o = constructor.newInstance(cppProperties); } catch (Exception e) { throw new RuntimeException(e); } return (CodeFormatterFacade) o; } @NotNull public static CodeFormatterFacade getJsFormatter(JSPropertiesProvider propertiesProvider) { Object o = null; try { ClassLoader classLoader = getEclipse44(); Class<?> aClass = Class.forName("krasa.formatter.adapter.JSCodeFormatterFacade", true, classLoader); Constructor<?> constructor = aClass.getConstructor(JSPropertiesProvider.class); o = constructor.newInstance(propertiesProvider); } catch (Exception e) { throw new RuntimeException(e); } return (CodeFormatterFacade) o; } public static Processor getGWTProcessor(Settings settings) { Object o = null; try { ClassLoader classLoader = getEclipse44(); Class<?> aClass = Class.forName("krasa.formatter.adapter.processor.GWTProcessor", true, classLoader); Constructor<?> constructor = aClass.getConstructor(Settings.class); o = constructor.newInstance(settings); } catch (Exception e) { throw new RuntimeException(e); } return (Processor) o; } public static Processor getJSCommentsFormatterProcessor(Settings settings) { Object o = null; try { ClassLoader classLoader = getEclipse44(); Class<?> aClass = Class.forName("krasa.formatter.adapter.processor.JSCommentsFormatterProcessor", true, classLoader); Constructor<?> constructor = aClass.getConstructor(Settings.class); o = constructor.newInstance(settings); } catch (Exception e) { throw new RuntimeException(e); } return (Processor) o; } }