]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/rules/MappedModelingRules.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / rules / MappedModelingRules.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2014 Association for Decentralized Information Management\r
3  * in 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  *     Semantum Oy - #5290\r
12  *******************************************************************************/\r
13 package org.simantics.modeling.rules;\r
14 \r
15 import java.util.ArrayList;\r
16 import java.util.Collection;\r
17 import java.util.HashSet;\r
18 import java.util.Set;\r
19 \r
20 import org.simantics.db.ReadGraph;\r
21 import org.simantics.db.Resource;\r
22 import org.simantics.db.Statement;\r
23 import org.simantics.db.WriteGraph;\r
24 import org.simantics.db.common.utils.NameUtils;\r
25 import org.simantics.db.exception.DatabaseException;\r
26 import org.simantics.diagram.stubs.DiagramResource;\r
27 import org.simantics.modeling.ModelingResources;\r
28 import org.simantics.structural.stubs.StructuralResource2;\r
29 import org.simantics.structural2.modelingRules.AbstractModelingRules;\r
30 import org.simantics.structural2.modelingRules.CPConnection;\r
31 import org.simantics.structural2.modelingRules.CPConnectionJoin;\r
32 import org.simantics.structural2.modelingRules.CPIgnore;\r
33 import org.simantics.structural2.modelingRules.CPTerminal;\r
34 import org.simantics.structural2.modelingRules.ConnectionJudgement;\r
35 import org.simantics.structural2.modelingRules.IAttachmentRelationMap;\r
36 import org.simantics.structural2.modelingRules.IConnectionPoint;\r
37 import org.simantics.structural2.modelingRules.IModelingRules;\r
38 import org.simantics.structural2.modelingRules.Policy;\r
39 \r
40 public class MappedModelingRules extends AbstractModelingRules {\r
41 \r
42     IModelingRules baseRules;\r
43     IMapping mapping;\r
44 \r
45     public MappedModelingRules(IModelingRules baseRules, IMapping mapping) {\r
46         super();\r
47         this.baseRules = baseRules;\r
48         this.mapping = mapping;\r
49     }\r
50 \r
51     public MappedModelingRules(ReadGraph g, IModelingRules baseRules) throws DatabaseException {\r
52         this(baseRules, new Mapping(g));\r
53     }\r
54 \r
55     @Override\r
56     public boolean canPopulate(ReadGraph g, Resource componentType)\r
57     throws DatabaseException {\r
58         Resource mappedComponentType = mapping.mapComponentType(g, componentType);\r
59         if(mappedComponentType == null)\r
60             return false;\r
61         return baseRules.canPopulate(g, mappedComponentType);\r
62     }\r
63 \r
64     @Override\r
65     public void setConnectionType(WriteGraph g, Resource connection,\r
66             Resource connectionType) throws DatabaseException {\r
67         StructuralResource2 sr = StructuralResource2.getInstance(g);\r
68         DiagramResource DIA = DiagramResource.getInstance(g); \r
69         ModelingResources MOD = ModelingResources.getInstance(g);\r
70 \r
71         if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
72             System.out.println("setConnectionType(" + NameUtils.getSafeName(g, connection) + ", " + NameUtils.getSafeName(g, connectionType) + ")");\r
73 \r
74         RelatedDiagramConnections rdc = new RelatedDiagramConnections(g);\r
75         rdc.addConnection(connection);\r
76         for(Resource c : rdc.connections) {\r
77             g.deny(c, sr.HasConnectionType);\r
78             g.claim(c, sr.HasConnectionType, null, connectionType);\r
79         }\r
80 \r
81         // Fix MOD.HasConnectionMappingSpecification in output connector(s).\r
82         if (!rdc.outputConnectors.isEmpty()) {\r
83             Resource requiredConnectionMappingSpecification = g.getPossibleObject(connectionType, MOD.ConnectionTypeToConnectionMappingSpecification);\r
84             for (Resource connector : rdc.outputConnectors) {\r
85                 for (Statement connects : g.getStatements(connector, sr.Connects)) {\r
86                     if (g.isInstanceOf(connects.getObject(), DIA.Connection))\r
87                         continue;\r
88                     Resource dcp  = g.getPossibleInverse(connects.getPredicate());\r
89                     if (dcp != null) {\r
90                         Resource cp = g.getPossibleObject(dcp, MOD.DiagramConnectionRelationToConnectionRelation);\r
91                         if (cp != null) {\r
92                             g.deny(connector, MOD.HasConnectionMappingSpecification);\r
93                             if (requiredConnectionMappingSpecification != null && g.hasStatement(cp, MOD.NeedsConnectionMappingSpecification)) {\r
94                                 g.claim(connector, MOD.HasConnectionMappingSpecification, requiredConnectionMappingSpecification);\r
95                             }\r
96                         }\r
97                     }\r
98                 }\r
99             }\r
100         }\r
101     }\r
102 \r
103     class MappedAttachmentRelationMap implements IAttachmentRelationMap {\r
104 \r
105         IAttachmentRelationMap baseMap;\r
106 \r
107         public MappedAttachmentRelationMap(IAttachmentRelationMap baseMap) {\r
108             this.baseMap = baseMap;\r
109         }\r
110 \r
111         @Override\r
112         public Resource get(ReadGraph g, CPTerminal cp)\r
113         throws DatabaseException {\r
114             IConnectionPoint mcp = mapping.mapConnectionPoint(g, cp);\r
115             if(mcp instanceof CPTerminal)\r
116                 return baseMap.get(g, (CPTerminal)mcp);\r
117             else\r
118                 return null;\r
119         }\r
120 \r
121     }\r
122     \r
123     private ArrayList<IConnectionPoint> getMappedConnectionPoints(ReadGraph g,\r
124                 Collection<IConnectionPoint> connectionPoints)\r
125                             throws DatabaseException {\r
126 \r
127         // Map connection points to configuration\r
128         ArrayList<IConnectionPoint> mappedConnectionPoints =\r
129                 new ArrayList<IConnectionPoint>(connectionPoints.size());\r
130         \r
131          // Map connection points to configuration\r
132         for(IConnectionPoint cp : connectionPoints) {\r
133             if(cp == null)\r
134                 throw new IllegalArgumentException("Null connection point encountered.");\r
135             if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
136                 System.out.println("Mapping CP: " + cp.toString(g));\r
137             int mcps = mapping.mapToConnectionPoints(g, cp, mappedConnectionPoints);\r
138             if(mcps > 0) {\r
139                 if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
140                     for (IConnectionPoint mcpt : mappedConnectionPoints.subList(mappedConnectionPoints.size()-mcps, mappedConnectionPoints.size()))\r
141                         System.out.println("Mapped CP: " + mcpt.toString(g));\r
142             } else {\r
143                 if(cp instanceof CPTerminal) {\r
144                     // TODO move this logic elsewhere\r
145                     CPTerminal terminal = (CPTerminal)cp;\r
146                     DiagramResource dr = DiagramResource.getInstance(g);\r
147                     if(terminal.component != null && g.isInstanceOf(terminal.component, dr.Flag)) {\r
148                         if(g.hasStatement(terminal.component, dr.Flag_ConnectionPoint))\r
149                             return null;\r
150                         for(Resource join : g.getObjects(terminal.component, dr.FlagIsJoinedBy))\r
151                             mappedConnectionPoints.add(new CPConnectionJoin(join));\r
152                         \r
153                         Resource isLiftedAs = g.getPossibleObject(terminal.component, dr.IsLiftedAs);\r
154                         if (isLiftedAs != null) {\r
155                             // This is a lifted flag in a structural configuration.\r
156                             mappedConnectionPoints.add(new CPTerminal(terminal.component, isLiftedAs));\r
157                         } else {\r
158                             // Do nothing, because the flag is not connected\r
159                         }\r
160                     }\r
161                 } else if (cp instanceof CPConnection) {\r
162                     // Do nothing, because ignored connection points are not\r
163                     // meant to affect modelling rules in any way.\r
164                     //System.out.println("Non-mappable connection " + cp.toString(g));\r
165                 } else if (cp instanceof CPIgnore) {\r
166                     // Do nothing, because ignored connection points are not\r
167                     // meant to affect modelling rules in any way.\r
168                     // FIXME: this is maybe a bit of a hack.\r
169                     //System.out.println("Ignoring " + cp.toString(g));\r
170                 }\r
171                 else\r
172                     return null;\r
173             }\r
174         }\r
175         \r
176         return mappedConnectionPoints;\r
177         \r
178     }\r
179     \r
180     @Override\r
181     public ConnectionJudgement judgeConnection(ReadGraph g, Collection<IConnectionPoint> connectionPoints)\r
182                 throws DatabaseException {\r
183 \r
184         ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);\r
185         if(mappedConnectionPoints == null) return ConnectionJudgement.ILLEGAL; \r
186 \r
187         // Judge mapped connection\r
188         ConnectionJudgement judgement = baseRules.judgeConnection(g, mappedConnectionPoints);\r
189 \r
190         // Inverse map attachment relations\r
191         if(judgement.attachmentRelations != null)\r
192             judgement.attachmentRelations =\r
193                 new MappedAttachmentRelationMap(judgement.attachmentRelations);\r
194 \r
195         return judgement;\r
196         \r
197     }\r
198     \r
199     @Override\r
200     public Resource computeConnectionType(ReadGraph g, Collection<IConnectionPoint> connectionPoints) throws DatabaseException {\r
201         \r
202         ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);\r
203         if(mappedConnectionPoints == null) return null;\r
204         \r
205         return baseRules.computeConnectionType(g, mappedConnectionPoints);\r
206         \r
207     }\r
208 \r
209     @Override\r
210     public IAttachmentRelationMap getAttachmentRelations(ReadGraph g,\r
211             Resource connection) throws DatabaseException {\r
212         Resource mappedConnection = mapping.mapConnection(g, connection);\r
213         if(mappedConnection == null)\r
214             System.err.println("Connection mapped from " + NameUtils.getSafeName(g, connection, true) + " is null");\r
215         return new MappedAttachmentRelationMap(\r
216                 baseRules.getAttachmentRelations(g, mappedConnection)\r
217         );\r
218     }\r
219     \r
220         @Override\r
221         public Set<CPTerminal> resolveTerminals(ReadGraph g, Collection<IConnectionPoint> connectionPoints) \r
222                         throws DatabaseException {\r
223                 Set<CPTerminal> terminals = new HashSet<CPTerminal>();\r
224                 StructuralResource2 STR = StructuralResource2.getInstance(g);\r
225                 DiagramResource DIA = DiagramResource.getInstance(g);\r
226                 for(IConnectionPoint cp : connectionPoints) {\r
227                         //System.out.println(this + ": translate connection point: " + cp.toString(g));\r
228                         if(cp instanceof CPTerminal)\r
229                                 terminals.add((CPTerminal)cp);\r
230                         else if(cp instanceof CPConnection) {\r
231                                 CPConnection connection = (CPConnection)cp;\r
232                                 for (Resource connector : g.getObjects(connection.connection, DIA.HasConnector)) {\r
233                                         for (Statement stat : g.getStatements(connector, STR.Connects)) {\r
234                                                 if(stat.getObject().equals(connection.connection)) continue;\r
235                                                 terminals.add(new CPTerminal(stat.getObject(),\r
236                                                                 g.getInverse(stat.getPredicate())));\r
237                                         }\r
238                                 }\r
239                         }\r
240                         else\r
241                                 throw new IllegalArgumentException("Connection point " + cp + " encountered.");\r
242                 }\r
243                 return terminals;\r
244         }\r
245 \r
246 }\r