]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/flags/ExpandFlags.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / flags / ExpandFlags.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.modeling.flags;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Collection;\r
16 import java.util.Iterator;\r
17 \r
18 import org.simantics.db.ReadGraph;\r
19 import org.simantics.db.Resource;\r
20 import org.simantics.db.Statement;\r
21 import org.simantics.db.WriteGraph;\r
22 import org.simantics.db.common.request.IndexRoot;\r
23 import org.simantics.db.common.utils.OrderedSetUtils;\r
24 import org.simantics.db.exception.DatabaseException;\r
25 import org.simantics.diagram.stubs.DiagramResource;\r
26 import org.simantics.diagram.stubs.G2DResource;\r
27 import org.simantics.diagram.synchronization.graph.AddElement;\r
28 import org.simantics.diagram.synchronization.graph.CopyAdvisorUtil;\r
29 import org.simantics.g2d.elementclass.FlagClass;\r
30 import org.simantics.layer0.Layer0;\r
31 import org.simantics.modeling.ModelingResources;\r
32 import org.simantics.scl.commands.Commands;\r
33 import org.simantics.structural.stubs.StructuralResource2;\r
34 \r
35 /**\r
36  * @author Hannu Niemistö\r
37  */\r
38 public class ExpandFlags {\r
39     \r
40     static class Connector {\r
41         Resource element;\r
42         Resource terminal;\r
43         \r
44         public Connector(Resource element, Resource terminal) {        \r
45             this.element = element;\r
46             this.terminal = terminal;\r
47         }\r
48     }\r
49     \r
50     private static ArrayList<Connector> getConnectors(ReadGraph g, Resource connection) throws DatabaseException {\r
51         StructuralResource2 STR = StructuralResource2.getInstance(g);\r
52         \r
53         ArrayList<Connector> result = new ArrayList<Connector>();\r
54         for(Resource connector : g.getObjects(connection, STR.IsConnectedTo)) {\r
55             for(Statement stat : g.getStatements(connector, STR.Connects)) \r
56                 if(!connection.equals(stat.getObject())) {\r
57                     result.add(new Connector(stat.getObject(), g.getInverse(stat.getPredicate())));\r
58                 }\r
59         }\r
60         return result;\r
61     }\r
62 \r
63     public static Resource[] expandFlag(WriteGraph graph, Resource flag) throws DatabaseException {\r
64         return (Resource[])Commands.get(graph, "Simantics/Flag/expandFlag")\r
65                 .execute(graph, graph.syncRequest(new IndexRoot(flag)), flag);\r
66     }\r
67     \r
68     /**\r
69      * @param graph\r
70      * @param flag\r
71      * @return the flags that result from the expansion operation\r
72      * @throws DatabaseException\r
73      */\r
74         public static Resource[] expandFlagWithoutMetadata(WriteGraph graph, Resource flag) throws DatabaseException {\r
75                 DiagramResource DIA = DiagramResource.getInstance(graph);\r
76                 G2DResource G2D = G2DResource.getInstance(graph);\r
77                 StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
78                 Layer0 L0 = Layer0.getInstance(graph);\r
79         ModelingResources MOD = ModelingResources.getInstance(graph);\r
80         \r
81                 // Find joins and check if this is multiflag\r
82                 Collection<Resource> joins_ = graph.getObjects(flag, DIA.FlagIsJoinedBy);\r
83                 if(joins_.size() <= 1)\r
84                         return Resource.NONE; // Nothing to do\r
85                                 \r
86                 // Analyze expanded flag\r
87                 Resource diagram = OrderedSetUtils.getSubjects(graph, flag).iterator().next();\r
88                 Resource flagType = graph.getSingleObject(flag, DIA.HasFlagType);\r
89                 double[] transform = graph.getRelatedValue(flag, DIA.HasTransform);\r
90                 Resource connector = graph.getSingleObject(flag, DIA.Flag_ConnectionPoint);\r
91                 Statement connectsStatement = null;\r
92                 for(Statement temp : graph.getStatements(connector, STR.Connects))\r
93                     if(!flag.equals(temp.getObject())) {\r
94                         connectsStatement = temp;\r
95                         break;\r
96                     }\r
97 \r
98         if(connectsStatement == null)\r
99             return Resource.NONE;\r
100                 Resource arrowType = connectsStatement.getPredicate();\r
101                 Resource diagramConnection = connectsStatement.getObject();\r
102                 Resource connection = graph.getSingleObject(diagramConnection, MOD.DiagramConnectionToConnection);\r
103                 \r
104         ArrayList<Connector> connectors = getConnectors(graph, diagramConnection);\r
105         if(connectors.size()==2) {\r
106             Iterator<Connector> it = connectors.iterator();\r
107             while(it.hasNext()) {\r
108                 if(it.next().element.equals(flag))\r
109                     it.remove();\r
110             }\r
111         }\r
112         Resource diagramRelation = connectors.size()!=1 ? null : \r
113             connectors.get(0).terminal;\r
114         Resource connectionPoint = diagramRelation == null ? null :\r
115             graph.getPossibleObject(diagramRelation, MOD.DiagramConnectionRelationToConnectionRelation); \r
116         Resource element=connectors.size()==1 ? connectors.get(0).element : null, \r
117                 component=null, connectionType=null;\r
118         Resource routeLine = null;\r
119         if(connectionPoint != null && \r
120                 !graph.isInstanceOf(connectionPoint, L0.FunctionalRelation)) {\r
121             component = graph.getSingleObject(element, MOD.ElementToComponent);\r
122             connectionType = graph.getSingleObject(diagramConnection, STR.HasConnectionType);\r
123         }\r
124         else if(element != null && graph.isInstanceOf(element, MOD.ReferenceElement)) {\r
125             component = graph.getSingleObject(element, MOD.HasParentComponent);\r
126             connectionPoint = graph.getSingleObject(element, MOD.HasReferenceRelation);\r
127             connectionType = graph.getSingleObject(diagramConnection, STR.HasConnectionType);\r
128         }\r
129         else {\r
130             routeLine = graph.getSingleObject(connector, DIA.AreConnected);       \r
131 \r
132             if(!graph.isInstanceOf(routeLine, DIA.RouteLine)) {\r
133                 Resource otherConnector = routeLine;\r
134                 routeLine = graph.newResource();\r
135                 graph.deny(connector, DIA.AreConnected, otherConnector);\r
136                 graph.claim(routeLine, L0.InstanceOf, DIA.RouteLine);\r
137                 graph.claim(diagramConnection, DIA.HasInteriorRouteNode, routeLine);\r
138                 graph.claimLiteral(routeLine, DIA.HasPosition, transform[4]-FlagClass.DEFAULT_WIDTH*0.5);\r
139                 graph.claimLiteral(routeLine, DIA.IsHorizontal, false);\r
140                 graph.claim(routeLine, DIA.AreConnected, connector);\r
141                 graph.claim(routeLine, DIA.AreConnected, otherConnector);\r
142             }   \r
143         }\r
144 \r
145                 Resource[] joins = joins_.toArray(new Resource[joins_.size()]);\r
146                 Resource[] flags = new Resource[joins.length];\r
147 \r
148                 final double flagSeparation = FlagClass.DEFAULT_HEIGHT;\r
149 \r
150                 flags[0] = flag;\r
151                 for(int i=1;i<flags.length;++i) {\r
152                         Resource newFlag = graph.newResource();\r
153                         flags[i] = newFlag;\r
154                         graph.claim(newFlag, L0.InstanceOf, DIA.Flag);\r
155                         graph.claim(newFlag, DIA.HasFlagType, flagType);\r
156                         OrderedSetUtils.add(graph, diagram, newFlag);\r
157                         graph.claim(diagram, L0.ConsistsOf, newFlag);\r
158                         graph.deny(flag, DIA.FlagIsJoinedBy, joins[i]);\r
159                         for(Resource otherFlag : graph.getObjects(joins[i], DIA.JoinsFlag)) {\r
160                                 for(Statement label : graph.getStatements(otherFlag, L0.HasLabel)) {\r
161                                         if (!label.isAsserted(otherFlag)) {\r
162                                                 Resource literalCopy = CopyAdvisorUtil.copy(graph, label.getObject(), null);\r
163                                                 graph.claim(newFlag, label.getPredicate(), literalCopy);\r
164                                         }\r
165                                 }\r
166                         }\r
167                         graph.claim(newFlag, DIA.FlagIsJoinedBy, joins[i]);\r
168 \r
169                         // URI: Make new flag a part of the diagram and give it a fresh name\r
170                         graph.claim(diagram, L0.ConsistsOf, newFlag);\r
171                         AddElement.claimFreshElementName(graph, diagram, newFlag);\r
172 \r
173                         double[] newTransform = new double[] {\r
174                                 transform[0], transform[1], transform[2], transform[3], \r
175                                 transform[4] + i*flagSeparation*transform[2], \r
176                                 transform[5] + i*flagSeparation*transform[3]\r
177                         };\r
178                         graph.claimLiteral(newFlag, DIA.HasTransform, G2D.Transform, newTransform);\r
179 \r
180                         // TODO: Handle branching and non-branching connections differently\r
181                         \r
182                         if(routeLine == null) {\r
183                             Resource newConnector1 = graph.newResource();\r
184                             Resource newDiagramConnection = graph.newResource();\r
185                             Resource newConnector2 = graph.newResource();\r
186                             Resource newConnection = graph.newResource();\r
187                             \r
188                             graph.claim(newConnector1, L0.InstanceOf, DIA.Connector);\r
189                             graph.claim(newDiagramConnection, L0.InstanceOf, DIA.RouteGraphConnection);\r
190                             graph.claim(newDiagramConnection, STR.HasConnectionType, connectionType);\r
191                             graph.claim(newConnector2, L0.InstanceOf, DIA.Connector);\r
192                             graph.claim(newConnection, L0.InstanceOf, STR.Connection);\r
193                             \r
194                             Resource arrow = graph.getInverse(arrowType);\r
195                             Resource otherArrow = arrow.equals(DIA.HasPlainConnector) ?\r
196                                 DIA.HasArrowConnector : DIA.HasPlainConnector;\r
197                             \r
198                             graph.claim(element, diagramRelation, newConnector1);\r
199                             graph.claim(newDiagramConnection, otherArrow, newConnector1);\r
200                             graph.claim(newDiagramConnection, arrow, newConnector2);\r
201                             graph.claim(newConnector1, DIA.AreConnected, newConnector2);\r
202                             graph.claim(newFlag, DIA.Flag_ConnectionPoint, newConnector2);\r
203                             \r
204                             graph.claim(component, connectionPoint, newConnection);\r
205                             graph.deny(joins[i], STR.Joins, connection);\r
206                             graph.claim(joins[i], STR.Joins, newConnection);\r
207                             \r
208                             graph.claim(newDiagramConnection, MOD.DiagramConnectionToConnection, newConnection);\r
209                             graph.claim(newConnection, MOD.Mapped, newConnection);\r
210                             \r
211                             AddElement.claimFreshElementName(graph, diagram, newDiagramConnection);\r
212                             \r
213                             OrderedSetUtils.addFirst(graph, diagram, newDiagramConnection);\r
214                             graph.claim(diagram, L0.ConsistsOf, newDiagramConnection);\r
215                         }\r
216                         else {\r
217                             Resource newConnector = graph.newResource();\r
218                     graph.claim(newConnector, L0.InstanceOf, DIA.Connector);\r
219                     graph.claim(newFlag, DIA.Flag_ConnectionPoint, newConnector);\r
220                             graph.claim(newConnector, arrowType, diagramConnection);\r
221                             graph.claim(newConnector, DIA.AreConnected, routeLine);\r
222                         }\r
223                 }\r
224 \r
225                 return flags;\r
226         }\r
227         \r
228         public static void collectGroupedFlags(ReadGraph graph, Resource composite, ArrayList<Resource> groups) throws DatabaseException {\r
229             DiagramResource DIA = DiagramResource.getInstance(graph);\r
230         ModelingResources MOD = ModelingResources.getInstance(graph);\r
231         Layer0 L0 = Layer0.getInstance(graph);\r
232         \r
233         Resource diagram = graph.getPossibleObject(composite, MOD.CompositeToDiagram);\r
234         if(diagram == null)\r
235             return;\r
236         \r
237         for(Resource element : graph.getObjects(diagram, L0.ConsistsOf))\r
238             if(graph.isInstanceOf(element, DIA.Flag)) {\r
239                 Collection<Resource> objects = (Collection<Resource>) graph.getObjects(element, DIA.FlagIsJoinedBy);\r
240                 if (objects.size() > 1) {\r
241                         groups.add(element);\r
242                 }\r
243             }\r
244         }\r
245 \r
246 }\r