|
1 |
| -// SPDX-FileCopyrightText: 2023 RTE FRANCE |
| 1 | +// SPDX-FileCopyrightText: 2023 2024 RTE FRANCE |
2 | 2 | //
|
3 | 3 | // SPDX-License-Identifier: Apache-2.0
|
4 | 4 |
|
|
15 | 15 | import org.lfenergy.compas.sct.commons.model.epf.TCBScopeType;
|
16 | 16 | import org.lfenergy.compas.sct.commons.model.epf.TChannel;
|
17 | 17 | import org.lfenergy.compas.sct.commons.model.epf.TChannelType;
|
18 |
| -import org.lfenergy.compas.sct.commons.scl.ExtRefService; |
19 | 18 | import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
|
20 | 19 | import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
|
21 | 20 | import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter;
|
22 | 21 | import org.lfenergy.compas.sct.commons.scl.ln.AbstractLNAdapter;
|
23 |
| -import org.lfenergy.compas.sct.commons.scl.ln.LN0Adapter; |
24 | 22 | import org.lfenergy.compas.sct.commons.util.ActiveStatus;
|
25 |
| -import org.lfenergy.compas.sct.commons.util.PrivateEnum; |
26 | 23 | import org.lfenergy.compas.sct.commons.util.PrivateUtils;
|
27 | 24 | import org.lfenergy.compas.sct.commons.util.Utils;
|
28 | 25 |
|
29 |
| -import java.math.BigInteger; |
30 | 26 | import java.util.*;
|
31 |
| -import java.util.function.BinaryOperator; |
32 |
| -import java.util.function.Function; |
33 |
| -import java.util.stream.Collectors; |
34 | 27 |
|
35 | 28 | import static org.apache.commons.lang3.StringUtils.*;
|
36 | 29 | import static org.lfenergy.compas.sct.commons.util.CommonConstants.*;
|
37 | 30 |
|
38 | 31 | @RequiredArgsConstructor
|
39 | 32 | public class ExtRefEditorService implements ExtRefEditor {
|
40 | 33 | private static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info";
|
41 |
| - private static final Map<String, String> voltageCodification = Map.of( |
42 |
| - "3", "HT", |
43 |
| - "4", "HT", |
44 |
| - "5", "THT", |
45 |
| - "6", "THT", |
46 |
| - "7", "THT" |
47 |
| - ); |
48 | 34 |
|
49 | 35 | private final IedService iedService;
|
50 | 36 | private final LdeviceService ldeviceService;
|
51 | 37 | private final LnEditor lnEditor;
|
52 |
| - private final ExtRefService extRefService; |
53 | 38 | private final DataTypeTemplatesService dataTypeTemplatesService;
|
54 | 39 |
|
55 | 40 | /**
|
@@ -274,31 +259,6 @@ public TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws ScdExce
|
274 | 259 | return anLNAdapter.updateExtRefSource(extRefInfo);
|
275 | 260 | }
|
276 | 261 |
|
277 |
| - @Override |
278 |
| - public List<SclReportItem> updateAllExtRefIedNames(SCL scd) { |
279 |
| - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); |
280 |
| - List<SclReportItem> iedErrors = validateIed(sclRootAdapter); |
281 |
| - if (!iedErrors.isEmpty()) { |
282 |
| - return iedErrors; |
283 |
| - } |
284 |
| - Map<String, IEDAdapter> icdSystemVersionToIed = sclRootAdapter.streamIEDAdapters() |
285 |
| - .collect(Collectors.toMap( |
286 |
| - iedAdapter -> iedAdapter.getCompasICDHeader() |
287 |
| - .map(TCompasICDHeader::getICDSystemVersionUUID) |
288 |
| - .orElseThrow(), // Value presence is checked by method validateIed called above |
289 |
| - Function.identity() |
290 |
| - )); |
291 |
| - |
292 |
| - return sclRootAdapter.streamIEDAdapters() |
293 |
| - .flatMap(IEDAdapter::streamLDeviceAdapters) |
294 |
| - .filter(LDeviceAdapter::hasLN0) |
295 |
| - .map(LDeviceAdapter::getLN0Adapter) |
296 |
| - .filter(LN0Adapter::hasInputs) |
297 |
| - .map(LN0Adapter::getInputsAdapter) |
298 |
| - .map(inputsAdapter -> inputsAdapter.updateAllExtRefIedNames(icdSystemVersionToIed)) |
299 |
| - .flatMap(List::stream).toList(); |
300 |
| - } |
301 |
| - |
302 | 262 | @Override
|
303 | 263 | public List<SclReportItem> manageBindingForLDEPF(SCL scd, EPF epf) {
|
304 | 264 | List<SclReportItem> sclReportItems = new ArrayList<>();
|
@@ -361,48 +321,6 @@ public void epfPostProcessing(SCL scd) {
|
361 | 321 | })));
|
362 | 322 | }
|
363 | 323 |
|
364 |
| - private List<SclReportItem> validateIed(SclRootAdapter sclRootAdapter) { |
365 |
| - List<SclReportItem> iedErrors = new ArrayList<>(checkIedCompasIcdHeaderAttributes(sclRootAdapter)); |
366 |
| - iedErrors.addAll(checkIedUnityOfIcdSystemVersionUuid(sclRootAdapter)); |
367 |
| - return iedErrors; |
368 |
| - } |
369 |
| - |
370 |
| - private List<SclReportItem> checkIedCompasIcdHeaderAttributes(SclRootAdapter sclRootAdapter) { |
371 |
| - return sclRootAdapter.streamIEDAdapters() |
372 |
| - .map(iedAdapter -> { |
373 |
| - Optional<TCompasICDHeader> compasPrivate = iedAdapter.getCompasICDHeader(); |
374 |
| - if (compasPrivate.isEmpty()) { |
375 |
| - return iedAdapter.buildFatalReportItem(String.format("IED has no Private %s element", PrivateEnum.COMPAS_ICDHEADER.getPrivateType())); |
376 |
| - } |
377 |
| - if (isBlank(compasPrivate.get().getICDSystemVersionUUID()) |
378 |
| - || isBlank(compasPrivate.get().getIEDName())) { |
379 |
| - return iedAdapter.buildFatalReportItem(String.format("IED private %s as no icdSystemVersionUUID or iedName attribute", |
380 |
| - PrivateEnum.COMPAS_ICDHEADER.getPrivateType())); |
381 |
| - } |
382 |
| - return null; |
383 |
| - } |
384 |
| - ).filter(Objects::nonNull) |
385 |
| - .toList(); |
386 |
| - } |
387 |
| - |
388 |
| - private List<SclReportItem> checkIedUnityOfIcdSystemVersionUuid(SclRootAdapter sclRootAdapter) { |
389 |
| - Map<String, List<TIED>> systemVersionToIedList = sclRootAdapter.getCurrentElem().getIED().stream() |
390 |
| - .collect(Collectors.groupingBy(ied -> PrivateUtils.extractCompasPrivate(ied, TCompasICDHeader.class) |
391 |
| - .map(TCompasICDHeader::getICDSystemVersionUUID) |
392 |
| - .orElse(""))); |
393 |
| - |
394 |
| - return systemVersionToIedList.entrySet().stream() |
395 |
| - .filter(entry -> isNotBlank(entry.getKey())) |
396 |
| - .filter(entry -> entry.getValue().size() > 1) |
397 |
| - .map(entry -> SclReportItem.error(entry.getValue().stream() |
398 |
| - .map(tied -> new IEDAdapter(sclRootAdapter, tied)) |
399 |
| - .map(IEDAdapter::getXPath) |
400 |
| - .collect(Collectors.joining(", ")), |
401 |
| - "/IED/Private/compas:ICDHeader[@ICDSystemVersionUUID] must be unique" + |
402 |
| - " but the same ICDSystemVersionUUID was found on several IED.")) |
403 |
| - .toList(); |
404 |
| - } |
405 |
| - |
406 | 324 | private void updateLDEPFExtRefBinding(TExtRef extRef, TIED iedSource, TChannel setting) {
|
407 | 325 | extRef.setIedName(iedSource.getName());
|
408 | 326 | extRef.setLdInst(setting.getLDInst());
|
@@ -456,122 +374,20 @@ private String computeDaiValue(AbstractLNAdapter<?> lnAdapter, TExtRef extRef, S
|
456 | 374 | return extRef.getIedName() +
|
457 | 375 | extRef.getLdInst() + "/" +
|
458 | 376 | trimToEmpty(extRef.getPrefix()) +
|
459 |
| - extRef.getLnClass().get(0) + |
| 377 | + extRef.getLnClass().getFirst() + |
460 | 378 | trimToEmpty(extRef.getLnInst()) + "." +
|
461 | 379 | extRef.getDoName() + "." + Q_DA_NAME;
|
462 | 380 | } else {
|
463 | 381 | return extRef.getIedName() +
|
464 | 382 | extRef.getLdInst() + "/" +
|
465 | 383 | trimToEmpty(extRef.getPrefix()) +
|
466 |
| - extRef.getLnClass().get(0) + |
| 384 | + extRef.getLnClass().getFirst() + |
467 | 385 | trimToEmpty(extRef.getLnInst()) + "." +
|
468 | 386 | extRef.getDoName() + "." +
|
469 | 387 | daName;
|
470 | 388 | }
|
471 | 389 | }
|
472 | 390 |
|
473 |
| - @Override |
474 |
| - public void debindCompasFlowsAndExtRefsBasedOnVoltageLevel(SCL scd) { |
475 |
| - scd.getSubstation() |
476 |
| - .stream() |
477 |
| - .flatMap(tSubstation -> tSubstation.getVoltageLevel().stream()) |
478 |
| - .map(TVoltageLevel::getName) |
479 |
| - .filter(tVoltageLevelName -> !"0".equals(tVoltageLevelName)) |
480 |
| - .forEach(tVoltageLevelName -> scd.getIED().stream() |
481 |
| - .flatMap(ldeviceService::getLdevices) |
482 |
| - .filter(TLDevice::isSetLN0) |
483 |
| - .filter(tlDevice -> tlDevice.getLN0().isSetInputs()) |
484 |
| - .forEach(tlDevice -> { |
485 |
| - String flowSource = voltageCodification.get(tVoltageLevelName); |
486 |
| - extRefService.getCompasFlows(tlDevice) |
487 |
| - .filter(TCompasFlow::isSetFlowSourceVoltageLevel) |
488 |
| - .filter(TCompasFlow::isSetExtRefiedName) |
489 |
| - .forEach(tCompasFlow -> { |
490 |
| - if (!tCompasFlow.getFlowSourceVoltageLevel().equals(flowSource)) { |
491 |
| - //debind extRefs correspondind to compas flow |
492 |
| - extRefService.getMatchingExtRefs(tlDevice, tCompasFlow) |
493 |
| - .forEach(extRefService::clearExtRefBinding); |
494 |
| - //debind all compas flow |
495 |
| - extRefService.clearCompasFlowBinding(tCompasFlow); |
496 |
| - } |
497 |
| - }); |
498 |
| - }) |
499 |
| - ); |
500 |
| - } |
501 |
| - |
502 |
| - |
503 |
| - @Override |
504 |
| - public List<SclReportItem> updateIedNameBasedOnLnode(SCL scl) { |
505 |
| - Map<TopoKey, TBay> bayByTopoKey = scl.getSubstation().stream() |
506 |
| - .flatMap(tSubstation -> tSubstation.getVoltageLevel().stream()) |
507 |
| - .flatMap(tVoltageLevel -> tVoltageLevel.getBay().stream()) |
508 |
| - .map(tBay -> PrivateUtils.extractCompasPrivate(tBay, TCompasTopo.class) |
509 |
| - .filter(tCompasTopo -> isNotBlank(tCompasTopo.getNode()) && Objects.nonNull(tCompasTopo.getNodeOrder())) |
510 |
| - .map(tCompasTopo -> new BayTopoKey(tBay, new TopoKey(tCompasTopo.getNode(), tCompasTopo.getNodeOrder()))) |
511 |
| - ) |
512 |
| - .flatMap(Optional::stream) |
513 |
| - .collect(Collectors.toMap(BayTopoKey::topoKey, BayTopoKey::bay)); |
514 |
| - |
515 |
| - List<SclReportItem> sclReportItems = new ArrayList<>(); |
516 |
| - scl.getIED().stream() |
517 |
| - .flatMap(ldeviceService::getLdevices) |
518 |
| - .forEach(tlDevice -> |
519 |
| - extRefService.getCompasFlows(tlDevice) |
520 |
| - .filter(tCompasFlow -> Objects.nonNull(tCompasFlow.getFlowSourceBayNode()) && Objects.nonNull(tCompasFlow.getFlowSourceBayNodeOrder())) |
521 |
| - .forEach(tCompasFlow -> |
522 |
| - Optional.ofNullable(bayByTopoKey.get(new TopoKey(tCompasFlow.getFlowSourceBayNode().toString(), tCompasFlow.getFlowSourceBayNodeOrder()))) |
523 |
| - .flatMap(tBay -> tBay.getFunction().stream() |
524 |
| - .flatMap(tFunction -> tFunction.getLNode().stream()) |
525 |
| - .filter(tlNode -> Objects.equals(tlNode.getLdInst(), tCompasFlow.getExtRefldinst()) |
526 |
| - && Objects.equals(tlNode.getLnInst(), tCompasFlow.getExtReflnInst()) |
527 |
| - && Utils.lnClassEquals(tlNode.getLnClass(), tCompasFlow.getExtReflnClass()) |
528 |
| - && Objects.equals(tlNode.getPrefix(), tCompasFlow.getExtRefprefix())) |
529 |
| - .filter(tlNode -> { |
530 |
| - Optional<TCompasICDHeader> tCompasICDHeader = PrivateUtils.extractCompasPrivate(tlNode, TCompasICDHeader.class); |
531 |
| - if (tCompasICDHeader.isPresent()) { |
532 |
| - return Objects.equals(tCompasFlow.getFlowSourceIEDType(), tCompasICDHeader.get().getIEDType()) |
533 |
| - && Objects.equals(tCompasFlow.getFlowIEDSystemVersioninstance(), tCompasICDHeader.get().getIEDSystemVersioninstance()) |
534 |
| - && Objects.equals(tCompasFlow.getFlowSourceIEDredundancy(), tCompasICDHeader.get().getIEDredundancy()); |
535 |
| - } else { |
536 |
| - sclReportItems.add(SclReportItem.error("", ("The substation LNode with following attributes : IedName:%s / LdInst:%s / LnClass:%s / LnInst:%s " + |
537 |
| - "does not contain the needed (COMPAS - ICDHeader) private") |
538 |
| - .formatted(tlNode.getIedName(), tlNode.getLdInst(), tlNode.getLnClass().getFirst(), tlNode.getLnInst()))); |
539 |
| - return false; |
540 |
| - } |
541 |
| - }) |
542 |
| - .map(TLNode::getIedName) |
543 |
| - .reduce(checkOnlyOneIed(tCompasFlow, tBay, sclReportItems)) |
544 |
| - ) |
545 |
| - .ifPresentOrElse(iedName -> { |
546 |
| - extRefService.getMatchingExtRefs(tlDevice, tCompasFlow).forEach(tExtRef -> tExtRef.setIedName(iedName)); |
547 |
| - tCompasFlow.setExtRefiedName(iedName); |
548 |
| - }, |
549 |
| - () -> { |
550 |
| - extRefService.getMatchingExtRefs(tlDevice, tCompasFlow).forEach(extRefService::clearExtRefBinding); |
551 |
| - extRefService.clearCompasFlowBinding(tCompasFlow); |
552 |
| - } |
553 |
| - ) |
554 |
| - ) |
555 |
| - ); |
556 |
| - return sclReportItems; |
557 |
| - } |
558 |
| - |
559 |
| - private static BinaryOperator<String> checkOnlyOneIed(TCompasFlow tCompasFlow, TBay tBay, List<SclReportItem> sclReportItems) { |
560 |
| - return (iedName1, iedName2) -> { |
561 |
| - sclReportItems.add(SclReportItem.error("", |
562 |
| - ("Several LNode@IedName ('%s', '%s') are found in the bay '%s' for the following compas-flow attributes :" + |
563 |
| - " @FlowSourceIEDType '%s' @FlowSourceIEDredundancy '%s' @FlowIEDSystemVersioninstance '%s'"). |
564 |
| - formatted(iedName1, iedName2, tBay.getName(), tCompasFlow.getFlowSourceIEDType(), tCompasFlow.getFlowSourceIEDredundancy(), tCompasFlow.getFlowIEDSystemVersioninstance()))); |
565 |
| - return iedName1; |
566 |
| - }; |
567 |
| - } |
568 |
| - |
569 |
| - record TopoKey(String FlowNode, BigInteger FlowNodeOrder) { |
570 |
| - } |
571 |
| - |
572 |
| - record BayTopoKey(TBay bay, TopoKey topoKey) { |
573 |
| - } |
574 |
| - |
575 | 391 | private record DoNameAndDaName(String doName, String daName) {
|
576 | 392 | }
|
577 | 393 |
|
|
0 commit comments