]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
Merge "Multiple reader thread support for db client"
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / DiagramContentRequest.java
index dbda69a421ee97d341791690cca766f91da94f57..9be72d29f53fabb6e8d2d906618a1fb0a2fb8f9f 100644 (file)
-/*******************************************************************************\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.diagram.adapter;\r
-\r
-import gnu.trove.list.array.TIntArrayList;\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TIntProcedure;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Set;\r
-import java.util.concurrent.atomic.AtomicInteger;\r
-\r
-import org.simantics.db.AsyncReadGraph;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.common.procedure.adapter.ProcedureAdapter;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.procedure.AsyncMultiProcedure;\r
-import org.simantics.db.procedure.AsyncProcedure;\r
-import org.simantics.diagram.content.ConnectionPartData;\r
-import org.simantics.diagram.content.ConnectionPartRequest;\r
-import org.simantics.diagram.content.DiagramContents;\r
-import org.simantics.diagram.content.EdgeResource;\r
-import org.simantics.diagram.content.RouteGraphConnectionPartData;\r
-import org.simantics.diagram.content.RouteGraphConnectionPartRequest;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.diagram.synchronization.ErrorHandler;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents> {\r
-\r
-    int previousElementCount = 32;\r
-    ErrorHandler errorHandler;\r
-\r
-    public DiagramContentRequest(ICanvasContext canvas, Resource resource, ErrorHandler errorHandler) {\r
-        super(canvas, resource);\r
-        this.errorHandler = errorHandler;\r
-    }\r
-\r
-    @Override\r
-    public DiagramContents perform(ReadGraph g) throws DatabaseException {\r
-\r
-        final DiagramResource DIA = DiagramResource.getInstance(g);\r
-        final DiagramContents result = new DiagramContents();\r
-\r
-        result.elements =   new ArrayList<Resource>(previousElementCount);\r
-        result.nodeSet = new THashSet<Resource>();\r
-        result.connectionSet = new THashSet<Resource>();\r
-        result.connectionSegments = new THashSet<EdgeResource>();\r
-        result.branchPoints = new THashSet<Resource>();\r
-        result.routeGraphConnectionSet = new THashSet<Resource>();\r
-        result.routeLinks = new THashSet<EdgeResource>();\r
-        result.routeLines = new THashSet<Resource>();\r
-        result.routePoints = new THashSet<Resource>();\r
-\r
-        result.partToConnection = new THashMap<Object, Resource>();\r
-\r
-        // These help loading result.elements in the correct order.\r
-        final AtomicInteger index = new AtomicInteger();\r
-        final TIntArrayList unrecognizedElementIndices = new TIntArrayList();\r
-\r
-        g.forOrderedSet(data, new AsyncMultiProcedure<Resource>() {\r
-\r
-            @Override\r
-            public void execute(AsyncReadGraph graph, final Resource component) {\r
-\r
-                // Must add the elements to the result set here in order to\r
-                // keep their order the same as in the ordered set.\r
-                final int elementIndex = index.getAndIncrement();\r
-                result.elements.add(component);\r
-\r
-                graph.forTypes(component, new AsyncProcedure<Set<Resource>>() {\r
-\r
-                    @Override\r
-                    public void exception(AsyncReadGraph graph, Throwable t) {\r
-                        if (errorHandler != null)\r
-                            errorHandler.error(t.getMessage(), t);\r
-                    }\r
-\r
-                    @Override\r
-                    public void execute(AsyncReadGraph graph, Set<Resource> types) {\r
-                        if (types.contains(DIA.Connection)) {\r
-                            if (types.contains(DIA.RouteGraphConnection)) {\r
-                                graph.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component),\r
-                                        new ProcedureAdapter<RouteGraphConnectionPartData>() {\r
-                                    @Override\r
-                                    public void execute(RouteGraphConnectionPartData partData) {\r
-                                        synchronized (result) {\r
-                                            for (EdgeResource link : partData.links) {\r
-                                                result.routeLinks.add(link);\r
-                                                result.partToConnection.put(link, component);\r
-                                                result.connectionToParts.add(component, link);\r
-                                            }\r
-                                            for (Resource line : partData.routeLines) {\r
-                                                result.routeLines.add(line);\r
-                                                result.connectionToParts.add(component, line);\r
-                                                result.partToConnection.put(line, component);\r
-                                            }\r
-                                            for (Resource point : partData.routePoints) {\r
-                                                result.routePoints.add(point);\r
-                                                result.connectionToParts.add(component, point);\r
-                                                result.partToConnection.put(point, component);\r
-                                            }\r
-                                        }\r
-                                    }\r
-                                });\r
-\r
-                                synchronized (result.routeGraphConnectionSet) {\r
-                                    result.routeGraphConnectionSet.add(component);\r
-                                }\r
-                            } else {\r
-                                graph.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component),\r
-                                        new ProcedureAdapter<ConnectionPartData>() {\r
-                                    @Override\r
-                                    public void execute(ConnectionPartData partData) {\r
-                                        synchronized (result) {\r
-                                            for (EdgeResource er : partData.edges) {\r
-                                                result.connectionSegments.add(er);\r
-                                                result.partToConnection.put(er, component);\r
-                                                result.connectionToParts.add(component, er);\r
-                                            }\r
-                                            for (Resource bp : partData.branchPoints) {\r
-                                                result.branchPoints.add(bp);\r
-                                                result.connectionToParts.add(component, bp);\r
-                                                result.partToConnection.put(bp, component);\r
-                                            }\r
-                                        }\r
-                                    }\r
-                                });\r
-\r
-                                synchronized (result.connectionSet) {\r
-                                    result.connectionSet.add(component);\r
-                                }\r
-                            }\r
-                        }\r
-                        else if (types.contains(DIA.Element)) {\r
-                            synchronized (result.nodeSet) {\r
-                                result.nodeSet.add(component);\r
-                            }\r
-                        }\r
-                        else {\r
-                            synchronized (unrecognizedElementIndices) {\r
-                                // Unrecognized element, mark it to be\r
-                                // removed after everything is processed.\r
-                                unrecognizedElementIndices.add(elementIndex);\r
-                            }\r
-                        }\r
-                    }\r
-\r
-                });\r
-\r
-            }\r
-\r
-            @Override\r
-            public void finished(AsyncReadGraph graph) {\r
-                // Remove elements that were not recognized in descending order.\r
-                unrecognizedElementIndices.sort();\r
-                unrecognizedElementIndices.forEachDescending(new TIntProcedure() {\r
-                    @Override\r
-                    public boolean execute(int index) {\r
-                        result.elements.remove(index);\r
-                        return true;\r
-                    }\r
-                });\r
-\r
-                // Help successive request executions by remembering the previous\r
-                // element count. This will relieve some ArrayList reallocation\r
-                // strain down the road.\r
-                previousElementCount = result.elements.size();\r
-            }\r
-\r
-            @Override\r
-            public void exception(AsyncReadGraph graph, Throwable t) {\r
-                if (errorHandler != null)\r
-                    errorHandler.error(t.getMessage(), t);\r
-            }\r
-        });\r
-\r
-        return result;\r
-    }\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2018 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.adapter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.utils.OrderedSetUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.AsyncRead;
+import org.simantics.diagram.content.ConnectionPartData;
+import org.simantics.diagram.content.ConnectionPartRequest;
+import org.simantics.diagram.content.DiagramContents;
+import org.simantics.diagram.content.EdgeResource;
+import org.simantics.diagram.content.RouteGraphConnectionPartData;
+import org.simantics.diagram.content.RouteGraphConnectionPartRequest;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.synchronization.ErrorHandler;
+import org.simantics.g2d.canvas.ICanvasContext;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.THashSet;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents> {
+
+    int previousElementCount = 32;
+    ErrorHandler errorHandler;
+
+    public DiagramContentRequest(ICanvasContext canvas, Resource resource, ErrorHandler errorHandler) {
+        super(canvas, resource);
+        this.errorHandler = errorHandler;
+    }
+
+    @Override
+    public DiagramContents perform(ReadGraph g) throws DatabaseException {
+
+        final DiagramResource DIA = DiagramResource.getInstance(g);
+
+        // These help loading result.elements in the correct order.
+        final AtomicInteger index = new AtomicInteger();
+        final TIntArrayList unrecognizedElementIndices = new TIntArrayList();
+
+        Collection<Resource> components = OrderedSetUtils.toList(g, data);
+        DiagramContents res = g.syncRequest((AsyncRead<DiagramContents>)(graph, procedure) -> {
+
+            DiagramContents result = new DiagramContents();
+            procedure.execute(graph, result);
+
+            result.elements =   new ArrayList<Resource>(previousElementCount);
+            result.nodeSet = new THashSet<Resource>();
+            result.connectionSet = new THashSet<Resource>();
+            result.connectionSegments = new THashSet<EdgeResource>();
+            result.branchPoints = new THashSet<Resource>();
+            result.routeGraphConnectionSet = new THashSet<Resource>();
+            result.routeLinks = new THashSet<EdgeResource>();
+            result.routeLines = new THashSet<Resource>();
+            result.routePoints = new THashSet<Resource>();
+
+            result.partToConnection = new THashMap<Object, Resource>();
+
+            for (Resource component : components) {
+
+                // Must add the elements to the result set here in order to
+                // keep their order the same as in the ordered set.
+                final int elementIndex = index.getAndIncrement();
+                result.elements.add(component);
+
+                graph.forTypes(component, new ProcedureAdapter<Set<Resource>>() {
+
+                    @Override
+                    public void execute(Set<Resource> types) {
+
+                        if (types.contains(DIA.Connection)) {
+                            if (types.contains(DIA.RouteGraphConnection)) {
+                                graph.asyncRequest(
+                                        new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
+                                        new ProcedureAdapter<RouteGraphConnectionPartData>() {
+                                            @Override
+                                            public void execute(RouteGraphConnectionPartData partData) {
+                                                synchronized (result) {
+                                                    for (EdgeResource link : partData.links) {
+                                                        result.routeLinks.add(link);
+                                                        result.partToConnection.put(link, component);
+                                                        result.connectionToParts.add(component, link);
+                                                    }
+                                                    for (Resource line : partData.routeLines) {
+                                                        result.routeLines.add(line);
+                                                        result.connectionToParts.add(component, line);
+                                                        result.partToConnection.put(line, component);
+                                                    }
+                                                    for (Resource point : partData.routePoints) {
+                                                        result.routePoints.add(point);
+                                                        result.connectionToParts.add(component, point);
+                                                        result.partToConnection.put(point, component);
+                                                    }
+                                                }
+                                            }
+                                        });
+
+                                synchronized (result.routeGraphConnectionSet) {
+                                    result.routeGraphConnectionSet.add(component);
+                                }
+                            } else {
+                                graph.asyncRequest(
+                                        new ConnectionPartRequest(errorHandler, DIA, component),
+                                        new ProcedureAdapter<ConnectionPartData>() {
+                                            @Override
+                                            public void execute(ConnectionPartData partData) {
+                                                synchronized (result) {
+                                                    for (EdgeResource er : partData.edges) {
+                                                        result.connectionSegments.add(er);
+                                                        result.partToConnection.put(er, component);
+                                                        result.connectionToParts.add(component, er);
+                                                    }
+                                                    for (Resource bp : partData.branchPoints) {
+                                                        result.branchPoints.add(bp);
+                                                        result.connectionToParts.add(component, bp);
+                                                        result.partToConnection.put(bp, component);
+                                                    }
+                                                }
+                                            }
+                                        });
+
+                                synchronized (result.connectionSet) {
+                                    result.connectionSet.add(component);
+                                }
+                            }
+                        }
+                        else if (types.contains(DIA.Element)) {
+                            synchronized (result.nodeSet) {
+                                result.nodeSet.add(component);
+                            }
+                        }
+                        else {
+                            synchronized (unrecognizedElementIndices) {
+                                // Unrecognized element, mark it to be
+                                // removed after everything is processed.
+                                unrecognizedElementIndices.add(elementIndex);
+                            }
+                        }
+                    }
+                });
+            }
+        });
+
+        // Remove elements that were not recognized in descending order.
+        unrecognizedElementIndices.sort();
+        unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
+            @Override
+            public boolean execute(int index) {
+                res.elements.remove(index);
+                return true;
+            }
+        });
+
+        // Help successive request executions by remembering the previous
+        // element count. This will relieve some ArrayList reallocation
+        // strain down the road.
+        previousElementCount = res.elements.size();
+
+        return res;
+    }
 }
\ No newline at end of file