1 package org.simantics.db.common.request;
\r
3 import gnu.trove.map.hash.THashMap;
\r
5 import java.util.ArrayList;
\r
6 import java.util.Collections;
\r
7 import java.util.List;
\r
8 import java.util.Map;
\r
9 import java.util.Set;
\r
11 import org.simantics.db.ReadGraph;
\r
12 import org.simantics.db.Resource;
\r
13 import org.simantics.db.ResourceSet;
\r
14 import org.simantics.db.exception.DatabaseException;
\r
15 import org.simantics.db.service.CollectionSupport;
\r
17 public class ResourceSetGraph {
\r
19 final public CollectionSupport coll;
\r
20 final public List<ResourceSetGraph> references;
\r
21 final public Resource resource;
\r
22 final public Map<ResourceSet,Set<Resource>> cache = new THashMap<ResourceSet,Set<Resource>>();
\r
24 public ResourceSetGraph(ReadGraph graph, Resource result) {
\r
25 this.resource = result;
\r
26 this.references = new ArrayList<ResourceSetGraph>();
\r
27 this.coll = graph.getService(CollectionSupport.class);
\r
30 private Set<Resource> probe(ReadGraph graph, ResourceSet types) {
\r
31 return cache.get(types);
\r
34 private Set<Resource> resolve(ReadGraph graph, ResourceSet types, Set<Resource> visited) throws DatabaseException {
\r
37 if(!visited.add(this.resource)) return Collections.emptySet();
\r
39 Set<Resource> cached = cache.get(types);
\r
40 if(cached != null) return cached;
\r
42 boolean includeThis = !types.disjoint(graph.getTypes(this.resource));
\r
44 Set<Resource> allRefs = null;
\r
45 for(ResourceSetGraph ref : references) {
\r
46 Set<Resource> refs = ref.probe(graph, types);
\r
48 if(visited == null) {
\r
49 visited = coll.createSet();
\r
50 visited.add(this.resource);
\r
52 refs = ref.resolve(graph, types, visited);
\r
54 if(!refs.isEmpty()) {
\r
55 if(allRefs == null) allRefs = coll.createSet(refs.size());
\r
56 allRefs.addAll(refs);
\r
60 Set<Resource> result = Collections.emptySet();
\r
61 if(allRefs != null) {
\r
62 if(allRefs.size() == 1) {
\r
64 allRefs.add(resource);
\r
65 if(allRefs.size() == 1) result = Collections.singleton(allRefs.iterator().next());
\r
66 else result = allRefs;
\r
68 result = Collections.singleton(allRefs.iterator().next());
\r
71 if(includeThis) allRefs.add(resource);
\r
75 if(includeThis) result = Collections.singleton(resource);
\r
78 cache.put(types, result);
\r
84 public Set<Resource> resolve(ReadGraph graph, ResourceSet types) throws DatabaseException {
\r
85 Set<Resource> result = resolve(graph, types, null);
\r
86 if(result == null) result = Collections.emptySet();
\r