--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modeling.flags;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Iterator;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.IndexRoot;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.diagram.synchronization.graph.AddElement;\r
+import org.simantics.diagram.synchronization.graph.CopyAdvisorUtil;\r
+import org.simantics.g2d.elementclass.FlagClass;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.scl.commands.Commands;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+\r
+/**\r
+ * @author Hannu Niemistö\r
+ */\r
+public class ExpandFlags {\r
+ \r
+ static class Connector {\r
+ Resource element;\r
+ Resource terminal;\r
+ \r
+ public Connector(Resource element, Resource terminal) { \r
+ this.element = element;\r
+ this.terminal = terminal;\r
+ }\r
+ }\r
+ \r
+ private static ArrayList<Connector> getConnectors(ReadGraph g, Resource connection) throws DatabaseException {\r
+ StructuralResource2 STR = StructuralResource2.getInstance(g);\r
+ \r
+ ArrayList<Connector> result = new ArrayList<Connector>();\r
+ for(Resource connector : g.getObjects(connection, STR.IsConnectedTo)) {\r
+ for(Statement stat : g.getStatements(connector, STR.Connects)) \r
+ if(!connection.equals(stat.getObject())) {\r
+ result.add(new Connector(stat.getObject(), g.getInverse(stat.getPredicate())));\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+ public static Resource[] expandFlag(WriteGraph graph, Resource flag) throws DatabaseException {\r
+ return (Resource[])Commands.get(graph, "Simantics/Flag/expandFlag")\r
+ .execute(graph, graph.syncRequest(new IndexRoot(flag)), flag);\r
+ }\r
+ \r
+ /**\r
+ * @param graph\r
+ * @param flag\r
+ * @return the flags that result from the expansion operation\r
+ * @throws DatabaseException\r
+ */\r
+ public static Resource[] expandFlagWithoutMetadata(WriteGraph graph, Resource flag) throws DatabaseException {\r
+ DiagramResource DIA = DiagramResource.getInstance(graph);\r
+ G2DResource G2D = G2DResource.getInstance(graph);\r
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ ModelingResources MOD = ModelingResources.getInstance(graph);\r
+ \r
+ // Find joins and check if this is multiflag\r
+ Collection<Resource> joins_ = graph.getObjects(flag, DIA.FlagIsJoinedBy);\r
+ if(joins_.size() <= 1)\r
+ return Resource.NONE; // Nothing to do\r
+ \r
+ // Analyze expanded flag\r
+ Resource diagram = OrderedSetUtils.getSubjects(graph, flag).iterator().next();\r
+ Resource flagType = graph.getSingleObject(flag, DIA.HasFlagType);\r
+ double[] transform = graph.getRelatedValue(flag, DIA.HasTransform);\r
+ Resource connector = graph.getSingleObject(flag, DIA.Flag_ConnectionPoint);\r
+ Statement connectsStatement = null;\r
+ for(Statement temp : graph.getStatements(connector, STR.Connects))\r
+ if(!flag.equals(temp.getObject())) {\r
+ connectsStatement = temp;\r
+ break;\r
+ }\r
+\r
+ if(connectsStatement == null)\r
+ return Resource.NONE;\r
+ Resource arrowType = connectsStatement.getPredicate();\r
+ Resource diagramConnection = connectsStatement.getObject();\r
+ Resource connection = graph.getSingleObject(diagramConnection, MOD.DiagramConnectionToConnection);\r
+ \r
+ ArrayList<Connector> connectors = getConnectors(graph, diagramConnection);\r
+ if(connectors.size()==2) {\r
+ Iterator<Connector> it = connectors.iterator();\r
+ while(it.hasNext()) {\r
+ if(it.next().element.equals(flag))\r
+ it.remove();\r
+ }\r
+ }\r
+ Resource diagramRelation = connectors.size()!=1 ? null : \r
+ connectors.get(0).terminal;\r
+ Resource connectionPoint = diagramRelation == null ? null :\r
+ graph.getPossibleObject(diagramRelation, MOD.DiagramConnectionRelationToConnectionRelation); \r
+ Resource element=connectors.size()==1 ? connectors.get(0).element : null, \r
+ component=null, connectionType=null;\r
+ Resource routeLine = null;\r
+ if(connectionPoint != null && \r
+ !graph.isInstanceOf(connectionPoint, L0.FunctionalRelation)) {\r
+ component = graph.getSingleObject(element, MOD.ElementToComponent);\r
+ connectionType = graph.getSingleObject(diagramConnection, STR.HasConnectionType);\r
+ }\r
+ else if(element != null && graph.isInstanceOf(element, MOD.ReferenceElement)) {\r
+ component = graph.getSingleObject(element, MOD.HasParentComponent);\r
+ connectionPoint = graph.getSingleObject(element, MOD.HasReferenceRelation);\r
+ connectionType = graph.getSingleObject(diagramConnection, STR.HasConnectionType);\r
+ }\r
+ else {\r
+ routeLine = graph.getSingleObject(connector, DIA.AreConnected); \r
+\r
+ if(!graph.isInstanceOf(routeLine, DIA.RouteLine)) {\r
+ Resource otherConnector = routeLine;\r
+ routeLine = graph.newResource();\r
+ graph.deny(connector, DIA.AreConnected, otherConnector);\r
+ graph.claim(routeLine, L0.InstanceOf, DIA.RouteLine);\r
+ graph.claim(diagramConnection, DIA.HasInteriorRouteNode, routeLine);\r
+ graph.claimLiteral(routeLine, DIA.HasPosition, transform[4]-FlagClass.DEFAULT_WIDTH*0.5);\r
+ graph.claimLiteral(routeLine, DIA.IsHorizontal, false);\r
+ graph.claim(routeLine, DIA.AreConnected, connector);\r
+ graph.claim(routeLine, DIA.AreConnected, otherConnector);\r
+ } \r
+ }\r
+\r
+ Resource[] joins = joins_.toArray(new Resource[joins_.size()]);\r
+ Resource[] flags = new Resource[joins.length];\r
+\r
+ final double flagSeparation = FlagClass.DEFAULT_HEIGHT;\r
+\r
+ flags[0] = flag;\r
+ for(int i=1;i<flags.length;++i) {\r
+ Resource newFlag = graph.newResource();\r
+ flags[i] = newFlag;\r
+ graph.claim(newFlag, L0.InstanceOf, DIA.Flag);\r
+ graph.claim(newFlag, DIA.HasFlagType, flagType);\r
+ OrderedSetUtils.add(graph, diagram, newFlag);\r
+ graph.claim(diagram, L0.ConsistsOf, newFlag);\r
+ graph.deny(flag, DIA.FlagIsJoinedBy, joins[i]);\r
+ for(Resource otherFlag : graph.getObjects(joins[i], DIA.JoinsFlag)) {\r
+ for(Statement label : graph.getStatements(otherFlag, L0.HasLabel)) {\r
+ if (!label.isAsserted(otherFlag)) {\r
+ Resource literalCopy = CopyAdvisorUtil.copy(graph, label.getObject(), null);\r
+ graph.claim(newFlag, label.getPredicate(), literalCopy);\r
+ }\r
+ }\r
+ }\r
+ graph.claim(newFlag, DIA.FlagIsJoinedBy, joins[i]);\r
+\r
+ // URI: Make new flag a part of the diagram and give it a fresh name\r
+ graph.claim(diagram, L0.ConsistsOf, newFlag);\r
+ AddElement.claimFreshElementName(graph, diagram, newFlag);\r
+\r
+ double[] newTransform = new double[] {\r
+ transform[0], transform[1], transform[2], transform[3], \r
+ transform[4] + i*flagSeparation*transform[2], \r
+ transform[5] + i*flagSeparation*transform[3]\r
+ };\r
+ graph.claimLiteral(newFlag, DIA.HasTransform, G2D.Transform, newTransform);\r
+\r
+ // TODO: Handle branching and non-branching connections differently\r
+ \r
+ if(routeLine == null) {\r
+ Resource newConnector1 = graph.newResource();\r
+ Resource newDiagramConnection = graph.newResource();\r
+ Resource newConnector2 = graph.newResource();\r
+ Resource newConnection = graph.newResource();\r
+ \r
+ graph.claim(newConnector1, L0.InstanceOf, DIA.Connector);\r
+ graph.claim(newDiagramConnection, L0.InstanceOf, DIA.RouteGraphConnection);\r
+ graph.claim(newDiagramConnection, STR.HasConnectionType, connectionType);\r
+ graph.claim(newConnector2, L0.InstanceOf, DIA.Connector);\r
+ graph.claim(newConnection, L0.InstanceOf, STR.Connection);\r
+ \r
+ Resource arrow = graph.getInverse(arrowType);\r
+ Resource otherArrow = arrow.equals(DIA.HasPlainConnector) ?\r
+ DIA.HasArrowConnector : DIA.HasPlainConnector;\r
+ \r
+ graph.claim(element, diagramRelation, newConnector1);\r
+ graph.claim(newDiagramConnection, otherArrow, newConnector1);\r
+ graph.claim(newDiagramConnection, arrow, newConnector2);\r
+ graph.claim(newConnector1, DIA.AreConnected, newConnector2);\r
+ graph.claim(newFlag, DIA.Flag_ConnectionPoint, newConnector2);\r
+ \r
+ graph.claim(component, connectionPoint, newConnection);\r
+ graph.deny(joins[i], STR.Joins, connection);\r
+ graph.claim(joins[i], STR.Joins, newConnection);\r
+ \r
+ graph.claim(newDiagramConnection, MOD.DiagramConnectionToConnection, newConnection);\r
+ graph.claim(newConnection, MOD.Mapped, newConnection);\r
+ \r
+ AddElement.claimFreshElementName(graph, diagram, newDiagramConnection);\r
+ \r
+ OrderedSetUtils.addFirst(graph, diagram, newDiagramConnection);\r
+ graph.claim(diagram, L0.ConsistsOf, newDiagramConnection);\r
+ }\r
+ else {\r
+ Resource newConnector = graph.newResource();\r
+ graph.claim(newConnector, L0.InstanceOf, DIA.Connector);\r
+ graph.claim(newFlag, DIA.Flag_ConnectionPoint, newConnector);\r
+ graph.claim(newConnector, arrowType, diagramConnection);\r
+ graph.claim(newConnector, DIA.AreConnected, routeLine);\r
+ }\r
+ }\r
+\r
+ return flags;\r
+ }\r
+ \r
+ public static void collectGroupedFlags(ReadGraph graph, Resource composite, ArrayList<Resource> groups) throws DatabaseException {\r
+ DiagramResource DIA = DiagramResource.getInstance(graph);\r
+ ModelingResources MOD = ModelingResources.getInstance(graph);\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ \r
+ Resource diagram = graph.getPossibleObject(composite, MOD.CompositeToDiagram);\r
+ if(diagram == null)\r
+ return;\r
+ \r
+ for(Resource element : graph.getObjects(diagram, L0.ConsistsOf))\r
+ if(graph.isInstanceOf(element, DIA.Flag)) {\r
+ Collection<Resource> objects = (Collection<Resource>) graph.getObjects(element, DIA.FlagIsJoinedBy);\r
+ if (objects.size() > 1) {\r
+ groups.add(element);\r
+ }\r
+ }\r
+ }\r
+\r
+}\r