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
198 and(deny(b(new Tag(MOD.ComponentToElement), Component)), deny(exists(Component)))
202 if_(b(mappedFromConnector, Component), // handle only mapped components
204 unless(bf(MOD.ComponentToConnector, Component, Connector),
205 and(deny(b(new Tag(MOD.ComponentToElement), Component)), deny(exists(Component)))
211 // Destroy connections
212 if_(and(bf(STR.HasConnectionJoin, Configuration, Join),
213 b(internalJoin, Join),
214 bf(STR.Joins, Join, Connection),
215 b(mapped, Connection)),
216 unless(and(bf(MOD.ConnectionMapsTo, Connection, Connection2),
217 or(b(new Negation(new Tag(MOD.ConnectionToDiagramConnectionSpecial)), Connection),
218 b(new Tag(MOD.ElementToComponent), Connection2)
221 and(deny(b(new Tag(MOD.ConnectionMapsTo), Connection)), deny(exists(Connection)))
224 if_(and(bf(STR.HasConnectionJoin, Configuration, Join),
225 bf(STR.Joins, Join, Connection),
226 b(mapped, Connection),
227 b(not(new Tag(STR.Connects)), Connection),
228 b(not(new Tag(MOD.ConnectionMapsTo)), Connection)),
229 deny(exists(Connection))
231 if_(and(bf(STR.HasConnectionJoin, Configuration, Join),
232 bf(STR.Joins, Join, Connection),
233 bf(MOD.ConnectionToDiagramConnection, Connection, Connection2)),
235 bf(DIA.HasConnector, Connection2, Connector),
236 bf(DIA.Flag_ConnectionPoint_Inverse, Connector, Element),
237 bb(DIA.FlagIsJoinedBy, Element, Join)
239 deny(bb(STR.Joins, Join, Connection)))
241 if_(and(bf(L0.ConsistsOf, Diagram, Element),
242 bf(MOD.DiagramConnectionToConnectionSpecial, Element, Connection),
243 not(b(new Tag(STR.Connects), Connection))),
244 deny(exists(Connection))
248 protected IRuleInstruction destructiveConnectionRule() {
249 // If component has a mapped connection
251 and(bf(MOD.ConnectionMapsTo, Connection, Connection2),
252 or(b(new Negation(new Tag(MOD.ConnectionToDiagramConnectionSpecial)), Connection),
253 b(new Tag(MOD.ElementToComponent), Connection2)
257 new DiagramConnectionExistence(Element, ConnectionRelation, Connection2),
258 /*and(bf(MOD.ConnectionRelationToDiagramConnectionRelation, ConnectionRelation, DiagramConnectionRelation),
259 statement_bbf(Element, DiagramConnectionRelation, Connector),
260 bb(DIA.IsConnectorOf, Connector, Connection2)
262 b(DIA.Connection, Element),
263 b(DIA.Flag, Element), /* This is not entirely correct.
264 It is new not possible to replace
265 a connection to an external signal
268 b(new Negation(new Tag(MOD.ConnectionRelationToDiagramConnectionRelation)), ConnectionRelation),
269 fb(MOD.HasReferenceRelation, CElement, ConnectionRelation)
271 deny(statement(Component, ConnectionRelation, Connection))
273 // If the configuration connection does not have a correspondence in the diagram remove it
274 and(deny(b(new Tag(MOD.ConnectionMapsTo), Connection)), deny(exists(Connection)))
278 protected IRuleInstruction createComponentRule() {
281 // Create a component corresponding to element, if it does not exist, and name it.
283 bf(MOD.ElementToComponent, Element, Component),
284 componentCreationInstruction(Component, ComponentType, Configuration)
286 bb(L0.InstanceOf, Component, ComponentType),
287 bb(L0.PartOf, Component, Configuration),
288 b(mapped, Component) // Mark the component mapped (for destructive rules)
292 IRuleInstruction createConnectionRule() {
294 b(DIA.Connection, Element),
295 // If element is a connection
296 createNormalConnectionRule()
300 protected Resource getConfigurationConnectionType() {
301 return STR.Connection;
304 protected IInstruction claimBasicConnection() {
306 bf(MOD.DiagramConnectionToConnection, Element, Connection),
309 b(getConfigurationConnectionType(), Connection),
310 b(mapped, Connection)
314 protected IRuleInstruction createNormalConnectionRule() {
315 return claim(claimBasicConnection(),
316 if_(and(bf(STR.IsConnectedTo, Element, Connector),
317 statement_ffb(CElement, DiagramConnectionRelation, Connector, STR.IsConnectedTo)
320 if_(and(bf(MOD.DiagramConnectionRelationToConnectionRelation, DiagramConnectionRelation, ConnectionRelation),
321 bf(MOD.ElementToComponent, CElement, Component)
325 if_(or(and(bf(MOD.DiagramConnectionRelationToConnectionRelationB, DiagramConnectionRelation, ConnectionRelation2),
326 b(hasOutputConnector, Element),
327 bf(MOD.DiagramConnectionRelationToConnectionRelationC, DiagramConnectionRelation, ConnectionRelation3),
328 bf(MOD.DiagramConnectionRelationToComponentType, DiagramConnectionRelation, ComponentType)
330 and(bf(MOD.HasConnectionMappingSpecification, Connector, ConnectionMappingSpecification),
331 b(hasOutputConnector, Element),
332 bf(MOD.DiagramConnectionRelationToConnectionRelationB, ConnectionMappingSpecification, ConnectionRelation2),
333 bf(MOD.DiagramConnectionRelationToConnectionRelationC, ConnectionMappingSpecification, ConnectionRelation3),
334 bf(MOD.DiagramConnectionRelationToComponentType, ConnectionMappingSpecification, ComponentType)
340 // Create a component corresponding to connector, if it does not exist, and name it.
342 bf(MOD.ElementToComponent, Element, Component2),
343 new NamingCreationInstruction(project, ConfigurationRoot, Component2, ComponentType, Configuration)
345 bb(L0.InstanceOf, Component2, ComponentType),
346 bb(L0.PartOf, Component2, Configuration),
347 bb(MOD.ConnectorToComponent, Connector, Component2),
348 b(mappedFromConnector, Component2), // Mark the component mapped (for destructive rules)
350 // Create a connection
352 bf(MOD.DiagramConnectionToConnectionSpecial, Element, Connection2),
355 statement(Component2, ConnectionRelation2, Connection2),
356 statement(Component, ConnectionRelation, Connection2),
357 b(getConfigurationConnectionType(), Connection2),
358 b(mapped, Connection2),
361 statement(Component2, ConnectionRelation3, Connection)
365 claim(statement(Component, ConnectionRelation, Connection))
369 if_(bf(MOD.HasReferenceRelation, CElement, ConnectionRelation),
370 if_(bf(MOD.HasParentComponent, CElement, Component),
372 claim(statement(Component, ConnectionRelation, Connection)),
374 claim(statement(CElement, ConnectionRelation, Connection))
382 protected IRuleInstruction createFlagRule() {
386 //print("Flag rule"),
387 if_(and(bf(DIA.FlagIsJoinedBy, Element, ConnectionJoin),
388 bf(compose(STR.IsConnectedTo, STR.Connects, MOD.DiagramConnectionToConnection),
392 bb(STR.Joins, ConnectionJoin, Connection),
393 bb(STR.HasConnectionJoin, Configuration, ConnectionJoin)
395 // This is maybe Apros specific
396 if_(and(b(and(external, inputFlag, flagIsConnected), Element),
397 bf(compose(STR.IsConnectedTo, STR.Connects), Element, Connection2),
398 bf(MOD.DiagramConnectionToConnection, Connection2, Connection),
399 bf(STR.HasConnectionType, Connection2, ConnectionType),
400 bf(MOD.ConnectionTypeToComponentType, ConnectionType, ComponentType),
401 bf(MOD.ConnectionTypeToConnectionRelation, ConnectionType, ConnectionRelation)
405 bf(MOD.ElementToComponent, Element, Component),
406 new NamingCreationInstruction(project, ConfigurationRoot, Component, ComponentType, Configuration)
408 bb(L0.InstanceOf, Component, ComponentType),
409 bb(L0.PartOf, Component, Configuration),
410 b(mapped, Component),
412 statement(Component, ConnectionRelation, Connection)
416 if_(and(bf(DIA.IsLiftedAs, Element, ConnectionRelation),
417 bf(fromFlagToConnection, Element, Connection)),
419 bb(STR.Binds, Connection, ConnectionRelation)
425 class RuleQuery implements Read<IRuleInstruction> {
428 public boolean equals(Object other) {
429 return other != null && other.getClass() == RuleQuery.class &&
430 getParentClass().equals(((RuleQuery)other).getParentClass());
433 private Class<? extends DiagramToCompositeMapping3> getParentClass() {
434 return DiagramToCompositeMapping3.this.getClass();
438 public int hashCode() {
439 return DiagramToCompositeMapping3.this.getClass().hashCode();
443 public IRuleInstruction perform(ReadGraph g) {
445 return createMappingRule();
446 } catch (DatabaseException e) {
455 IRuleInstruction instruction;
456 public Resource source;
457 public Resource target;
458 protected IProject project;
459 protected Resource configurationRoot;
461 protected void setup(ReadGraph graph) {
465 public DiagramToCompositeMapping3(ReadGraph g, Resource mapping) throws DatabaseException {
469 this.session = g.getSession();
471 this.source = g.getPossibleObject(mapping, g.getInverse(Layer0X.getInstance(g).HasTrigger));
473 this.target = g.getPossibleObject(this.source, ModelingResources.getInstance(g).DiagramToComposite);
474 if (target != null) {
475 configurationRoot = ComponentUtils.getCompositeConfigurationRoot(g, target);
476 assert configurationRoot != null;
479 this.project = Simantics.peekProject();
480 this.instruction = g.syncRequest(new RuleQuery());
482 // System.out.println(this + "(mapping=" + mapping
483 // + ", source=" + source
484 // + ", target=" + target
485 // + ", configurationRoot=" + configurationRoot
491 public boolean equals(Object other) {
494 if(!(other instanceof DiagramToCompositeMapping3))
496 DiagramToCompositeMapping3 map = (DiagramToCompositeMapping3)other;
497 return ObjectUtils.objectEquals(map.source, source) && ObjectUtils.objectEquals(map.target, target);
501 public int hashCode() {
502 return ObjectUtils.hashCode(source) + 31 * ObjectUtils.hashCode(target);
506 public IModification perform(ReadGraph g) throws DatabaseException {
507 // System.out.println(this + ": Find modification (source=" + source + ", target=" + target + ", configurationRoot=" + configurationRoot + ")");
509 if(IInstruction.DEBUG_MODI)
510 System.out.println("--- MAPPING ROUND -------------------------------- " + NameUtils.getURIOrSafeNameInternal(g, target));
512 if (source == null || target == null)
515 final Object[] bindings = new Object[VARIABLE_COUNT];
516 bindings[Diagram] = source;
517 bindings[Configuration] = target;
518 bindings[ConfigurationRoot] = configurationRoot;
519 IModification modi = instruction.execute(g, bindings);
520 //System.out.println("modi = " + modi);