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);
}
}