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
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
15 import java.util.ArrayList;
\r
16 import java.util.Collection;
\r
17 import java.util.HashSet;
\r
18 import java.util.Set;
\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
40 public class MappedModelingRules extends AbstractModelingRules {
\r
42 IModelingRules baseRules;
\r
45 public MappedModelingRules(IModelingRules baseRules, IMapping mapping) {
\r
47 this.baseRules = baseRules;
\r
48 this.mapping = mapping;
\r
51 public MappedModelingRules(ReadGraph g, IModelingRules baseRules) throws DatabaseException {
\r
52 this(baseRules, new Mapping(g));
\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
61 return baseRules.canPopulate(g, mappedComponentType);
\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
71 if(Policy.DEBUG_STANDARD_MODELING_RULES)
\r
72 System.out.println("setConnectionType(" + NameUtils.getSafeName(g, connection) + ", " + NameUtils.getSafeName(g, connectionType) + ")");
\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
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
88 Resource dcp = g.getPossibleInverse(connects.getPredicate());
\r
90 Resource cp = g.getPossibleObject(dcp, MOD.DiagramConnectionRelationToConnectionRelation);
\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
103 class MappedAttachmentRelationMap implements IAttachmentRelationMap {
\r
105 IAttachmentRelationMap baseMap;
\r
107 public MappedAttachmentRelationMap(IAttachmentRelationMap baseMap) {
\r
108 this.baseMap = baseMap;
\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
123 private ArrayList<IConnectionPoint> getMappedConnectionPoints(ReadGraph g,
\r
124 Collection<IConnectionPoint> connectionPoints)
\r
125 throws DatabaseException {
\r
127 // Map connection points to configuration
\r
128 ArrayList<IConnectionPoint> mappedConnectionPoints =
\r
129 new ArrayList<IConnectionPoint>(connectionPoints.size());
\r
131 // Map connection points to configuration
\r
132 for(IConnectionPoint cp : connectionPoints) {
\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
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
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
150 for(Resource join : g.getObjects(terminal.component, dr.FlagIsJoinedBy))
\r
151 mappedConnectionPoints.add(new CPConnectionJoin(join));
\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
158 // Do nothing, because the flag is not connected
\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
176 return mappedConnectionPoints;
\r
181 public ConnectionJudgement judgeConnection(ReadGraph g, Collection<IConnectionPoint> connectionPoints)
\r
182 throws DatabaseException {
\r
184 ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);
\r
185 if(mappedConnectionPoints == null) return ConnectionJudgement.ILLEGAL;
\r
187 // Judge mapped connection
\r
188 ConnectionJudgement judgement = baseRules.judgeConnection(g, mappedConnectionPoints);
\r
190 // Inverse map attachment relations
\r
191 if(judgement.attachmentRelations != null)
\r
192 judgement.attachmentRelations =
\r
193 new MappedAttachmentRelationMap(judgement.attachmentRelations);
\r
200 public Resource computeConnectionType(ReadGraph g, Collection<IConnectionPoint> connectionPoints) throws DatabaseException {
\r
202 ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);
\r
203 if(mappedConnectionPoints == null) return null;
\r
205 return baseRules.computeConnectionType(g, mappedConnectionPoints);
\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
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
241 throw new IllegalArgumentException("Connection point " + cp + " encountered.");
\r