]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / DiagramContentRequest.java
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
new file mode 100644 (file)
index 0000000..dbda69a
--- /dev/null
@@ -0,0 +1,194 @@
+/*******************************************************************************\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
+}
\ No newline at end of file