]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DefinedElementFactory.java
Merge "(refs #7521) Added FunctionalRelation types to properties in graphfile"
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / DefinedElementFactory.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.awt.Shape;
15 import java.awt.geom.AffineTransform;
16 import java.util.Collections;
17 import java.util.concurrent.ConcurrentLinkedQueue;
18 import java.util.concurrent.atomic.AtomicInteger;
19
20 import org.simantics.databoard.Bindings;
21 import org.simantics.db.AsyncReadGraph;
22 import org.simantics.db.Resource;
23 import org.simantics.db.common.primitiverequest.PossibleAdapter;
24 import org.simantics.db.common.procedure.adapter.AsyncProcedureAdapter;
25 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
26 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
27 import org.simantics.db.common.procedure.guarded.GuardedAsyncProcedureWrapper;
28 import org.simantics.db.common.request.BinaryAsyncRead;
29 import org.simantics.db.common.request.SafeName;
30 import org.simantics.db.procedure.AsyncMultiProcedure;
31 import org.simantics.db.procedure.AsyncProcedure;
32 import org.simantics.diagram.content.ResourceTerminal;
33 import org.simantics.diagram.stubs.DiagramResource;
34 import org.simantics.diagram.stubs.G2DResource;
35 import org.simantics.diagram.synchronization.SynchronizationHints;
36 import org.simantics.diagram.synchronization.graph.TransformSynchronizer;
37 import org.simantics.g2d.canvas.ICanvasContext;
38 import org.simantics.g2d.diagram.IDiagram;
39 import org.simantics.g2d.element.ElementClass;
40 import org.simantics.g2d.element.ElementUtils;
41 import org.simantics.g2d.element.IElement;
42 import org.simantics.g2d.element.handler.impl.DefaultParameters;
43 import org.simantics.g2d.element.handler.impl.DefaultTransform;
44 import org.simantics.g2d.element.handler.impl.ObjectTerminal;
45 import org.simantics.g2d.element.handler.impl.SimpleElementLayers;
46 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
47 import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;
48 import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;
49 import org.simantics.g2d.element.handler.impl.TextImpl;
50 import org.simantics.g2d.elementclass.PlainElementPropertySetter;
51 import org.simantics.g2d.tooltip.TerminalTooltipProvider;
52 import org.simantics.g2d.tooltip.TooltipParticipant;
53 import org.simantics.g2d.utils.geom.DirectionSet;
54 import org.simantics.structural.stubs.StructuralResource2;
55 import org.simantics.utils.Container;
56
57 /**
58  * @author Tuukka Lehtonen
59  * 
60  * TODO: not merged https://www.simulationsite.net/trac/simantics/changeset/14463/2d/trunk/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java
61  */
62 public class DefinedElementFactory extends ElementFactoryAdapter {
63
64     protected static class ShapeContainer implements Container<Shape> {
65
66         private IElement element;
67         private Shape shape = null;
68
69         public ShapeContainer(IElement element) {
70             this.element = element;
71         }
72
73         @Override
74         public Shape get() {
75             if(shape == null) {
76                 shape = ElementUtils.getElementShapeOrBounds(element);
77                 element = null;
78             }
79             return shape;
80         }
81
82     }
83
84
85     static class ClassRequest extends BinaryAsyncRead<Resource, ICanvasContext, ElementClass> {
86
87         final private IDiagram diagram;
88
89         public ClassRequest(Resource elementType, ICanvasContext canvas, IDiagram diagram) {
90             super(elementType, canvas);
91             this.diagram = diagram;
92         }
93
94         @Override
95         public void perform(AsyncReadGraph graph, AsyncProcedure<ElementClass> procedure) {
96
97             createzz(graph, parameter2, diagram, parameter, procedure);
98
99         }
100
101     }
102
103     @Override
104     public void create(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
105             final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
106
107         graph.asyncRequest(new ClassRequest(elementType, canvas, diagram), new TransientCacheAsyncListener<ElementClass>() {
108
109             @Override
110             public void exception(AsyncReadGraph graph, Throwable t) {
111                 t.printStackTrace();
112                 procedure.exception(graph, t);
113             }
114
115             @Override
116             public void execute(AsyncReadGraph graph, ElementClass result) {
117                 procedure.execute(graph, result);
118             }
119
120         });
121
122     }
123
124     public static void createzz(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
125             final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
126
127         final StructuralResource2 sr = graph.getService(StructuralResource2.class);
128         final G2DResource g2d = graph.getService(G2DResource.class);
129         final DiagramResource dr = graph.getService(DiagramResource.class);
130
131         graph.forSingleObject(elementType, sr.IsDefinedBy, new AsyncProcedure<Resource>() {
132
133             @Override
134             public void exception(AsyncReadGraph graph, Throwable throwable) {
135              
136                 graph.asyncRequest(new SafeName(elementType), new ProcedureAdapter<String>() {
137                     @Override
138                     public void execute(String result) {
139                         System.out.println("DefinedElement '" + result + " ' does not have a single IsDefinedBy relation");
140                     }
141                 });
142              
143                 procedure.exception(graph, throwable);
144                 
145             }
146
147             @Override
148             public void execute(AsyncReadGraph graph, final Resource definingResource) {
149
150                 graph.asyncRequest(new NodeRequest(canvas, diagram, definingResource, null), new TransientCacheAsyncListener<IElement>() {
151
152                     @Override
153                     public void exception(AsyncReadGraph graph, Throwable throwable) {
154                         throwable.printStackTrace();
155                     }
156
157                     @Override
158                     public void execute(AsyncReadGraph graph, final IElement e) {
159
160                         final CompositeImage img = new CompositeImage(Collections.singletonList(e));
161                         final ConcurrentLinkedQueue<ObjectTerminal> terminals = new ConcurrentLinkedQueue<ObjectTerminal>();
162                         final AtomicInteger ready = new AtomicInteger(1);
163
164                         graph.forOrderedSet(definingResource, new AsyncMultiProcedure<Resource>() {
165
166                             @Override
167                             public void exception(AsyncReadGraph graph, Throwable throwable) {
168                                 throwable.printStackTrace();
169                             }
170
171                             @Override
172                             public void execute(AsyncReadGraph graph, final Resource r) {
173
174                                 ready.incrementAndGet();
175
176                                 graph.forIsInstanceOf(r, dr.Terminal, new AsyncProcedure<Boolean>() {
177
178                                     @Override
179                                     public void exception(AsyncReadGraph graph, Throwable throwable) {
180                                         throwable.printStackTrace();
181                                     }
182
183                                     public void execute(AsyncReadGraph graph, Boolean isTerminal) {
184
185                                         if (isTerminal) {
186                                             graph.asyncRequest(new NodeRequest(canvas, diagram, r, null), new TransientCacheAsyncListener<IElement>() {
187                                                 @Override
188                                                 public void exception(AsyncReadGraph graph, Throwable throwable) {
189                                                     throwable.printStackTrace();
190                                                 }
191
192                                                 @Override
193                                                 public void execute(AsyncReadGraph graph, final IElement t) {
194                                                     graph.forPossibleRelatedValue(r, g2d.HasTransform, Bindings.DOUBLE_ARRAY, new AsyncProcedure<double[]>() {
195                                                         @Override
196                                                         public void exception(AsyncReadGraph graph, Throwable throwable) {
197                                                             throwable.printStackTrace();
198                                                         }
199
200                                                         @Override
201                                                         public void execute(AsyncReadGraph graph, double[] mat) {
202                                                             AffineTransform tr = mat != null ? new AffineTransform(mat) : new AffineTransform();
203                                                             terminals.add(new ResourceTerminal(r, tr, DirectionSet.ANY, new ShapeContainer(t)));
204
205                                                             worked(graph);
206                                                         }
207                                                     });
208                                                 }
209                                             });
210                                         } else {
211                                             worked(graph);
212                                         }
213
214                                     }
215
216                                 });
217
218                             }
219
220                             @Override
221                             public void finished(AsyncReadGraph graph) {
222                                 worked(graph);
223                             }
224
225                             void worked(AsyncReadGraph graph) {
226                                 if (ready.decrementAndGet() == 0) {
227                                     String id = "DefinedElement: " + elementType.getResourceId();
228                                     procedure.execute(graph, ElementClass.compile(
229                                             TextImpl.INSTANCE,
230                                             new StaticObjectAdapter(elementType),
231                                             DefaultTransform.INSTANCE,
232                                             DefaultParameters.INSTANCE,
233                                             StaticSymbolImageInitializer.INSTANCE,
234                                             new StaticSymbolImpl(img),
235                                             DefinedElementHandler.INSTANCE,
236                                             new DefinedElementTerminals(terminals),
237                                             SimpleElementLayers.INSTANCE,
238                                             PlainElementPropertySetter.INSTANCE
239                                             ).setId(id));
240                                 }
241                             }
242                         });
243
244                     }
245
246                 });
247
248             }
249
250         });
251
252     }
253
254     @Override
255     public void load(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e, final AsyncProcedure<IElement> procedure) {
256         e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, TransformSynchronizer.INSTANCE);
257         // FIXME : this just adds test tooltip to the element.
258         //e.setHint(TooltipParticipant.TOOLTIP_KEY, DefinedElementTooltipProvider.INSTANCE);
259         // This is needed for terminal tooltips.
260         e.setHint(TooltipParticipant.TOOLTIP_KEY, TerminalTooltipProvider.INSTANCE);
261
262         graph.asyncRequest(new PossibleAdapter<ElementFactory>(element, ElementFactory.class), new AsyncProcedureAdapter<ElementFactory>() {
263             @Override
264             public void execute(AsyncReadGraph graph, ElementFactory factory) {
265                 if (factory != null) {
266                     graph.asyncRequest(new GetElementClassRequest(factory, element, canvas, diagram));
267                 }
268             }
269         });
270
271         ElementFactoryUtil.readParameters(graph, element, e);
272
273         GuardedAsyncProcedureWrapper<IElement> guard = new GuardedAsyncProcedureWrapper<IElement>(procedure, 1);
274         ElementFactoryUtil.readTransform(graph, element, e, guard);
275
276 //        graph.asyncRequest(new SafeName(resource), new ProcedureAdapter<String>() {
277 //            @Override
278 //            public void execute(String result) {
279 //                System.out.println("DefinedElementFactory.load: "  + result);
280 //            }
281 //        });
282     }
283
284 }