From b1bce085fd23e825ecec690446c6f2531cb8618b Mon Sep 17 00:00:00 2001
From: Ludovic Apvrille <ludovic.apvrille@telecom-paris.fr>
Date: Fri, 21 Jun 2024 16:06:12 +0200
Subject: [PATCH] Adding countermeasure drawing

---
 src/main/java/attacktrees/Defense.java        |  8 +++
 src/main/java/ui/MainGUI.java                 |  2 +-
 .../java/ui/atd/AttackTreeDiagramPanel.java   | 68 +++++++++++++++++--
 3 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/src/main/java/attacktrees/Defense.java b/src/main/java/attacktrees/Defense.java
index 80524661dc..8b5cf87f4e 100644
--- a/src/main/java/attacktrees/Defense.java
+++ b/src/main/java/attacktrees/Defense.java
@@ -85,6 +85,14 @@ public class Defense extends AttackElement {
                 relatedAttacks.add(_attack);
     }
 
+    public boolean hasRelatedAttacks() {
+        if (relatedAttacks == null) {
+            return false;
+        }
+
+        return relatedAttacks.size() > 0;
+    }
+
     public ArrayList<Attack> getRelatedAttacks() {
         return relatedAttacks;
     }
diff --git a/src/main/java/ui/MainGUI.java b/src/main/java/ui/MainGUI.java
index 867acb410d..b55c6ff311 100644
--- a/src/main/java/ui/MainGUI.java
+++ b/src/main/java/ui/MainGUI.java
@@ -1903,7 +1903,7 @@ public class MainGUI implements ActionListener, WindowListener, KeyListener, Per
         atp.addAttackTreeDiagram(tabName);
         atp.atdp.drawable = false;
         atp.atdp.drawFromAttackTreeModel(_at);
-        atp.atdp.drawConnectionlessAttacks(_at);
+        //atp.atdp.drawConnectionlessAttacks(_at);
         atp.atdp.drawable = true;
         atp.atdp.repaint();
         TraceManager.addDev("Draw AT 4");
diff --git a/src/main/java/ui/atd/AttackTreeDiagramPanel.java b/src/main/java/ui/atd/AttackTreeDiagramPanel.java
index 323bf128b2..c0eab5aa4e 100644
--- a/src/main/java/ui/atd/AttackTreeDiagramPanel.java
+++ b/src/main/java/ui/atd/AttackTreeDiagramPanel.java
@@ -43,10 +43,7 @@ package ui.atd;
 
 //import java.awt.*;
 
-import attacktrees.Attack;
-import attacktrees.AttackElement;
-import attacktrees.AttackNode;
-import attacktrees.AttackTree;
+import attacktrees.*;
 import avatartranslator.AvatarElement;
 import avatartranslator.avatarucd.AvatarActor;
 import myutil.NameChecker;
@@ -213,8 +210,11 @@ public class AttackTreeDiagramPanel extends TDiagramPanel implements TDPWithAttr
 
         HashMap<AttackElement, TGComponent> mapOfComponents = new HashMap<>();
 
+        String ret = drawAttackFromAttackTreeModel(mapOfComponents, _at, root, null, -1, 600, 100, 1200);
+        drawConnectionlessAttacks(_at);
+
+        return ret;
 
-        return drawAttackFromAttackTreeModel(mapOfComponents, _at, root, null, -1, 600, 100, 1200);
     }
 
     public void drawConnectionlessAttacks(AttackTree _at) {
@@ -300,8 +300,7 @@ public class AttackTreeDiagramPanel extends TDiagramPanel implements TDPWithAttr
             TGConnectingPoint p2 = attack.closerFreeTGConnectingPoint(constraint.getX(), constraint.getY(), true, false);
 
             if (p1 != null && p2 != null) {
-                p1.setFree(false);
-                p2.setFree(false);
+
 
                 TGConnector conn = null;
                 Vector<Point> points = new Vector<Point>();
@@ -312,6 +311,8 @@ public class AttackTreeDiagramPanel extends TDiagramPanel implements TDPWithAttr
                 }
 
                 if (conn != null) {
+                    p1.setFree(false);
+                    p2.setFree(false);
                     addComponent(conn, 0, 0, false, true);
                 }
             }
@@ -334,6 +335,59 @@ public class AttackTreeDiagramPanel extends TDiagramPanel implements TDPWithAttr
             }
         }
 
+        // Handling countermeasures
+        int xNoRel = 100;
+        int yNoRel = 100;
+        int newX, newY;
+        for(Defense def : _at.getDefenses()) {
+            if (def.hasRelatedAttacks()) {
+                Attack firstAttack = def.getRelatedAttacks().get(0);
+                TGComponent refToAtt = _mapOfComponents.get(firstAttack);
+                if (refToAtt != null) {
+                    newX = refToAtt.getX();
+                    newY = refToAtt.getY() + 100;
+                } else {
+                    newX = xNoRel;
+                    newY = yNoRel;
+                    yNoRel += 100;
+                }
+            } else {
+                newX = xNoRel;
+                newY = yNoRel;
+                yNoRel += 100;
+            }
+            ATDCountermeasure atdc = new ATDCountermeasure(newX, newY, getMinX(), getMaxX(), getMinY(), getMaxY(), true, null, this);
+            atdc.setDescription(def.getDescription());
+            atdc.setEnabled(def.isEnabled());
+            addBuiltComponent(atdc);
+
+            // Connections
+            for(Attack relatedAtt: def.getRelatedAttacks()) {
+                TGComponent refToAtt = _mapOfComponents.get(relatedAtt);
+                if (refToAtt != null) {
+                    TGConnectingPoint p1 = atdc.closerFreeTGConnectingPoint(refToAtt.getX(), refToAtt.getY(), false, true);
+                    TGConnectingPoint p2 = refToAtt.closerFreeTGConnectingPoint(atdc.getX(), atdc.getY(), true, false);
+
+                    if ((p1 != null) && (p2 != null)) {
+                        
+                        TGConnector conn = null;
+                        Vector<Point> points = new Vector<Point>();
+                        conn = new ATDCountermeasureConnector(0, 0, 0, 0, 0, 0, true, null,
+                                this, p1, p2, points);
+                        if (_valueConst != -1) {
+                            conn.setValue("" + _valueConst);
+                        }
+
+                        if (conn != null) {
+                            p1.setFree(false);
+                            p2.setFree(false);
+                            addComponent(conn, 0, 0, false, true);
+                        }
+                    }
+                }
+            }
+        }
+
         return null;
     }
 
-- 
GitLab