1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.diagram.adapter;
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;
19 import java.util.ArrayList;
20 import java.util.Collection;
22 import java.util.concurrent.Semaphore;
23 import java.util.concurrent.atomic.AtomicInteger;
25 import org.simantics.db.AsyncReadGraph;
26 import org.simantics.db.ReadGraph;
27 import org.simantics.db.Resource;
28 import org.simantics.db.common.primitiverequest.OrderedSet;
29 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
30 import org.simantics.db.common.utils.OrderedSetUtils;
31 import org.simantics.db.exception.DatabaseException;
32 import org.simantics.db.procedure.AsyncMultiProcedure;
33 import org.simantics.db.procedure.AsyncProcedure;
34 import org.simantics.diagram.content.ConnectionPartData;
35 import org.simantics.diagram.content.ConnectionPartRequest;
36 import org.simantics.diagram.content.DiagramContents;
37 import org.simantics.diagram.content.EdgeResource;
38 import org.simantics.diagram.content.RouteGraphConnectionPartData;
39 import org.simantics.diagram.content.RouteGraphConnectionPartRequest;
40 import org.simantics.diagram.stubs.DiagramResource;
41 import org.simantics.diagram.synchronization.ErrorHandler;
42 import org.simantics.g2d.canvas.ICanvasContext;
45 * @author Tuukka Lehtonen
47 public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents> {
49 int previousElementCount = 32;
50 ErrorHandler errorHandler;
52 public DiagramContentRequest(ICanvasContext canvas, Resource resource, ErrorHandler errorHandler) {
53 super(canvas, resource);
54 this.errorHandler = errorHandler;
58 public DiagramContents perform(ReadGraph g) throws DatabaseException {
60 final DiagramResource DIA = DiagramResource.getInstance(g);
61 final DiagramContents result = new DiagramContents();
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>();
73 result.partToConnection = new THashMap<Object, Resource>();
75 // These help loading result.elements in the correct order.
76 final AtomicInteger index = new AtomicInteger();
77 final TIntArrayList unrecognizedElementIndices = new TIntArrayList();
79 Collection<Resource> components = OrderedSetUtils.toList(g, data);
81 Semaphore s = new Semaphore(0);
83 for(Resource component : components) {
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);
90 Set<Resource> types = g.getTypes(component);
92 if (types.contains(DIA.Connection)) {
93 if (types.contains(DIA.RouteGraphConnection)) {
94 g.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
95 new ProcedureAdapter<RouteGraphConnectionPartData>() {
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);
104 for (Resource line : partData.routeLines) {
105 result.routeLines.add(line);
106 result.connectionToParts.add(component, line);
107 result.partToConnection.put(line, component);
109 for (Resource point : partData.routePoints) {
110 result.routePoints.add(point);
111 result.connectionToParts.add(component, point);
112 result.partToConnection.put(point, component);
119 synchronized (result.routeGraphConnectionSet) {
120 result.routeGraphConnectionSet.add(component);
123 g.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component),
124 new ProcedureAdapter<ConnectionPartData>() {
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);
133 for (Resource bp : partData.branchPoints) {
134 result.branchPoints.add(bp);
135 result.connectionToParts.add(component, bp);
136 result.partToConnection.put(bp, component);
143 synchronized (result.connectionSet) {
144 result.connectionSet.add(component);
148 else if (types.contains(DIA.Element)) {
149 synchronized (result.nodeSet) {
150 result.nodeSet.add(component);
156 synchronized (unrecognizedElementIndices) {
157 // Unrecognized element, mark it to be
158 // removed after everything is processed.
159 unrecognizedElementIndices.add(elementIndex);
167 s.acquire(components.size());
168 } catch (InterruptedException e) {
172 // Remove elements that were not recognized in descending order.
173 unrecognizedElementIndices.sort();
174 unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
176 public boolean execute(int index) {
177 result.elements.remove(index);
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();
188 // g.forOrderedSet(data, new AsyncMultiProcedure<Resource>() {
191 // public void execute(AsyncReadGraph graph, final Resource component) {
193 // graph.forTypes(component, new AsyncProcedure<Set<Resource>>() {
196 // public void exception(AsyncReadGraph graph, Throwable t) {
197 // if (errorHandler != null)
198 // errorHandler.error(t.getMessage(), t);
202 // public void execute(AsyncReadGraph graph, Set<Resource> types) {
211 // public void finished(AsyncReadGraph graph) {
215 // public void exception(AsyncReadGraph graph, Throwable t) {
216 // if (errorHandler != null)
217 // errorHandler.error(t.getMessage(), t);