]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / DiagramContentRequest.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.diagram.adapter;
13
14 import gnu.trove.list.array.TIntArrayList;
15 import gnu.trove.map.hash.THashMap;
16 import gnu.trove.procedure.TIntProcedure;
17 import gnu.trove.set.hash.THashSet;
18
19 import java.util.ArrayList;
20 import java.util.Set;
21 import java.util.concurrent.atomic.AtomicInteger;
22
23 import org.simantics.db.AsyncReadGraph;
24 import org.simantics.db.ReadGraph;
25 import org.simantics.db.Resource;
26 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.db.procedure.AsyncMultiProcedure;
29 import org.simantics.db.procedure.AsyncProcedure;
30 import org.simantics.diagram.content.ConnectionPartData;
31 import org.simantics.diagram.content.ConnectionPartRequest;
32 import org.simantics.diagram.content.DiagramContents;
33 import org.simantics.diagram.content.EdgeResource;
34 import org.simantics.diagram.content.RouteGraphConnectionPartData;
35 import org.simantics.diagram.content.RouteGraphConnectionPartRequest;
36 import org.simantics.diagram.stubs.DiagramResource;
37 import org.simantics.diagram.synchronization.ErrorHandler;
38 import org.simantics.g2d.canvas.ICanvasContext;
39
40 /**
41  * @author Tuukka Lehtonen
42  */
43 public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents> {
44
45     int previousElementCount = 32;
46     ErrorHandler errorHandler;
47
48     public DiagramContentRequest(ICanvasContext canvas, Resource resource, ErrorHandler errorHandler) {
49         super(canvas, resource);
50         this.errorHandler = errorHandler;
51     }
52
53     @Override
54     public DiagramContents perform(ReadGraph g) throws DatabaseException {
55
56         final DiagramResource DIA = DiagramResource.getInstance(g);
57         final DiagramContents result = new DiagramContents();
58
59         result.elements =   new ArrayList<Resource>(previousElementCount);
60         result.nodeSet = new THashSet<Resource>();
61         result.connectionSet = new THashSet<Resource>();
62         result.connectionSegments = new THashSet<EdgeResource>();
63         result.branchPoints = new THashSet<Resource>();
64         result.routeGraphConnectionSet = new THashSet<Resource>();
65         result.routeLinks = new THashSet<EdgeResource>();
66         result.routeLines = new THashSet<Resource>();
67         result.routePoints = new THashSet<Resource>();
68
69         result.partToConnection = new THashMap<Object, Resource>();
70
71         // These help loading result.elements in the correct order.
72         final AtomicInteger index = new AtomicInteger();
73         final TIntArrayList unrecognizedElementIndices = new TIntArrayList();
74
75         g.forOrderedSet(data, new AsyncMultiProcedure<Resource>() {
76
77             @Override
78             public void execute(AsyncReadGraph graph, final Resource component) {
79
80                 // Must add the elements to the result set here in order to
81                 // keep their order the same as in the ordered set.
82                 final int elementIndex = index.getAndIncrement();
83                 result.elements.add(component);
84
85                 graph.forTypes(component, new AsyncProcedure<Set<Resource>>() {
86
87                     @Override
88                     public void exception(AsyncReadGraph graph, Throwable t) {
89                         if (errorHandler != null)
90                             errorHandler.error(t.getMessage(), t);
91                     }
92
93                     @Override
94                     public void execute(AsyncReadGraph graph, Set<Resource> types) {
95                         if (types.contains(DIA.Connection)) {
96                             if (types.contains(DIA.RouteGraphConnection)) {
97                                 graph.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
98                                         new ProcedureAdapter<RouteGraphConnectionPartData>() {
99                                     @Override
100                                     public void execute(RouteGraphConnectionPartData partData) {
101                                         synchronized (result) {
102                                             for (EdgeResource link : partData.links) {
103                                                 result.routeLinks.add(link);
104                                                 result.partToConnection.put(link, component);
105                                                 result.connectionToParts.add(component, link);
106                                             }
107                                             for (Resource line : partData.routeLines) {
108                                                 result.routeLines.add(line);
109                                                 result.connectionToParts.add(component, line);
110                                                 result.partToConnection.put(line, component);
111                                             }
112                                             for (Resource point : partData.routePoints) {
113                                                 result.routePoints.add(point);
114                                                 result.connectionToParts.add(component, point);
115                                                 result.partToConnection.put(point, component);
116                                             }
117                                         }
118                                     }
119                                 });
120
121                                 synchronized (result.routeGraphConnectionSet) {
122                                     result.routeGraphConnectionSet.add(component);
123                                 }
124                             } else {
125                                 graph.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component),
126                                         new ProcedureAdapter<ConnectionPartData>() {
127                                     @Override
128                                     public void execute(ConnectionPartData partData) {
129                                         synchronized (result) {
130                                             for (EdgeResource er : partData.edges) {
131                                                 result.connectionSegments.add(er);
132                                                 result.partToConnection.put(er, component);
133                                                 result.connectionToParts.add(component, er);
134                                             }
135                                             for (Resource bp : partData.branchPoints) {
136                                                 result.branchPoints.add(bp);
137                                                 result.connectionToParts.add(component, bp);
138                                                 result.partToConnection.put(bp, component);
139                                             }
140                                         }
141                                     }
142                                 });
143
144                                 synchronized (result.connectionSet) {
145                                     result.connectionSet.add(component);
146                                 }
147                             }
148                         }
149                         else if (types.contains(DIA.Element)) {
150                             synchronized (result.nodeSet) {
151                                 result.nodeSet.add(component);
152                             }
153                         }
154                         else {
155                             synchronized (unrecognizedElementIndices) {
156                                 // Unrecognized element, mark it to be
157                                 // removed after everything is processed.
158                                 unrecognizedElementIndices.add(elementIndex);
159                             }
160                         }
161                     }
162
163                 });
164
165             }
166
167             @Override
168             public void finished(AsyncReadGraph graph) {
169                 // Remove elements that were not recognized in descending order.
170                 unrecognizedElementIndices.sort();
171                 unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
172                     @Override
173                     public boolean execute(int index) {
174                         result.elements.remove(index);
175                         return true;
176                     }
177                 });
178
179                 // Help successive request executions by remembering the previous
180                 // element count. This will relieve some ArrayList reallocation
181                 // strain down the road.
182                 previousElementCount = result.elements.size();
183             }
184
185             @Override
186             public void exception(AsyncReadGraph graph, Throwable t) {
187                 if (errorHandler != null)
188                     errorHandler.error(t.getMessage(), t);
189             }
190         });
191
192         return result;
193     }
194 }