--- /dev/null
+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<Resource> children(Resource resource) throws DatabaseException {
+ Resource parent = graph.getPossibleObject(resource, L0.PartOf);
+ if(parent != null)
+ return Collections.singletonList(parent);
+
+ ArrayList<Resource> result = new ArrayList<Resource>(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<Resource> findParentsWithType(ReadGraph graph, Resource r, Resource type) throws DatabaseException {
+ Set<Resource> set = new FindParentsWithType(graph, type).get(r);
+ if(set == null)
+ return Collections.emptyList();
+ else
+ return new ArrayList<Resource>(set);
+ }
+}