]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
ffcfd38ee6f988ac485aadbbdc8cca6fee3fee9e
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2010 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.sysdyn.ui.editor;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Arrays;\r
16 \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
37 \r
38 public class SysdynConnectionAdvisor  implements IConnectionAdvisor {\r
39 \r
40         IModelingRules modelingRules;\r
41         RequestProcessor processor;\r
42 \r
43         public SysdynConnectionAdvisor(IModelingRules modelingRules,\r
44                         RequestProcessor processor) {\r
45                 this.modelingRules = modelingRules;\r
46                 this.processor = processor;\r
47         }\r
48 \r
49         IConnectionPoint getConnectionPoint(ReadGraph g, IElement element, Terminal term) throws DatabaseException {\r
50                 Object obj = null;\r
51                 if (element != null)\r
52                         obj = ElementUtils.getObject(element);\r
53 \r
54                 if (obj instanceof Resource) {\r
55                         Resource elementResource = (Resource) obj;\r
56                         return ConnectionUtil.toConnectionPoint(g, elementResource, term);\r
57                 }\r
58 \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
63                 }\r
64 \r
65                 return null;\r
66         }\r
67 \r
68         @Override\r
69         public Object canBeConnected(Object backend,\r
70                         final IElement element1, final Terminal term1,\r
71                         final IElement element2, final Terminal term2) {\r
72                 try {\r
73                         if(backend == null)\r
74                                 backend = processor;\r
75                         return ((RequestProcessor)backend).syncRequest(new Read<Object>() {\r
76 \r
77                                 @Override\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
84                                                     return null;\r
85                                                 Resource endElementResource = (Resource) r;\r
86                                                 \r
87                                                 DiagramResource dr = DiagramResource.getInstance(g);\r
88                                                 Resource terminal2 = ((ResourceTerminal) term2).getResource();\r
89                                                 SysdynResource sr = SysdynResource.getInstance(g);\r
90                                                 \r
91                                                 \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
95                             return null;\r
96                         }\r
97 \r
98                                                 \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
103                                                 }\r
104                                                 \r
105                                         }\r
106 \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
113 \r
114                                         if(judgement.type == ConnectionJudgementType.LEGAL)\r
115                                                 return judgement;\r
116                                         else\r
117                                                 return null;\r
118                                 }\r
119 \r
120                         });\r
121                 } catch(DatabaseException e) {\r
122                         e.printStackTrace();\r
123                         return null;\r
124                 }\r
125         }\r
126 \r
127         @Override\r
128         public boolean canBeginConnection(Object backend,\r
129                         final IElement element, final Terminal term) {\r
130                 try {\r
131                         if(backend == null)\r
132                                 backend = processor;\r
133                         return ((RequestProcessor)backend).syncRequest(new Read<Boolean>() {\r
134 \r
135                                 @Override\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
140                                 }\r
141 \r
142                         });\r
143                 } catch(DatabaseException e) {\r
144                         e.printStackTrace();\r
145                         return false;\r
146                 }\r
147         }\r
148 \r
149 }\r