-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 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
- *******************************************************************************/\r
-package org.simantics.modeling.mapping;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-\r
-import org.simantics.Simantics;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.layer0.utils.binaryPredicates.BinaryPredicateAdapter;\r
-import org.simantics.layer0.utils.binaryPredicates.IBinaryPredicate;\r
-import org.simantics.layer0.utils.binaryPredicates.InversePredicate;\r
-import org.simantics.layer0.utils.binaryPredicates.OrderedSetElementsPredicate;\r
-import org.simantics.layer0.utils.predicates.IUnaryPredicate;\r
-import org.simantics.layer0.utils.predicates.Negation;\r
-import org.simantics.layer0.utils.predicates.Type;\r
-import org.simantics.layer0.utils.predicates.UnaryTest;\r
-import org.simantics.layer0.utils.triggers.IModification;\r
-import org.simantics.mapping.constraint.instructions.IInstruction;\r
-import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction;\r
-import org.simantics.mapping.rule.instructions.IRuleInstruction;\r
-import org.simantics.modeling.ComponentUtils;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.operation.Layer0X;\r
-import org.simantics.project.IProject;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-import org.simantics.utils.ObjectUtils;\r
-\r
-public class DiagramToCompositeMapping3 extends MappingBase {\r
-\r
- static public int VARIABLE_COUNT = 0;\r
- \r
- final static protected int Diagram = VARIABLE_COUNT++;\r
- final static protected int Configuration = VARIABLE_COUNT++;\r
- final static protected int Element = VARIABLE_COUNT++;\r
- final static protected int ElementType = VARIABLE_COUNT++;\r
- final static protected int ComponentType = VARIABLE_COUNT++;\r
- final static protected int Component = VARIABLE_COUNT++;\r
- \r
- final static protected int DiagramConnectionRelation = VARIABLE_COUNT++;\r
- final static protected int DiagramConnectionRelation2 = VARIABLE_COUNT++;\r
- final static protected int CElement = VARIABLE_COUNT++;\r
- final static protected int ConnectionRelation = VARIABLE_COUNT++;\r
- final static protected int Connector = VARIABLE_COUNT++;\r
- final static protected int Connection = VARIABLE_COUNT++; \r
- final static protected int Connection2 = VARIABLE_COUNT++; \r
- final static protected int ConnectionType = VARIABLE_COUNT++;\r
- final static protected int ConnectionRelation2 = VARIABLE_COUNT++;\r
- final static protected int ConnectionRelation3 = VARIABLE_COUNT++;\r
- final static protected int Component2 = VARIABLE_COUNT++;\r
- final static protected int FlagType = VARIABLE_COUNT++;\r
- final static protected int ConnectionDirection = VARIABLE_COUNT++;\r
- final static protected int ConnectionJoin = VARIABLE_COUNT++;\r
- final static protected int ConfigurationRoot = VARIABLE_COUNT++;\r
- \r
- final static protected int Join = VARIABLE_COUNT++;\r
- final static protected int ConnectionMappingSpecification = VARIABLE_COUNT++;\r
-\r
- protected Session session;\r
- \r
- protected Layer0 L0;\r
- protected DiagramResource DIA;\r
- protected ModelingResources MOD;\r
- protected StructuralResource2 STR;\r
- \r
- protected IUnaryPredicate mapped;\r
- protected IUnaryPredicate mappedFromConnector;\r
- protected IUnaryPredicate external;\r
- protected IUnaryPredicate inputFlag;\r
- protected IUnaryPredicate hasOutputConnector;\r
- protected IUnaryPredicate flagIsConnected;\r
- protected IUnaryPredicate internalJoin;\r
- protected IBinaryPredicate fromFlagToConnection;\r
- \r
- IRuleInstruction createMappingRule() throws DatabaseException { \r
- L0 = Layer0.getInstance(session);\r
- DIA = DiagramResource.getInstance(session);\r
- MOD = ModelingResources.getInstance(session);\r
- STR = StructuralResource2.getInstance(session);\r
- mapped = new Tag(MOD.Mapped);\r
- mappedFromConnector = new Tag(MOD.MappedFromConnector);\r
- external = new Tag(DIA.ExternalFlag);\r
- inputFlag = new UnaryTest() {\r
- @Override\r
- public boolean has(ReadGraph g, Resource resource) throws DatabaseException {\r
- return g.hasStatement(resource, DIA.HasFlagType, DIA.FlagType_InputFlag);\r
- }\r
- };\r
- hasOutputConnector = new UnaryTest() { \r
- @Override\r
- public boolean has(ReadGraph g, Resource resource) throws DatabaseException {\r
- Resource connection = g.getPossibleObject(resource, MOD.DiagramConnectionToConnection);\r
- if(connection == null)\r
- return false;\r
- for(Resource connectionRelation : g.getObjects(connection, STR.Binds)) {\r
- if (!g.hasStatement(connectionRelation, MOD.GeneratesConnectionComponentInternally))\r
- return false;\r
- }\r
- for(Resource join : g.getObjects(connection, STR.IsJoinedBy))\r
- for(Resource connection2 : g.getObjects(join, STR.Joins))\r
- if(!connection.equals(connection2) && g.hasStatement(connection, STR.Binds))\r
- return false;\r
- return true; \r
- }\r
- };\r
- flagIsConnected = new UnaryTest() { \r
- @Override\r
- public boolean has(ReadGraph g, Resource resource) throws DatabaseException {\r
- return g.hasStatement(resource, DIA.Flag_ConnectionPoint); \r
- }\r
- };\r
- internalJoin = new UnaryTest() { \r
- @Override\r
- public boolean has(ReadGraph g, Resource resource) throws DatabaseException {\r
- return g.getObjects(resource, STR.JoinsComposite).size() <= 1; \r
- }\r
- };\r
- fromFlagToConnection = new BinaryPredicateAdapter() {\r
- @Override\r
- public boolean supportsGetObjects() {\r
- return true;\r
- }\r
- \r
- @Override\r
- public Collection<Resource> getObjects(ReadGraph g, Resource flag)\r
- throws DatabaseException {\r
- ArrayList<Resource> result = new ArrayList<Resource>(2);\r
- for(Resource connector : g.getObjects(flag, DIA.Flag_ConnectionPoint))\r
- for(Resource routeGraph : g.getObjects(connector, DIA.IsConnectorOf))\r
- if(!flag.equals(routeGraph)) \r
- result.addAll(g.getObjects(routeGraph, MOD.DiagramConnectionToConnection));\r
- return result;\r
- }\r
- };\r
- return and(destructiveRule(), additiveRule());\r
- } \r
- \r
- public CreationInstruction componentCreationInstruction(int component, int componentType, int configuration) {\r
- return new NamingCreationInstruction(project, ConfigurationRoot, component, componentType, configuration);\r
- }\r
- \r
- protected IRuleInstruction additiveRule() {\r
- return \r
- if_(bf(OrderedSetElementsPredicate.INSTANCE, Diagram, Element),\r
- query(\r
- if_(and(bf(L0.InstanceOf, Element, ElementType),\r
- bf(MOD.SymbolToComponentType, ElementType, ComponentType)\r
- ),\r
- // If element type of the element has a corresponding component type\r
- createComponentRule(),\r
- \r
- if_(b(DIA.Connection, Element),\r
- createNormalConnectionRule(),\r
- \r
- if_(b(DIA.Flag, Element),\r
- createFlagRule()\r
- )\r
- )\r
- )\r
- )\r
- );\r
- }\r
- \r
- protected IRuleInstruction destructiveRule() {\r
- return and(\r
- if_(bf(L0.ConsistsOf, Configuration, Component),\r
- and(\r
- if_(b(mapped, Component), // handle only mapped components\r
- query(\r
- if_(and(bf(MOD.ComponentToElement, Component, Element),\r
- bf(new InversePredicate(OrderedSetElementsPredicate.INSTANCE), Element, Diagram), \r
- b(implies(new Type(DIA.Flag), and(external, flagIsConnected)), Element),\r
- b(implies(new Type(DIA.Connection), hasOutputConnector), Element)\r
- ),\r
- // If component has a corresponding element in the diagram\r
- if_(and(statement_bff(Component, ConnectionRelation, Connection, STR.IsConnectedTo),\r
- b(mapped, Connection)\r
- ),\r
- destructiveConnectionRule()\r
- ),\r
- // If component does not have a corresponding element in the diagram, remove it\r
- and(deny(b(new Tag(MOD.ComponentToElement), Component)), deny(exists(Component)))\r
- )\r
- )\r
- ),\r
- if_(b(mappedFromConnector, Component), // handle only mapped components\r
- query(\r
- unless(bf(MOD.ComponentToConnector, Component, Connector),\r
- and(deny(b(new Tag(MOD.ComponentToElement), Component)), deny(exists(Component)))\r
- )\r
- )\r
- )\r
- )\r
- ),\r
- // Destroy connections \r
- if_(and(bf(STR.HasConnectionJoin, Configuration, Join),\r
- b(internalJoin, Join),\r
- bf(STR.Joins, Join, Connection), \r
- b(mapped, Connection)),\r
- unless(and(bf(MOD.ConnectionMapsTo, Connection, Connection2),\r
- or(b(new Negation(new Tag(MOD.ConnectionToDiagramConnectionSpecial)), Connection),\r
- b(new Tag(MOD.ElementToComponent), Connection2)\r
- )\r
- ),\r
- and(deny(b(new Tag(MOD.ConnectionMapsTo), Connection)), deny(exists(Connection)))\r
- )\r
- ),\r
- if_(and(bf(STR.HasConnectionJoin, Configuration, Join),\r
- bf(STR.Joins, Join, Connection), \r
- b(mapped, Connection), \r
- b(not(new Tag(STR.Connects)), Connection),\r
- b(not(new Tag(MOD.ConnectionMapsTo)), Connection)),\r
- deny(exists(Connection))\r
- ),\r
- if_(and(bf(STR.HasConnectionJoin, Configuration, Join),\r
- bf(STR.Joins, Join, Connection),\r
- bf(MOD.ConnectionToDiagramConnection, Connection, Connection2)), \r
- unless(and(\r
- bf(DIA.HasConnector, Connection2, Connector),\r
- bf(DIA.Flag_ConnectionPoint_Inverse, Connector, Element),\r
- bb(DIA.FlagIsJoinedBy, Element, Join)\r
- ),\r
- deny(bb(STR.Joins, Join, Connection)))\r
- ),\r
- if_(and(bf(L0.ConsistsOf, Diagram, Element),\r
- bf(MOD.DiagramConnectionToConnectionSpecial, Element, Connection),\r
- not(b(new Tag(STR.Connects), Connection))),\r
- deny(exists(Connection))\r
- ));\r
- }\r
- \r
- protected IRuleInstruction destructiveConnectionRule() {\r
- // If component has a mapped connection\r
- return if_(\r
- and(bf(MOD.ConnectionMapsTo, Connection, Connection2),\r
- or(b(new Negation(new Tag(MOD.ConnectionToDiagramConnectionSpecial)), Connection),\r
- b(new Tag(MOD.ElementToComponent), Connection2)\r
- )\r
- ),\r
- unless(or(\r
- new DiagramConnectionExistence(Element, ConnectionRelation, Connection2),\r
- /*and(bf(MOD.ConnectionRelationToDiagramConnectionRelation, ConnectionRelation, DiagramConnectionRelation),\r
- statement_bbf(Element, DiagramConnectionRelation, Connector),\r
- bb(DIA.IsConnectorOf, Connector, Connection2)\r
- ),*/\r
- b(DIA.Connection, Element), \r
- b(DIA.Flag, Element), /* This is not entirely correct.\r
- It is new not possible to replace\r
- a connection to an external signal \r
- flag.\r
- */\r
- b(new Negation(new Tag(MOD.ConnectionRelationToDiagramConnectionRelation)), ConnectionRelation),\r
- fb(MOD.HasReferenceRelation, CElement, ConnectionRelation)\r
- ),\r
- deny(statement(Component, ConnectionRelation, Connection))\r
- ),\r
- // If the configuration connection does not have a correspondence in the diagram remove it\r
- and(deny(b(new Tag(MOD.ConnectionMapsTo), Connection)), deny(exists(Connection)))\r
- );\r
- }\r
- \r
- protected IRuleInstruction createComponentRule() { \r
- return \r
- claim(\r
- // Create a component corresponding to element, if it does not exist, and name it.\r
- exists(\r
- bf(MOD.ElementToComponent, Element, Component),\r
- componentCreationInstruction(Component, ComponentType, Configuration)\r
- ), \r
- bb(L0.InstanceOf, Component, ComponentType),\r
- bb(L0.PartOf, Component, Configuration),\r
- b(mapped, Component) // Mark the component mapped (for destructive rules)\r
- );\r
- }\r
-\r
- IRuleInstruction createConnectionRule() {\r
- return if_(\r
- b(DIA.Connection, Element),\r
- // If element is a connection\r
- createNormalConnectionRule()\r
- ); \r
- }\r
- \r
- protected Resource getConfigurationConnectionType() {\r
- return STR.Connection;\r
- }\r
- \r
- protected IInstruction claimBasicConnection() {\r
- return and(exists(\r
- bf(MOD.DiagramConnectionToConnection, Element, Connection),\r
- Connection\r
- ),\r
- b(getConfigurationConnectionType(), Connection),\r
- b(mapped, Connection)\r
- );\r
- }\r
- \r
- protected IRuleInstruction createNormalConnectionRule() {\r
- return claim(claimBasicConnection(),\r
- if_(and(bf(STR.IsConnectedTo, Element, Connector),\r
- statement_ffb(CElement, DiagramConnectionRelation, Connector, STR.IsConnectedTo)\r
- ),\r
- \r
- if_(and(bf(MOD.DiagramConnectionRelationToConnectionRelation, DiagramConnectionRelation, ConnectionRelation),\r
- bf(MOD.ElementToComponent, CElement, Component)\r
- ), \r
- \r
- // then\r
- if_(or(and(bf(MOD.DiagramConnectionRelationToConnectionRelationB, DiagramConnectionRelation, ConnectionRelation2),\r
- b(hasOutputConnector, Element),\r
- bf(MOD.DiagramConnectionRelationToConnectionRelationC, DiagramConnectionRelation, ConnectionRelation3),\r
- bf(MOD.DiagramConnectionRelationToComponentType, DiagramConnectionRelation, ComponentType)\r
- ),\r
- and(bf(MOD.HasConnectionMappingSpecification, Connector, ConnectionMappingSpecification),\r
- b(hasOutputConnector, Element),\r
- bf(MOD.DiagramConnectionRelationToConnectionRelationB, ConnectionMappingSpecification, ConnectionRelation2), \r
- bf(MOD.DiagramConnectionRelationToConnectionRelationC, ConnectionMappingSpecification, ConnectionRelation3),\r
- bf(MOD.DiagramConnectionRelationToComponentType, ConnectionMappingSpecification, ComponentType)\r
- )\r
- ),\r
- \r
- // then\r
- claim(\r
- // Create a component corresponding to connector, if it does not exist, and name it.\r
- exists(\r
- bf(MOD.ElementToComponent, Element, Component2),\r
- new NamingCreationInstruction(project, ConfigurationRoot, Component2, ComponentType, Configuration)\r
- ), \r
- bb(L0.InstanceOf, Component2, ComponentType),\r
- bb(L0.PartOf, Component2, Configuration),\r
- bb(MOD.ConnectorToComponent, Connector, Component2),\r
- b(mappedFromConnector, Component2), // Mark the component mapped (for destructive rules) \r
- \r
- // Create a connection\r
- exists(\r
- bf(MOD.DiagramConnectionToConnectionSpecial, Element, Connection2), \r
- Connection2\r
- ),\r
- statement(Component2, ConnectionRelation2, Connection2),\r
- statement(Component, ConnectionRelation, Connection2),\r
- b(getConfigurationConnectionType(), Connection2),\r
- b(mapped, Connection2),\r
- \r
- // \r
- statement(Component2, ConnectionRelation3, Connection)\r
- ),\r
- \r
- // else\r
- claim(statement(Component, ConnectionRelation, Connection))\r
- ), \r
- \r
- // else\r
- if_(bf(MOD.HasReferenceRelation, CElement, ConnectionRelation),\r
- if_(bf(MOD.HasParentComponent, CElement, Component),\r
- // then\r
- claim(statement(Component, ConnectionRelation, Connection)),\r
- // else\r
- claim(statement(CElement, ConnectionRelation, Connection))\r
- )\r
- )\r
- )\r
- )\r
- );\r
- }\r
- \r
- protected IRuleInstruction createFlagRule() {\r
-\r
- return \r
- and(\r
- //print("Flag rule"),\r
- if_(and(bf(DIA.FlagIsJoinedBy, Element, ConnectionJoin),\r
- bf(compose(STR.IsConnectedTo, STR.Connects, MOD.DiagramConnectionToConnection), \r
- Element, Connection) \r
- ),\r
- claim(\r
- bb(STR.Joins, ConnectionJoin, Connection),\r
- bb(STR.HasConnectionJoin, Configuration, ConnectionJoin)\r
- ),\r
- // This is maybe Apros specific \r
- if_(and(b(and(external, inputFlag, flagIsConnected), Element),\r
- bf(compose(STR.IsConnectedTo, STR.Connects), Element, Connection2),\r
- bf(MOD.DiagramConnectionToConnection, Connection2, Connection),\r
- bf(STR.HasConnectionType, Connection2, ConnectionType),\r
- bf(MOD.ConnectionTypeToComponentType, ConnectionType, ComponentType),\r
- bf(MOD.ConnectionTypeToConnectionRelation, ConnectionType, ConnectionRelation)\r
- ),\r
- claim(\r
- exists(\r
- bf(MOD.ElementToComponent, Element, Component),\r
- new NamingCreationInstruction(project, ConfigurationRoot, Component, ComponentType, Configuration)\r
- ),\r
- bb(L0.InstanceOf, Component, ComponentType),\r
- bb(L0.PartOf, Component, Configuration),\r
- b(mapped, Component),\r
- \r
- statement(Component, ConnectionRelation, Connection)\r
- )\r
- )\r
- ),\r
- if_(and(bf(DIA.IsLiftedAs, Element, ConnectionRelation),\r
- bf(fromFlagToConnection, Element, Connection)),\r
- claim(\r
- bb(STR.Binds, Connection, ConnectionRelation)\r
- )\r
- )\r
- );\r
- }\r
-\r
- class RuleQuery implements Read<IRuleInstruction> {\r
-\r
- @Override\r
- public boolean equals(Object other) {\r
- return other != null && other.getClass() == RuleQuery.class &&\r
- getParentClass().equals(((RuleQuery)other).getParentClass());\r
- }\r
-\r
- private Class<? extends DiagramToCompositeMapping3> getParentClass() {\r
- return DiagramToCompositeMapping3.this.getClass();\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- return DiagramToCompositeMapping3.this.getClass().hashCode();\r
- }\r
-\r
- @Override\r
- public IRuleInstruction perform(ReadGraph g) {\r
- try {\r
- return createMappingRule();\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
- return null;\r
- \r
- }\r
- \r
- }\r
- \r
- IRuleInstruction instruction;\r
- public Resource source;\r
- public Resource target;\r
- protected IProject project;\r
- protected Resource configurationRoot;\r
- \r
- protected void setup(ReadGraph graph) {\r
- \r
- }\r
- \r
- public DiagramToCompositeMapping3(ReadGraph g, Resource mapping) throws DatabaseException {\r
-\r
- setup(g);\r
-\r
- this.session = g.getSession();\r
-\r
- this.source = g.getPossibleObject(mapping, g.getInverse(Layer0X.getInstance(g).HasTrigger));\r
- if (source != null)\r
- this.target = g.getPossibleObject(this.source, ModelingResources.getInstance(g).DiagramToComposite);\r
- if (target != null) {\r
- configurationRoot = ComponentUtils.getCompositeConfigurationRoot(g, target);\r
- assert configurationRoot != null;\r
- }\r
-\r
- this.project = Simantics.peekProject();\r
- this.instruction = g.syncRequest(new RuleQuery());\r
-\r
-// System.out.println(this + "(mapping=" + mapping\r
-// + ", source=" + source\r
-// + ", target=" + target\r
-// + ", configurationRoot=" + configurationRoot\r
-// + ")");\r
-\r
- }\r
- \r
- @Override\r
- public boolean equals(Object other) {\r
- if(this==other)\r
- return true;\r
- if(!(other instanceof DiagramToCompositeMapping3))\r
- return false;\r
- DiagramToCompositeMapping3 map = (DiagramToCompositeMapping3)other;\r
- return ObjectUtils.objectEquals(map.source, source) && ObjectUtils.objectEquals(map.target, target);\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- return ObjectUtils.hashCode(source) + 31 * ObjectUtils.hashCode(target);\r
- }\r
-\r
- @Override\r
- public IModification perform(ReadGraph g) throws DatabaseException {\r
-// System.out.println(this + ": Find modification (source=" + source + ", target=" + target + ", configurationRoot=" + configurationRoot + ")");\r
-\r
- if(IInstruction.DEBUG_MODI)\r
- System.out.println("--- MAPPING ROUND -------------------------------- " + NameUtils.getURIOrSafeNameInternal(g, target));\r
- \r
- if (source == null || target == null)\r
- return null;\r
-\r
- final Object[] bindings = new Object[VARIABLE_COUNT];\r
- bindings[Diagram] = source;\r
- bindings[Configuration] = target;\r
- bindings[ConfigurationRoot] = configurationRoot;\r
- IModification modi = instruction.execute(g, bindings);\r
- //System.out.println("modi = " + modi);\r
- return modi;\r
- }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling.mapping;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Read;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.layer0.utils.binaryPredicates.BinaryPredicateAdapter;
+import org.simantics.layer0.utils.binaryPredicates.IBinaryPredicate;
+import org.simantics.layer0.utils.binaryPredicates.InversePredicate;
+import org.simantics.layer0.utils.binaryPredicates.OrderedSetElementsPredicate;
+import org.simantics.layer0.utils.predicates.IUnaryPredicate;
+import org.simantics.layer0.utils.predicates.Negation;
+import org.simantics.layer0.utils.predicates.Type;
+import org.simantics.layer0.utils.predicates.UnaryTest;
+import org.simantics.layer0.utils.triggers.IModification;
+import org.simantics.mapping.constraint.instructions.IInstruction;
+import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction;
+import org.simantics.mapping.rule.instructions.IRuleInstruction;
+import org.simantics.modeling.ComponentUtils;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.operation.Layer0X;
+import org.simantics.project.IProject;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.utils.ObjectUtils;
+
+public class DiagramToCompositeMapping3 extends MappingBase {
+
+ static public int VARIABLE_COUNT = 0;
+
+ final static protected int Diagram = VARIABLE_COUNT++;
+ final static protected int Configuration = VARIABLE_COUNT++;
+ final static protected int Element = VARIABLE_COUNT++;
+ final static protected int ElementType = VARIABLE_COUNT++;
+ final static protected int ComponentType = VARIABLE_COUNT++;
+ final static protected int Component = VARIABLE_COUNT++;
+
+ final static protected int DiagramConnectionRelation = VARIABLE_COUNT++;
+ final static protected int DiagramConnectionRelation2 = VARIABLE_COUNT++;
+ final static protected int CElement = VARIABLE_COUNT++;
+ final static protected int ConnectionRelation = VARIABLE_COUNT++;
+ final static protected int Connector = VARIABLE_COUNT++;
+ final static protected int Connection = VARIABLE_COUNT++;
+ final static protected int Connection2 = VARIABLE_COUNT++;
+ final static protected int ConnectionType = VARIABLE_COUNT++;
+ final static protected int ConnectionRelation2 = VARIABLE_COUNT++;
+ final static protected int ConnectionRelation3 = VARIABLE_COUNT++;
+ final static protected int Component2 = VARIABLE_COUNT++;
+ final static protected int FlagType = VARIABLE_COUNT++;
+ final static protected int ConnectionDirection = VARIABLE_COUNT++;
+ final static protected int ConnectionJoin = VARIABLE_COUNT++;
+ final static protected int ConfigurationRoot = VARIABLE_COUNT++;
+
+ final static protected int Join = VARIABLE_COUNT++;
+ final static protected int ConnectionMappingSpecification = VARIABLE_COUNT++;
+
+ protected Session session;
+
+ protected Layer0 L0;
+ protected DiagramResource DIA;
+ protected ModelingResources MOD;
+ protected StructuralResource2 STR;
+
+ protected IUnaryPredicate mapped;
+ protected IUnaryPredicate mappedFromConnector;
+ protected IUnaryPredicate external;
+ protected IUnaryPredicate inputFlag;
+ protected IUnaryPredicate hasOutputConnector;
+ protected IUnaryPredicate flagIsConnected;
+ protected IUnaryPredicate internalJoin;
+ protected IBinaryPredicate fromFlagToConnection;
+
+ IRuleInstruction createMappingRule() throws DatabaseException {
+ L0 = Layer0.getInstance(session);
+ DIA = DiagramResource.getInstance(session);
+ MOD = ModelingResources.getInstance(session);
+ STR = StructuralResource2.getInstance(session);
+ mapped = new Tag(MOD.Mapped);
+ mappedFromConnector = new Tag(MOD.MappedFromConnector);
+ external = new Tag(DIA.ExternalFlag);
+ inputFlag = new UnaryTest() {
+ @Override
+ public boolean has(ReadGraph g, Resource resource) throws DatabaseException {
+ return g.hasStatement(resource, DIA.HasFlagType, DIA.FlagType_InputFlag);
+ }
+ };
+ hasOutputConnector = new UnaryTest() {
+ @Override
+ public boolean has(ReadGraph g, Resource resource) throws DatabaseException {
+ Resource connection = g.getPossibleObject(resource, MOD.DiagramConnectionToConnection);
+ if(connection == null)
+ return false;
+ for(Resource connectionRelation : g.getObjects(connection, STR.Binds)) {
+ if (!g.hasStatement(connectionRelation, MOD.GeneratesConnectionComponentInternally))
+ return false;
+ }
+ for(Resource join : g.getObjects(connection, STR.IsJoinedBy))
+ for(Resource connection2 : g.getObjects(join, STR.Joins))
+ if(!connection.equals(connection2) && g.hasStatement(connection, STR.Binds))
+ return false;
+ return true;
+ }
+ };
+ flagIsConnected = new UnaryTest() {
+ @Override
+ public boolean has(ReadGraph g, Resource resource) throws DatabaseException {
+ return g.hasStatement(resource, DIA.Flag_ConnectionPoint);
+ }
+ };
+ internalJoin = new UnaryTest() {
+ @Override
+ public boolean has(ReadGraph g, Resource resource) throws DatabaseException {
+ return g.getObjects(resource, STR.JoinsComposite).size() <= 1;
+ }
+ };
+ fromFlagToConnection = new BinaryPredicateAdapter() {
+ @Override
+ public boolean supportsGetObjects() {
+ return true;
+ }
+
+ @Override
+ public Collection<Resource> getObjects(ReadGraph g, Resource flag)
+ throws DatabaseException {
+ ArrayList<Resource> result = new ArrayList<Resource>(2);
+ for(Resource connector : g.getObjects(flag, DIA.Flag_ConnectionPoint))
+ for(Resource routeGraph : g.getObjects(connector, DIA.IsConnectorOf))
+ if(!flag.equals(routeGraph))
+ result.addAll(g.getObjects(routeGraph, MOD.DiagramConnectionToConnection));
+ return result;
+ }
+ };
+ return and(destructiveRule(), additiveRule());
+ }
+
+ public CreationInstruction componentCreationInstruction(int component, int componentType, int configuration) {
+ return new NamingCreationInstruction(project, ConfigurationRoot, component, componentType, configuration);
+ }
+
+ protected IRuleInstruction additiveRule() {
+ return
+ if_(bf(OrderedSetElementsPredicate.INSTANCE, Diagram, Element),
+ query(
+ if_(and(bf(L0.InstanceOf, Element, ElementType),
+ bf(MOD.SymbolToComponentType, ElementType, ComponentType)
+ ),
+ // If element type of the element has a corresponding component type
+ createComponentRule(),
+
+ if_(b(DIA.Connection, Element),
+ createNormalConnectionRule(),
+
+ if_(b(DIA.Flag, Element),
+ createFlagRule()
+ )
+ )
+ )
+ )
+ );
+ }
+
+ protected IRuleInstruction destructiveRule() {
+ return and(
+ if_(bf(L0.ConsistsOf, Configuration, Component),
+ and(
+ if_(b(mapped, Component), // handle only mapped components
+ query(
+ if_(and(bf(MOD.ComponentToElement, Component, Element),
+ bf(new InversePredicate(OrderedSetElementsPredicate.INSTANCE), Element, Diagram),
+ b(implies(new Type(DIA.Flag), and(external, flagIsConnected)), Element),
+ b(implies(new Type(DIA.Connection), hasOutputConnector), Element)
+ ),
+ // If component has a corresponding element in the diagram
+ if_(and(statement_bff(Component, ConnectionRelation, Connection, STR.IsConnectedTo),
+ b(mapped, Connection)
+ ),
+ destructiveConnectionRule()
+ ),
+ // If component does not have a corresponding element in the diagram, remove it
+ and(deny(b(new Tag(MOD.ComponentToElement), Component)), deny(exists(Component)))
+ )
+ )
+ ),
+ if_(b(mappedFromConnector, Component), // handle only mapped components
+ query(
+ unless(bf(MOD.ComponentToConnector, Component, Connector),
+ and(deny(b(new Tag(MOD.ComponentToElement), Component)), deny(exists(Component)))
+ )
+ )
+ )
+ )
+ ),
+ // Destroy connections
+ if_(and(bf(STR.HasConnectionJoin, Configuration, Join),
+ b(internalJoin, Join),
+ bf(STR.Joins, Join, Connection),
+ b(mapped, Connection)),
+ unless(and(bf(MOD.ConnectionMapsTo, Connection, Connection2),
+ or(b(new Negation(new Tag(MOD.ConnectionToDiagramConnectionSpecial)), Connection),
+ b(new Tag(MOD.ElementToComponent), Connection2)
+ )
+ ),
+ and(deny(b(new Tag(MOD.ConnectionMapsTo), Connection)), deny(exists(Connection)))
+ )
+ ),
+ if_(and(bf(STR.HasConnectionJoin, Configuration, Join),
+ bf(STR.Joins, Join, Connection),
+ b(mapped, Connection),
+ b(not(new Tag(STR.Connects)), Connection),
+ b(not(new Tag(MOD.ConnectionMapsTo)), Connection)),
+ deny(exists(Connection))
+ ),
+ if_(and(bf(STR.HasConnectionJoin, Configuration, Join),
+ bf(STR.Joins, Join, Connection),
+ bf(MOD.ConnectionToDiagramConnection, Connection, Connection2)),
+ unless(and(
+ bf(DIA.HasConnector, Connection2, Connector),
+ bf(DIA.Flag_ConnectionPoint_Inverse, Connector, Element),
+ bb(DIA.FlagIsJoinedBy, Element, Join)
+ ),
+ deny(bb(STR.Joins, Join, Connection)))
+ ),
+ if_(and(bf(L0.ConsistsOf, Diagram, Element),
+ bf(MOD.DiagramConnectionToConnectionSpecial, Element, Connection),
+ not(b(new Tag(STR.Connects), Connection))),
+ deny(exists(Connection))
+ ));
+ }
+
+ protected IRuleInstruction destructiveConnectionRule() {
+ // If component has a mapped connection
+ return if_(
+ and(bf(MOD.ConnectionMapsTo, Connection, Connection2),
+ or(b(new Negation(new Tag(MOD.ConnectionToDiagramConnectionSpecial)), Connection),
+ b(new Tag(MOD.ElementToComponent), Connection2)
+ )
+ ),
+ unless(or(
+ new DiagramConnectionExistence(Element, ConnectionRelation, Connection2),
+ /*and(bf(MOD.ConnectionRelationToDiagramConnectionRelation, ConnectionRelation, DiagramConnectionRelation),
+ statement_bbf(Element, DiagramConnectionRelation, Connector),
+ bb(DIA.IsConnectorOf, Connector, Connection2)
+ ),*/
+ b(DIA.Connection, Element),
+ b(DIA.Flag, Element), /* This is not entirely correct.
+ It is new not possible to replace
+ a connection to an external signal
+ flag.
+ */
+ b(new Negation(new Tag(MOD.ConnectionRelationToDiagramConnectionRelation)), ConnectionRelation),
+ fb(MOD.HasReferenceRelation, CElement, ConnectionRelation)
+ ),
+ deny(statement(Component, ConnectionRelation, Connection))
+ ),
+ // If the configuration connection does not have a correspondence in the diagram remove it
+ and(deny(b(new Tag(MOD.ConnectionMapsTo), Connection)), deny(exists(Connection)))
+ );
+ }
+
+ protected IRuleInstruction createComponentRule() {
+ return
+ claim(
+ // Create a component corresponding to element, if it does not exist, and name it.
+ exists(
+ bf(MOD.ElementToComponent, Element, Component),
+ componentCreationInstruction(Component, ComponentType, Configuration)
+ ),
+ bb(L0.InstanceOf, Component, ComponentType),
+ bb(L0.PartOf, Component, Configuration),
+ b(mapped, Component) // Mark the component mapped (for destructive rules)
+ );
+ }
+
+ IRuleInstruction createConnectionRule() {
+ return if_(
+ b(DIA.Connection, Element),
+ // If element is a connection
+ createNormalConnectionRule()
+ );
+ }
+
+ protected Resource getConfigurationConnectionType() {
+ return STR.Connection;
+ }
+
+ protected IInstruction claimBasicConnection() {
+ return and(exists(
+ bf(MOD.DiagramConnectionToConnection, Element, Connection),
+ Connection
+ ),
+ b(getConfigurationConnectionType(), Connection),
+ b(mapped, Connection)
+ );
+ }
+
+ protected IRuleInstruction createNormalConnectionRule() {
+ return claim(claimBasicConnection(),
+ if_(and(bf(STR.IsConnectedTo, Element, Connector),
+ statement_ffb(CElement, DiagramConnectionRelation, Connector, STR.IsConnectedTo)
+ ),
+
+ if_(and(bf(MOD.DiagramConnectionRelationToConnectionRelation, DiagramConnectionRelation, ConnectionRelation),
+ bf(MOD.ElementToComponent, CElement, Component)
+ ),
+
+ // then
+ if_(or(and(bf(MOD.DiagramConnectionRelationToConnectionRelationB, DiagramConnectionRelation, ConnectionRelation2),
+ b(hasOutputConnector, Element),
+ bf(MOD.DiagramConnectionRelationToConnectionRelationC, DiagramConnectionRelation, ConnectionRelation3),
+ bf(MOD.DiagramConnectionRelationToComponentType, DiagramConnectionRelation, ComponentType)
+ ),
+ and(bf(MOD.HasConnectionMappingSpecification, Connector, ConnectionMappingSpecification),
+ b(hasOutputConnector, Element),
+ bf(MOD.DiagramConnectionRelationToConnectionRelationB, ConnectionMappingSpecification, ConnectionRelation2),
+ bf(MOD.DiagramConnectionRelationToConnectionRelationC, ConnectionMappingSpecification, ConnectionRelation3),
+ bf(MOD.DiagramConnectionRelationToComponentType, ConnectionMappingSpecification, ComponentType)
+ )
+ ),
+
+ // then
+ claim(
+ // Create a component corresponding to connector, if it does not exist, and name it.
+ exists(
+ bf(MOD.ElementToComponent, Element, Component2),
+ new NamingCreationInstruction(project, ConfigurationRoot, Component2, ComponentType, Configuration)
+ ),
+ bb(L0.InstanceOf, Component2, ComponentType),
+ bb(L0.PartOf, Component2, Configuration),
+ bb(MOD.ConnectorToComponent, Connector, Component2),
+ b(mappedFromConnector, Component2), // Mark the component mapped (for destructive rules)
+
+ // Create a connection
+ exists(
+ bf(MOD.DiagramConnectionToConnectionSpecial, Element, Connection2),
+ Connection2
+ ),
+ statement(Component2, ConnectionRelation2, Connection2),
+ statement(Component, ConnectionRelation, Connection2),
+ b(getConfigurationConnectionType(), Connection2),
+ b(mapped, Connection2),
+
+ //
+ statement(Component2, ConnectionRelation3, Connection)
+ ),
+
+ // else
+ claim(statement(Component, ConnectionRelation, Connection))
+ ),
+
+ // else
+ if_(bf(MOD.HasReferenceRelation, CElement, ConnectionRelation),
+ if_(bf(MOD.HasParentComponent, CElement, Component),
+ // then
+ claim(statement(Component, ConnectionRelation, Connection)),
+ // else
+ claim(statement(CElement, ConnectionRelation, Connection))
+ )
+ )
+ )
+ )
+ );
+ }
+
+ protected IRuleInstruction createFlagRule() {
+
+ return
+ and(
+ //print("Flag rule"),
+ if_(and(bf(DIA.FlagIsJoinedBy, Element, ConnectionJoin),
+ bf(compose(STR.IsConnectedTo, STR.Connects, MOD.DiagramConnectionToConnection),
+ Element, Connection)
+ ),
+ claim(
+ bb(STR.Joins, ConnectionJoin, Connection),
+ bb(STR.HasConnectionJoin, Configuration, ConnectionJoin)
+ ),
+ // This is maybe Apros specific
+ if_(and(b(and(external, inputFlag, flagIsConnected), Element),
+ bf(compose(STR.IsConnectedTo, STR.Connects), Element, Connection2),
+ bf(MOD.DiagramConnectionToConnection, Connection2, Connection),
+ bf(STR.HasConnectionType, Connection2, ConnectionType),
+ bf(MOD.ConnectionTypeToComponentType, ConnectionType, ComponentType),
+ bf(MOD.ConnectionTypeToConnectionRelation, ConnectionType, ConnectionRelation)
+ ),
+ claim(
+ exists(
+ bf(MOD.ElementToComponent, Element, Component),
+ new NamingCreationInstruction(project, ConfigurationRoot, Component, ComponentType, Configuration)
+ ),
+ bb(L0.InstanceOf, Component, ComponentType),
+ bb(L0.PartOf, Component, Configuration),
+ b(mapped, Component),
+
+ statement(Component, ConnectionRelation, Connection)
+ )
+ )
+ ),
+ if_(and(bf(DIA.IsLiftedAs, Element, ConnectionRelation),
+ bf(fromFlagToConnection, Element, Connection)),
+ claim(
+ bb(STR.Binds, Connection, ConnectionRelation)
+ )
+ )
+ );
+ }
+
+ class RuleQuery implements Read<IRuleInstruction> {
+
+ @Override
+ public boolean equals(Object other) {
+ return other != null && other.getClass() == RuleQuery.class &&
+ getParentClass().equals(((RuleQuery)other).getParentClass());
+ }
+
+ private Class<? extends DiagramToCompositeMapping3> getParentClass() {
+ return DiagramToCompositeMapping3.this.getClass();
+ }
+
+ @Override
+ public int hashCode() {
+ return DiagramToCompositeMapping3.this.getClass().hashCode();
+ }
+
+ @Override
+ public IRuleInstruction perform(ReadGraph g) {
+ try {
+ return createMappingRule();
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+ return null;
+
+ }
+
+ }
+
+ IRuleInstruction instruction;
+ public Resource source;
+ public Resource target;
+ protected IProject project;
+ protected Resource configurationRoot;
+
+ protected void setup(ReadGraph graph) {
+
+ }
+
+ public DiagramToCompositeMapping3(ReadGraph g, Resource mapping) throws DatabaseException {
+
+ setup(g);
+
+ this.session = g.getSession();
+
+ this.source = g.getPossibleObject(mapping, g.getInverse(Layer0X.getInstance(g).HasTrigger));
+ if (source != null)
+ this.target = g.getPossibleObject(this.source, ModelingResources.getInstance(g).DiagramToComposite);
+ if (target != null) {
+ configurationRoot = ComponentUtils.getCompositeConfigurationRoot(g, target);
+ assert configurationRoot != null;
+ }
+
+ this.project = Simantics.peekProject();
+ this.instruction = g.syncRequest(new RuleQuery());
+
+// System.out.println(this + "(mapping=" + mapping
+// + ", source=" + source
+// + ", target=" + target
+// + ", configurationRoot=" + configurationRoot
+// + ")");
+
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if(this==other)
+ return true;
+ if(!(other instanceof DiagramToCompositeMapping3))
+ return false;
+ DiagramToCompositeMapping3 map = (DiagramToCompositeMapping3)other;
+ return ObjectUtils.objectEquals(map.source, source) && ObjectUtils.objectEquals(map.target, target);
+ }
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(source) + 31 * ObjectUtils.hashCode(target);
+ }
+
+ @Override
+ public IModification perform(ReadGraph g) throws DatabaseException {
+// System.out.println(this + ": Find modification (source=" + source + ", target=" + target + ", configurationRoot=" + configurationRoot + ")");
+
+ if(IInstruction.DEBUG_MODI)
+ System.out.println("--- MAPPING ROUND -------------------------------- " + NameUtils.getURIOrSafeNameInternal(g, target));
+
+ if (source == null || target == null)
+ return null;
+
+ final Object[] bindings = new Object[VARIABLE_COUNT];
+ bindings[Diagram] = source;
+ bindings[Configuration] = target;
+ bindings[ConfigurationRoot] = configurationRoot;
+ IModification modi = instruction.execute(g, bindings);
+ //System.out.println("modi = " + modi);
+ return modi;
+ }
+}