]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/EntityInstances.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / adapter / impl / EntityInstances.java
diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/EntityInstances.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/impl/EntityInstances.java
new file mode 100644 (file)
index 0000000..b0d7150
--- /dev/null
@@ -0,0 +1,189 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.db.layer0.adapter.impl;\r
+\r
+import gnu.trove.set.hash.THashSet;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.primitiverequest.Adapter;\r
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.TernaryRead;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.Instances;\r
+import org.simantics.db.layer0.genericrelation.IndexQueries;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.service.CollectionSupport;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.scl.runtime.function.Function;\r
+\r
+/**\r
+ * @author Antti Villberg\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class EntityInstances implements Instances {\r
+\r
+    private static final boolean TRACE_QUERIES = false;\r
+\r
+    private final Resource type;\r
+\r
+    public EntityInstances(Resource type) {\r
+        this.type = type;\r
+    }\r
+\r
+    @Override\r
+    public Collection<Resource> find(ReadGraph graph, Resource index) throws DatabaseException {\r
+        return find(graph, index, "");\r
+    }\r
+\r
+    /**\r
+     * A (cacheable) query to optimize single index queries for immutable\r
+     * indexes such as ontologies.\r
+     */\r
+    public static class QueryIndex extends TernaryRead<Resource, Resource, String, List<Resource>> {\r
+\r
+        public QueryIndex(Resource index, Resource type, String filter) {\r
+            super(index, type, filter);\r
+        }\r
+\r
+        @Override\r
+        public List<Resource> perform(ReadGraph graph)\r
+                throws DatabaseException {\r
+            Resource type = parameter2;\r
+\r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            Layer0X L0X = Layer0X.getInstance(graph);\r
+            String typeName = graph.getRelatedValue(type, L0.HasName);\r
+            if (typeName.isEmpty())\r
+                return Collections.emptyList();\r
+\r
+            @SuppressWarnings({ "unchecked", "rawtypes" })\r
+            Function dependencyResources = graph.syncRequest(new Adapter(L0X.DependencyResources, Function.class), TransientCacheListener.<Function>instance());\r
+\r
+            StringBuilder filtersb = new StringBuilder();\r
+            filtersb.append("Types:*").append( IndexQueries.escape( typeName, true ) );\r
+            if (parameter3.length() > 0)\r
+                filtersb.append(" AND ").append( parameter3 );\r
+            String filter = filtersb.toString();\r
+\r
+            if (TRACE_QUERIES) {\r
+                System.out.println("EntityInstances.QueryIndex: finding " + filter + " from index " + graph.getPossibleURI(parameter));\r
+                //new Exception("EntityInstances: finding " + filter + " from index " + graph.getPossibleURI(parameter)).printStackTrace();\r
+            }\r
+            \r
+            @SuppressWarnings("unchecked")\r
+                       List<Resource> results = (List<Resource>)dependencyResources.apply(graph, parameter, filter);\r
+            if (results == null || results.isEmpty())\r
+                return Collections.emptyList();\r
+\r
+            if (TRACE_QUERIES)\r
+                System.out.println("  EntityInstances.QueryIndex: got " + results.size() + " results");\r
+\r
+//            // TreeSet to keep the results in deterministic order.\r
+//            Set<Resource> resultSet = new TreeSet<Resource>();\r
+//            for (Map<String, Object> entry : results) {\r
+//                Resource res = (Resource)entry.get("Resource");\r
+//                if (res != null && !resultSet.contains(res))\r
+//                    resultSet.add(res);\r
+//            }\r
+\r
+            CollectionSupport coll = graph.getService(CollectionSupport.class);\r
+            List<Resource> result = coll.createList();\r
+            \r
+            for (Resource res : Layer0Utils.sortByCluster(graph, results)) {\r
+                if (graph.isInstanceOf(res, type))\r
+                    result.add(res);\r
+            }\r
+\r
+            if (TRACE_QUERIES)\r
+                System.out.println("  EntityInstances.QueryIndex: got " + results.size() + " unique type-matching results");\r
+            \r
+            return result;\r
+\r
+        }\r
+        \r
+        @Override\r
+        public String toString() {\r
+               return "QueryIndex " + parameter + " " + parameter2 + " " + parameter3;\r
+        }\r
+\r
+    }\r
+\r
+    private List<Resource> findRec(ReadGraph graph, Resource index, String filter, Set<Resource> visited) throws DatabaseException {\r
+\r
+       if(!visited.add(index)) return Collections.emptyList();\r
+\r
+       CollectionSupport coll = graph.getService(CollectionSupport.class);\r
+\r
+       List<Resource> indexResult = graph.syncRequest(new QueryIndex(index, type, filter), TransientCacheListener.<List<Resource>>instance());\r
+\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        Collection<Resource> linkedRoots = graph.syncRequest(new ObjectsWithType(index, L0.IsLinkedTo, L0.IndexRoot));\r
+        if (linkedRoots.isEmpty())\r
+            return indexResult;\r
+\r
+        List<Resource> result = indexResult;\r
+        for (Resource dep : linkedRoots) {\r
+            Collection<Resource> linkedIndexResults = findRec(graph, dep, filter, visited);\r
+            if (linkedIndexResults.isEmpty())\r
+                continue;\r
+            if (result == indexResult) {\r
+               result = coll.createList();\r
+                result.addAll(indexResult);\r
+            } else {\r
+            }\r
+            result.addAll(linkedIndexResults);\r
+        }\r
+        \r
+        return result;\r
+        \r
+    }\r
+\r
+    @Override\r
+    public Collection<Resource> find(ReadGraph graph, Resource index, String filter) throws DatabaseException {\r
+       CollectionSupport coll = graph.getService(CollectionSupport.class);\r
+       \r
+       List<Resource> rec = findRec(graph, index, filter, new THashSet<Resource>());\r
+       for(Resource global : Layer0Utils.listGlobalOntologies(graph)) {\r
+               List<Resource> rs = graph.syncRequest(new QueryIndex(global, type, filter), TransientCacheListener.<List<Resource>>instance());\r
+               if(rec.isEmpty() && !rs.isEmpty()) {\r
+                       // TODO: rec could be an immutable empty list\r
+                       rec = new ArrayList<Resource>();\r
+               }\r
+               rec.addAll(rs);\r
+       }\r
+       Collection<Resource> result = coll.asSortedList(rec);\r
+       return result; \r
+    }\r
+    \r
+    @Override\r
+    public Collection<Resource> findByName(ReadGraph graph, Resource model,\r
+            String name) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+       CollectionSupport coll = graph.getService(CollectionSupport.class);\r
+        List<Resource> results = coll.createList();\r
+        for(Resource match : find(graph, model, name)) {\r
+            if(name.equals(graph.getPossibleRelatedValue(match, L0.HasName, Bindings.STRING))) results.add(match);\r
+        }\r
+        return results;\r
+    }\r
+\r
+}\r