package jetbrains.mps.ide.platform.dependencyViewer;
/*Generated by MPS */
import java.util.Collection;
import org.jetbrains.mps.openapi.module.SModuleReference;
import org.jetbrains.mps.openapi.model.SModelReference;
import org.jetbrains.mps.openapi.model.SNodeReference;
import org.jetbrains.mps.openapi.module.SRepository;
import jetbrains.mps.internal.collections.runtime.CollectionSequence;
import java.util.LinkedHashSet;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.module.SModule;
import jetbrains.mps.internal.collections.runtime.ISelector;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.internal.collections.runtime.ITranslator2;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
public class DependencyViewerScope {
private final Collection<SModuleReference> myModules;
private final Collection<SModelReference> myModels;
private final Collection<SNodeReference> myRoots;
private final SRepository myRepo;
public DependencyViewerScope(SRepository contextRepo) {
// This class assumes clients are responsible to obtain proper model read access
// (they pass/obtain model/node/module, so that they need access anyway).
// Scope doesn't keep model/node instances to to hog/retain too much, and resolve them as needed
// with the repository supplied
myModules = CollectionSequence.fromCollection(new LinkedHashSet<SModuleReference>());
myModels = CollectionSequence.fromCollection(new LinkedHashSet<SModelReference>());
myRoots = CollectionSequence.fromCollection(new LinkedHashSet<SNodeReference>());
myRepo = contextRepo;
}
public boolean contains(SNode node) {
if (node == null) {
return false;
}
SNode root = node.getContainingRoot();
if (CollectionSequence.fromCollection(myRoots).contains(root.getReference()) || CollectionSequence.fromCollection(myRoots).contains(node.getReference())) {
return true;
}
return contains(root.getModel());
}
public boolean contains(SModel model) {
if (model == null) {
return false;
}
if (CollectionSequence.fromCollection(myModels).contains(model.getReference())) {
return true;
}
return model.getModule() != null && CollectionSequence.fromCollection(myModules).contains(model.getModule().getModuleReference());
}
public void add(SModuleReference moduleRef) {
if (moduleRef == null) {
return;
}
CollectionSequence.fromCollection(myModules).addElement(moduleRef);
}
public void add(@Nullable SModule module) {
if (module == null) {
return;
}
CollectionSequence.fromCollection(myModules).addElement(module.getModuleReference());
}
public void add(SModelReference modelRef) {
if (modelRef == null) {
return;
}
CollectionSequence.fromCollection(myModels).addElement(modelRef);
}
public void add(@Nullable SModel model) {
if (model == null) {
return;
}
CollectionSequence.fromCollection(myModels).addElement(model.getReference());
}
public void add(SNodeReference nodeRef) {
if (nodeRef == null) {
return;
}
// indeed, nodeRef is not necessarily points to root node,
// we shall account for this once we resolve back to nodes.
CollectionSequence.fromCollection(myRoots).addElement(nodeRef);
}
public void add(@Nullable SNode root) {
if (root == null) {
return;
}
CollectionSequence.fromCollection(myRoots).addElement(root.getContainingRoot().getReference());
}
public Collection<SModel> getModels() {
return CollectionSequence.fromCollection(myModels).select(new ISelector<SModelReference, SModel>() {
public SModel select(SModelReference it) {
return it.resolve(myRepo);
}
}).where(new IWhereFilter<SModel>() {
public boolean accept(SModel it) {
return it != null;
}
}).toListSequence();
}
public Collection<SModule> getModules() {
return CollectionSequence.fromCollection(myModules).select(new ISelector<SModuleReference, SModule>() {
public SModule select(SModuleReference it) {
return it.resolve(myRepo);
}
}).where(new IWhereFilter<SModule>() {
public boolean accept(SModule it) {
return it != null;
}
}).toListSequence();
}
public Collection<SNode> getRoots() {
return CollectionSequence.fromCollection(myRoots).select(new ISelector<SNodeReference, SNode>() {
public SNode select(SNodeReference it) {
return it.resolve(myRepo);
}
}).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return it != null;
}
}).select(new ISelector<SNode, SNode>() {
public SNode select(SNode it) {
return it.getContainingRoot();
}
}).toListSequence();
}
public boolean isEmpty() {
return CollectionSequence.fromCollection(myModels).isEmpty() && CollectionSequence.fromCollection(myModules).isEmpty() && CollectionSequence.fromCollection(myRoots).isEmpty();
}
public String getPresentation() {
StringBuilder sb = new StringBuilder();
if (CollectionSequence.fromCollection(myModules).isNotEmpty()) {
sb.append(getPresentation(myModules, "module"));
}
if (CollectionSequence.fromCollection(myModels).isNotEmpty()) {
if (sb.length() > 0) {
sb.append(" and ");
}
if (CollectionSequence.fromCollection(myModels).count() == 1) {
sb.append("model " + CollectionSequence.fromCollection(myModels).first().getName().getValue());
} else {
sb.append(CollectionSequence.fromCollection(myModels).count() + " models");
}
}
if (CollectionSequence.fromCollection(myRoots).isNotEmpty()) {
if (sb.length() > 0) {
sb.append(" and ");
}
sb.append(getPresentation(myRoots, "node"));
}
return sb.toString();
}
private <T> String getPresentation(Collection<T> list, String elementType) {
if (CollectionSequence.fromCollection(list).isEmpty()) {
return "";
}
if (CollectionSequence.fromCollection(list).count() == 1) {
return elementType + " " + CollectionSequence.fromCollection(list).first();
}
return CollectionSequence.fromCollection(list).count() + " " + elementType + "s";
}
public Iterable<SNode> getNodes() {
Iterable<SModel> models = CollectionSequence.fromCollection(getModules()).translate(new ITranslator2<SModule, SModel>() {
public Iterable<SModel> translate(SModule it) {
return it.getModels();
}
}).concat(CollectionSequence.fromCollection(getModels()));
Iterable<SNode> roots = Sequence.fromIterable(models).translate(new ITranslator2<SModel, SNode>() {
public Iterable<SNode> translate(SModel it) {
return it.getRootNodes();
}
}).concat(CollectionSequence.fromCollection(getRoots()));
return Sequence.fromIterable(roots).translate(new ITranslator2<SNode, SNode>() {
public Iterable<SNode> translate(SNode it) {
return SNodeOperations.getNodeDescendants(((SNode) it), null, true, new SAbstractConcept[]{});
}
});
}
}