Skip to content

Commit a1482d3

Browse files
committed
fix sonar issues
1 parent b03d915 commit a1482d3

File tree

3 files changed

+100
-79
lines changed

3 files changed

+100
-79
lines changed

src/main/java/org/gridsuite/network/map/dto/definition/extension/BusbarSectionFinderTraverser.java

Lines changed: 76 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@
66
*/
77
package org.gridsuite.network.map.dto.definition.extension;
88

9-
import com.powsybl.iidm.network.IdentifiableType;
10-
import com.powsybl.iidm.network.SwitchKind;
11-
import com.powsybl.iidm.network.Terminal;
12-
import com.powsybl.iidm.network.VoltageLevel;
9+
import com.powsybl.iidm.network.*;
1310

1411
import java.util.*;
1512

1613
/**
1714
* @author Slimane Amar <slimane.amar at rte-france.com>
1815
*/
16+
// TODO : to remove when this class is available in network-store
1917
public final class BusbarSectionFinderTraverser {
2018

2119
/**
@@ -32,10 +30,10 @@ private BusbarSectionFinderTraverser() {
3230
* @param terminal the starting terminal
3331
* @return the best busbar result according to selection criteria, or null if none found
3432
*/
35-
public static BusbarResult findBestBusbar(Terminal terminal) {
33+
public static BusbarSectionResult findBestBusbar(Terminal terminal) {
3634
VoltageLevel.NodeBreakerView view = terminal.getVoltageLevel().getNodeBreakerView();
3735
int startNode = terminal.getNodeBreakerView().getNode();
38-
List<BusbarResult> allResults = searchAllBusbars(view, startNode);
36+
List<BusbarSectionResult> allResults = searchAllBusbars(view, startNode);
3937
if (allResults.isEmpty()) {
4038
return null;
4139
}
@@ -51,27 +49,23 @@ public static BusbarResult findBestBusbar(Terminal terminal) {
5149
* @param results list of all found busbar results
5250
* @return the best busbar according to selection criteria
5351
*/
54-
private static BusbarResult selectBestBusbar(List<BusbarResult> results) {
52+
private static BusbarSectionResult selectBestBusbar(List<BusbarSectionResult> results) {
5553
// Priority 1: Search for busbar with closed last switch
56-
List<BusbarResult> withClosedSwitch = results.stream().filter(r -> r.lastSwitch() != null && !r.lastSwitch().isOpen()).toList();
54+
List<BusbarSectionResult> withClosedSwitch = results.stream().filter(r -> r.lastSwitch() != null && !r.lastSwitch().isOpen()).toList();
5755
if (!withClosedSwitch.isEmpty()) {
58-
return withClosedSwitch.stream().min(Comparator.comparingInt(BusbarResult::depth)
59-
.thenComparingInt(BusbarResult::switchesBeforeLast))
60-
.get();
56+
return withClosedSwitch.stream().min(Comparator.comparingInt(BusbarSectionResult::depth).thenComparingInt(BusbarSectionResult::switchesBeforeLast)).orElse(null);
6157
}
6258

6359
// Priority 2: Search for busbar with open last switch
64-
List<BusbarResult> withOpenSwitch = results.stream().filter(r -> r.lastSwitch() != null && r.lastSwitch().isOpen()).toList();
60+
List<BusbarSectionResult> withOpenSwitch = results.stream().filter(r -> r.lastSwitch() != null && r.lastSwitch().isOpen()).toList();
6561
if (!withOpenSwitch.isEmpty()) {
66-
return withOpenSwitch.stream().min(Comparator.comparingInt(BusbarResult::depth)
67-
.thenComparingInt(BusbarResult::switchesBeforeLast))
68-
.get();
62+
return withOpenSwitch.stream().min(Comparator.comparingInt(BusbarSectionResult::depth).thenComparingInt(BusbarSectionResult::switchesBeforeLast)).orElse(null);
6963
}
7064

71-
// Priority 3: Busbars without switch (direct connection)
72-
List<BusbarResult> withoutSwitch = results.stream().filter(r -> r.lastSwitch() == null).toList();
65+
// Priority 3: Busbars without switch direct connection
66+
List<BusbarSectionResult> withoutSwitch = results.stream().filter(r -> r.lastSwitch() == null).toList();
7367
if (!withoutSwitch.isEmpty()) {
74-
return withoutSwitch.stream().min(Comparator.comparingInt(BusbarResult::depth)).get();
68+
return withoutSwitch.stream().min(Comparator.comparingInt(BusbarSectionResult::depth)).orElse(null);
7569
}
7670

7771
// Fallback: select first busbar
@@ -86,50 +80,77 @@ private static BusbarResult selectBestBusbar(List<BusbarResult> results) {
8680
* @param startNode the starting node index
8781
* @return list of all busbar results found
8882
*/
89-
private static List<BusbarResult> searchAllBusbars(VoltageLevel.NodeBreakerView view, int startNode) {
90-
List<BusbarResult> results = new ArrayList<>();
83+
private static List<BusbarSectionResult> searchAllBusbars(VoltageLevel.NodeBreakerView view, int startNode) {
84+
List<BusbarSectionResult> results = new ArrayList<>();
9185
Set<Integer> visited = new HashSet<>();
9286
Queue<NodePath> queue = new LinkedList<>();
9387
queue.offer(new NodePath(startNode, new ArrayList<>(), null));
9488
while (!queue.isEmpty()) {
95-
NodePath current = queue.poll();
96-
if (visited.contains(current.node())) {
89+
NodePath currentNodePath = queue.poll();
90+
if (!hasNotBeenVisited(currentNodePath.node(), visited)) {
9791
continue;
9892
}
99-
visited.add(current.node());
100-
// Check if current node is a busbar section
101-
Optional<Terminal> nodeTerminal = view.getOptionalTerminal(current.node());
102-
if (nodeTerminal.isPresent()) {
103-
Terminal term = nodeTerminal.get();
104-
if (term.getConnectable().getType() == IdentifiableType.BUSBAR_SECTION) {
105-
String busbarId = term.getConnectable().getId();
106-
int depth = current.pathSwitches().size();
107-
SwitchInfo lastSwitch = current.lastSwitch();
108-
// Calculate number of switches BEFORE the last one
109-
int switchesBeforeLast = lastSwitch != null ? (depth - 1) : 0;
110-
results.add(new BusbarResult(busbarId, depth, switchesBeforeLast, lastSwitch));
111-
continue; // Don't explore beyond busbar
112-
}
93+
visited.add(currentNodePath.node());
94+
Optional<BusbarSectionResult> busbarSectionResult = tryCreateBusbarResult(view, currentNodePath);
95+
if (busbarSectionResult.isPresent()) {
96+
results.add(busbarSectionResult.get());
97+
} else {
98+
exploreAdjacentNodes(view, currentNodePath, visited, queue);
11399
}
114-
115-
// Explore adjacent nodes through switches
116-
view.getSwitchStream().forEach(sw -> {
117-
int node1 = view.getNode1(sw.getId());
118-
int node2 = view.getNode2(sw.getId());
119-
if (node1 == current.node() || node2 == current.node()) {
120-
int nextNode = (node1 == current.node()) ? node2 : node1;
121-
if (!visited.contains(nextNode)) {
122-
List<SwitchInfo> newPathSwitches = new ArrayList<>(current.pathSwitches());
123-
SwitchInfo switchInfo = new SwitchInfo(sw.getId(), sw.getKind(), sw.isOpen(), node1, node2);
124-
newPathSwitches.add(switchInfo);
125-
queue.offer(new NodePath(nextNode, newPathSwitches, switchInfo));
126-
}
127-
}
128-
});
129100
}
130101
return results;
131102
}
132103

104+
private static boolean hasNotBeenVisited(int node, Set<Integer> visited) {
105+
return !visited.contains(node);
106+
}
107+
108+
private static Optional<BusbarSectionResult> tryCreateBusbarResult(VoltageLevel.NodeBreakerView view, NodePath currentNodePath) {
109+
Optional<Terminal> nodeTerminal = view.getOptionalTerminal(currentNodePath.node());
110+
if (nodeTerminal.isEmpty()) {
111+
return Optional.empty();
112+
}
113+
Terminal term = nodeTerminal.get();
114+
// Check if current node is a busbar section
115+
if (term.getConnectable().getType() == IdentifiableType.BUSBAR_SECTION) {
116+
String busbarSectionId = term.getConnectable().getId();
117+
int depth = currentNodePath.pathSwitches().size();
118+
SwitchInfo lastSwitch = currentNodePath.lastSwitch();
119+
int switchesBeforeLast = lastSwitch != null ? (depth - 1) : 0;
120+
return Optional.of(new BusbarSectionResult(busbarSectionId, depth, switchesBeforeLast, lastSwitch));
121+
}
122+
return Optional.empty();
123+
}
124+
125+
private static void exploreAdjacentNodes(VoltageLevel.NodeBreakerView view, NodePath currentNodePath, Set<Integer> visited, Queue<NodePath> queue) {
126+
view.getSwitchStream().forEach(sw -> {
127+
int node1 = view.getNode1(sw.getId());
128+
int node2 = view.getNode2(sw.getId());
129+
Optional<Integer> nextNode = getNextNodeIfAdjacent(currentNodePath.node(), node1, node2);
130+
if (nextNode.isPresent() && !visited.contains(nextNode.get())) {
131+
NodePath newPath = createNodePath(currentNodePath, sw, node1, node2, nextNode.get());
132+
queue.offer(newPath);
133+
}
134+
});
135+
}
136+
137+
private static Optional<Integer> getNextNodeIfAdjacent(int currentNode, int node1, int node2) {
138+
if (node1 == currentNode) {
139+
return Optional.of(node2);
140+
}
141+
if (node2 == currentNode) {
142+
return Optional.of(node1);
143+
}
144+
return Optional.empty();
145+
}
146+
147+
private static NodePath createNodePath(NodePath currentNodePath, Switch sw, int node1, int node2, int nextNode) {
148+
List<SwitchInfo> newPathSwitches = new ArrayList<>(currentNodePath.pathSwitches());
149+
SwitchInfo switchInfo = new SwitchInfo(sw.getId(), sw.getKind(), sw.isOpen(), node1, node2);
150+
newPathSwitches.add(switchInfo);
151+
return new NodePath(nextNode, newPathSwitches, switchInfo);
152+
}
153+
133154
/**
134155
* Internal record to track the path during graph traversal.
135156
*/
@@ -143,16 +164,16 @@ public record SwitchInfo(String id, SwitchKind kind, boolean isOpen, int node1,
143164
/**
144165
* Record containing the result of a busbar search with selection metadata.
145166
*/
146-
public record BusbarResult(String busbarId, int depth, int switchesBeforeLast, SwitchInfo lastSwitch) { }
167+
public record BusbarSectionResult(String busbarSectionId, int depth, int switchesBeforeLast, SwitchInfo lastSwitch) { }
147168

148169
/**
149170
* Convenience method to get only the busbar ID.
150171
*
151172
* @param terminal the starting terminal
152173
* @return the busbar ID or null if none found
153174
*/
154-
public static String findBusbarId(Terminal terminal) {
155-
BusbarResult result = findBestBusbar(terminal);
156-
return result != null ? result.busbarId() : null;
175+
public static String findBusbarSectionId(Terminal terminal) {
176+
BusbarSectionResult result = findBestBusbar(terminal);
177+
return result != null ? result.busbarSectionId() : null;
157178
}
158179
}

src/main/java/org/gridsuite/network/map/dto/utils/ElementUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public static String getBusOrBusbarSection(Terminal terminal) {
9292
}
9393
} else {
9494
// NODE_BREAKER: explore all paths and choose the busbar with the closed disconnector
95-
return BusbarSectionFinderTraverser.findBusbarId(terminal);
95+
return BusbarSectionFinderTraverser.findBusbarSectionId(terminal);
9696
}
9797
}
9898

src/test/java/org/gridsuite/network/map/mapper/BusbarSectionFinderTraverserTest.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ void setUp() {
215215
.add()
216216
.add();
217217

218-
// VLGEN9 - Independent line destination
218+
// VLGEN9 - Independent line destination
219219
VoltageLevel vlgen9 = network.newVoltageLevel()
220220
.setId("VLGEN9")
221221
.setName("Independent Line Destination")
@@ -270,9 +270,9 @@ void setUp() {
270270
void testLine7FindsBus2ViaFork() {
271271
Line line7 = network.getLine("LINE7_FORK");
272272
Terminal terminal = line7.getTerminal2(); // VLGEN7 side
273-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
273+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
274274
assertNotNull(result);
275-
assertEquals("BUS2_NGEN7", result.busbarId());
275+
assertEquals("BUS2_NGEN7", result.busbarSectionId());
276276
assertEquals(4, result.depth());
277277
assertNotNull(result.lastSwitch());
278278
assertEquals("SECT_BUS2", result.lastSwitch().id());
@@ -283,9 +283,9 @@ void testLine7FindsBus2ViaFork() {
283283
void testLine8FindsBus2ViaFork() {
284284
Line line8 = network.getLine("LINE8_FORK");
285285
Terminal terminal = line8.getTerminal1(); // VLGEN7 side
286-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
286+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
287287
assertNotNull(result);
288-
assertEquals("BUS2_NGEN7", result.busbarId());
288+
assertEquals("BUS2_NGEN7", result.busbarSectionId());
289289
assertEquals(4, result.depth());
290290
assertNotNull(result.lastSwitch());
291291
assertEquals("SECT_BUS2", result.lastSwitch().id());
@@ -296,9 +296,9 @@ void testLine8FindsBus2ViaFork() {
296296
void testLine9FindsBus4DirectPath() {
297297
Line line9 = network.getLine("LINE9_INDEPENDENT");
298298
Terminal terminal = line9.getTerminal1(); // VLGEN7 side
299-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
299+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
300300
assertNotNull(result);
301-
assertEquals("BUS4_NGEN7", result.busbarId());
301+
assertEquals("BUS4_NGEN7", result.busbarSectionId());
302302
assertEquals(3, result.depth());
303303
assertNotNull(result.lastSwitch());
304304
assertEquals("SECT_BUS4", result.lastSwitch().id());
@@ -309,10 +309,10 @@ void testLine9FindsBus4DirectPath() {
309309
void testBus1AccessibleThroughOpenSwitch() {
310310
Line line7 = network.getLine("LINE7_FORK");
311311
Terminal terminal = line7.getTerminal2();
312-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
312+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
313313
// Should prefer BUS2 (closed) over BUS1 (open)
314314
assertNotNull(result);
315-
assertEquals("BUS2_NGEN7", result.busbarId());
315+
assertEquals("BUS2_NGEN7", result.busbarSectionId());
316316
}
317317

318318
@Test
@@ -322,9 +322,9 @@ void testFindsBus1WhenBus2SwitchOpen() {
322322
sectBus2.setOpen(true); // Open the switch to BUS2
323323
Line line7 = network.getLine("LINE7_FORK");
324324
Terminal terminal = line7.getTerminal2();
325-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
325+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
326326
assertNotNull(result);
327-
assertEquals("BUS1_NGEN7", result.busbarId());
327+
assertEquals("BUS1_NGEN7", result.busbarSectionId());
328328
assertEquals(4, result.depth());
329329
assertNotNull(result.lastSwitch());
330330
assertTrue(result.lastSwitch().isOpen());
@@ -337,16 +337,16 @@ void testBus3AccessibleWhenBus4Open() {
337337
sectBus4.setOpen(true); // Open BUS4 connection
338338
Line line9 = network.getLine("LINE9_INDEPENDENT");
339339
Terminal terminal = line9.getTerminal1();
340-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
340+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
341341
assertNotNull(result);
342-
assertEquals("BUS4_NGEN7", result.busbarId());
342+
assertEquals("BUS4_NGEN7", result.busbarSectionId());
343343
}
344344

345345
@Test
346-
void testFindBusbarIdConvenienceMethod() {
346+
void testFindBusbarSectionIdConvenienceMethod() {
347347
Line line7 = network.getLine("LINE7_FORK");
348348
Terminal terminal = line7.getTerminal2();
349-
String busbarId = BusbarSectionFinderTraverser.findBusbarId(terminal);
349+
String busbarId = BusbarSectionFinderTraverser.findBusbarSectionId(terminal);
350350
assertNotNull(busbarId);
351351
assertEquals("BUS2_NGEN7", busbarId);
352352
}
@@ -363,9 +363,9 @@ void testReturnsNullWhenNoBusbarAccessible() {
363363
vlgen7.getNodeBreakerView().getSwitch("FORK_SW2").setOpen(true);
364364
Line line7 = network.getLine("LINE7_FORK");
365365
Terminal terminal = line7.getTerminal2();
366-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
366+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
367367
assertNotNull(result);
368-
assertEquals("BUS1_NGEN7", result.busbarId());
368+
assertEquals("BUS1_NGEN7", result.busbarSectionId());
369369
assertEquals(4, result.depth());
370370
assertEquals(3, result.switchesBeforeLast());
371371
assertNotNull(result.lastSwitch());
@@ -380,19 +380,19 @@ void testReturnsNullWhenNoBusbarAccessible() {
380380
void testPrefersShortestClosedPath() {
381381
Line line7 = network.getLine("LINE7_FORK");
382382
Terminal terminal = line7.getTerminal2();
383-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
383+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
384384
// BUS2 should be preferred (3 switches) over potential longer paths
385385
assertNotNull(result);
386-
assertEquals("BUS2_NGEN7", result.busbarId());
386+
assertEquals("BUS2_NGEN7", result.busbarSectionId());
387387
assertEquals(4, result.depth());
388388
}
389389

390390
@Test
391391
void testForkTopologySharesBusbar() {
392392
Line line7 = network.getLine("LINE7_FORK");
393393
Line line8 = network.getLine("LINE8_FORK");
394-
String busbar7 = BusbarSectionFinderTraverser.findBusbarId(line7.getTerminal2());
395-
String busbar8 = BusbarSectionFinderTraverser.findBusbarId(line8.getTerminal1());
394+
String busbar7 = BusbarSectionFinderTraverser.findBusbarSectionId(line7.getTerminal2());
395+
String busbar8 = BusbarSectionFinderTraverser.findBusbarSectionId(line8.getTerminal1());
396396
assertEquals(busbar7, busbar8);
397397
assertEquals("BUS2_NGEN7", busbar7);
398398
}
@@ -401,7 +401,7 @@ void testForkTopologySharesBusbar() {
401401
void testSwitchesBeforeLastCount() {
402402
Line line7 = network.getLine("LINE7_FORK");
403403
Terminal terminal = line7.getTerminal2();
404-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
404+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
405405
assertNotNull(result);
406406
assertEquals(4, result.depth());
407407
assertEquals(3, result.switchesBeforeLast());
@@ -411,7 +411,7 @@ void testSwitchesBeforeLastCount() {
411411
void testHandlesMixedSwitchTypes() {
412412
Line line7 = network.getLine("LINE7_FORK");
413413
Terminal terminal = line7.getTerminal2();
414-
BusbarSectionFinderTraverser.BusbarResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
414+
BusbarSectionFinderTraverser.BusbarSectionResult result = BusbarSectionFinderTraverser.findBestBusbar(terminal);
415415
assertNotNull(result);
416416
// Path contains both breakers and disconnectors
417417
assertTrue(result.depth() > 0);

0 commit comments

Comments
 (0)