1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.sysdyn.ui.editor;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Arrays;
\r
17 import org.simantics.db.ReadGraph;
\r
18 import org.simantics.db.RequestProcessor;
\r
19 import org.simantics.db.Resource;
\r
20 import org.simantics.db.exception.DatabaseException;
\r
21 import org.simantics.db.request.Read;
\r
22 import org.simantics.diagram.content.ConnectionUtil;
\r
23 import org.simantics.diagram.content.ResourceTerminal;
\r
24 import org.simantics.diagram.stubs.DiagramResource;
\r
25 import org.simantics.g2d.connection.IConnectionAdvisor;
\r
26 import org.simantics.g2d.diagram.handler.Topology.Terminal;
\r
27 import org.simantics.g2d.element.ElementUtils;
\r
28 import org.simantics.g2d.element.IElement;
\r
29 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
\r
30 import org.simantics.structural2.modelingRules.CPIgnore;
\r
31 import org.simantics.structural2.modelingRules.ConnectionJudgement;
\r
32 import org.simantics.structural2.modelingRules.ConnectionJudgementType;
\r
33 import org.simantics.structural2.modelingRules.IConnectionPoint;
\r
34 import org.simantics.structural2.modelingRules.IModelingRules;
\r
35 import org.simantics.sysdyn.SysdynResource;
\r
36 import org.simantics.sysdyn.ui.elements.CloudFactory.CloudSceneGraph;
\r
38 public class SysdynConnectionAdvisor implements IConnectionAdvisor {
\r
40 IModelingRules modelingRules;
\r
41 RequestProcessor processor;
\r
43 public SysdynConnectionAdvisor(IModelingRules modelingRules,
\r
44 RequestProcessor processor) {
\r
45 this.modelingRules = modelingRules;
\r
46 this.processor = processor;
\r
49 IConnectionPoint getConnectionPoint(ReadGraph g, IElement element, Terminal term) throws DatabaseException {
\r
51 if (element != null)
\r
52 obj = ElementUtils.getObject(element);
\r
54 if (obj instanceof Resource) {
\r
55 Resource elementResource = (Resource) obj;
\r
56 return ConnectionUtil.toConnectionPoint(g, elementResource, term);
\r
59 // FIXME: this currently allows connections to begin from flags
\r
60 // but is rather hackish.
\r
61 if(element.getElementClass().containsClass(CloudSceneGraph.class)) {
\r
62 return CPIgnore.NULL_INSTANCE;
\r
69 public Object canBeConnected(Object backend,
\r
70 final IElement element1, final Terminal term1,
\r
71 final IElement element2, final Terminal term2) {
\r
74 backend = processor;
\r
75 return ((RequestProcessor)backend).syncRequest(new Read<Object>() {
\r
78 public Object perform(ReadGraph g) throws DatabaseException {
\r
79 if(element1 != null && term1 != null && element2 != null && term2 != null) {
\r
80 StaticObjectAdapter soa = element1.getElementClass().getSingleItem(StaticObjectAdapter.class);
\r
81 Resource startElementResource = soa.adapt(Resource.class);
\r
82 Object r = ElementUtils.getObject(element2);
\r
83 if(r == null || !(r instanceof Resource))
\r
85 Resource endElementResource = (Resource) r;
\r
87 DiagramResource dr = DiagramResource.getInstance(g);
\r
88 Resource terminal2 = ((ResourceTerminal) term2).getResource();
\r
89 SysdynResource sr = SysdynResource.getInstance(g);
\r
92 // Chech that end terminal has IsHeadOfTerminal relation
\r
93 Resource connectionPoint = g.getPossibleObject(terminal2, dr.HasConnectionPoint);
\r
94 if(connectionPoint == null || !g.isSubrelationOf(connectionPoint, sr.IsHeadOfTerminal)) {
\r
99 // If end element is input symbol, allow only one connection and only from a module
\r
100 if(g.isInstanceOf(endElementResource, sr.InputSymbol)) {
\r
101 if(!g.isInheritedFrom(startElementResource, sr.ModuleSymbol)) return null;
\r
102 if(g.getObjects(endElementResource, sr.IsHeadOfTerminal).size() > 0) return null;
\r
107 ArrayList<IConnectionPoint> cps = new ArrayList<IConnectionPoint>();
\r
108 cps.add(getConnectionPoint(g, element1, term1));
\r
109 if(element2 != null)
\r
110 cps.add(getConnectionPoint(g, element2, term2));
\r
111 ConnectionJudgement judgement =
\r
112 modelingRules.judgeConnection(g, cps);
\r
114 if(judgement.type == ConnectionJudgementType.LEGAL)
\r
121 } catch(DatabaseException e) {
\r
122 e.printStackTrace();
\r
128 public boolean canBeginConnection(Object backend,
\r
129 final IElement element, final Terminal term) {
\r
131 if(backend == null)
\r
132 backend = processor;
\r
133 return ((RequestProcessor)backend).syncRequest(new Read<Boolean>() {
\r
136 public Boolean perform(ReadGraph g) throws DatabaseException {
\r
137 return modelingRules.judgeConnection(g,
\r
138 Arrays.asList(getConnectionPoint(g, element, term)))
\r
139 .type != ConnectionJudgementType.ILLEGAL;
\r
143 } catch(DatabaseException e) {
\r
144 e.printStackTrace();
\r