]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ConsistsOfProcess.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / ConsistsOfProcess.java
1 package org.simantics.db.layer0.util;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashSet;
6 import java.util.List;
7 import java.util.Set;
8
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;
23
24 class ConsistsOfProcess {
25
26         final List<ConsistsOfProcessEntry> result;
27         final Set<Resource> childrenWithNoName;
28         final SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource> structure;
29         final SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource> names;
30
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);
33         }
34
35         public static Pair<List<ConsistsOfProcessEntry>,Set<Resource>> walk(ReadGraph graph, ResourceMap<ExtentStatus> status, Collection<SeedSpec> specs, boolean ignoreVirtual) throws DatabaseException {
36                 
37         ConsistsOfProcess process = new ConsistsOfProcess(graph, status, specs, ignoreVirtual);
38         return Pair.make(process.result, process.childrenWithNoName);
39         
40     }
41     
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) {
48                 this.parent = parent;
49                 this.resource = resource;
50         }
51     }
52         
53     private ConsistsOfProcess(ReadGraph graph, ResourceMap<ExtentStatus> status, final Collection<SeedSpec> seeds, final boolean ignoreVirtual) throws DatabaseException {
54
55                 final Layer0 L0 = Layer0.getInstance(graph);
56                 final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
57                 
58                 result = new ArrayList<>();
59                 childrenWithNoName = new HashSet<>();
60                 names = dqs.compileForEachObject(graph, L0.HasName, new SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource>() {
61
62                         @Override
63                         public void execute(ReadGraph graph, ConsistsOfProcessEntry entry, Resource nameResource) throws DatabaseException {
64                 
65                                 if(status != null)
66                                         status.put(nameResource, ExtentStatus.EXCLUDED);
67                                 
68                             if(!entry.valid) return;
69
70                                 String name = graph.getValue(nameResource, Bindings.STRING);
71                                 if(name == null) {
72                                         entry.valid = false;
73                                 } else if (entry.name != null) {
74                                         entry.valid = false;
75                                 } else {
76                                         entry.name = name;
77                                 }
78
79                                 
80                         }
81
82                         @Override
83                         public void exception(ReadGraph graph, Throwable throwable) {
84                                 Logger.defaultLogError(throwable);
85                         }
86
87                         @Override
88                         public void finished(ReadGraph graph, ConsistsOfProcessEntry entry) {
89                             if(entry.valid) {
90                                 if(entry.name != null) {
91                                     result.add(entry);
92                                 } else {
93                                     // This one did not have a name - not a valid internal
94                                     childrenWithNoName.add(entry.resource);
95                                 }
96                             } else {
97                                 // Something wrong has happened. Do not treat as valid internal
98                                 childrenWithNoName.add(entry.resource);
99                             }
100                         }
101                 });
102                 
103                 structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new SyncContextMultiProcedure<ConsistsOfProcessEntry, Resource>() {
104
105                         @Override
106                         public void execute(ReadGraph graph, ConsistsOfProcessEntry parent, Resource child) {
107
108                                 if(status != null)
109                                         if(ExtentStatus.EXCLUDED.equals(status.get(child))) return;
110                                 
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);
115                                 }
116                                 
117                         }
118
119                         @Override
120                         public void finished(ReadGraph graph, ConsistsOfProcessEntry parent) {
121                         }
122
123                         @Override
124                         public void exception(ReadGraph graph, Throwable throwable) {
125                                 Logger.defaultLogError(throwable);
126                         }
127
128                 });
129                 
130                 graph.syncRequest(new ReadRequest() {
131
132                         @Override
133                         public void run(ReadGraph graph) throws DatabaseException {
134                                 for(SeedSpec seed  : seeds) {
135                                         
136                                         if(status != null) {
137                                                 ExtentStatus es = status.get(seed.resource);
138                                                 if(ExtentStatus.EXCLUDED.equals(es)) continue;
139                                                 if(ExtentStatus.EXTERNAL.equals(es)) continue;
140                                         }
141                                         
142                                         ConsistsOfProcessEntry entry = new ConsistsOfProcessEntry(null, seed.resource);
143                                         
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);
148                                         }
149                                 }
150                         }
151                         
152                 });
153                 
154         }
155         
156     
157 }