]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/content/RouteGraphConnectionPartRequest.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / content / RouteGraphConnectionPartRequest.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.content;
13
14 import java.util.HashSet;
15 import java.util.Set;
16 import java.util.concurrent.ConcurrentLinkedQueue;
17 import java.util.concurrent.atomic.AtomicInteger;
18
19 import org.simantics.db.AsyncReadGraph;
20 import org.simantics.db.Resource;
21 import org.simantics.db.common.request.ResourceAsyncRead;
22 import org.simantics.db.procedure.AsyncMultiProcedure;
23 import org.simantics.db.procedure.AsyncProcedure;
24 import org.simantics.diagram.stubs.DiagramResource;
25 import org.simantics.diagram.synchronization.ErrorHandler;
26
27 /**
28  * @author Antti Villberg
29  * @author Tuukka Lehtonen
30  */
31 public class RouteGraphConnectionPartRequest extends ResourceAsyncRead<RouteGraphConnectionPartData> {
32
33     final ErrorHandler    errorHandler;
34     final DiagramResource DIA;
35
36     public RouteGraphConnectionPartRequest(ErrorHandler errorHandler, DiagramResource dia, Resource resource) {
37         super(resource);
38         this.errorHandler = errorHandler;
39         this.DIA = dia;
40     }
41
42     @Override
43     public void perform(AsyncReadGraph graph, final AsyncProcedure<RouteGraphConnectionPartData> procedure) {
44
45         final AtomicInteger ready = new AtomicInteger(3);
46         final RouteGraphConnectionPartData result = new RouteGraphConnectionPartData();
47         final HashSet<EdgeResource> connectorLinks = new HashSet<EdgeResource>();
48         final HashSet<EdgeResource> routeLinks = new HashSet<EdgeResource>();
49
50         result.links = connectorLinks;
51         result.routeLines = new ConcurrentLinkedQueue<Resource>();
52         result.routePoints = new ConcurrentLinkedQueue<Resource>();
53
54         AsyncMultiProcedure<Resource> locationProcedure = new AsyncMultiProcedure<Resource>() {
55
56             @Override
57             public void exception(AsyncReadGraph graph, Throwable throwable) {
58                 errorHandler.error("forEachObject(connection, Has I/O) failure", throwable);
59             }
60
61             @Override
62             public void execute(AsyncReadGraph graph, final Resource location) {
63
64                 ready.incrementAndGet();
65
66                 graph.forEachObject(location, DIA.AreConnected, new AsyncMultiProcedure<Resource>() {
67
68                     @Override
69                     public void exception(AsyncReadGraph graph, Throwable throwable) {
70                         errorHandler.error("forEachObject(:I/O Connector, Are Connected) failure", throwable);
71                     }
72
73                     @Override
74                     public void execute(AsyncReadGraph graph, Resource connectedTo) {
75                         synchronized (connectorLinks) {
76                             connectorLinks.add(new EdgeResource(location, connectedTo));
77                         }
78                     }
79
80                     @Override
81                     public void finished(AsyncReadGraph graph) {
82                         if (ready.decrementAndGet() == 0) {
83                             connectorLinks.addAll(routeLinks);
84                             procedure.execute(graph, result);
85                         }
86                     }
87
88                 });
89
90             }
91
92             @Override
93             public void finished(AsyncReadGraph graph) {
94                 if (ready.decrementAndGet() == 0) {
95                     connectorLinks.addAll(routeLinks);
96                     procedure.execute(graph, result);
97                 }
98             }
99
100         };
101
102         AsyncMultiProcedure<Resource> locationProcedure2 = new AsyncMultiProcedure<Resource>() {
103
104             @Override
105             public void exception(AsyncReadGraph graph, Throwable throwable) {
106                 errorHandler.error("forEachObject(connection, Has Branch Point) failure", throwable);
107             }
108
109             @Override
110             public void execute(AsyncReadGraph graph, final Resource location) {
111
112                 ready.incrementAndGet();
113
114                 graph.forTypes(location, new AsyncProcedure<Set<Resource>>() {
115                     @Override
116                     public void execute(AsyncReadGraph graph, Set<Resource> types) {
117                         if (types.contains(DIA.RouteLine)) {
118                             result.routeLines.add(location);
119                         } else if (types.contains(DIA.RoutePoint)) {
120                             result.routePoints.add(location);
121                         } else {
122                             errorHandler.error("unrecognized interior route node: " + location, new Exception("trace"));
123                         }
124
125                         graph.forEachObject(location, DIA.AreConnected, new AsyncMultiProcedure<Resource>() {
126
127                             @Override
128                             public void exception(AsyncReadGraph graph, Throwable throwable) {
129                                 errorHandler.error("forEachObject(:Branch Point, Are Connected) failure", throwable);
130                             }
131
132                             @Override
133                             public void execute(AsyncReadGraph graph, Resource connectedTo) {
134                                 synchronized (routeLinks) {
135                                     routeLinks.add(new EdgeResource(location, connectedTo));
136                                 }
137                             }
138
139                             @Override
140                             public void finished(AsyncReadGraph graph) {
141                                if (ready.decrementAndGet() == 0) {
142                                     connectorLinks.addAll(routeLinks);
143                                     procedure.execute(graph, result);
144                                 }
145                             }
146
147                         });
148                     }
149                     @Override
150                     public void exception(AsyncReadGraph graph, Throwable throwable) {
151                         errorHandler.error("forEachObject(:Branch Point, Are Connected) failure", throwable);
152                     }
153                 });
154             }
155
156             @Override
157             public void finished(AsyncReadGraph graph) {
158                 if (ready.decrementAndGet() == 0) {
159                     connectorLinks.addAll(routeLinks);
160                     procedure.execute(graph, result);
161                 }
162             }
163
164         };
165
166         AsyncMultiProcedure<Resource> locationProcedure3 = new AsyncMultiProcedure<Resource>() {
167
168             @Override
169             public void exception(AsyncReadGraph graph, Throwable throwable) {
170                 errorHandler.error("forEachObject(connection, Has I/O) failure", throwable);
171             }
172
173             @Override
174             public void execute(AsyncReadGraph graph, final Resource location) {
175
176                 ready.incrementAndGet();
177
178                 graph.forEachObject(location, DIA.AreConnected, new AsyncMultiProcedure<Resource>() {
179
180                     @Override
181                     public void exception(AsyncReadGraph graph, Throwable throwable) {
182                         errorHandler.error("forEachObject(:I/O Connector, Are Connected) failure", throwable);
183                     }
184
185                     @Override
186                     public void execute(AsyncReadGraph graph, Resource connectedTo) {
187                         synchronized (connectorLinks) {
188                             connectorLinks.add(new EdgeResource(connectedTo, location));
189                         }
190                     }
191
192                     @Override
193                     public void finished(AsyncReadGraph graph) {
194                         if (ready.decrementAndGet() == 0) {
195                             connectorLinks.addAll(routeLinks);
196                             procedure.execute(graph, result);
197                         }
198                     }
199
200                 });
201
202             }
203
204             @Override
205             public void finished(AsyncReadGraph graph) {
206                 if (ready.decrementAndGet() == 0) {
207                     connectorLinks.addAll(routeLinks);
208                     procedure.execute(graph, result);
209                 }
210             }
211
212         };
213
214         graph.forEachObject(resource, DIA.HasPlainConnector, locationProcedure);
215         graph.forEachObject(resource, DIA.HasInteriorRouteNode, locationProcedure2);
216         graph.forEachObject(resource, DIA.HasArrowConnector, locationProcedure3);
217
218     }
219
220 }