package jetbrains.mps.vcs.changesmanager;
/*Generated by MPS */
import com.intellij.openapi.components.AbstractProjectComponent;
import java.util.Map;
import org.jetbrains.mps.openapi.model.SNodeReference;
import com.intellij.openapi.vcs.FileStatus;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.HashMap;
import jetbrains.mps.project.MPSProject;
import jetbrains.mps.nodefs.NodeVirtualFileSystem;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.vcs.FileStatusManager;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.util.ComputeRunnable;
import jetbrains.mps.util.Computable;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.model.EditableSModel;
import jetbrains.mps.extapi.persistence.FileDataSource;
import jetbrains.mps.vcs.platform.util.ConflictsUtil;
import java.util.List;
import jetbrains.mps.vcs.diff.changes.ModelChange;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.vcs.diff.changes.AddRootChange;
import com.intellij.openapi.vfs.VirtualFile;
import jetbrains.mps.ide.vfs.VirtualFileUtils;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.smodel.SNodePointer;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import java.util.ArrayList;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import jetbrains.mps.vcs.diff.ChangeSet;
public class NodeFileStatusMapping extends AbstractProjectComponent {
private final CurrentDifferenceRegistry myRegistry;
private final Map<SNodeReference, FileStatus> myFileStatusMap = MapSequence.fromMap(new HashMap<SNodeReference, FileStatus>());
private final CurrentDifferenceListener myGlobalListener = new NodeFileStatusMapping.MyGlobalListener();
protected final MPSProject myMPSProject;
protected final NodeVirtualFileSystem myNodeFileSystem;
public NodeFileStatusMapping(MPSProject project, CurrentDifferenceRegistry registry, NodeVirtualFileSystem nodeFileSystem) {
super(project.getProject());
myRegistry = registry;
myMPSProject = project;
myNodeFileSystem = nodeFileSystem;
}
@Override
public void projectOpened() {
myRegistry.addGlobalDifferenceListener(myGlobalListener);
}
@Override
public void projectClosed() {
myRegistry.removeGlobalDifferenceListener(myGlobalListener);
}
private void statusChanged(@NotNull final SNodeReference nodePointer) {
myMPSProject.getModelAccess().runReadAction(new Runnable() {
public void run() {
FileStatusManager fsm = FileStatusManager.getInstance(myProject);
SNode currentNode = nodePointer.resolve(myMPSProject.getRepository());
if (currentNode == null) {
return;
}
statusChanged(fsm, currentNode);
}
});
}
protected void statusChanged(FileStatusManager fsm, @NotNull SNode node) {
fsm.fileStatusChanged(myNodeFileSystem.getFileFor(myMPSProject.getRepository(), node));
}
private void updateNodeStatus(@NotNull final SNodeReference nodePointer) {
myRegistry.getCommandQueue().runTask(new Runnable() {
public void run() {
if (calcStatus(nodePointer)) {
statusChanged(nodePointer);
}
}
});
}
private boolean calcStatus(@NotNull final SNodeReference root) {
ComputeRunnable<FileStatus> cr = new ComputeRunnable<FileStatus>(new Computable<FileStatus>() {
public FileStatus compute() {
SModel m = root.getModelReference().resolve(myMPSProject.getRepository());
if (m instanceof EditableSModel && m.getSource() instanceof FileDataSource && !(m.isReadOnly())) {
EditableSModel model = (EditableSModel) m;
if (ConflictsUtil.isModelOrModuleConflicting(model, myProject)) {
return FileStatus.MERGED_WITH_CONFLICTS;
}
CurrentDifference diff = myRegistry.getCurrentDifference(model);
List<ModelChange> modelChanges = check_onkh7z_a0d0b0a0a0a0o(diff.getChangeSet());
List<ModelChange> rootChanges = ListSequence.fromList(modelChanges).where(new IWhereFilter<ModelChange>() {
public boolean accept(ModelChange ch) {
return root.getNodeId().equals(ch.getRootId());
}
}).toListSequence();
if (ListSequence.fromList(rootChanges).count() != 0) {
if (ListSequence.fromList(rootChanges).first() instanceof AddRootChange) {
VirtualFile vf = VirtualFileUtils.getVirtualFile(((FileDataSource) m.getSource()).getFile());
if (vf != null) {
FileStatus modelStatus = FileStatusManager.getInstance(myProject).getStatus(vf);
if (BaseVersionUtil.isAddedFileStatus(modelStatus)) {
return modelStatus;
}
}
return FileStatus.ADDED;
}
return FileStatus.MODIFIED;
}
}
return FileStatus.NOT_CHANGED;
}
});
myMPSProject.getModelAccess().runReadAction(cr);
FileStatus status = cr.getResult();
synchronized (myFileStatusMap) {
if (MapSequence.fromMap(myFileStatusMap).get(root) != status) {
MapSequence.fromMap(myFileStatusMap).put(root, status);
return true;
} else {
return false;
}
}
}
@Nullable
public FileStatus getStatus(@NotNull final SNode root) {
final SNodeReference nodePointer = new SNodePointer(root);
myRegistry.getCommandQueue().runTask(new Runnable() {
public void run() {
myMPSProject.getModelAccess().runReadAction(new Runnable() {
public void run() {
SModel md = null;
SNode node = nodePointer.resolve(myMPSProject.getRepository());
if (node != null) {
md = SNodeOperations.getModel(root);
}
if (md instanceof EditableSModel && !(md.isReadOnly())) {
myRegistry.getCurrentDifference((EditableSModel) md).setEnabled(true);
}
}
});
}
});
synchronized (myFileStatusMap) {
return MapSequence.fromMap(myFileStatusMap).get(nodePointer);
}
}
@Nullable
public FileStatus getStatus(@NotNull SNodeReference nodePointer) {
synchronized (myFileStatusMap) {
return MapSequence.fromMap(myFileStatusMap).get(nodePointer);
}
}
private class MyGlobalListener extends CurrentDifferenceAdapter {
private List<SNodeReference> myAffectedRoots = ListSequence.fromList(new ArrayList<SNodeReference>());
private MyGlobalListener() {
}
@Override
public void changeUpdateFinished() {
ListSequence.fromList(myAffectedRoots).visitAll(new IVisitor<SNodeReference>() {
public void visit(SNodeReference np) {
updateNodeStatus(np);
}
});
ListSequence.fromList(myAffectedRoots).clear();
}
private void addAffectedRoot(@NotNull ModelChange change) {
if (change.getRootId() != null) {
ListSequence.fromList(myAffectedRoots).addElement(new SNodePointer(change.getChangeSet().getNewModel().getReference(), change.getRootId()));
}
}
@Override
public void changeAdded(@NotNull ModelChange change) {
addAffectedRoot(change);
}
@Override
public void changeRemoved(@NotNull ModelChange change) {
addAffectedRoot(change);
}
}
private static List<ModelChange> check_onkh7z_a0d0b0a0a0a0o(ChangeSet checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getModelChanges();
}
return null;
}
}