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.connection;
14 import java.util.ArrayList;
15 import java.util.Arrays;
17 import org.simantics.db.ReadGraph;
18 import org.simantics.db.RequestProcessor;
19 import org.simantics.db.Resource;
20 import org.simantics.db.Session;
21 import org.simantics.db.exception.DatabaseException;
22 import org.simantics.db.request.Read;
23 import org.simantics.diagram.content.ConnectionUtil;
24 import org.simantics.g2d.connection.IConnectionAdvisor;
25 import org.simantics.g2d.diagram.handler.Topology.Terminal;
26 import org.simantics.g2d.element.ElementUtils;
27 import org.simantics.g2d.element.IElement;
28 import org.simantics.g2d.elementclass.FlagHandler;
29 import org.simantics.structural2.modelingRules.CPIgnore;
30 import org.simantics.structural2.modelingRules.ConnectionJudgement;
31 import org.simantics.structural2.modelingRules.ConnectionJudgementType;
32 import org.simantics.structural2.modelingRules.IConnectionPoint;
33 import org.simantics.structural2.modelingRules.IModelingRules;
36 * To customize, prefer overriding
37 * {@link #canBeConnected(ReadGraph, IElement, Terminal, IElement, Terminal)}
38 * and {@link #canBeginConnection(ReadGraph, IElement, Terminal)}.
40 * @author Hannu Niemistö
42 public class ModelledConnectionAdvisor implements IConnectionAdvisor {
44 protected IModelingRules modelingRules;
45 protected Session session;
48 * @param modelingRules
51 public ModelledConnectionAdvisor(IModelingRules modelingRules,
53 this.modelingRules = modelingRules;
54 this.session = session;
57 protected IConnectionPoint getConnectionPoint(ReadGraph g, IElement element, Terminal term) throws DatabaseException {
58 return getConnectionPoint(g, element, term, false);
61 protected IConnectionPoint getConnectionPoint(ReadGraph g, IElement element, Terminal term, boolean ignoreUnrecognized) throws DatabaseException {
64 obj = ElementUtils.getObject(element);
66 if (obj instanceof Resource) {
67 Resource elementResource = (Resource) obj;
68 return ConnectionUtil.toConnectionPoint(g, elementResource, term);
71 // FIXME: this currently allows connections to begin from flags
72 // but is rather hackish.
73 if (element.getElementClass().containsClass(FlagHandler.class)) {
74 return CPIgnore.NULL_INSTANCE;
77 if (ignoreUnrecognized)
78 return CPIgnore.NULL_INSTANCE;
80 throw new IllegalArgumentException("Cannot get IConnectionPoint for (element,terminal) pair:\n\t" + element + "\n\t" + term);
84 public Object canBeConnected(Object backend,
85 final IElement element1, final Terminal term1,
86 final IElement element2, final Terminal term2) {
90 return ((RequestProcessor)backend).syncRequest(new Read<Object>() {
92 public Object perform(ReadGraph g) throws DatabaseException {
93 return canBeConnected(g, element1, term1, element2, term2);
96 } catch(DatabaseException e) {
103 public boolean canBeginConnection(Object backend,
104 final IElement element, final Terminal term) {
108 return ((RequestProcessor)backend).syncRequest(new Read<Boolean>() {
110 public Boolean perform(ReadGraph g) throws DatabaseException {
111 return canBeginConnection(g, element, term);
114 } catch (DatabaseException e) {
120 protected Object canBeConnected(ReadGraph graph,
121 IElement element1, Terminal term1,
122 IElement element2, Terminal term2) throws DatabaseException {
123 ArrayList<IConnectionPoint> cps = new ArrayList<IConnectionPoint>(2);
124 if (element1 != null)
125 cps.add(getConnectionPoint(graph, element1, term1, true));
126 if (element2 != null)
127 cps.add(getConnectionPoint(graph, element2, term2, true));
129 ConnectionJudgement judgement = modelingRules.judgeConnection(graph, cps);
130 if (judgement.type == ConnectionJudgementType.LEGAL
131 // #6751, Apros #12404: a connection should not be automatically
132 // denied just because it is not perfectly legal. Further legality
133 // should be decided on the client side even though the IConnectionAdvisor
134 // interface is not documented to return ConnectionJudgement instances,
135 // because the interface knows nothing about this class.
136 || judgement.type == ConnectionJudgementType.CANBEMADELEGAL)
141 protected boolean canBeginConnection(ReadGraph graph,
142 IElement element, Terminal term) throws DatabaseException {
143 return modelingRules.judgeConnection(graph,
144 Arrays.asList(getConnectionPoint(graph, element, term)))
145 .type != ConnectionJudgementType.ILLEGAL;