package jetbrains.mps.tool.environment; /*Generated by MPS */ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Set; import jetbrains.mps.library.contributor.LibDescriptor; import java.util.LinkedHashSet; import java.util.Arrays; import jetbrains.mps.core.tool.environment.util.PathManager; import java.io.File; import jetbrains.mps.core.tool.environment.classloading.UrlClassLoader; import jetbrains.mps.vfs.impl.IoFileSystem; import java.util.Collections; import java.util.List; import java.net.URL; import java.util.ArrayList; import java.net.MalformedURLException; import jetbrains.mps.library.LibraryInitializer; import jetbrains.mps.library.contributor.LibraryContributor; import jetbrains.mps.core.tool.environment.util.SetLibraryContributor; import java.util.Map; import java.util.LinkedHashMap; /*package*/ class LibraryContributorHelper { private static final String MODULES_PREFIX = "!/modules"; private final EnvironmentConfig myConfig; private final ClassLoader myRootClassLoader; public LibraryContributorHelper(@NotNull EnvironmentConfig config, @Nullable ClassLoader rootCLForLibraries) { myConfig = config; myRootClassLoader = rootCLForLibraries; } /** * fixme this logic intersects with the classloading logic of the idea platform. * however, e.g. in test mode idea urges us to put all the classes into the boot classpath, * since the PluginClassLoaders are not created in the test mode. */ private Set<LibDescriptor> getPluginLibDescriptors() { Set<LibDescriptor> paths = new LinkedHashSet<LibDescriptor>(); for (PluginDescriptor descriptor : myConfig.getPlugins()) { String pluginFolder = descriptor.getPath(); for (String pluginsPath : Arrays.asList(PathManager.getPluginsPath(), PathManager.getPreInstalledPluginsPath())) { File pluginDirectory = new File(pluginsPath, pluginFolder); File libFolder = new File(pluginDirectory, "lib"); UrlClassLoader pluginCL = null; if (libFolder.exists() && libFolder.isDirectory()) { pluginCL = createPluginClassLoader(libFolder); for (File jar : libFolder.listFiles(jetbrains.mps.util.PathManager.JAR_FILE_FILTER)) { paths.add(new LibDescriptor(IoFileSystem.INSTANCE.getFile(jar.getAbsolutePath() + MODULES_PREFIX), pluginCL)); } } File languagesFolder = new File(pluginDirectory, "languages"); if (languagesFolder.exists() && languagesFolder.isDirectory()) { paths.add(new LibDescriptor(IoFileSystem.INSTANCE.getFile(languagesFolder.getAbsolutePath()), pluginCL)); } File classesFolder = new File(pluginDirectory, "classes"); if (classesFolder.exists() && classesFolder.isDirectory()) { paths.add(new LibDescriptor(IoFileSystem.INSTANCE.getFile(classesFolder.getAbsolutePath()), pluginCL)); } } } return Collections.unmodifiableSet(paths); } private static UrlClassLoader createPluginClassLoader(File lib) { List<URL> urls = new ArrayList<URL>(); File[] files = lib.listFiles(jetbrains.mps.util.PathManager.JAR_FILE_FILTER); if (files == null) { return null; } for (File libjar : files) { try { urls.add(libjar.toURI().toURL()); } catch (MalformedURLException ignored) { } } return new UrlClassLoader(urls, LibraryInitializer.class.getClassLoader()); } public LibraryContributor createLibContributorForPlugins() { return SetLibraryContributor.fromSet("Plugin contributor", getPluginLibDescriptors()); } public LibraryContributor createLibContributorForLibs() { ClassLoader defaultCL = myRootClassLoader; Map<String, ClassLoader> libToCLMap = new LinkedHashMap<String, ClassLoader>(); for (String lib : myConfig.getLibs()) { libToCLMap.put(lib, defaultCL); } return SetLibraryContributor.fromMap("Library contributor", libToCLMap); } }