package jetbrains.mps.build.util; /*Generated by MPS */ import org.jetbrains.mps.openapi.model.SNode; import java.util.Map; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import jetbrains.mps.internal.collections.runtime.ListSequence; import org.jetbrains.annotations.NotNull; import jetbrains.mps.baseLanguage.tuples.runtime.Tuples; import jetbrains.mps.generator.TransientModelsModule; import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes; import java.util.concurrent.ConcurrentMap; import jetbrains.mps.smodel.ModelAccess; public class VisibleArtifacts { protected final SNode project; protected final Map<SNode, SNode> parentMap = new HashMap<SNode, SNode>(); private final List<SNode> visibleArtifacts = new ArrayList<SNode>(); private final List<SNode> visibleLayouts = new ArrayList<SNode>(); private ArtifactLookup myLookup; public VisibleArtifacts(SNode project) { this.project = project; } public void collect(boolean localProjectOnly) { if (!(localProjectOnly)) { for (SNode layoutDependency : SNodeOperations.ofConcept(SLinkOperations.getChildren(project, MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4df58c6f18f84a13L, 0x4df58c6f18f84a25L, "dependencies")), MetaAdapterFactory.getConcept(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x63a87b9320d3d0a4L, "jetbrains.mps.build.structure.BuildExternalLayoutDependency"))) { SNode target = SLinkOperations.getTarget(layoutDependency, MetaAdapterFactory.getReferenceLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x63a87b9320d3d0a4L, 0x63a87b9320d3d0a7L, "layout")); collectInExternalLayout(layoutDependency, target); } for (SNode projectDependency : SNodeOperations.ofConcept(SLinkOperations.getChildren(project, MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4df58c6f18f84a13L, 0x4df58c6f18f84a25L, "dependencies")), MetaAdapterFactory.getConcept(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x454b730dd908c220L, "jetbrains.mps.build.structure.BuildProjectDependency"))) { SNode target = SLinkOperations.getTarget(projectDependency, MetaAdapterFactory.getReferenceLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x454b730dd908c220L, 0x4df58c6f18f84a24L, "script")); collectInProject(projectDependency, target); } } collectProjectArtifacts(); } private void collectProjectArtifacts() { collectInProject(SLinkOperations.getTarget(project, MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4df58c6f18f84a13L, 0x4df58c6f18f84a1cL, "layout")), project); } private void collectInProject(SNode parent, SNode target) { if (target == null) { return; } ListSequence.fromList(visibleLayouts).addElement(SLinkOperations.getTarget(target, MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4df58c6f18f84a13L, 0x4df58c6f18f84a1cL, "layout"))); if (SLinkOperations.getTarget(target, MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4df58c6f18f84a13L, 0x4df58c6f18f84a1cL, "layout")) != parent) { parentMap.put(SLinkOperations.getTarget(target, MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4df58c6f18f84a13L, 0x4df58c6f18f84a1cL, "layout")), parent); } for (SNode node : SLinkOperations.getChildren(SLinkOperations.getTarget(target, MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4df58c6f18f84a13L, 0x4df58c6f18f84a1cL, "layout")), MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4140393b234482c3L, 0x668c6cfbafac4c8eL, "children"))) { collectInLayout(parent, node); } } private void collectInExternalLayout(SNode parent, SNode target) { ListSequence.fromList(visibleLayouts).addElement(target); parentMap.put(target, parent); for (SNode node : SLinkOperations.getChildren(target, MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4140393b234482c3L, 0x668c6cfbafac4c8eL, "children"))) { collectInLayout(parent, node); } } protected void collectInLayout(SNode parent, SNode node) { if (node == null) { return; } if (parentMap.containsKey(node)) { return; } ListSequence.fromList(visibleArtifacts).addElement(node); parentMap.put(node, parent); if (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x668c6cfbafabcf0cL, "jetbrains.mps.build.structure.BuildLayout_AbstractContainer"))) { for (SNode child : SLinkOperations.getChildren(SNodeOperations.as(node, MetaAdapterFactory.getConcept(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x668c6cfbafabcf0cL, "jetbrains.mps.build.structure.BuildLayout_AbstractContainer")), MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4140393b234482c3L, 0x668c6cfbafac4c8eL, "children"))) { collectInLayout(node, child); } } else if (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4ddcec86af9fdb53L, "jetbrains.mps.build.structure.BuildLayout_ImportContent"))) { for (SNode child : ListSequence.fromList(SLinkOperations.getChildren(SLinkOperations.getTarget(SNodeOperations.as(node, MetaAdapterFactory.getConcept(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4ddcec86af9fdb53L, "jetbrains.mps.build.structure.BuildLayout_ImportContent")), MetaAdapterFactory.getReferenceLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4ddcec86af9fdb53L, 0x4ddcec86af9fdb55L, "target")), MetaAdapterFactory.getContainmentLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0x4140393b234482c3L, 0x668c6cfbafac4c8eL, "children")))) { collectInLayout(parent, child); } } else if (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0xbabdfbeee1350f2L, "jetbrains.mps.build.structure.BuildLayout_Import"))) { collectInLayout(parent, SLinkOperations.getTarget(SNodeOperations.as(node, MetaAdapterFactory.getConcept(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0xbabdfbeee1350f2L, "jetbrains.mps.build.structure.BuildLayout_Import")), MetaAdapterFactory.getReferenceLink(0x798100da4f0a421aL, 0xb99171f8c50ce5d2L, 0xbabdfbeee1350f2L, 0xbabdfbeee1350f4L, "target"))); } } public SNode getProject() { return project; } public Iterable<SNode> getArtifacts() { return ListSequence.fromList(visibleArtifacts).asUnmodifiable(); } public Iterable<SNode> getLayouts() { return ListSequence.fromList(visibleLayouts).asUnmodifiable(); } public boolean contains(SNode node) { return parentMap.containsKey(node); } public SNode parent(SNode node) { SNode result = parentMap.get(node); if (result == node) { throw new IllegalStateException(); } return result; } protected ArtifactLookup createLookup() { return new ArtifactLookup(this); } /** * Logic to look artifacts up kept separate to facilitate caching during generation. * Clients that are capable of caching (has access to DependenciesHelper) shall override {@link jetbrains.mps.build.util.VisibleArtifacts#createLookup() } */ public ArtifactLookup getLookup() { if (myLookup == null) { myLookup = createLookup(); } return myLookup; } /** * FIXME check why BL_PathElement is return value, why not BL_Node */ public SNode findArtifact(Object id) { return getLookup().findArtifact(id); } @NotNull public Tuples._2<SNode, String> getResource(SNode path) { return getLookup().getResource(path); } public static VisibleArtifacts createFor(final SNode project) { assert !(SNodeOperations.getModel(project).getModule() instanceof TransientModelsModule); return getFromCache(VisibleArtifacts.class, project, new _FunctionTypes._return_P0_E0<VisibleArtifacts>() { public VisibleArtifacts invoke() { VisibleArtifacts artifacts = new VisibleArtifacts(project); artifacts.collect(false); return artifacts; } }); } private static <K, V> V getFromCache(Class clazz, K key, _FunctionTypes._return_P0_E0<? extends V> creator) { ConcurrentMap<K, V> cache = ModelAccess.instance().getRepositoryStateCache(clazz.getName()); V v = cache.get(key); if (v != null) { return v; } cache.putIfAbsent(key, creator.invoke()); return cache.get(key); } }