package org.simantics.db.common.recursive; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Statement; import org.simantics.db.exception.DatabaseException; import org.simantics.layer0.Layer0; public class FindParentsWithType extends FindRoots { private final ReadGraph graph; private final Resource rootType; private final Layer0 L0; public FindParentsWithType(ReadGraph graph, Resource rootType) { this.graph = graph; this.rootType = rootType; this.L0 = Layer0.getInstance(graph); } @Override protected boolean isRoot(Resource resource) throws DatabaseException { return graph.isInstanceOf(resource, rootType); } @Override protected Collection children(Resource resource) throws DatabaseException { Resource parent = graph.getPossibleObject(resource, L0.PartOf); if(parent != null) return Collections.singletonList(parent); ArrayList result = new ArrayList(4); for(Statement s : graph.getStatements(resource, L0.IsWeaklyRelatedTo)) { if(!s.getSubject().equals(resource)) continue; Resource inverse = graph.getPossibleInverse(s.getPredicate()); if(inverse != null && graph.isSubrelationOf(inverse, L0.IsRelatedTo)) result.add(s.getObject()); } return result; } /** * Makes a query for just one resource. If you want to make multiple queries with the same type, * instantiate this class and call the {@code get} method. */ public static List findParentsWithType(ReadGraph graph, Resource r, Resource type) throws DatabaseException { Set set = new FindParentsWithType(graph, type).get(r); if(set == null) return Collections.emptyList(); else return new ArrayList(set); } }