--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2014 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ * Semantum Oy - #5290\r
+ *******************************************************************************/\r
+package org.simantics.modeling.rules;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.structural2.modelingRules.AbstractModelingRules;\r
+import org.simantics.structural2.modelingRules.CPConnection;\r
+import org.simantics.structural2.modelingRules.CPConnectionJoin;\r
+import org.simantics.structural2.modelingRules.CPIgnore;\r
+import org.simantics.structural2.modelingRules.CPTerminal;\r
+import org.simantics.structural2.modelingRules.ConnectionJudgement;\r
+import org.simantics.structural2.modelingRules.IAttachmentRelationMap;\r
+import org.simantics.structural2.modelingRules.IConnectionPoint;\r
+import org.simantics.structural2.modelingRules.IModelingRules;\r
+import org.simantics.structural2.modelingRules.Policy;\r
+\r
+public class MappedModelingRules extends AbstractModelingRules {\r
+\r
+ IModelingRules baseRules;\r
+ IMapping mapping;\r
+\r
+ public MappedModelingRules(IModelingRules baseRules, IMapping mapping) {\r
+ super();\r
+ this.baseRules = baseRules;\r
+ this.mapping = mapping;\r
+ }\r
+\r
+ public MappedModelingRules(ReadGraph g, IModelingRules baseRules) throws DatabaseException {\r
+ this(baseRules, new Mapping(g));\r
+ }\r
+\r
+ @Override\r
+ public boolean canPopulate(ReadGraph g, Resource componentType)\r
+ throws DatabaseException {\r
+ Resource mappedComponentType = mapping.mapComponentType(g, componentType);\r
+ if(mappedComponentType == null)\r
+ return false;\r
+ return baseRules.canPopulate(g, mappedComponentType);\r
+ }\r
+\r
+ @Override\r
+ public void setConnectionType(WriteGraph g, Resource connection,\r
+ Resource connectionType) throws DatabaseException {\r
+ StructuralResource2 sr = StructuralResource2.getInstance(g);\r
+ DiagramResource DIA = DiagramResource.getInstance(g); \r
+ ModelingResources MOD = ModelingResources.getInstance(g);\r
+\r
+ if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
+ System.out.println("setConnectionType(" + NameUtils.getSafeName(g, connection) + ", " + NameUtils.getSafeName(g, connectionType) + ")");\r
+\r
+ RelatedDiagramConnections rdc = new RelatedDiagramConnections(g);\r
+ rdc.addConnection(connection);\r
+ for(Resource c : rdc.connections) {\r
+ g.deny(c, sr.HasConnectionType);\r
+ g.claim(c, sr.HasConnectionType, null, connectionType);\r
+ }\r
+\r
+ // Fix MOD.HasConnectionMappingSpecification in output connector(s).\r
+ if (!rdc.outputConnectors.isEmpty()) {\r
+ Resource requiredConnectionMappingSpecification = g.getPossibleObject(connectionType, MOD.ConnectionTypeToConnectionMappingSpecification);\r
+ for (Resource connector : rdc.outputConnectors) {\r
+ for (Statement connects : g.getStatements(connector, sr.Connects)) {\r
+ if (g.isInstanceOf(connects.getObject(), DIA.Connection))\r
+ continue;\r
+ Resource dcp = g.getPossibleInverse(connects.getPredicate());\r
+ if (dcp != null) {\r
+ Resource cp = g.getPossibleObject(dcp, MOD.DiagramConnectionRelationToConnectionRelation);\r
+ if (cp != null) {\r
+ g.deny(connector, MOD.HasConnectionMappingSpecification);\r
+ if (requiredConnectionMappingSpecification != null && g.hasStatement(cp, MOD.NeedsConnectionMappingSpecification)) {\r
+ g.claim(connector, MOD.HasConnectionMappingSpecification, requiredConnectionMappingSpecification);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ class MappedAttachmentRelationMap implements IAttachmentRelationMap {\r
+\r
+ IAttachmentRelationMap baseMap;\r
+\r
+ public MappedAttachmentRelationMap(IAttachmentRelationMap baseMap) {\r
+ this.baseMap = baseMap;\r
+ }\r
+\r
+ @Override\r
+ public Resource get(ReadGraph g, CPTerminal cp)\r
+ throws DatabaseException {\r
+ IConnectionPoint mcp = mapping.mapConnectionPoint(g, cp);\r
+ if(mcp instanceof CPTerminal)\r
+ return baseMap.get(g, (CPTerminal)mcp);\r
+ else\r
+ return null;\r
+ }\r
+\r
+ }\r
+ \r
+ private ArrayList<IConnectionPoint> getMappedConnectionPoints(ReadGraph g,\r
+ Collection<IConnectionPoint> connectionPoints)\r
+ throws DatabaseException {\r
+\r
+ // Map connection points to configuration\r
+ ArrayList<IConnectionPoint> mappedConnectionPoints =\r
+ new ArrayList<IConnectionPoint>(connectionPoints.size());\r
+ \r
+ // Map connection points to configuration\r
+ for(IConnectionPoint cp : connectionPoints) {\r
+ if(cp == null)\r
+ throw new IllegalArgumentException("Null connection point encountered.");\r
+ if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
+ System.out.println("Mapping CP: " + cp.toString(g));\r
+ int mcps = mapping.mapToConnectionPoints(g, cp, mappedConnectionPoints);\r
+ if(mcps > 0) {\r
+ if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
+ for (IConnectionPoint mcpt : mappedConnectionPoints.subList(mappedConnectionPoints.size()-mcps, mappedConnectionPoints.size()))\r
+ System.out.println("Mapped CP: " + mcpt.toString(g));\r
+ } else {\r
+ if(cp instanceof CPTerminal) {\r
+ // TODO move this logic elsewhere\r
+ CPTerminal terminal = (CPTerminal)cp;\r
+ DiagramResource dr = DiagramResource.getInstance(g);\r
+ if(terminal.component != null && g.isInstanceOf(terminal.component, dr.Flag)) {\r
+ if(g.hasStatement(terminal.component, dr.Flag_ConnectionPoint))\r
+ return null;\r
+ for(Resource join : g.getObjects(terminal.component, dr.FlagIsJoinedBy))\r
+ mappedConnectionPoints.add(new CPConnectionJoin(join));\r
+ \r
+ Resource isLiftedAs = g.getPossibleObject(terminal.component, dr.IsLiftedAs);\r
+ if (isLiftedAs != null) {\r
+ // This is a lifted flag in a structural configuration.\r
+ mappedConnectionPoints.add(new CPTerminal(terminal.component, isLiftedAs));\r
+ } else {\r
+ // Do nothing, because the flag is not connected\r
+ }\r
+ }\r
+ } else if (cp instanceof CPConnection) {\r
+ // Do nothing, because ignored connection points are not\r
+ // meant to affect modelling rules in any way.\r
+ //System.out.println("Non-mappable connection " + cp.toString(g));\r
+ } else if (cp instanceof CPIgnore) {\r
+ // Do nothing, because ignored connection points are not\r
+ // meant to affect modelling rules in any way.\r
+ // FIXME: this is maybe a bit of a hack.\r
+ //System.out.println("Ignoring " + cp.toString(g));\r
+ }\r
+ else\r
+ return null;\r
+ }\r
+ }\r
+ \r
+ return mappedConnectionPoints;\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public ConnectionJudgement judgeConnection(ReadGraph g, Collection<IConnectionPoint> connectionPoints)\r
+ throws DatabaseException {\r
+\r
+ ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);\r
+ if(mappedConnectionPoints == null) return ConnectionJudgement.ILLEGAL; \r
+\r
+ // Judge mapped connection\r
+ ConnectionJudgement judgement = baseRules.judgeConnection(g, mappedConnectionPoints);\r
+\r
+ // Inverse map attachment relations\r
+ if(judgement.attachmentRelations != null)\r
+ judgement.attachmentRelations =\r
+ new MappedAttachmentRelationMap(judgement.attachmentRelations);\r
+\r
+ return judgement;\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public Resource computeConnectionType(ReadGraph g, Collection<IConnectionPoint> connectionPoints) throws DatabaseException {\r
+ \r
+ ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);\r
+ if(mappedConnectionPoints == null) return null;\r
+ \r
+ return baseRules.computeConnectionType(g, mappedConnectionPoints);\r
+ \r
+ }\r
+\r
+ @Override\r
+ public IAttachmentRelationMap getAttachmentRelations(ReadGraph g,\r
+ Resource connection) throws DatabaseException {\r
+ Resource mappedConnection = mapping.mapConnection(g, connection);\r
+ if(mappedConnection == null)\r
+ System.err.println("Connection mapped from " + NameUtils.getSafeName(g, connection, true) + " is null");\r
+ return new MappedAttachmentRelationMap(\r
+ baseRules.getAttachmentRelations(g, mappedConnection)\r
+ );\r
+ }\r
+ \r
+ @Override\r
+ public Set<CPTerminal> resolveTerminals(ReadGraph g, Collection<IConnectionPoint> connectionPoints) \r
+ throws DatabaseException {\r
+ Set<CPTerminal> terminals = new HashSet<CPTerminal>();\r
+ StructuralResource2 STR = StructuralResource2.getInstance(g);\r
+ DiagramResource DIA = DiagramResource.getInstance(g);\r
+ for(IConnectionPoint cp : connectionPoints) {\r
+ //System.out.println(this + ": translate connection point: " + cp.toString(g));\r
+ if(cp instanceof CPTerminal)\r
+ terminals.add((CPTerminal)cp);\r
+ else if(cp instanceof CPConnection) {\r
+ CPConnection connection = (CPConnection)cp;\r
+ for (Resource connector : g.getObjects(connection.connection, DIA.HasConnector)) {\r
+ for (Statement stat : g.getStatements(connector, STR.Connects)) {\r
+ if(stat.getObject().equals(connection.connection)) continue;\r
+ terminals.add(new CPTerminal(stat.getObject(),\r
+ g.getInverse(stat.getPredicate())));\r
+ }\r
+ }\r
+ }\r
+ else\r
+ throw new IllegalArgumentException("Connection point " + cp + " encountered.");\r
+ }\r
+ return terminals;\r
+ }\r
+\r
+}\r