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.procedure.adapter.ProcedureAdapter;
24 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
25 import org.simantics.db.common.procedure.guarded.GuardedAsyncProcedureWrapper;
26 import org.simantics.db.common.request.BinaryAsyncRead;
27 import org.simantics.db.common.request.SafeName;
28 import org.simantics.db.procedure.AsyncMultiProcedure;
29 import org.simantics.db.procedure.AsyncProcedure;
30 import org.simantics.diagram.content.ResourceTerminal;
31 import org.simantics.diagram.stubs.DiagramResource;
32 import org.simantics.diagram.stubs.G2DResource;
33 import org.simantics.diagram.synchronization.SynchronizationHints;
34 import org.simantics.diagram.synchronization.graph.TransformSynchronizer;
35 import org.simantics.g2d.canvas.ICanvasContext;
36 import org.simantics.g2d.diagram.IDiagram;
37 import org.simantics.g2d.element.ElementClass;
38 import org.simantics.g2d.element.ElementUtils;
39 import org.simantics.g2d.element.IElement;
40 import org.simantics.g2d.element.handler.impl.DefaultTransform;
41 import org.simantics.g2d.element.handler.impl.ObjectTerminal;
42 import org.simantics.g2d.element.handler.impl.SimpleElementLayers;
43 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
44 import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;
45 import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;
46 import org.simantics.g2d.element.handler.impl.Terminals;
47 import org.simantics.g2d.element.handler.impl.TextImpl;
48 import org.simantics.g2d.elementclass.ImageClass;
49 import org.simantics.g2d.elementclass.PlainElementPropertySetter;
50 import org.simantics.g2d.tooltip.TerminalTooltipProvider;
51 import org.simantics.g2d.tooltip.TooltipParticipant;
52 import org.simantics.g2d.utils.geom.DirectionSet;
53 import org.simantics.structural.stubs.StructuralResource2;
54 import org.simantics.utils.Container;
57 * @author Tuukka Lehtonen
59 * TODO: not merged https://www.simulationsite.net/trac/simantics/changeset/14463/2d/trunk/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java
61 public class DefinedElementFactory extends ElementFactoryAdapter {
63 protected static class ShapeContainer implements Container<Shape> {
65 private IElement element;
66 private Shape shape = null;
68 public ShapeContainer(IElement element) {
69 this.element = element;
75 shape = ElementUtils.getElementShapeOrBounds(element);
84 static class ClassRequest extends BinaryAsyncRead<Resource, ICanvasContext, ElementClass> {
86 final private IDiagram diagram;
88 public ClassRequest(Resource elementType, ICanvasContext canvas, IDiagram diagram) {
89 super(elementType, canvas);
90 this.diagram = diagram;
94 public void perform(AsyncReadGraph graph, AsyncProcedure<ElementClass> procedure) {
96 createzz(graph, parameter2, diagram, parameter, procedure);
103 public void create(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
104 final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
106 graph.asyncRequest(new ClassRequest(elementType, canvas, diagram), new TransientCacheAsyncListener<ElementClass>() {
109 public void exception(AsyncReadGraph graph, Throwable t) {
111 procedure.exception(graph, t);
115 public void execute(AsyncReadGraph graph, ElementClass result) {
116 procedure.execute(graph, result);
123 public static void createzz(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
124 final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
126 final StructuralResource2 sr = graph.getService(StructuralResource2.class);
127 final G2DResource g2d = graph.getService(G2DResource.class);
128 final DiagramResource dr = graph.getService(DiagramResource.class);
130 graph.forSingleObject(elementType, sr.IsDefinedBy, new AsyncProcedure<Resource>() {
133 public void exception(AsyncReadGraph graph, Throwable throwable) {
135 graph.asyncRequest(new SafeName(elementType), new ProcedureAdapter<String>() {
137 public void execute(String result) {
138 System.out.println("DefinedElement '" + result + " ' does not have a single IsDefinedBy relation");
142 procedure.exception(graph, throwable);
147 public void execute(AsyncReadGraph graph, final Resource definingResource) {
149 graph.asyncRequest(new NodeRequest(canvas, diagram, definingResource, null), new TransientCacheAsyncListener<IElement>() {
152 public void exception(AsyncReadGraph graph, Throwable throwable) {
153 throwable.printStackTrace();
157 public void execute(AsyncReadGraph graph, final IElement e) {
159 final CompositeImage img = new CompositeImage(Collections.singletonList(e));
160 final ConcurrentLinkedQueue<ObjectTerminal> terminals = new ConcurrentLinkedQueue<ObjectTerminal>();
161 final AtomicInteger ready = new AtomicInteger(1);
163 graph.forOrderedSet(definingResource, new AsyncMultiProcedure<Resource>() {
166 public void exception(AsyncReadGraph graph, Throwable throwable) {
167 throwable.printStackTrace();
171 public void execute(AsyncReadGraph graph, final Resource r) {
173 ready.incrementAndGet();
175 graph.forIsInstanceOf(r, dr.Terminal, new AsyncProcedure<Boolean>() {
178 public void exception(AsyncReadGraph graph, Throwable throwable) {
179 throwable.printStackTrace();
182 public void execute(AsyncReadGraph graph, Boolean isTerminal) {
185 graph.asyncRequest(new NodeRequest(canvas, diagram, r, null), new TransientCacheAsyncListener<IElement>() {
187 public void exception(AsyncReadGraph graph, Throwable throwable) {
188 throwable.printStackTrace();
192 public void execute(AsyncReadGraph graph, final IElement t) {
193 graph.forPossibleRelatedValue(r, g2d.HasTransform, Bindings.DOUBLE_ARRAY, new AsyncProcedure<double[]>() {
195 public void exception(AsyncReadGraph graph, Throwable throwable) {
196 throwable.printStackTrace();
200 public void execute(AsyncReadGraph graph, double[] mat) {
201 AffineTransform tr = mat != null ? new AffineTransform(mat) : new AffineTransform();
202 terminals.add(new ResourceTerminal(r, tr, DirectionSet.ANY, new ShapeContainer(t)));
220 public void finished(AsyncReadGraph graph) {
224 void worked(AsyncReadGraph graph) {
225 if (ready.decrementAndGet() == 0) {
226 String id = "DefinedElement: " + elementType.getResourceId();
227 procedure.execute(graph, ElementClass.compile(
229 new StaticObjectAdapter(elementType),
230 DefaultTransform.INSTANCE,
231 StaticSymbolImageInitializer.INSTANCE,
232 new StaticSymbolImpl(img),
233 DefinedElementHandler.INSTANCE,
234 new DefinedElementTerminals(terminals),
235 SimpleElementLayers.INSTANCE,
236 PlainElementPropertySetter.INSTANCE
253 public void load(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e, final AsyncProcedure<IElement> procedure) {
254 e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, TransformSynchronizer.INSTANCE);
255 // FIXME : this just adds test tooltip to the element.
256 //e.setHint(TooltipParticipant.TOOLTIP_KEY, DefinedElementTooltipProvider.INSTANCE);
257 // This is needed for terminal tooltips.
258 e.setHint(TooltipParticipant.TOOLTIP_KEY, TerminalTooltipProvider.INSTANCE);
260 GuardedAsyncProcedureWrapper<IElement> guard = new GuardedAsyncProcedureWrapper<IElement>(procedure, 1);
261 ElementFactoryUtil.readTransform(graph, element, e, guard);
263 // graph.asyncRequest(new SafeName(resource), new ProcedureAdapter<String>() {
265 // public void execute(String result) {
266 // System.out.println("DefinedElementFactory.load: " + result);