package org.simantics.db.common.request; import gnu.trove.map.hash.THashMap; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.ResourceSet; import org.simantics.db.exception.DatabaseException; import org.simantics.db.service.CollectionSupport; public class ResourceSetGraph { final public CollectionSupport coll; final public List references; final public Resource resource; final public Map> cache = new THashMap>(); public ResourceSetGraph(ReadGraph graph, Resource result) { this.resource = result; this.references = new ArrayList(); this.coll = graph.getService(CollectionSupport.class); } private Set probe(ReadGraph graph, ResourceSet types) { return cache.get(types); } private Set resolve(ReadGraph graph, ResourceSet types, Set visited) throws DatabaseException { if(visited != null) if(!visited.add(this.resource)) return Collections.emptySet(); Set cached = cache.get(types); if(cached != null) return cached; boolean includeThis = !types.disjoint(graph.getTypes(this.resource)); Set allRefs = null; for(ResourceSetGraph ref : references) { Set refs = ref.probe(graph, types); if(refs == null) { if(visited == null) { visited = coll.createSet(); visited.add(this.resource); } refs = ref.resolve(graph, types, visited); } if(!refs.isEmpty()) { if(allRefs == null) allRefs = coll.createSet(refs.size()); allRefs.addAll(refs); } } Set result = Collections.emptySet(); if(allRefs != null) { if(allRefs.size() == 1) { if(includeThis) { allRefs.add(resource); if(allRefs.size() == 1) result = Collections.singleton(allRefs.iterator().next()); else result = allRefs; } else { result = Collections.singleton(allRefs.iterator().next()); } } else { if(includeThis) allRefs.add(resource); result = allRefs; } } else { if(includeThis) result = Collections.singleton(resource); } cache.put(types, result); return result; } public Set resolve(ReadGraph graph, ResourceSet types) throws DatabaseException { Set result = resolve(graph, types, null); if(result == null) result = Collections.emptySet(); return result; } }