]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
Work in progress
[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 java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Set;
17 import java.util.concurrent.atomic.AtomicInteger;
18
19 import org.simantics.db.ReadGraph;
20 import org.simantics.db.Resource;
21 import org.simantics.db.common.GraphSemaphore;
22 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
23 import org.simantics.db.common.utils.OrderedSetUtils;
24 import org.simantics.db.exception.DatabaseException;
25 import org.simantics.diagram.content.ConnectionPartData;
26 import org.simantics.diagram.content.ConnectionPartRequest;
27 import org.simantics.diagram.content.DiagramContents;
28 import org.simantics.diagram.content.EdgeResource;
29 import org.simantics.diagram.content.RouteGraphConnectionPartData;
30 import org.simantics.diagram.content.RouteGraphConnectionPartRequest;
31 import org.simantics.diagram.stubs.DiagramResource;
32 import org.simantics.diagram.synchronization.ErrorHandler;
33 import org.simantics.g2d.canvas.ICanvasContext;
34
35 import gnu.trove.list.array.TIntArrayList;
36 import gnu.trove.map.hash.THashMap;
37 import gnu.trove.procedure.TIntProcedure;
38 import gnu.trove.set.hash.THashSet;
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         Collection<Resource> components = OrderedSetUtils.toList(g, data);
76         
77         GraphSemaphore s = new GraphSemaphore(g, 0);
78         
79         for(Resource component : components) {
80                 
81             // Must add the elements to the result set here in order to
82             // keep their order the same as in the ordered set.
83             final int elementIndex = index.getAndIncrement();
84             result.elements.add(component);
85
86                 Set<Resource> types = g.getTypes(component);
87                 
88                  if (types.contains(DIA.Connection)) {
89                  if (types.contains(DIA.RouteGraphConnection)) {
90                      g.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
91                              new ProcedureAdapter<RouteGraphConnectionPartData>() {
92                          @Override
93                          public void execute(RouteGraphConnectionPartData partData) {
94                              synchronized (result) {
95                                  for (EdgeResource link : partData.links) {
96                                      result.routeLinks.add(link);
97                                      result.partToConnection.put(link, component);
98                                      result.connectionToParts.add(component, link);
99                                  }
100                                  for (Resource line : partData.routeLines) {
101                                      result.routeLines.add(line);
102                                      result.connectionToParts.add(component, line);
103                                      result.partToConnection.put(line, component);
104                                  }
105                                  for (Resource point : partData.routePoints) {
106                                      result.routePoints.add(point);
107                                      result.connectionToParts.add(component, point);
108                                      result.partToConnection.put(point, component);
109                                  }
110                              }
111                              s.release();
112                          }
113                      });
114
115                      synchronized (result.routeGraphConnectionSet) {
116                          result.routeGraphConnectionSet.add(component);
117                      }
118                  } else {
119                      g.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component),
120                              new ProcedureAdapter<ConnectionPartData>() {
121                          @Override
122                          public void execute(ConnectionPartData partData) {
123                              synchronized (result) {
124                                  for (EdgeResource er : partData.edges) {
125                                      result.connectionSegments.add(er);
126                                      result.partToConnection.put(er, component);
127                                      result.connectionToParts.add(component, er);
128                                  }
129                                  for (Resource bp : partData.branchPoints) {
130                                      result.branchPoints.add(bp);
131                                      result.connectionToParts.add(component, bp);
132                                      result.partToConnection.put(bp, component);
133                                  }
134                              }
135                              s.release();
136                          }
137                      });
138
139                      synchronized (result.connectionSet) {
140                          result.connectionSet.add(component);
141                      }
142                  }
143              }
144              else if (types.contains(DIA.Element)) {
145                  synchronized (result.nodeSet) {
146                      result.nodeSet.add(component);
147                  }
148                  s.release();
149
150              }
151              else {
152                  synchronized (unrecognizedElementIndices) {
153                      // Unrecognized element, mark it to be
154                      // removed after everything is processed.
155                      unrecognizedElementIndices.add(elementIndex);
156                  }
157                  s.release();
158              }          
159                 
160         }
161         
162         try {
163                         s.waitFor(components.size());
164                 } catch (InterruptedException e) {
165                         e.printStackTrace();
166                 }
167         
168         // Remove elements that were not recognized in descending order.
169         unrecognizedElementIndices.sort();
170         unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
171             @Override
172             public boolean execute(int index) {
173                 result.elements.remove(index);
174                 return true;
175             }
176         });
177
178         // Help successive request executions by remembering the previous
179         // element count. This will relieve some ArrayList reallocation
180         // strain down the road.
181         previousElementCount = result.elements.size();
182         
183
184 //        g.forOrderedSet(data, new AsyncMultiProcedure<Resource>() {
185 //
186 //            @Override
187 //            public void execute(AsyncReadGraph graph, final Resource component) {
188 //
189 //                graph.forTypes(component, new AsyncProcedure<Set<Resource>>() {
190 //
191 //                    @Override
192 //                    public void exception(AsyncReadGraph graph, Throwable t) {
193 //                        if (errorHandler != null)
194 //                            errorHandler.error(t.getMessage(), t);
195 //                    }
196 //
197 //                    @Override
198 //                    public void execute(AsyncReadGraph graph, Set<Resource> types) {
199 //                       
200 //                    }
201 //
202 //                });
203 //
204 //            }
205 //
206 //            @Override
207 //            public void finished(AsyncReadGraph graph) {
208 //            }
209 //
210 //            @Override
211 //            public void exception(AsyncReadGraph graph, Throwable t) {
212 //                if (errorHandler != null)
213 //                    errorHandler.error(t.getMessage(), t);
214 //            }
215 //        });
216
217         return result;
218     }
219 }