]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
Adding Logger to DiagramContentRequest
[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 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 import gnu.trove.list.array.TIntArrayList;
38 import gnu.trove.map.hash.THashMap;
39 import gnu.trove.procedure.TIntProcedure;
40 import gnu.trove.set.hash.THashSet;
41
42 /**
43  * @author Tuukka Lehtonen
44  */
45 public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents> {
46
47     private static final Logger LOGGER = LoggerFactory.getLogger(DiagramContentRequest.class);
48
49     int previousElementCount = 32;
50     ErrorHandler errorHandler;
51
52     public DiagramContentRequest(ICanvasContext canvas, Resource resource, ErrorHandler errorHandler) {
53         super(canvas, resource);
54         this.errorHandler = errorHandler;
55     }
56
57     @Override
58     public DiagramContents perform(ReadGraph g) throws DatabaseException {
59
60         final DiagramResource DIA = DiagramResource.getInstance(g);
61         final DiagramContents result = new DiagramContents();
62
63         result.elements =   new ArrayList<Resource>(previousElementCount);
64         result.nodeSet = new THashSet<Resource>();
65         result.connectionSet = new THashSet<Resource>();
66         result.connectionSegments = new THashSet<EdgeResource>();
67         result.branchPoints = new THashSet<Resource>();
68         result.routeGraphConnectionSet = new THashSet<Resource>();
69         result.routeLinks = new THashSet<EdgeResource>();
70         result.routeLines = new THashSet<Resource>();
71         result.routePoints = new THashSet<Resource>();
72
73         result.partToConnection = new THashMap<Object, Resource>();
74
75         // These help loading result.elements in the correct order.
76         final AtomicInteger index = new AtomicInteger();
77         final TIntArrayList unrecognizedElementIndices = new TIntArrayList();
78         
79         Collection<Resource> components = OrderedSetUtils.toList(g, data);
80         
81         GraphSemaphore s = new GraphSemaphore(g, 0);
82         
83         for(Resource component : components) {
84                 
85             // Must add the elements to the result set here in order to
86             // keep their order the same as in the ordered set.
87             final int elementIndex = index.getAndIncrement();
88             result.elements.add(component);
89
90                 Set<Resource> types = g.getTypes(component);
91                 
92                  if (types.contains(DIA.Connection)) {
93                  if (types.contains(DIA.RouteGraphConnection)) {
94                      g.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
95                              new ProcedureAdapter<RouteGraphConnectionPartData>() {
96                          @Override
97                          public void execute(RouteGraphConnectionPartData partData) {
98                              synchronized (result) {
99                                  for (EdgeResource link : partData.links) {
100                                      result.routeLinks.add(link);
101                                      result.partToConnection.put(link, component);
102                                      result.connectionToParts.add(component, link);
103                                  }
104                                  for (Resource line : partData.routeLines) {
105                                      result.routeLines.add(line);
106                                      result.connectionToParts.add(component, line);
107                                      result.partToConnection.put(line, component);
108                                  }
109                                  for (Resource point : partData.routePoints) {
110                                      result.routePoints.add(point);
111                                      result.connectionToParts.add(component, point);
112                                      result.partToConnection.put(point, component);
113                                  }
114                              }
115                              s.release();
116                          }
117                      });
118
119                      synchronized (result.routeGraphConnectionSet) {
120                          result.routeGraphConnectionSet.add(component);
121                      }
122                  } else {
123                      g.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component),
124                              new ProcedureAdapter<ConnectionPartData>() {
125                          @Override
126                          public void execute(ConnectionPartData partData) {
127                              synchronized (result) {
128                                  for (EdgeResource er : partData.edges) {
129                                      result.connectionSegments.add(er);
130                                      result.partToConnection.put(er, component);
131                                      result.connectionToParts.add(component, er);
132                                  }
133                                  for (Resource bp : partData.branchPoints) {
134                                      result.branchPoints.add(bp);
135                                      result.connectionToParts.add(component, bp);
136                                      result.partToConnection.put(bp, component);
137                                  }
138                              }
139                              s.release();
140                          }
141                      });
142
143                      synchronized (result.connectionSet) {
144                          result.connectionSet.add(component);
145                      }
146                  }
147              }
148              else if (types.contains(DIA.Element)) {
149                  synchronized (result.nodeSet) {
150                      result.nodeSet.add(component);
151                  }
152                  s.release();
153
154              }
155              else {
156                  synchronized (unrecognizedElementIndices) {
157                      // Unrecognized element, mark it to be
158                      // removed after everything is processed.
159                      unrecognizedElementIndices.add(elementIndex);
160                  }
161                  s.release();
162              }          
163                 
164         }
165
166         try {
167             s.waitFor(components.size());
168         } catch (InterruptedException e) {
169             LOGGER.error("An error occured while waiting for diagram to load", e);
170         }
171
172         // Remove elements that were not recognized in descending order.
173         unrecognizedElementIndices.sort();
174         unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
175             @Override
176             public boolean execute(int index) {
177                 result.elements.remove(index);
178                 return true;
179             }
180         });
181
182         // Help successive request executions by remembering the previous
183         // element count. This will relieve some ArrayList reallocation
184         // strain down the road.
185         previousElementCount = result.elements.size();
186         
187
188 //        g.forOrderedSet(data, new AsyncMultiProcedure<Resource>() {
189 //
190 //            @Override
191 //            public void execute(AsyncReadGraph graph, final Resource component) {
192 //
193 //                graph.forTypes(component, new AsyncProcedure<Set<Resource>>() {
194 //
195 //                    @Override
196 //                    public void exception(AsyncReadGraph graph, Throwable t) {
197 //                        if (errorHandler != null)
198 //                            errorHandler.error(t.getMessage(), t);
199 //                    }
200 //
201 //                    @Override
202 //                    public void execute(AsyncReadGraph graph, Set<Resource> types) {
203 //                       
204 //                    }
205 //
206 //                });
207 //
208 //            }
209 //
210 //            @Override
211 //            public void finished(AsyncReadGraph graph) {
212 //            }
213 //
214 //            @Override
215 //            public void exception(AsyncReadGraph graph, Throwable t) {
216 //                if (errorHandler != null)
217 //                    errorHandler.error(t.getMessage(), t);
218 //            }
219 //        });
220
221         return result;
222     }
223 }