]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/flags/ExpandFlags.java
Find SCL references in SCLModuleEditor with Ctrl+Shift+G
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / flags / ExpandFlags.java
1 /*******************************************************************************
2  * Copyright (c) 2012 Association for Decentralized Information Management in
3  * Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.modeling.flags;
13
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Iterator;
17
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;
34
35 /**
36  * @author Hannu Niemistö
37  */
38 public class ExpandFlags {
39     
40     static class Connector {
41         Resource element;
42         Resource terminal;
43         
44         public Connector(Resource element, Resource terminal) {        
45             this.element = element;
46             this.terminal = terminal;
47         }
48     }
49     
50     private static ArrayList<Connector> getConnectors(ReadGraph g, Resource connection) throws DatabaseException {
51         StructuralResource2 STR = StructuralResource2.getInstance(g);
52         
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())));
58                 }
59         }
60         return result;
61     }
62
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);
66     }
67     
68     /**
69      * @param graph
70      * @param flag
71      * @return the flags that result from the expansion operation
72      * @throws DatabaseException
73      */
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);
80         
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
85                                 
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;
95                         break;
96                     }
97
98         if(connectsStatement == null)
99             return Resource.NONE;
100                 Resource arrowType = connectsStatement.getPredicate();
101                 Resource diagramConnection = connectsStatement.getObject();
102                 Resource connection = graph.getSingleObject(diagramConnection, MOD.DiagramConnectionToConnection);
103                 
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))
109                     it.remove();
110             }
111         }
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);
123         }
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);
128         }
129         else {
130             routeLine = graph.getSingleObject(connector, DIA.AreConnected);       
131
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);
142             }   
143         }
144
145                 Resource[] joins = joins_.toArray(new Resource[joins_.size()]);
146                 Resource[] flags = new Resource[joins.length];
147
148                 final double flagSeparation = FlagClass.DEFAULT_HEIGHT;
149
150                 flags[0] = flag;
151                 for(int i=1;i<flags.length;++i) {
152                         Resource newFlag = graph.newResource();
153                         flags[i] = newFlag;
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);
164                                         }
165                                 }
166                         }
167                         graph.claim(newFlag, DIA.FlagIsJoinedBy, joins[i]);
168
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);
172
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]
177                         };
178                         graph.claimLiteral(newFlag, DIA.HasTransform, G2D.Transform, newTransform);
179
180                         // TODO: Handle branching and non-branching connections differently
181                         
182                         if(routeLine == null) {
183                             Resource newConnector1 = graph.newResource();
184                             Resource newDiagramConnection = graph.newResource();
185                             Resource newConnector2 = graph.newResource();
186                             Resource newConnection = graph.newResource();
187                             
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);
193                             
194                             Resource arrow = graph.getInverse(arrowType);
195                             Resource otherArrow = arrow.equals(DIA.HasPlainConnector) ?
196                                 DIA.HasArrowConnector : DIA.HasPlainConnector;
197                             
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);
203                             
204                             graph.claim(component, connectionPoint, newConnection);
205                             graph.deny(joins[i], STR.Joins, connection);
206                             graph.claim(joins[i], STR.Joins, newConnection);
207                             
208                             graph.claim(newDiagramConnection, MOD.DiagramConnectionToConnection, newConnection);
209                             graph.claim(newConnection, MOD.Mapped, newConnection);
210                             
211                             AddElement.claimFreshElementName(graph, diagram, newDiagramConnection);
212                             
213                             OrderedSetUtils.addFirst(graph, diagram, newDiagramConnection);
214                             graph.claim(diagram, L0.ConsistsOf, newDiagramConnection);
215                         }
216                         else {
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);
222                         }
223                 }
224
225                 return flags;
226         }
227         
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);
232         
233         Resource diagram = graph.getPossibleObject(composite, MOD.CompositeToDiagram);
234         if(diagram == null)
235             return;
236         
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) {
241                         groups.add(element);
242                 }
243             }
244         }
245
246 }