1 /*******************************************************************************
2 * Copyright (c) 2012 Association for Decentralized Information Management in
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.flags;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Iterator;
18 import org.simantics.db.ReadGraph;
19 import org.simantics.db.Resource;
20 import org.simantics.db.Statement;
21 import org.simantics.db.WriteGraph;
22 import org.simantics.db.common.request.IndexRoot;
23 import org.simantics.db.common.utils.OrderedSetUtils;
24 import org.simantics.db.exception.DatabaseException;
25 import org.simantics.diagram.stubs.DiagramResource;
26 import org.simantics.diagram.stubs.G2DResource;
27 import org.simantics.diagram.synchronization.graph.AddElement;
28 import org.simantics.diagram.synchronization.graph.CopyAdvisorUtil;
29 import org.simantics.g2d.elementclass.FlagClass;
30 import org.simantics.layer0.Layer0;
31 import org.simantics.modeling.ModelingResources;
32 import org.simantics.scl.commands.Commands;
33 import org.simantics.structural.stubs.StructuralResource2;
36 * @author Hannu Niemistö
38 public class ExpandFlags {
40 static class Connector {
44 public Connector(Resource element, Resource terminal) {
45 this.element = element;
46 this.terminal = terminal;
50 private static ArrayList<Connector> getConnectors(ReadGraph g, Resource connection) throws DatabaseException {
51 StructuralResource2 STR = StructuralResource2.getInstance(g);
53 ArrayList<Connector> result = new ArrayList<Connector>();
54 for(Resource connector : g.getObjects(connection, STR.IsConnectedTo)) {
55 for(Statement stat : g.getStatements(connector, STR.Connects))
56 if(!connection.equals(stat.getObject())) {
57 result.add(new Connector(stat.getObject(), g.getInverse(stat.getPredicate())));
63 public static Resource[] expandFlag(WriteGraph graph, Resource flag) throws DatabaseException {
64 return (Resource[])Commands.get(graph, "Simantics/Flag/expandFlag")
65 .execute(graph, graph.syncRequest(new IndexRoot(flag)), flag);
71 * @return the flags that result from the expansion operation
72 * @throws DatabaseException
74 public static Resource[] expandFlagWithoutMetadata(WriteGraph graph, Resource flag) throws DatabaseException {
75 DiagramResource DIA = DiagramResource.getInstance(graph);
76 G2DResource G2D = G2DResource.getInstance(graph);
77 StructuralResource2 STR = StructuralResource2.getInstance(graph);
78 Layer0 L0 = Layer0.getInstance(graph);
79 ModelingResources MOD = ModelingResources.getInstance(graph);
81 // Find joins and check if this is multiflag
82 Collection<Resource> joins_ = graph.getObjects(flag, DIA.FlagIsJoinedBy);
83 if(joins_.size() <= 1)
84 return Resource.NONE; // Nothing to do
86 // Analyze expanded flag
87 Resource diagram = OrderedSetUtils.getSubjects(graph, flag).iterator().next();
88 Resource flagType = graph.getSingleObject(flag, DIA.HasFlagType);
89 double[] transform = graph.getRelatedValue(flag, DIA.HasTransform);
90 Resource connector = graph.getSingleObject(flag, DIA.Flag_ConnectionPoint);
91 Statement connectsStatement = null;
92 for(Statement temp : graph.getStatements(connector, STR.Connects))
93 if(!flag.equals(temp.getObject())) {
94 connectsStatement = temp;
98 if(connectsStatement == null)
100 Resource arrowType = connectsStatement.getPredicate();
101 Resource diagramConnection = connectsStatement.getObject();
102 Resource connection = graph.getSingleObject(diagramConnection, MOD.DiagramConnectionToConnection);
104 ArrayList<Connector> connectors = getConnectors(graph, diagramConnection);
105 if(connectors.size()==2) {
106 Iterator<Connector> it = connectors.iterator();
107 while(it.hasNext()) {
108 if(it.next().element.equals(flag))
112 Resource diagramRelation = connectors.size()!=1 ? null :
113 connectors.get(0).terminal;
114 Resource connectionPoint = diagramRelation == null ? null :
115 graph.getPossibleObject(diagramRelation, MOD.DiagramConnectionRelationToConnectionRelation);
116 Resource element=connectors.size()==1 ? connectors.get(0).element : null,
117 component=null, connectionType=null;
118 Resource routeLine = null;
119 if(connectionPoint != null &&
120 !graph.isInstanceOf(connectionPoint, L0.FunctionalRelation)) {
121 component = graph.getSingleObject(element, MOD.ElementToComponent);
122 connectionType = graph.getSingleObject(diagramConnection, STR.HasConnectionType);
124 else if(element != null && graph.isInstanceOf(element, MOD.ReferenceElement)) {
125 component = graph.getSingleObject(element, MOD.HasParentComponent);
126 connectionPoint = graph.getSingleObject(element, MOD.HasReferenceRelation);
127 connectionType = graph.getSingleObject(diagramConnection, STR.HasConnectionType);
130 routeLine = graph.getSingleObject(connector, DIA.AreConnected);
132 if(!graph.isInstanceOf(routeLine, DIA.RouteLine)) {
133 Resource otherConnector = routeLine;
134 routeLine = graph.newResource();
135 graph.deny(connector, DIA.AreConnected, otherConnector);
136 graph.claim(routeLine, L0.InstanceOf, DIA.RouteLine);
137 graph.claim(diagramConnection, DIA.HasInteriorRouteNode, routeLine);
138 graph.claimLiteral(routeLine, DIA.HasPosition, transform[4]-FlagClass.DEFAULT_WIDTH*0.5);
139 graph.claimLiteral(routeLine, DIA.IsHorizontal, false);
140 graph.claim(routeLine, DIA.AreConnected, connector);
141 graph.claim(routeLine, DIA.AreConnected, otherConnector);
145 Resource[] joins = joins_.toArray(new Resource[joins_.size()]);
146 Resource[] flags = new Resource[joins.length];
148 final double flagSeparation = FlagClass.DEFAULT_HEIGHT;
151 for(int i=1;i<flags.length;++i) {
152 Resource newFlag = graph.newResource();
154 graph.claim(newFlag, L0.InstanceOf, DIA.Flag);
155 graph.claim(newFlag, DIA.HasFlagType, flagType);
156 OrderedSetUtils.add(graph, diagram, newFlag);
157 graph.claim(diagram, L0.ConsistsOf, newFlag);
158 graph.deny(flag, DIA.FlagIsJoinedBy, joins[i]);
159 for(Resource otherFlag : graph.getObjects(joins[i], DIA.JoinsFlag)) {
160 for(Statement label : graph.getStatements(otherFlag, L0.HasLabel)) {
161 if (!label.isAsserted(otherFlag)) {
162 Resource literalCopy = CopyAdvisorUtil.copy(graph, label.getObject(), null);
163 graph.claim(newFlag, label.getPredicate(), literalCopy);
167 graph.claim(newFlag, DIA.FlagIsJoinedBy, joins[i]);
169 // URI: Make new flag a part of the diagram and give it a fresh name
170 graph.claim(diagram, L0.ConsistsOf, newFlag);
171 AddElement.claimFreshElementName(graph, diagram, newFlag);
173 double[] newTransform = new double[] {
174 transform[0], transform[1], transform[2], transform[3],
175 transform[4] + i*flagSeparation*transform[2],
176 transform[5] + i*flagSeparation*transform[3]
178 graph.claimLiteral(newFlag, DIA.HasTransform, G2D.Transform, newTransform);
180 // TODO: Handle branching and non-branching connections differently
182 if(routeLine == null) {
183 Resource newConnector1 = graph.newResource();
184 Resource newDiagramConnection = graph.newResource();
185 Resource newConnector2 = graph.newResource();
186 Resource newConnection = graph.newResource();
188 graph.claim(newConnector1, L0.InstanceOf, DIA.Connector);
189 graph.claim(newDiagramConnection, L0.InstanceOf, DIA.RouteGraphConnection);
190 graph.claim(newDiagramConnection, STR.HasConnectionType, connectionType);
191 graph.claim(newConnector2, L0.InstanceOf, DIA.Connector);
192 graph.claim(newConnection, L0.InstanceOf, STR.Connection);
194 Resource arrow = graph.getInverse(arrowType);
195 Resource otherArrow = arrow.equals(DIA.HasPlainConnector) ?
196 DIA.HasArrowConnector : DIA.HasPlainConnector;
198 graph.claim(element, diagramRelation, newConnector1);
199 graph.claim(newDiagramConnection, otherArrow, newConnector1);
200 graph.claim(newDiagramConnection, arrow, newConnector2);
201 graph.claim(newConnector1, DIA.AreConnected, newConnector2);
202 graph.claim(newFlag, DIA.Flag_ConnectionPoint, newConnector2);
204 graph.claim(component, connectionPoint, newConnection);
205 graph.deny(joins[i], STR.Joins, connection);
206 graph.claim(joins[i], STR.Joins, newConnection);
208 graph.claim(newDiagramConnection, MOD.DiagramConnectionToConnection, newConnection);
209 graph.claim(newConnection, MOD.Mapped, newConnection);
211 AddElement.claimFreshElementName(graph, diagram, newDiagramConnection);
213 OrderedSetUtils.addFirst(graph, diagram, newDiagramConnection);
214 graph.claim(diagram, L0.ConsistsOf, newDiagramConnection);
217 Resource newConnector = graph.newResource();
218 graph.claim(newConnector, L0.InstanceOf, DIA.Connector);
219 graph.claim(newFlag, DIA.Flag_ConnectionPoint, newConnector);
220 graph.claim(newConnector, arrowType, diagramConnection);
221 graph.claim(newConnector, DIA.AreConnected, routeLine);
228 public static void collectGroupedFlags(ReadGraph graph, Resource composite, ArrayList<Resource> groups) throws DatabaseException {
229 DiagramResource DIA = DiagramResource.getInstance(graph);
230 ModelingResources MOD = ModelingResources.getInstance(graph);
231 Layer0 L0 = Layer0.getInstance(graph);
233 Resource diagram = graph.getPossibleObject(composite, MOD.CompositeToDiagram);
237 for(Resource element : graph.getObjects(diagram, L0.ConsistsOf))
238 if(graph.isInstanceOf(element, DIA.Flag)) {
239 Collection<Resource> objects = (Collection<Resource>) graph.getObjects(element, DIA.FlagIsJoinedBy);
240 if (objects.size() > 1) {