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 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;
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;
58 * @author Tuukka Lehtonen
60 * TODO: not merged https://www.simulationsite.net/trac/simantics/changeset/14463/2d/trunk/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java
62 public class DefinedElementFactory extends ElementFactoryAdapter {
64 protected static class ShapeContainer implements Container<Shape> {
66 private IElement element;
67 private Shape shape = null;
69 public ShapeContainer(IElement element) {
70 this.element = element;
76 shape = ElementUtils.getElementShapeOrBounds(element);
85 static class ClassRequest extends BinaryAsyncRead<Resource, ICanvasContext, ElementClass> {
87 final private IDiagram diagram;
89 public ClassRequest(Resource elementType, ICanvasContext canvas, IDiagram diagram) {
90 super(elementType, canvas);
91 this.diagram = diagram;
95 public void perform(AsyncReadGraph graph, AsyncProcedure<ElementClass> procedure) {
97 createzz(graph, parameter2, diagram, parameter, procedure);
104 public void create(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
105 final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
107 graph.asyncRequest(new ClassRequest(elementType, canvas, diagram), new TransientCacheAsyncListener<ElementClass>() {
110 public void exception(AsyncReadGraph graph, Throwable t) {
112 procedure.exception(graph, t);
116 public void execute(AsyncReadGraph graph, ElementClass result) {
117 procedure.execute(graph, result);
124 public static void createzz(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
125 final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
127 final StructuralResource2 sr = graph.getService(StructuralResource2.class);
128 final G2DResource g2d = graph.getService(G2DResource.class);
129 final DiagramResource dr = graph.getService(DiagramResource.class);
131 graph.forSingleObject(elementType, sr.IsDefinedBy, new AsyncProcedure<Resource>() {
134 public void exception(AsyncReadGraph graph, Throwable throwable) {
136 graph.asyncRequest(new SafeName(elementType), new ProcedureAdapter<String>() {
138 public void execute(String result) {
139 System.out.println("DefinedElement '" + result + " ' does not have a single IsDefinedBy relation");
143 procedure.exception(graph, throwable);
148 public void execute(AsyncReadGraph graph, final Resource definingResource) {
150 graph.asyncRequest(new NodeRequest(canvas, diagram, definingResource, null), new TransientCacheAsyncListener<IElement>() {
153 public void exception(AsyncReadGraph graph, Throwable throwable) {
154 throwable.printStackTrace();
158 public void execute(AsyncReadGraph graph, final IElement e) {
160 final CompositeImage img = new CompositeImage(Collections.singletonList(e));
161 final ConcurrentLinkedQueue<ObjectTerminal> terminals = new ConcurrentLinkedQueue<ObjectTerminal>();
162 final AtomicInteger ready = new AtomicInteger(1);
164 graph.forOrderedSet(definingResource, new AsyncMultiProcedure<Resource>() {
167 public void exception(AsyncReadGraph graph, Throwable throwable) {
168 throwable.printStackTrace();
172 public void execute(AsyncReadGraph graph, final Resource r) {
174 ready.incrementAndGet();
176 graph.forIsInstanceOf(r, dr.Terminal, new AsyncProcedure<Boolean>() {
179 public void exception(AsyncReadGraph graph, Throwable throwable) {
180 throwable.printStackTrace();
183 public void execute(AsyncReadGraph graph, Boolean isTerminal) {
186 graph.asyncRequest(new NodeRequest(canvas, diagram, r, null), new TransientCacheAsyncListener<IElement>() {
188 public void exception(AsyncReadGraph graph, Throwable throwable) {
189 throwable.printStackTrace();
193 public void execute(AsyncReadGraph graph, final IElement t) {
194 graph.forPossibleRelatedValue(r, g2d.HasTransform, Bindings.DOUBLE_ARRAY, new AsyncProcedure<double[]>() {
196 public void exception(AsyncReadGraph graph, Throwable throwable) {
197 throwable.printStackTrace();
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)));
221 public void finished(AsyncReadGraph graph) {
225 void worked(AsyncReadGraph graph) {
226 if (ready.decrementAndGet() == 0) {
227 String id = "DefinedElement: " + elementType.getResourceId();
228 procedure.execute(graph, ElementClass.compile(
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
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);
262 graph.asyncRequest(new PossibleAdapter<ElementFactory>(element, ElementFactory.class), new AsyncProcedureAdapter<ElementFactory>() {
264 public void execute(AsyncReadGraph graph, ElementFactory factory) {
265 if (factory != null) {
266 graph.asyncRequest(new GetElementClassRequest(factory, element, canvas, diagram));
271 ElementFactoryUtil.readParameters(graph, element, e);
273 GuardedAsyncProcedureWrapper<IElement> guard = new GuardedAsyncProcedureWrapper<IElement>(procedure, 1);
274 ElementFactoryUtil.readTransform(graph, element, e, guard);
276 // graph.asyncRequest(new SafeName(resource), new ProcedureAdapter<String>() {
278 // public void execute(String result) {
279 // System.out.println("DefinedElementFactory.load: " + result);