1 package org.simantics.db.layer0.util;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashSet;
9 import org.simantics.databoard.Bindings;
10 import org.simantics.db.ReadGraph;
11 import org.simantics.db.Resource;
12 import org.simantics.db.ResourceMap;
13 import org.simantics.db.common.request.ReadRequest;
14 import org.simantics.db.common.utils.Logger;
15 import org.simantics.db.exception.DatabaseException;
16 import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
17 import org.simantics.db.layer0.util.TransferableGraphConfiguration2.SeedSpec;
18 import org.simantics.db.layer0.util.TransferableGraphConfiguration2.SeedSpec.SeedSpecType;
19 import org.simantics.db.procedure.SyncContextMultiProcedure;
20 import org.simantics.db.service.DirectQuerySupport;
21 import org.simantics.layer0.Layer0;
22 import org.simantics.utils.datastructures.Pair;
24 class ConsistsOfProcess {
26 final List<ConsistsOfProcessEntry> result;
27 final Set<Resource> childrenWithNoName;
28 final SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource> structure;
29 final SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource> names;
31 public static Pair<List<ConsistsOfProcessEntry>,Set<Resource>> walk(ReadGraph graph, Collection<SeedSpec> specs, boolean ignoreVirtual) throws DatabaseException {
32 return walk(graph, null, specs, ignoreVirtual);
35 public static Pair<List<ConsistsOfProcessEntry>,Set<Resource>> walk(ReadGraph graph, ResourceMap<ExtentStatus> status, Collection<SeedSpec> specs, boolean ignoreVirtual) throws DatabaseException {
37 ConsistsOfProcess process = new ConsistsOfProcess(graph, status, specs, ignoreVirtual);
38 return Pair.make(process.result, process.childrenWithNoName);
42 static class ConsistsOfProcessEntry {
43 public ConsistsOfProcessEntry parent;
44 public Resource resource;
45 public boolean valid = true;
46 public String name = null;
47 ConsistsOfProcessEntry(ConsistsOfProcessEntry parent, Resource resource) {
49 this.resource = resource;
53 private ConsistsOfProcess(ReadGraph graph, ResourceMap<ExtentStatus> status, final Collection<SeedSpec> seeds, final boolean ignoreVirtual) throws DatabaseException {
55 final Layer0 L0 = Layer0.getInstance(graph);
56 final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
58 result = new ArrayList<>();
59 childrenWithNoName = new HashSet<>();
60 names = dqs.compileForEachObject(graph, L0.HasName, new SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource>() {
63 public void execute(ReadGraph graph, ConsistsOfProcessEntry entry, Resource nameResource) throws DatabaseException {
66 status.put(nameResource, ExtentStatus.EXCLUDED);
68 if(!entry.valid) return;
70 String name = graph.getValue(nameResource, Bindings.STRING);
73 } else if (entry.name != null) {
83 public void exception(ReadGraph graph, Throwable throwable) {
84 Logger.defaultLogError(throwable);
88 public void finished(ReadGraph graph, ConsistsOfProcessEntry entry) {
90 if(entry.name != null) {
93 // This one did not have a name - not a valid internal
94 childrenWithNoName.add(entry.resource);
97 // Something wrong has happened. Do not treat as valid internal
98 childrenWithNoName.add(entry.resource);
103 structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource>() {
106 public void execute(ReadGraph graph, ConsistsOfProcessEntry parent, Resource child) {
109 if(ExtentStatus.EXCLUDED.equals(status.get(child))) return;
111 if(!ignoreVirtual || child.isPersistent()) {
112 ConsistsOfProcessEntry entry = new ConsistsOfProcessEntry(parent, child);
113 dqs.forEachObjectCompiled(graph, child, entry, structure);
114 dqs.forEachObjectCompiled(graph, child, entry, names);
120 public void finished(ReadGraph graph, ConsistsOfProcessEntry parent) {
124 public void exception(ReadGraph graph, Throwable throwable) {
125 Logger.defaultLogError(throwable);
130 graph.syncRequest(new ReadRequest() {
133 public void run(ReadGraph graph) throws DatabaseException {
134 for(SeedSpec seed : seeds) {
137 ExtentStatus es = status.get(seed.resource);
138 if(ExtentStatus.EXCLUDED.equals(es)) continue;
139 if(ExtentStatus.EXTERNAL.equals(es)) continue;
142 ConsistsOfProcessEntry entry = new ConsistsOfProcessEntry(null, seed.resource);
144 dqs.forEachObjectCompiled(graph, seed.resource, entry, structure);
145 if(SeedSpecType.INTERNAL.equals(seed.specType)) {
146 // Process names only for internal seeds
147 dqs.forEachObjectCompiled(graph, seed.resource, entry, names);