]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceSetGraph.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / request / ResourceSetGraph.java
1 package org.simantics.db.common.request;
2
3 import gnu.trove.map.hash.THashMap;
4
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Set;
10
11 import org.simantics.db.ReadGraph;
12 import org.simantics.db.Resource;
13 import org.simantics.db.ResourceSet;
14 import org.simantics.db.exception.DatabaseException;
15 import org.simantics.db.service.CollectionSupport;
16
17 public class ResourceSetGraph {
18         
19         final public CollectionSupport coll; 
20         final public List<ResourceSetGraph> references;
21         final public Resource resource;
22         final public Map<ResourceSet,Set<Resource>> cache = new THashMap<ResourceSet,Set<Resource>>();
23         
24         public ResourceSetGraph(ReadGraph graph, Resource result) {
25                 this.resource = result;
26                 this.references = new ArrayList<ResourceSetGraph>();
27                 this.coll = graph.getService(CollectionSupport.class);
28         }
29
30         private Set<Resource> probe(ReadGraph graph, ResourceSet types) {
31             return cache.get(types);
32         }
33         
34         private Set<Resource> resolve(ReadGraph graph, ResourceSet types, Set<Resource> visited) throws DatabaseException {
35
36             if(visited != null)
37                 if(!visited.add(this.resource)) return Collections.emptySet();
38
39             Set<Resource> cached = cache.get(types);
40             if(cached != null) return cached;
41             
42                 boolean includeThis = !types.disjoint(graph.getTypes(this.resource));
43                 
44                 Set<Resource> allRefs = null;
45                 for(ResourceSetGraph ref : references) {
46                     Set<Resource> refs = ref.probe(graph, types);
47                     if(refs == null) {
48                         if(visited == null) {
49                             visited = coll.createSet();
50                             visited.add(this.resource);
51                         }
52                         refs = ref.resolve(graph, types, visited);
53                     }
54                     if(!refs.isEmpty()) {
55                         if(allRefs == null) allRefs = coll.createSet(refs.size());
56                         allRefs.addAll(refs);
57                     }
58                 }
59                 
60                 Set<Resource> result = Collections.emptySet();
61                 if(allRefs != null) {
62                     if(allRefs.size() == 1) {
63                         if(includeThis) {
64                             allRefs.add(resource);
65                             if(allRefs.size() == 1) result =  Collections.singleton(allRefs.iterator().next());
66                             else result = allRefs;
67                         } else {
68                            result = Collections.singleton(allRefs.iterator().next());
69                         }
70                     } else {
71                 if(includeThis) allRefs.add(resource);
72                 result = allRefs;
73                     }
74                 } else {
75                     if(includeThis) result = Collections.singleton(resource);
76                 }
77                 
78                 cache.put(types, result);
79                 
80                 return result;
81                 
82         }
83         
84         public Set<Resource> resolve(ReadGraph graph, ResourceSet types) throws DatabaseException {
85                 Set<Resource> result = resolve(graph, types, null);
86                 if(result == null) result = Collections.emptySet();
87                 return result;
88         }
89         
90 }