1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 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
11 *******************************************************************************/
12 package org.simantics.modeling.mapping;
14 import java.util.ArrayList;
15 import java.util.Collection;
17 import org.simantics.Simantics;
18 import org.simantics.db.ReadGraph;
19 import org.simantics.db.Resource;
20 import org.simantics.db.Session;
21 import org.simantics.db.common.utils.NameUtils;
22 import org.simantics.db.exception.DatabaseException;
23 import org.simantics.db.request.Read;
24 import org.simantics.diagram.stubs.DiagramResource;
25 import org.simantics.layer0.Layer0;
26 import org.simantics.layer0.utils.binaryPredicates.BinaryPredicateAdapter;
27 import org.simantics.layer0.utils.binaryPredicates.IBinaryPredicate;
28 import org.simantics.layer0.utils.binaryPredicates.InversePredicate;
29 import org.simantics.layer0.utils.binaryPredicates.OrderedSetElementsPredicate;
30 import org.simantics.layer0.utils.predicates.IUnaryPredicate;
31 import org.simantics.layer0.utils.predicates.Negation;
32 import org.simantics.layer0.utils.predicates.Type;
33 import org.simantics.layer0.utils.predicates.UnaryTest;
34 import org.simantics.layer0.utils.triggers.IModification;
35 import org.simantics.mapping.constraint.instructions.IInstruction;
36 import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction;
37 import org.simantics.mapping.rule.instructions.IRuleInstruction;
38 import org.simantics.modeling.ComponentUtils;
39 import org.simantics.modeling.ModelingResources;
40 import org.simantics.operation.Layer0X;
41 import org.simantics.project.IProject;
42 import org.simantics.structural.stubs.StructuralResource2;
43 import org.simantics.utils.ObjectUtils;
45 public class DiagramToCompositeMapping3 extends MappingBase {
47 static public int VARIABLE_COUNT = 0;
49 final static protected int Diagram = VARIABLE_COUNT++;
50 final static protected int Configuration = VARIABLE_COUNT++;
51 final static protected int Element = VARIABLE_COUNT++;
52 final static protected int ElementType = VARIABLE_COUNT++;
53 final static protected int ComponentType = VARIABLE_COUNT++;
54 final static protected int Component = VARIABLE_COUNT++;
56 final static protected int DiagramConnectionRelation = VARIABLE_COUNT++;
57 final static protected int DiagramConnectionRelation2 = VARIABLE_COUNT++;
58 final static protected int CElement = VARIABLE_COUNT++;
59 final static protected int ConnectionRelation = VARIABLE_COUNT++;
60 final static protected int Connector = VARIABLE_COUNT++;
61 final static protected int Connection = VARIABLE_COUNT++;
62 final static protected int Connection2 = VARIABLE_COUNT++;
63 final static protected int ConnectionType = VARIABLE_COUNT++;
64 final static protected int ConnectionRelation2 = VARIABLE_COUNT++;
65 final static protected int ConnectionRelation3 = VARIABLE_COUNT++;
66 final static protected int Component2 = VARIABLE_COUNT++;
67 final static protected int FlagType = VARIABLE_COUNT++;
68 final static protected int ConnectionDirection = VARIABLE_COUNT++;
69 final static protected int ConnectionJoin = VARIABLE_COUNT++;
70 final static protected int ConfigurationRoot = VARIABLE_COUNT++;
72 final static protected int Join = VARIABLE_COUNT++;
73 final static protected int ConnectionMappingSpecification = VARIABLE_COUNT++;
75 protected Session session;
78 protected DiagramResource DIA;
79 protected ModelingResources MOD;
80 protected StructuralResource2 STR;
82 protected IUnaryPredicate mapped;
83 protected IUnaryPredicate mappedFromConnector;
84 protected IUnaryPredicate external;
85 protected IUnaryPredicate inputFlag;
86 protected IUnaryPredicate hasOutputConnector;
87 protected IUnaryPredicate flagIsConnected;
88 protected IUnaryPredicate internalJoin;
89 protected IBinaryPredicate fromFlagToConnection;
91 IRuleInstruction createMappingRule() throws DatabaseException {
92 L0 = Layer0.getInstance(session);
93 DIA = DiagramResource.getInstance(session);
94 MOD = ModelingResources.getInstance(session);
95 STR = StructuralResource2.getInstance(session);
96 mapped = new Tag(MOD.Mapped);
97 mappedFromConnector = new Tag(MOD.MappedFromConnector);
98 external = new Tag(DIA.ExternalFlag);
99 inputFlag = new UnaryTest() {
101 public boolean has(ReadGraph g, Resource resource) throws DatabaseException {
102 return g.hasStatement(resource, DIA.HasFlagType, DIA.FlagType_InputFlag);
105 hasOutputConnector = new UnaryTest() {
107 public boolean has(ReadGraph g, Resource resource) throws DatabaseException {
108 Resource connection = g.getPossibleObject(resource, MOD.DiagramConnectionToConnection);
109 if(connection == null)
111 for(Resource connectionRelation : g.getObjects(connection, STR.Binds)) {
112 if (!g.hasStatement(connectionRelation, MOD.GeneratesConnectionComponentInternally))
115 for(Resource join : g.getObjects(connection, STR.IsJoinedBy))
116 for(Resource connection2 : g.getObjects(join, STR.Joins))
117 if(!connection.equals(connection2) && g.hasStatement(connection, STR.Binds))
122 flagIsConnected = new UnaryTest() {
124 public boolean has(ReadGraph g, Resource resource) throws DatabaseException {
125 return g.hasStatement(resource, DIA.Flag_ConnectionPoint);
128 internalJoin = new UnaryTest() {
130 public boolean has(ReadGraph g, Resource resource) throws DatabaseException {
131 return g.getObjects(resource, STR.JoinsComposite).size() <= 1;
134 fromFlagToConnection = new BinaryPredicateAdapter() {
136 public boolean supportsGetObjects() {
141 public Collection<Resource> getObjects(ReadGraph g, Resource flag)
142 throws DatabaseException {
143 ArrayList<Resource> result = new ArrayList<Resource>(2);
144 for(Resource connector : g.getObjects(flag, DIA.Flag_ConnectionPoint))
145 for(Resource routeGraph : g.getObjects(connector, DIA.IsConnectorOf))
146 if(!flag.equals(routeGraph))
147 result.addAll(g.getObjects(routeGraph, MOD.DiagramConnectionToConnection));
151 return and(destructiveRule(), additiveRule());
154 public CreationInstruction componentCreationInstruction(int component, int componentType, int configuration) {
155 return new NamingCreationInstruction(project, ConfigurationRoot, component, componentType, configuration);
158 protected IRuleInstruction additiveRule() {
160 if_(bf(OrderedSetElementsPredicate.INSTANCE, Diagram, Element),
162 if_(and(bf(L0.InstanceOf, Element, ElementType),
163 bf(MOD.SymbolToComponentType, ElementType, ComponentType)
165 // If element type of the element has a corresponding component type
166 createComponentRule(),
168 if_(b(DIA.Connection, Element),
169 createNormalConnectionRule(),
171 if_(b(DIA.Flag, Element),
180 protected IRuleInstruction destructiveRule() {
182 if_(bf(L0.ConsistsOf, Configuration, Component),
184 if_(b(mapped, Component), // handle only mapped components
186 if_(and(bf(MOD.ComponentToElement, Component, Element),
187 bf(new InversePredicate(OrderedSetElementsPredicate.INSTANCE), Element, Diagram),
188 b(implies(new Type(DIA.Flag), and(external, flagIsConnected)), Element),
189 b(implies(new Type(DIA.Connection), hasOutputConnector), Element)
191 // If component has a corresponding element in the diagram
192 if_(and(statement_bff(Component, ConnectionRelation, Connection, STR.IsConnectedTo),
193 b(mapped, Connection)
195 destructiveConnectionRule()
197 // If component does not have a corresponding element in the diagram, remove it
199 deny(b(new Tag(MOD.ComponentToElement), Component)),
200 deny(b(new Tag(STR.IsConnectedTo), Component)),
201 deny(exists(Component)))
205 if_(b(mappedFromConnector, Component), // handle only mapped components
207 unless(bf(MOD.ComponentToConnector, Component, Connector),
209 deny(b(new Tag(MOD.ComponentToElement), Component)),
210 deny(b(new Tag(STR.IsConnectedTo), Component)),
211 deny(exists(Component)))
217 // Destroy connections
218 if_(and(bf(STR.HasConnectionJoin, Configuration, Join),
219 b(internalJoin, Join),
220 bf(STR.Joins, Join, Connection),
221 b(mapped, Connection)),
222 unless(and(bf(MOD.ConnectionMapsTo, Connection, Connection2),
223 or(b(new Negation(new Tag(MOD.ConnectionToDiagramConnectionSpecial)), Connection),
224 b(new Tag(MOD.ElementToComponent), Connection2)
227 and(deny(b(new Tag(MOD.ConnectionMapsTo), Connection)), deny(exists(Connection)))
230 if_(and(bf(STR.HasConnectionJoin, Configuration, Join),
231 bf(STR.Joins, Join, Connection),
232 b(mapped, Connection),
233 b(not(new Tag(STR.Connects)), Connection),
234 b(not(new Tag(MOD.ConnectionMapsTo)), Connection)),
235 deny(exists(Connection))
237 if_(and(bf(STR.HasConnectionJoin, Configuration, Join),
238 bf(STR.Joins, Join, Connection),
239 bf(MOD.ConnectionToDiagramConnection, Connection, Connection2)),
241 bf(DIA.HasConnector, Connection2, Connector),
242 bf(DIA.Flag_ConnectionPoint_Inverse, Connector, Element),
243 bb(DIA.FlagIsJoinedBy, Element, Join)
245 deny(bb(STR.Joins, Join, Connection)))
247 if_(and(bf(L0.ConsistsOf, Diagram, Element),
248 bf(MOD.DiagramConnectionToConnectionSpecial, Element, Connection),
249 not(b(new Tag(STR.Connects), Connection))),
250 deny(exists(Connection))
254 protected IRuleInstruction destructiveConnectionRule() {
255 // If component has a mapped connection
257 and(bf(MOD.ConnectionMapsTo, Connection, Connection2),
258 or(b(new Negation(new Tag(MOD.ConnectionToDiagramConnectionSpecial)), Connection),
259 b(new Tag(MOD.ElementToComponent), Connection2)
263 new DiagramConnectionExistence(Element, ConnectionRelation, Connection2),
264 /*and(bf(MOD.ConnectionRelationToDiagramConnectionRelation, ConnectionRelation, DiagramConnectionRelation),
265 statement_bbf(Element, DiagramConnectionRelation, Connector),
266 bb(DIA.IsConnectorOf, Connector, Connection2)
268 b(DIA.Connection, Element),
269 b(DIA.Flag, Element), /* This is not entirely correct.
270 It is new not possible to replace
271 a connection to an external signal
274 b(new Negation(new Tag(MOD.ConnectionRelationToDiagramConnectionRelation)), ConnectionRelation),
275 fb(MOD.HasReferenceRelation, CElement, ConnectionRelation)
277 deny(statement(Component, ConnectionRelation, Connection))
279 // If the configuration connection does not have a correspondence in the diagram remove it
280 and(deny(b(new Tag(MOD.ConnectionMapsTo), Connection)), deny(exists(Connection)))
284 protected IRuleInstruction createComponentRule() {
287 // Create a component corresponding to element, if it does not exist, and name it.
289 bf(MOD.ElementToComponent, Element, Component),
290 componentCreationInstruction(Component, ComponentType, Configuration)
292 bb(L0.InstanceOf, Component, ComponentType),
293 bb(L0.PartOf, Component, Configuration),
294 b(mapped, Component) // Mark the component mapped (for destructive rules)
298 IRuleInstruction createConnectionRule() {
300 b(DIA.Connection, Element),
301 // If element is a connection
302 createNormalConnectionRule()
306 protected Resource getConfigurationConnectionType() {
307 return STR.Connection;
310 protected IInstruction claimBasicConnection() {
312 bf(MOD.DiagramConnectionToConnection, Element, Connection),
315 b(getConfigurationConnectionType(), Connection),
316 b(mapped, Connection)
320 protected IRuleInstruction createNormalConnectionRule() {
321 return claim(claimBasicConnection(),
322 if_(and(bf(STR.IsConnectedTo, Element, Connector),
323 statement_ffb(CElement, DiagramConnectionRelation, Connector, STR.IsConnectedTo)
326 if_(and(bf(MOD.DiagramConnectionRelationToConnectionRelation, DiagramConnectionRelation, ConnectionRelation),
327 bf(MOD.ElementToComponent, CElement, Component)
331 if_(or(and(bf(MOD.DiagramConnectionRelationToConnectionRelationB, DiagramConnectionRelation, ConnectionRelation2),
332 b(hasOutputConnector, Element),
333 bf(MOD.DiagramConnectionRelationToConnectionRelationC, DiagramConnectionRelation, ConnectionRelation3),
334 bf(MOD.DiagramConnectionRelationToComponentType, DiagramConnectionRelation, ComponentType)
336 and(bf(MOD.HasConnectionMappingSpecification, Connector, ConnectionMappingSpecification),
337 b(hasOutputConnector, Element),
338 bf(MOD.DiagramConnectionRelationToConnectionRelationB, ConnectionMappingSpecification, ConnectionRelation2),
339 bf(MOD.DiagramConnectionRelationToConnectionRelationC, ConnectionMappingSpecification, ConnectionRelation3),
340 bf(MOD.DiagramConnectionRelationToComponentType, ConnectionMappingSpecification, ComponentType)
346 // Create a component corresponding to connector, if it does not exist, and name it.
348 bf(MOD.ElementToComponent, Element, Component2),
349 new NamingCreationInstruction(project, ConfigurationRoot, Component2, ComponentType, Configuration)
351 bb(L0.InstanceOf, Component2, ComponentType),
352 bb(L0.PartOf, Component2, Configuration),
353 bb(MOD.ConnectorToComponent, Connector, Component2),
354 b(mappedFromConnector, Component2), // Mark the component mapped (for destructive rules)
356 // Create a connection
358 bf(MOD.DiagramConnectionToConnectionSpecial, Element, Connection2),
361 statement(Component2, ConnectionRelation2, Connection2),
362 statement(Component, ConnectionRelation, Connection2),
363 b(getConfigurationConnectionType(), Connection2),
364 b(mapped, Connection2),
367 statement(Component2, ConnectionRelation3, Connection)
371 claim(statement(Component, ConnectionRelation, Connection))
375 if_(bf(MOD.HasReferenceRelation, CElement, ConnectionRelation),
376 if_(bf(MOD.HasParentComponent, CElement, Component),
378 claim(statement(Component, ConnectionRelation, Connection)),
380 claim(statement(CElement, ConnectionRelation, Connection))
388 protected IRuleInstruction createFlagRule() {
392 //print("Flag rule"),
393 if_(and(bf(DIA.FlagIsJoinedBy, Element, ConnectionJoin),
394 bf(compose(STR.IsConnectedTo, STR.Connects, MOD.DiagramConnectionToConnection),
398 bb(STR.Joins, ConnectionJoin, Connection),
399 bb(STR.HasConnectionJoin, Configuration, ConnectionJoin)
401 // This is maybe Apros specific
402 if_(and(b(and(external, inputFlag, flagIsConnected), Element),
403 bf(compose(STR.IsConnectedTo, STR.Connects), Element, Connection2),
404 bf(MOD.DiagramConnectionToConnection, Connection2, Connection),
405 bf(STR.HasConnectionType, Connection2, ConnectionType),
406 bf(MOD.ConnectionTypeToComponentType, ConnectionType, ComponentType),
407 bf(MOD.ConnectionTypeToConnectionRelation, ConnectionType, ConnectionRelation)
411 bf(MOD.ElementToComponent, Element, Component),
412 new NamingCreationInstruction(project, ConfigurationRoot, Component, ComponentType, Configuration)
414 bb(L0.InstanceOf, Component, ComponentType),
415 bb(L0.PartOf, Component, Configuration),
416 b(mapped, Component),
418 statement(Component, ConnectionRelation, Connection)
422 if_(and(bf(DIA.IsLiftedAs, Element, ConnectionRelation),
423 bf(fromFlagToConnection, Element, Connection)),
425 bb(STR.Binds, Connection, ConnectionRelation)
431 class RuleQuery implements Read<IRuleInstruction> {
434 public boolean equals(Object other) {
435 return other != null && other.getClass() == RuleQuery.class &&
436 getParentClass().equals(((RuleQuery)other).getParentClass());
439 private Class<? extends DiagramToCompositeMapping3> getParentClass() {
440 return DiagramToCompositeMapping3.this.getClass();
444 public int hashCode() {
445 return DiagramToCompositeMapping3.this.getClass().hashCode();
449 public IRuleInstruction perform(ReadGraph g) {
451 return createMappingRule();
452 } catch (DatabaseException e) {
461 IRuleInstruction instruction;
462 public Resource source;
463 public Resource target;
464 protected IProject project;
465 protected Resource configurationRoot;
467 protected void setup(ReadGraph graph) {
471 public DiagramToCompositeMapping3(ReadGraph g, Resource mapping) throws DatabaseException {
475 this.session = g.getSession();
477 this.source = g.getPossibleObject(mapping, g.getInverse(Layer0X.getInstance(g).HasTrigger));
479 this.target = g.getPossibleObject(this.source, ModelingResources.getInstance(g).DiagramToComposite);
480 if (target != null) {
481 configurationRoot = ComponentUtils.getCompositeConfigurationRoot(g, target);
482 assert configurationRoot != null;
485 this.project = Simantics.peekProject();
486 this.instruction = g.syncRequest(new RuleQuery());
488 // System.out.println(this + "(mapping=" + mapping
489 // + ", source=" + source
490 // + ", target=" + target
491 // + ", configurationRoot=" + configurationRoot
497 public boolean equals(Object other) {
500 if(!(other instanceof DiagramToCompositeMapping3))
502 DiagramToCompositeMapping3 map = (DiagramToCompositeMapping3)other;
503 return ObjectUtils.objectEquals(map.source, source) && ObjectUtils.objectEquals(map.target, target);
507 public int hashCode() {
508 return ObjectUtils.hashCode(source) + 31 * ObjectUtils.hashCode(target);
512 public IModification perform(ReadGraph g) throws DatabaseException {
513 // System.out.println(this + ": Find modification (source=" + source + ", target=" + target + ", configurationRoot=" + configurationRoot + ")");
515 if(IInstruction.DEBUG_MODI)
516 System.out.println("--- MAPPING ROUND -------------------------------- " + NameUtils.getURIOrSafeNameInternal(g, target));
518 if (source == null || target == null)
521 final Object[] bindings = new Object[VARIABLE_COUNT];
522 bindings[Diagram] = source;
523 bindings[Configuration] = target;
524 bindings[ConfigurationRoot] = configurationRoot;
525 IModification modi = instruction.execute(g, bindings);
526 //System.out.println("modi = " + modi);