package jetbrains.mps.vcs.platform.mergedriver;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import java.util.Arrays;
import com.intellij.openapi.application.PathManager;
import java.io.File;
import com.intellij.openapi.project.Project;
import jetbrains.mps.ide.ThreadUtils;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.progress.ProgressIndicator;
import org.jetbrains.mps.openapi.util.ProgressMonitor;
import jetbrains.mps.progress.ProgressMonitorAdapter;
import jetbrains.mps.util.FileUtil;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import java.util.Map;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.LinkedHashMap;
import java.util.Queue;
import jetbrains.mps.internal.collections.runtime.QueueSequence;
import java.util.LinkedList;
import org.apache.log4j.Level;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.extensions.PluginId;
import jetbrains.mps.internal.collections.runtime.ISelector;
import java.util.Set;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.LinkedHashSet;
public abstract class MergeDriverPacker {
private static final Logger LOG = LogManager.getLogger(MergeDriverPacker.class);
private static MergeDriverPacker ourInstance;
private static final Iterable<String> mpsLibJars = Arrays.asList("mps-closures.jar", "mps-collections.jar", "mps-tuples.jar", "mps-core.jar", "mps-openapi.jar", "mps-behavior-api.jar", "mps-behavior-runtime.jar", "mps-logging.jar", "mps-annotations.jar", "mps-boot-util.jar");
protected static Iterable<String> mpsAddJars = Arrays.asList("diffutils-1.2.1.jar");
private static final Iterable<String> ideaLibJars = Arrays.asList("asm-all.jar", "xstream-1.4.8.jar", "guava-17.0.jar", "jdom.jar", "log4j.jar", "trove4j.jar", "annotations.jar");
private static final Iterable<String> svnJars = Arrays.asList("svnkit.jar", "sequence-library.jar");
private static final String MERGEDRIVER_PATH = "mergedriver";
private static final String MERGER_RT = "merger-rt.jar";
private Boolean myFromSources = null;
public MergeDriverPacker() {
}
public String getPath() {
return PathManager.getConfigPath() + File.separator + MERGEDRIVER_PATH;
}
private File getFile() {
return new File(getPath());
}
public void pack(final Project project) {
ThreadUtils.runInUIThreadAndWait(new Runnable() {
public void run() {
ProgressManager.getInstance().run(new Task.Modal(project, "Installing", false) {
public void run(@NotNull ProgressIndicator indicator) {
ProgressMonitor monitor = new ProgressMonitorAdapter(indicator);
monitor.start("Installing vcs add-ons", 4);
monitor.step("Deleting old files");
File tmpDir = FileUtil.createTmpDir();
FileUtil.delete(getFile());
Iterable<String> classpathDirs = getClasspath(false);
Iterable<String> classPathJars = Sequence.fromIterable(classpathDirs).where(new IWhereFilter<String>() {
public boolean accept(String cpd) {
return cpd.endsWith(".jar");
}
});
monitor.step("Packing new merge driver");
internalPack(classPathJars, tmpDir, false);
if (isFromSources()) {
packMergerRT(Sequence.fromIterable(classpathDirs).where(new IWhereFilter<String>() {
public boolean accept(String cpd) {
return !(cpd.endsWith(".jar"));
}
}), new File(tmpDir, MERGER_RT));
}
monitor.step("Installing merge driver");
FileUtil.copyDir(tmpDir, getFile());
monitor.step("Deleting temporary files");
FileUtil.delete(tmpDir);
}
});
}
});
}
private void packMergerRT(Iterable<String> classpathDirs, File to) {
Map<String, File> files = MapSequence.fromMap(new LinkedHashMap<String, File>(16, (float) 0.75, false));
for (String basePath : classpathDirs) {
File baseDir = new File(basePath);
Queue<String> pathQueue = QueueSequence.fromQueueAndArray(new LinkedList<String>(), baseDir.list());
while (QueueSequence.fromQueue(pathQueue).isNotEmpty()) {
String path = QueueSequence.fromQueue(pathQueue).removeFirstElement();
File f = new File(baseDir, path);
if (f.isDirectory()) {
for (String child : f.list()) {
QueueSequence.fromQueue(pathQueue).addLastElement(path + "/" + child);
}
} else if (path.endsWith(".class")) {
MapSequence.fromMap(files).put(path, f);
}
}
}
if (MapSequence.fromMap(files).isNotEmpty()) {
FileUtil.zip(files, to);
}
}
private void internalPack(Iterable<String> classpathDirs, File tmpDir, boolean isForZip) {
for (String classpathDir : classpathDirs) {
File file = new File(classpathDir);
if (file.exists()) {
if (file.isDirectory()) {
FileUtil.copyDir(file, tmpDir);
} else {
FileUtil.copyFile(file, tmpDir);
}
} else {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error("couldn't find class path: " + classpathDir);
}
}
}
// Workaround for rare case when MPS build is invoked with internal flag (MPS-13819)
if (isForZip && Sequence.fromIterable(classpathDirs).isEmpty()) {
FileUtil.write(new File(tmpDir, "dummy.txt"), new byte[0]);
}
}
private Iterable<String> getSvnJars() {
final IdeaPluginDescriptor svnPlugin = PluginManager.getPlugin(PluginId.getId("Subversion"));
if (svnPlugin != null) {
return Sequence.fromIterable(svnJars).select(new ISelector<String, String>() {
public String select(String it) {
return svnPlugin.getPath() + File.separator + "lib" + File.separator + it;
}
});
}
return null;
}
protected String getVCSCorePluginPath() {
IdeaPluginDescriptor vcsCorePlugin = PluginManager.getPlugin(PluginId.getId("jetbrains.mps.vcs"));
assert vcsCorePlugin != null;
return vcsCorePlugin.getPath().getPath();
}
protected abstract String getMPSCorePath();
protected abstract Set<String> getClasspathInternal();
protected abstract String getVCSCoreFileName();
public Set<String> getClasspath(boolean withSvnkit) {
Set<String> classpathItems = SetSequence.fromSet(new LinkedHashSet<String>());
if (isFromSources()) {
SetSequence.fromSet(classpathItems).addSequence(SetSequence.fromSet(getClasspathInternal()));
} else {
final String mpsCorePath = getMPSCorePath();
SetSequence.fromSet(classpathItems).addSequence(Sequence.fromIterable(mpsLibJars).select(new ISelector<String, String>() {
public String select(String it) {
return mpsCorePath + File.separator + it;
}
}));
SetSequence.fromSet(classpathItems).addSequence(Sequence.fromIterable(mpsAddJars).select(new ISelector<String, String>() {
public String select(String it) {
return mpsCorePath + File.separator + it;
}
}));
SetSequence.fromSet(classpathItems).addElement(getVCSCorePluginPath() + File.separator + "lib" + File.separator + getVCSCoreFileName());
}
SetSequence.fromSet(classpathItems).addSequence(Sequence.fromIterable(ideaLibJars).select(new ISelector<String, String>() {
public String select(String it) {
return PathManager.getLibPath() + File.separator + it;
}
}));
SetSequence.fromSet(classpathItems).addSequence(Sequence.fromIterable(getSvnJars()));
return classpathItems;
}
private boolean isFromSources() {
if (myFromSources == null) {
myFromSources = !(new File(getMPSCorePath() + File.separator + Sequence.fromIterable(mpsLibJars).first()).exists());
}
return myFromSources;
}
public static MergeDriverPacker getInstance() {
return ourInstance;
}
protected static void setInstance(MergeDriverPacker instance) {
ourInstance = instance;
}
}