From 948ee90f11a94d8953b2ac1d3cc64e2f745528dd Mon Sep 17 00:00:00 2001
From: SebastianEbert <sebastian.ebert@tu-dresden.de>
Date: Tue, 28 Feb 2023 17:38:48 +0100
Subject: [PATCH] finished implementation of stateful nodes, fixed service
 transition mapping

---
 .../tudresden/inf/st/pnml/flatter/Main.java   |   8 +-
 .../flatter/transform/ChannelFlatter.java     | 131 +++++++++---------
 2 files changed, 72 insertions(+), 67 deletions(-)

diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java
index 1577f0a..495eb3e 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/Main.java
@@ -30,7 +30,7 @@ public class Main {
         }
 
         // parse the global not flatted petri net
-        // pnmlPath = "../pnml-relast-nets/src/main/resources/useCaseNets/RoboticUseCase-TopLayer-Left.pnml";
+        // pnmlPath = "../pnml-relast-nets/src/main/resources/useCaseNets/Paper/RoboticUseCase-AllLayers.pnml";
         // configPath = "src/main/config/siftConfig.json";
         PetriNet petriNet = PnmlParser.parsePnml(pnmlPath).get(0);
 
@@ -89,7 +89,7 @@ public class Main {
         ndrioProxy.includeInhibitorArcs(petriNet, ndrioTargetPath, inhibitorTargetPath);
 
         // insert into tina
-        if(tinaConfig.length > 1){
+        if (tinaConfig.length > 1) {
             System.out.println("[FLATTER] Inserting into tina.");
             TinaProxy tinaProxy = new TinaProxy();
             String tinaTargetPath = homeDirectory + "/temp/tina/" + "tina-result-" + exportId + ".txt";
@@ -97,7 +97,7 @@ public class Main {
         }
 
         // insert into sift
-        if(siftConfig.length > 1){
+        if (siftConfig.length > 1) {
             System.out.println("[FLATTER] Inserting into sift.");
             SiftProxy siftProxy = new SiftProxy();
             String siftTargetPath = homeDirectory + "/temp/sift/" + "sift-result-" + exportId + ".ktz";
@@ -118,6 +118,8 @@ public class Main {
         // combine results and generate report in html/md/xml/json? format
         // TODO for v2
 
+        System.out.println("Finished.");
+
     }
 
     public static void printNet(PetriNet petriNet) {
diff --git a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ChannelFlatter.java b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ChannelFlatter.java
index d1514b5..e9cf70a 100644
--- a/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ChannelFlatter.java
+++ b/src/main/java/de/tudresden/inf/st/pnml/flatter/transform/ChannelFlatter.java
@@ -4,7 +4,6 @@ import de.tudresden.inf.st.pnml.base.constants.PnmlConstants;
 import de.tudresden.inf.st.pnml.base.data.CommunicatorInformation;
 import de.tudresden.inf.st.pnml.flatter.template.*;
 import de.tudresden.inf.st.pnml.jastadd.model.*;
-import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -24,7 +23,6 @@ public class ChannelFlatter extends Flatter {
         int callbackCount = 0;
         int channelCount = 0;
 
-        List<Transition> topicTransitions = new ArrayList<>();
         List<Arc> arcsToRemove = new ArrayList<>();
         List<Transition> transitionsToRemove = new ArrayList<>();
 
@@ -33,7 +31,7 @@ public class ChannelFlatter extends Flatter {
 
             if (t.asInputSignalTransition().getStaticTransitionInformation().isTopicTransitionInformation()) {
 
-                logger.error("Found topictransition: " + t.getId());
+                logger.error("Found topic transition: " + t.getId());
                 int senderCapacity = t.asInputSignalTransition().getStaticTransitionInformation().getInputLimit();
                 int receiverCapacity = t.asInputSignalTransition().getStaticTransitionInformation().getOutputLimit();
 
@@ -60,8 +58,6 @@ public class ChannelFlatter extends Flatter {
                     }
                 }
 
-                topicTransitions.add(t);
-
                 // create und insert "the channel" elements
                 insertChannelElements(petriNet, channelCount);
 
@@ -290,7 +286,6 @@ public class ChannelFlatter extends Flatter {
                     break;
                 }
 
-                // unflattedLeaves.remove(t);
                 unflattedLeaves = getUnflattedServiceCallLeaves(petriNet, resolvedSubnets);
                 serverInstanceCount++;
                 break;
@@ -315,7 +310,7 @@ public class ChannelFlatter extends Flatter {
 
         // get response and request transition
         InputSignalTransition requestTransition = requestTransitionPnObject.asInputSignalTransition();
-        InputSignalTransition responseTransition = getResponseTransition(petriNet, requestTransition).asInputSignalTransition();
+        InputSignalTransition responseTransition = Objects.requireNonNull(getResponseTransition(petriNet, requestTransition)).asInputSignalTransition();
 
         // get elements of server subnet
         Set<Place> serverPlaces = new HashSet<>();
@@ -342,6 +337,7 @@ public class ChannelFlatter extends Flatter {
         // insert channel queue template
         String queue_suffix = "serverInstance-" + serverInstanceCount;
         OutputSignalPlace queueCapacityPlace = PrimitiveTemplates.getOutputSignalPlace();
+        assert queueCapacityPlace != null;
         queueCapacityPlace.setId(TemplateConstants.SERVICE_QUEUE_CAPACITY_PLACE + "-" + queue_suffix);
 
         PlaceInformation pi = new PlaceInformation();
@@ -357,17 +353,15 @@ public class ChannelFlatter extends Flatter {
 
         int clientCount = 0;
 
+        List<Tuple2<Node, Node>> externalElementsToReconnect = new ArrayList<>(); // true -> element is source
+        List<Arc> oldConnectorArcs = getDirectlyConnectedElements(petriNet, serverSubnet, externalElementsToReconnect);
+
         for (Place incomingPlace : requestTransition.incomingPlaces()) {
 
             // create clone for each client
             Set<OutputSignalPlace> topicInputPlaces = new HashSet<>();
 
             System.out.println("[FLATTER] Copying server net: " + serverSubnet);
-
-            // TODO: get the directly connected elements
-            List<Tuple2<Node, Node>> externalElementsToReconnect = new ArrayList<>(); // true -> element is source
-            getDirectlyConnectedElements(petriNet, serverSubnet, externalElementsToReconnect);
-
             Pair<OutputSignalPlace, OutputSignalPlace> ioPlacePair = copyServerNet(petriNet, serverPlaces, serverTransitions, topicInputPlaces,
                     serverInstanceCount + "-" + clientCount, serverSubnet, copiedObjects, externalElementsToReconnect);
 
@@ -476,8 +470,6 @@ public class ChannelFlatter extends Flatter {
 
             createAndIncludeArc(topPage, "queue-to-server-place-arc-" + channel_suffix, getPlaceByID(petriNet, TemplateConstants.SERVICE_QUEUE_TO_SERVER_PLACE + "-" + channel_suffix),
                     getTransitionByID(petriNet, TemplateConstants.SERVICE_SERVER_INPUT_TRANSITION + "-" + channel_suffix));
-           // createAndIncludeArc(topPage, "client-to-server-input" + channel_suffix, getPlaceByID(petriNet, TemplateConstants.SERVICE_TO_QUEUE_PLACE + "-" + channel_suffix),
-             //       getTransitionByID(petriNet, TemplateConstants.SERVICE_SERVER_INPUT_TRANSITION + "-" + channel_suffix));
             createAndIncludeArc(topPage, "server-output-to-queue-cap-arc-" + channel_suffix, getTransitionByID(petriNet, TemplateConstants.SERVICE_SERVER_OUTPUT_TRANSITION + "-" + channel_suffix),
                     getPlaceByID(petriNet, TemplateConstants.SERVICE_QUEUE_CAPACITY_PLACE + "-" + queue_suffix));
             createAndIncludeArc(topPage, "client-connector-to-service-to-queue-arc-" + channel_suffix, getTransitionByID(petriNet, TemplateConstants.SERVICE_CLIENT_CONNECTOR_TRANSITION + "-" + channel_suffix),
@@ -498,6 +490,7 @@ public class ChannelFlatter extends Flatter {
             OutputSignalPlace serverFeedbackPlace = PrimitiveTemplates.getOutputSignalPlace();
             serverFeedbackPlace.setId(TemplateConstants.SERVICE_FEEDBACK_PLACE + "-" + channel_suffix);
             Place capPlace = getPlaceByID(petriNet, TemplateConstants.SERVICE_QUEUE_CAPACITY_PLACE + "-" + queue_suffix);
+            assert capPlace != null;
             serverFeedbackPlace.setToolspecificList(capPlace.getToolspecificList().treeCopy());
             serverFeedbackPlace.getName().setText(TemplateConstants.SERVICE_FEEDBACK_PLACE + "-" + channel_suffix);
             serverFeedbackPlace.setNodeGraphics(capPlace.getNodeGraphics().treeCopy());
@@ -528,8 +521,11 @@ public class ChannelFlatter extends Flatter {
             a.removeSelf();
         }
 
+        for( Arc oldArc : oldConnectorArcs){
+            oldArc.removeSelf();
+        }
+
         for (PnObject po : serverObjectsWithoutArcs) {
-            //    System.out.println("Removing server objects without arcs: " + po.getId());
             po.removeSelf();
         }
 
@@ -566,44 +562,65 @@ public class ChannelFlatter extends Flatter {
         return petriNet;
     }
 
-    private static void getDirectlyConnectedElements(PetriNet petriNet, String serverSubnet, List<Tuple2<Node, Node>> externalElementsToReconnect) {
+    private static List<Arc> getDirectlyConnectedElements(PetriNet petriNet, String serverSubnet, List<Tuple2<Node, Node>> externalElementsToReconnect) {
+
+        List<Arc> connectingArcs = new ArrayList<>();
+
         for (Place p : petriNet.allPlaces()){
 
             for(Arc a : p.getInArcList()){
                 if(a.getSource().asTransitionNode().asTransition().asInputSignalTransition().getStaticTransitionInformation().getSubNet()
                         .equals(serverSubnet) && !p.asOutputSignalPlace().getStaticPlaceInformation().getSubNet().equals(serverSubnet)){
-                    externalElementsToReconnect.add(new Tuple2<>(a.getSource(), p));
-                    break;
+
+                    String tType = a.getSource().asTransitionNode().asTransition().asInputSignalTransition().getStaticTransitionInformation().getType();
+                    if(!tType.equals(PnmlConstants.TRANSITION_TYPE_SERVICE_REQUEST) && !tType.equals(PnmlConstants.TRANSITION_TYPE_SERVICE_RESPONSE)){
+                        externalElementsToReconnect.add(new Tuple2<>(a.getSource(), p));
+                        connectingArcs.add(a);
+                        break;
+                    }
                 }
             }
 
             for(Arc a : p.getOutArcList()){
                 if(a.getTarget().asTransitionNode().asTransition().asInputSignalTransition().getStaticTransitionInformation().getSubNet()
                         .equals(serverSubnet) && !p.asOutputSignalPlace().getStaticPlaceInformation().getSubNet().equals(serverSubnet)){
-                    externalElementsToReconnect.add(new Tuple2<>(p, a.getTarget()));
-                    break;
+
+                    String tType = a.getTarget().asTransitionNode().asTransition().asInputSignalTransition().getStaticTransitionInformation().getType();
+                    if(!tType.equals(PnmlConstants.TRANSITION_TYPE_SERVICE_REQUEST) && !tType.equals(PnmlConstants.TRANSITION_TYPE_SERVICE_RESPONSE)) {
+                        externalElementsToReconnect.add(new Tuple2<>(p, a.getTarget()));
+                        connectingArcs.add(a);
+                        break;
+                    }
                 }
             }
         }
 
         for (Transition t : petriNet.allTransitions()){
 
-            for(Arc a : t.getInArcList()){
-                if(a.getSource().asPlaceNode().asPlace().asOutputSignalPlace().getStaticPlaceInformation().getSubNet()
-                        .equals(serverSubnet) && !t.asInputSignalTransition().getStaticTransitionInformation().getSubNet().equals(serverSubnet)){
-                    externalElementsToReconnect.add(new Tuple2<>(a.getSource(), t));
-                    break;
+
+            if(!t.asInputSignalTransition().getStaticTransitionInformation().getType().equals(PnmlConstants.TRANSITION_TYPE_SERVICE_REQUEST)
+                    && !t.asInputSignalTransition().getStaticTransitionInformation().getType().equals(PnmlConstants.TRANSITION_TYPE_SERVICE_RESPONSE)) {
+                for (Arc a : t.getInArcList()) {
+                    if (a.getSource().asPlaceNode().asPlace().asOutputSignalPlace().getStaticPlaceInformation().getSubNet()
+                            .equals(serverSubnet) && !t.asInputSignalTransition().getStaticTransitionInformation().getSubNet().equals(serverSubnet)) {
+                        externalElementsToReconnect.add(new Tuple2<>(a.getSource(), t));
+                        connectingArcs.add(a);
+                        break;
+                    }
                 }
-            }
 
-            for(Arc a : t.getOutArcList()){
-                if(a.getTarget().asPlaceNode().asPlace().asOutputSignalPlace().getStaticPlaceInformation().getSubNet()
-                        .equals(serverSubnet) && !t.asInputSignalTransition().getStaticTransitionInformation().getSubNet().equals(serverSubnet)){
-                    externalElementsToReconnect.add(new Tuple2<>(a.getSource(), t));
-                    break;
+                for (Arc a : t.getOutArcList()) {
+                    if (a.getTarget().asPlaceNode().asPlace().asOutputSignalPlace().getStaticPlaceInformation().getSubNet()
+                            .equals(serverSubnet) && !t.asInputSignalTransition().getStaticTransitionInformation().getSubNet().equals(serverSubnet)) {
+                        externalElementsToReconnect.add(new Tuple2<>(t, a.getTarget()));
+                        connectingArcs.add(a);
+                        break;
+                    }
                 }
             }
         }
+
+        return connectingArcs;
     }
 
     private static Pair<OutputSignalPlace, OutputSignalPlace> copyServerNet(PetriNet petriNet, Set<Place> serverPlaces,
@@ -611,19 +628,21 @@ public class ChannelFlatter extends Flatter {
                                                                             String suffix, String serverSubnet, Set<PnObject> copiedObjects,
                                                                             List<Tuple2<Node, Node>> externalElementsToReconnect) {
 
+        petriNet.flushTreeCache();
+
         final String instanceId = "server-instance-" + UUID.randomUUID().toString();
 
         Page topPage = petriNet.getPage(0);
         OutputSignalPlace serverInPlace = null;
         OutputSignalPlace serverOutPlace = null;
 
-        Set<PnObject> addedPnObjects = new HashSet<>();
         copiedObjects.addAll(serverPlaces);
         copiedObjects.addAll(serverTransitions);
 
         // Elements
         for (Place p : serverPlaces) {
             OutputSignalPlace copy = PrimitiveTemplates.getOutputSignalPlace();
+            assert copy != null;
             copy.setId(p.getId() + "-" + suffix);
             Name copyName = new Name();
             copyName.setText(copy.getId());
@@ -647,20 +666,6 @@ public class ChannelFlatter extends Flatter {
             copy.setMutualPlaceInformation(pi);
 
             topPage.addObject(copy);
-            addedPnObjects.add(copy);
-
-            for(Tuple2<Node, Node> t : externalElementsToReconnect){
-
-                if(p.getId().equals(t.get_1().getId())){
-                    createAndIncludeArc(topPage, "ext-" + t.get_1().getId() + "-to-" + t.get_2().getId(), t.get_1(), p);
-                }
-
-                if(p.getId().equals(t.get_2().getId())){
-                    createAndIncludeArc(topPage, "ext-" + t.get_2().getId() + "-to-" + t.get_1().getId(), p, t.get_1());
-                }
-            }
-
-            // todo: remove old arcs connecting external elements
 
             for (Arc a : p.getOutArcList()) {
                 if (!a.getTarget().getSubnet().equals(serverSubnet)) {
@@ -690,6 +695,7 @@ public class ChannelFlatter extends Flatter {
 
         for (Transition t : serverTransitions) {
             InputSignalTransition copy = PrimitiveTemplates.getInputSignalTransition();
+            assert copy != null;
             copy.setId(t.getId() + "-" + suffix);
             copy.getName().setText(t.getName().getText());
             copy.setMutualInputSignalBindingList(t.asInputSignalTransition().getMutualInputSignalBindingList().treeCopy());
@@ -707,7 +713,17 @@ public class ChannelFlatter extends Flatter {
             copy.setMutualTransitionInformation(ti);
 
             topPage.addObject(copy);
-            addedPnObjects.add(copy);
+
+            for(Tuple2<Node, Node> tuple : externalElementsToReconnect){
+
+                //System.out.println("--1: " + tuple.get_1().getId() + ", 2: " + tuple.get_2().getId() + " ,t: " + t.getId());
+                if(t.getId().equals(tuple.get_1().getId())){
+                    createAndIncludeArc(topPage, "ext-" + copy.getId() + "-to-" + tuple.get_2().getId(), copy, tuple.get_2());
+                }
+                if(t.getId().equals(tuple.get_2().getId())){
+                    createAndIncludeArc(topPage, "ext-" +  tuple.get_1().getId() + "-to-" + copy.getId(), tuple.get_1(), copy);
+                }
+            }
         }
 
         petriNet.flushTreeCache();
@@ -746,7 +762,6 @@ public class ChannelFlatter extends Flatter {
                         a.getSource().asPlaceNode().asPlace().asOutputSignalPlace().getStaticPlaceInformation().getSubNet().equals(subnet)) {
                     arcs.add(a);
                 }
-
             } else {
                 if (a.getSource().asTransitionNode().asTransition().asInputSignalTransition().getStaticTransitionInformation().getSubNet().equals(subnet) &&
                         a.getTarget().asPlaceNode().asPlace().asOutputSignalPlace().getStaticPlaceInformation().getSubNet().equals(subnet)) {
@@ -763,8 +778,6 @@ public class ChannelFlatter extends Flatter {
         Set<Arc> arcs = new HashSet<>();
 
         for (Arc a : petriNet.allArcs()) {
-            // System.out.println(">>>> Arc target: " + a.getTarget().getId());
-
             if (getArcTargetSubnet(a).equals(subnet) && getArcSourceSubnet(a).equals(subnet)) {
                 arcs.add(a);
             } else if (getArcSourceSubnet(a).equals(subnet) && !getArcTargetSubnet(a).equals(subnet)) {
@@ -796,20 +809,11 @@ public class ChannelFlatter extends Flatter {
     private static Transition getResponseTransition(PetriNet petriNet, Transition requestTransition) {
 
         for (Transition t : petriNet.allTransitions()) {
-
             if (t.asInputSignalTransition().getStaticTransitionInformation().isServiceTransitionInformation()
                     && t.asInputSignalTransition().getStaticTransitionInformation().getType().equals(PnmlConstants.TRANSITION_TYPE_SERVICE_RESPONSE)) {
-                for (Place p1 : t.outgoingPlaces()) {
-                    String subnetOut = p1.asOutputSignalPlace().getStaticPlaceInformation().getSubNet();
-
-                    for (Place p2 : requestTransition.incomingPlaces()) {
-                        String subnetIn = p2.asOutputSignalPlace().getStaticPlaceInformation().getSubNet();
-
-                        if (subnetIn.equals(subnetOut)) {
-                            // System.out.println("FOUND PAIR: " + t.getId() + " -- " + requestTransition.getId());
-                            return t;
-                        }
-                    }
+                if(t.asInputSignalTransition().getStaticTransitionInformation().getSubNet()
+                        .equals(requestTransition.asInputSignalTransition().getStaticTransitionInformation().getSubNet())){
+                    return t;
                 }
             }
         }
@@ -875,5 +879,4 @@ public class ChannelFlatter extends Flatter {
 
         return pnObjects;
     }
-
-}
+}
\ No newline at end of file
-- 
GitLab