1 /*******************************************************************************
2 * Copyright (c) 2007, 2014 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
12 *******************************************************************************/
13 package org.simantics.modeling.rules;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.HashSet;
20 import org.simantics.db.ReadGraph;
21 import org.simantics.db.Resource;
22 import org.simantics.db.Statement;
23 import org.simantics.db.WriteGraph;
24 import org.simantics.db.common.utils.NameUtils;
25 import org.simantics.db.exception.DatabaseException;
26 import org.simantics.diagram.stubs.DiagramResource;
27 import org.simantics.modeling.ModelingResources;
28 import org.simantics.structural.stubs.StructuralResource2;
29 import org.simantics.structural2.modelingRules.AbstractModelingRules;
30 import org.simantics.structural2.modelingRules.CPConnection;
31 import org.simantics.structural2.modelingRules.CPConnectionJoin;
32 import org.simantics.structural2.modelingRules.CPIgnore;
33 import org.simantics.structural2.modelingRules.CPTerminal;
34 import org.simantics.structural2.modelingRules.ConnectionJudgement;
35 import org.simantics.structural2.modelingRules.IAttachmentRelationMap;
36 import org.simantics.structural2.modelingRules.IConnectionPoint;
37 import org.simantics.structural2.modelingRules.IModelingRules;
38 import org.simantics.structural2.modelingRules.Policy;
40 public class MappedModelingRules extends AbstractModelingRules {
42 IModelingRules baseRules;
45 public MappedModelingRules(IModelingRules baseRules, IMapping mapping) {
47 this.baseRules = baseRules;
48 this.mapping = mapping;
51 public MappedModelingRules(ReadGraph g, IModelingRules baseRules) throws DatabaseException {
52 this(baseRules, new Mapping(g));
56 public boolean canPopulate(ReadGraph g, Resource componentType)
57 throws DatabaseException {
58 Resource mappedComponentType = mapping.mapComponentType(g, componentType);
59 if(mappedComponentType == null)
61 return baseRules.canPopulate(g, mappedComponentType);
65 public void setConnectionType(WriteGraph g, Resource connection,
66 Resource connectionType) throws DatabaseException {
67 StructuralResource2 sr = StructuralResource2.getInstance(g);
68 DiagramResource DIA = DiagramResource.getInstance(g);
69 ModelingResources MOD = ModelingResources.getInstance(g);
71 if(Policy.DEBUG_STANDARD_MODELING_RULES)
72 System.out.println("setConnectionType(" + NameUtils.getSafeName(g, connection) + ", " + NameUtils.getSafeName(g, connectionType) + ")");
74 RelatedDiagramConnections rdc = new RelatedDiagramConnections(g);
75 rdc.addConnection(connection);
76 for(Resource c : rdc.connections) {
77 g.deny(c, sr.HasConnectionType);
78 g.claim(c, sr.HasConnectionType, null, connectionType);
81 // Fix MOD.HasConnectionMappingSpecification in output connector(s).
82 if (!rdc.outputConnectors.isEmpty()) {
83 Resource requiredConnectionMappingSpecification = g.getPossibleObject(connectionType, MOD.ConnectionTypeToConnectionMappingSpecification);
84 for (Resource connector : rdc.outputConnectors) {
85 for (Statement connects : g.getStatements(connector, sr.Connects)) {
86 if (g.isInstanceOf(connects.getObject(), DIA.Connection))
88 Resource dcp = g.getPossibleInverse(connects.getPredicate());
90 Resource cp = g.getPossibleObject(dcp, MOD.DiagramConnectionRelationToConnectionRelation);
92 g.deny(connector, MOD.HasConnectionMappingSpecification);
93 if (requiredConnectionMappingSpecification != null && g.hasStatement(cp, MOD.NeedsConnectionMappingSpecification)) {
94 g.claim(connector, MOD.HasConnectionMappingSpecification, requiredConnectionMappingSpecification);
103 class MappedAttachmentRelationMap implements IAttachmentRelationMap {
105 IAttachmentRelationMap baseMap;
107 public MappedAttachmentRelationMap(IAttachmentRelationMap baseMap) {
108 this.baseMap = baseMap;
112 public Resource get(ReadGraph g, CPTerminal cp)
113 throws DatabaseException {
114 IConnectionPoint mcp = mapping.mapConnectionPoint(g, cp);
115 if(mcp instanceof CPTerminal)
116 return baseMap.get(g, (CPTerminal)mcp);
123 private ArrayList<IConnectionPoint> getMappedConnectionPoints(ReadGraph g,
124 Collection<IConnectionPoint> connectionPoints)
125 throws DatabaseException {
127 // Map connection points to configuration
128 ArrayList<IConnectionPoint> mappedConnectionPoints =
129 new ArrayList<IConnectionPoint>(connectionPoints.size());
131 // Map connection points to configuration
132 for(IConnectionPoint cp : connectionPoints) {
134 throw new IllegalArgumentException("Null connection point encountered.");
135 if(Policy.DEBUG_STANDARD_MODELING_RULES)
136 System.out.println("Mapping CP: " + cp.toString(g));
137 int mcps = mapping.mapToConnectionPoints(g, cp, mappedConnectionPoints);
139 if(Policy.DEBUG_STANDARD_MODELING_RULES)
140 for (IConnectionPoint mcpt : mappedConnectionPoints.subList(mappedConnectionPoints.size()-mcps, mappedConnectionPoints.size()))
141 System.out.println("Mapped CP: " + mcpt.toString(g));
143 if(cp instanceof CPTerminal) {
144 // TODO move this logic elsewhere
145 CPTerminal terminal = (CPTerminal)cp;
146 DiagramResource dr = DiagramResource.getInstance(g);
147 if(terminal.component != null && g.isInstanceOf(terminal.component, dr.Flag)) {
148 if(g.hasStatement(terminal.component, dr.Flag_ConnectionPoint))
150 for(Resource join : g.getObjects(terminal.component, dr.FlagIsJoinedBy))
151 mappedConnectionPoints.add(new CPConnectionJoin(join));
153 Resource isLiftedAs = g.getPossibleObject(terminal.component, dr.IsLiftedAs);
154 if (isLiftedAs != null) {
155 // This is a lifted flag in a structural configuration.
156 mappedConnectionPoints.add(new CPTerminal(terminal.component, isLiftedAs));
158 // Do nothing, because the flag is not connected
161 } else if (cp instanceof CPConnection) {
162 // Do nothing, because ignored connection points are not
163 // meant to affect modelling rules in any way.
164 //System.out.println("Non-mappable connection " + cp.toString(g));
165 } else if (cp instanceof CPIgnore) {
166 // Do nothing, because ignored connection points are not
167 // meant to affect modelling rules in any way.
168 // FIXME: this is maybe a bit of a hack.
169 //System.out.println("Ignoring " + cp.toString(g));
176 return mappedConnectionPoints;
181 public ConnectionJudgement judgeConnection(ReadGraph g, Collection<IConnectionPoint> connectionPoints)
182 throws DatabaseException {
184 ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);
185 if(mappedConnectionPoints == null) return ConnectionJudgement.ILLEGAL;
187 // Judge mapped connection
188 ConnectionJudgement judgement = baseRules.judgeConnection(g, mappedConnectionPoints);
190 // Inverse map attachment relations
191 if(judgement.attachmentRelations != null)
192 judgement.attachmentRelations =
193 new MappedAttachmentRelationMap(judgement.attachmentRelations);
200 public Resource computeConnectionType(ReadGraph g, Collection<IConnectionPoint> connectionPoints) throws DatabaseException {
202 ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);
203 if(mappedConnectionPoints == null) return null;
205 return baseRules.computeConnectionType(g, mappedConnectionPoints);
210 public IAttachmentRelationMap getAttachmentRelations(ReadGraph g,
211 Resource connection) throws DatabaseException {
212 Resource mappedConnection = mapping.mapConnection(g, connection);
213 if(mappedConnection == null)
214 System.err.println("Connection mapped from " + NameUtils.getSafeName(g, connection, true) + " is null");
215 return new MappedAttachmentRelationMap(
216 baseRules.getAttachmentRelations(g, mappedConnection)
221 public Set<CPTerminal> resolveTerminals(ReadGraph g, Collection<IConnectionPoint> connectionPoints)
222 throws DatabaseException {
223 Set<CPTerminal> terminals = new HashSet<CPTerminal>();
224 StructuralResource2 STR = StructuralResource2.getInstance(g);
225 DiagramResource DIA = DiagramResource.getInstance(g);
226 for(IConnectionPoint cp : connectionPoints) {
227 //System.out.println(this + ": translate connection point: " + cp.toString(g));
228 if(cp instanceof CPTerminal)
229 terminals.add((CPTerminal)cp);
230 else if(cp instanceof CPConnection) {
231 CPConnection connection = (CPConnection)cp;
232 for (Resource connector : g.getObjects(connection.connection, DIA.HasConnector)) {
233 for (Statement stat : g.getStatements(connector, STR.Connects)) {
234 if(stat.getObject().equals(connection.connection)) continue;
235 terminals.add(new CPTerminal(stat.getObject(),
236 g.getInverse(stat.getPredicate())));
241 throw new IllegalArgumentException("Connection point " + cp + " encountered.");