X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fmapping%2FDiagramToCompositeMapping3.java;fp=bundles%2Forg.simantics.modeling%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fmapping%2FDiagramToCompositeMapping3.java;h=df54d5426f2dc3ffc71c541baf23e5afc69500a8;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/DiagramToCompositeMapping3.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/DiagramToCompositeMapping3.java new file mode 100644 index 000000000..df54d5426 --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/DiagramToCompositeMapping3.java @@ -0,0 +1,518 @@ +/******************************************************************************* + * 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 getObjects(ReadGraph g, Resource flag) + throws DatabaseException { + ArrayList result = new ArrayList(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))) + )); + } + + 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 { + + @Override + public boolean equals(Object other) { + return other != null && other.getClass() == RuleQuery.class && + getParentClass().equals(((RuleQuery)other).getParentClass()); + } + + private Class 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; + } +}