|
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