From 090141f192dd2a142cd70c085e8783824d960aca Mon Sep 17 00:00:00 2001 From: Samir Romdhani Date: Thu, 8 Sep 2022 17:59:03 +0200 Subject: [PATCH] [68][164] Activation used LDevice and Deactivation unused LDevice Signed-off-by: Aliou DIAITE Signed-off-by: Samir Romdhani --- .../sct/commons/dto/ResumedDataTemplate.java | 7 + .../compas/sct/commons/dto/SclReport.java | 40 +++ .../sct/commons/scl/LDeviceActivation.java | 132 +++++++++ .../sct/commons/scl/SclElementAdapter.java | 14 +- .../sct/commons/scl/SclRootAdapter.java | 15 + .../compas/sct/commons/scl/SclService.java | 25 ++ .../sct/commons/scl/SubstationService.java | 1 - .../commons/scl/com/CommunicationAdapter.java | 5 + .../commons/scl/com/ConnectedAPAdapter.java | 9 +- .../commons/scl/com/SubNetworkAdapter.java | 7 + .../compas/sct/commons/scl/dtt/DAAdapter.java | 8 + .../sct/commons/scl/dtt/DATypeAdapter.java | 13 + .../compas/sct/commons/scl/dtt/DOAdapter.java | 8 + .../sct/commons/scl/dtt/DOTypeAdapter.java | 8 + .../scl/dtt/DataTypeTemplateAdapter.java | 7 +- .../sct/commons/scl/dtt/EnumTypeAdapter.java | 7 + .../sct/commons/scl/dtt/LNodeTypeAdapter.java | 8 + .../sct/commons/scl/header/HeaderAdapter.java | 9 + .../commons/scl/ied/AbstractLNAdapter.java | 19 ++ .../sct/commons/scl/ied/DOIAdapter.java | 13 + .../sct/commons/scl/ied/IEDAdapter.java | 6 + .../sct/commons/scl/ied/LDeviceAdapter.java | 6 + .../sct/commons/scl/ied/LN0Adapter.java | 126 ++++++++- .../compas/sct/commons/scl/ied/LNAdapter.java | 10 + .../sct/commons/scl/ied/RootSDIAdapter.java | 14 + .../sct/commons/scl/ied/SDIAdapter.java | 12 + .../sct/commons/scl/sstation/BayAdapter.java | 1 + .../scl/sstation/SubstationAdapter.java | 19 ++ .../compas/sct/commons/util/STValEnum.java | 21 ++ .../commons/scl/LDeviceActivationTest.java | 135 +++++++++ .../sct/commons/scl/SclServiceTest.java | 258 ++++++++++++++++++ .../commons/scl/SubstationServiceTest.java | 3 + .../scl/com/CommunicationAdapterTest.java | 12 + .../scl/com/ConnectedAPAdapterTest.java | 20 +- .../scl/com/SubNetworkAdapterTest.java | 18 ++ .../sct/commons/scl/dtt/BDAAdapterTest.java | 13 + .../sct/commons/scl/dtt/DAAdapterTest.java | 13 + .../commons/scl/dtt/DATypeAdapterTest.java | 12 + .../sct/commons/scl/dtt/DOAdapterTest.java | 35 +++ .../commons/scl/dtt/DOTypeAdapterTest.java | 14 + .../scl/dtt/DataTypeTemplateAdapterTest.java | 12 + .../commons/scl/dtt/EnumTypeAdapterTest.java | 15 + .../commons/scl/dtt/LNodeTypeAdapterTest.java | 13 + .../commons/scl/header/HeaderAdapterTest.java | 20 +- .../sct/commons/scl/ied/DAITrackerTest.java | 2 + .../sct/commons/scl/ied/DOIAdapterTest.java | 27 ++ .../sct/commons/scl/ied/IEDAdapterTest.java | 19 ++ .../commons/scl/ied/LDeviceAdapterTest.java | 17 ++ .../sct/commons/scl/ied/LN0AdapterTest.java | 62 +++++ .../sct/commons/scl/ied/LNAdapterTest.java | 12 + .../commons/scl/ied/RootSDIAdapterTest.java | 31 +++ .../sct/commons/scl/ied/SDIAdapterTest.java | 16 ++ .../scl/sstation/SubstationAdapterTest.java | 30 ++ .../issue68_Test1_LD_STATUS_INACTIVE.scd | 224 +++++++++++++++ .../issue68_Test2_LD_STATUS_INACTIVE.scd | 222 +++++++++++++++ .../issue68_Test_Dai_Not_Updatable.scd | 223 +++++++++++++++ .../issue68_Test_KO_MissingBeh.scd | 114 ++++++++ .../issue68_Test_KO_MissingLDevicePrivate.scd | 112 ++++++++ ...Test_KO_MissingLDevicePrivateAttribute.scd | 115 ++++++++ .../issue68_Test_KO_MissingMod.scd | 114 ++++++++ .../issue68_Test_LD_STATUS_ACTIVE.scd | 219 +++++++++++++++ .../issue68_Test_LD_STATUS_UNTESTED.scd | 219 +++++++++++++++ .../issue68_Test_Template.scd | 223 +++++++++++++++ 63 files changed, 3144 insertions(+), 20 deletions(-) create mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SclReport.java create mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/LDeviceActivation.java create mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/STValEnum.java create mode 100644 sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/LDeviceActivationTest.java create mode 100644 sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOAdapterTest.java create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test1_LD_STATUS_INACTIVE.scd create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test2_LD_STATUS_INACTIVE.scd create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_Dai_Not_Updatable.scd create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingBeh.scd create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivate.scd create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivateAttribute.scd create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingMod.scd create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_LD_STATUS_ACTIVE.scd create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_LD_STATUS_UNTESTED.scd create mode 100644 sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_Template.scd diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplate.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplate.java index fe50c79c5..dd702a8c9 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplate.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplate.java @@ -322,4 +322,11 @@ public void setValImport(boolean valImport) { public boolean isValImport(){ return daName.isValImport(); } + + public ResumedDataTemplate setNewVal(String daiValue) { + TVal newDaiVal = new TVal(); + newDaiVal.setValue(daiValue); + this.setDaiValues(List.of(newDaiVal)); + return this; + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SclReport.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SclReport.java new file mode 100644 index 000000000..2a9e42679 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SclReport.java @@ -0,0 +1,40 @@ +/* + * // SPDX-FileCopyrightText: 2022 RTE FRANCE + * // + * // SPDX-License-Identifier: Apache-2.0 + */ + +package org.lfenergy.compas.sct.commons.dto; + +import lombok.*; +import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; + +import java.util.ArrayList; +import java.util.List; + +@AllArgsConstructor +@NoArgsConstructor +@Setter +@Getter +@Builder +public class SclReport { + + private SclRootAdapter scdFile; + + private List errorDescriptionList = new ArrayList<>(); + + public boolean isSuccess() { + return errorDescriptionList.isEmpty(); + } + + @Getter + @Setter + @AllArgsConstructor + @ToString + @EqualsAndHashCode + @Builder + public static class ErrorDescription{ + private String xpath; + private String message; + } +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/LDeviceActivation.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/LDeviceActivation.java new file mode 100644 index 000000000..984e8a56f --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/LDeviceActivation.java @@ -0,0 +1,132 @@ +// SPDX-FileCopyrightText: 2022 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.scl; + +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.tuple.Pair; +import org.lfenergy.compas.scl2007b4.model.TCompasLDeviceStatus; +import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate; +import org.lfenergy.compas.sct.commons.util.STValEnum; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Common class for all states that define if LDevice should be activated or not + * regardless of the CompasLDeviceStatus Private, Enum Values of DO 'Beh' and if it's referenced in Substation...LNode or not + */ +@Getter +@Setter +public class LDeviceActivation { + + private final List> iedNameLdInstList; + + private TCompasLDeviceStatus compasLDeviceStatus; + private boolean isUpdatable; + private ResumedDataTemplate resumedDataTemplate; + private List errorMessages = new ArrayList<>(); + + public LDeviceActivation(List> iedNameLdInstList) { + this.iedNameLdInstList = iedNameLdInstList; + } + + /** + * checks whether LDevice status is authorized to be activated or Not + * @param iedName Ied name value which LDevice appear + * @param ldInst LDevice inst value + * @param compasLDeviceStatus Private value + * @param enumValues enum values + */ + public void checkLDeviceActivationStatus(String iedName, String ldInst, TCompasLDeviceStatus compasLDeviceStatus, Set enumValues) { + if (!enumValues.contains(STValEnum.ON.value) && !enumValues.contains(STValEnum.OFF.value)) { + errorMessages.add(String.format("Unexpected error: The IED@%s/LDevice@%s cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'.", + iedName, ldInst)); + } + if (!enumValues.contains(STValEnum.ON.value) && enumValues.contains(STValEnum.OFF.value)) { + if (isAuthorized(iedName, ldInst)) { + errorMessages.add(String.format("Unexpected error: The IED@%s/LDevice@%s cannot be set to 'on' but has been selected into SSD: this case should not occur.", + iedName, ldInst)); + } else { + isUpdatable = true; + resumedDataTemplate.setNewVal(STValEnum.OFF.value); + } + } + if(compasLDeviceStatus.equals(TCompasLDeviceStatus.ACTIVE) || + compasLDeviceStatus.equals(TCompasLDeviceStatus.UNTESTED)){ + isAuthorizedToActivateLDevice(iedName, ldInst, enumValues); + } + if(compasLDeviceStatus.equals(TCompasLDeviceStatus.INACTIVE)){ + isAuthorizedToDeactivateLDevice(iedName, ldInst, enumValues); + } + } + + /** + * checks whether LDevice status is authorized to be activated when CompasLDeviceStatus Private is ACTIVE or UNTESTED + * @param iedName Ied name value which contains LDevice + * @param ldInst LDevice inst value + * @param enumValues enum values + */ + private void isAuthorizedToActivateLDevice(String iedName, String ldInst, Set enumValues) { + if (!enumValues.contains(STValEnum.OFF.value) && enumValues.contains(STValEnum.ON.value)) { + if (isAuthorized(iedName, ldInst)) { + isUpdatable = true; + resumedDataTemplate.setNewVal(STValEnum.ON.value); + } else { + errorMessages.add(String.format("Unexpected error: The IED@%s/LDevice@%s cannot be set to 'off' but has not been selected into SSD: this case should not occur.", + iedName, ldInst)); + } + } + if (enumValues.contains(STValEnum.ON.value) && enumValues.contains(STValEnum.OFF.value)) { + isUpdatable = true; + if (isAuthorized(iedName, ldInst)) { + resumedDataTemplate.setNewVal(STValEnum.ON.value); + } else { + resumedDataTemplate.setNewVal(STValEnum.OFF.value); + } + } + + } + + /** + * checks whether LDevice Status is authorized to be deactivated when CompasLDeviceStatus Private is INACTIVE + * @param iedName Ied name value which contains LDevice + * @param ldInst LDevice inst value + * @param enumValues enum values + */ + private void isAuthorizedToDeactivateLDevice(String iedName, String ldInst, Set enumValues) { + if (!enumValues.contains(STValEnum.OFF.value) && enumValues.contains(STValEnum.ON.value)) { + if (isAuthorized(iedName, ldInst)) { + errorMessages.add(String.format("Unexpected error: The IED@%s/LDevice@%s is not qualified into STD but has been selected into SSD: this case should not occur.", + iedName, ldInst)); + } else { + errorMessages.add(String.format("Unexpected error: The IED@%s/LDevice@%s cannot be set to 'off' but has not been selected into SSD: this case should not occur.", + iedName, ldInst)); + } + } + if (enumValues.contains(STValEnum.ON.value) && enumValues.contains(STValEnum.OFF.value)) { + if (isAuthorized(iedName, ldInst)) { + errorMessages.add(String.format("Unexpected error: The IED@%s/LDevice@%s is not qualified into STD but has been selected into SSD: this case should not occur.", + iedName, ldInst)); + } else { + isUpdatable = true; + resumedDataTemplate.setNewVal(STValEnum.OFF.value); + } + } + } + + /** + * checks whether a pair of IED name and LDevice inst are referenced in Substation...LNode list + * @param iedName Ied name value + * @param ldInst LDevice inst value + * @return Returns whether a pair of IED name and LDevice inst are referenced in Substation...LNode list + */ + private boolean isAuthorized(String iedName, String ldInst){ + return iedNameLdInstList.contains(Pair.of(iedName, ldInst)); + } + + +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclElementAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclElementAdapter.java index 8d4b36f2b..1939dc07a 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclElementAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclElementAdapter.java @@ -67,6 +67,12 @@ protected boolean amRootElement(){ return parentAdapter == null; } + /** + * Returns XPath path to current element + * @return message as undefined + */ + protected abstract String elementXPath(); + protected void customInit() { // do nothing } @@ -109,12 +115,4 @@ public String getXPath(){ return parentXpath + "/" + elementXPath(); } - /** - * Returns XPath path to current element - * @return message as undefined - */ - protected String elementXPath(){ - return String.format("undefined(%s)", currentElem.getClass().getSimpleName()); - } - } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclRootAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclRootAdapter.java index c7698a6ac..4371d0abb 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclRootAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclRootAdapter.java @@ -18,6 +18,7 @@ import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -140,6 +141,19 @@ public SubstationAdapter getSubstationAdapter(String ssName) throws ScdException return new SubstationAdapter(this,ssName); } + /** + * Gets the first Substation from SCL root node + * @return SubstationAdapter object + * @throws ScdException throws when unknown Substation + */ + public SubstationAdapter getSubstationAdapter() throws ScdException { + TSubstation tSubstation = currentElem.getSubstation() + .stream() + .findFirst() + .orElseThrow(() -> new ScdException("No Substation in SCL file")); + return new SubstationAdapter(this, tSubstation); + } + /** * Add Header to SCL root node * @param hId SCL Header ID @@ -275,4 +289,5 @@ public IEDAdapter checkObjRef(String val) throws ScdException { } throw new ScdException("Invalid ObjRef: " + val); } + } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java index 21119cd86..5a04a79e8 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java @@ -18,6 +18,7 @@ import org.lfenergy.compas.sct.commons.scl.dtt.LNodeTypeAdapter; import org.lfenergy.compas.sct.commons.scl.header.HeaderAdapter; import org.lfenergy.compas.sct.commons.scl.ied.*; +import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter; import org.lfenergy.compas.sct.commons.util.Utils; import java.util.*; @@ -680,4 +681,28 @@ public static void removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(final S .forEach(LNAdapter::removeAllControlBlocksAndDatasets); } + /** + * Activate used LDevice and Deactivate unused LDevice in {@link TLNode TLNode } + * @param scd SCL file for which LDevice should be activated or deactivated + * @return SclReport Object that contain SCL file and set of errors + */ + public static SclReport updateLDeviceStatus(SCL scd) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + SubstationAdapter substationAdapter = sclRootAdapter.getSubstationAdapter(); + final List> iedNameLdInstList = substationAdapter.getLDevicesFromLNode(true); + LDeviceActivation lDeviceActivation = new LDeviceActivation(iedNameLdInstList); + List errors = sclRootAdapter.getIEDAdapters().stream() + .map(IEDAdapter::getLDeviceAdapters) + .flatMap(Collection::stream) + .map(LDeviceAdapter::getLN0Adapter) + .map(ln0Adapter -> ln0Adapter.checkAndUpdateLDeviceStatus(lDeviceActivation)) + .reduce(new ArrayList<>(),(sclReportErrors, partialSclReportErrors) -> { + sclReportErrors.addAll(partialSclReportErrors); + return sclReportErrors; + }); + SclReport sclReport = new SclReport(); + sclReport.getErrorDescriptionList().addAll(errors); + sclReport.setScdFile(sclRootAdapter); + return sclReport; + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java index dec6e4b22..8316d957a 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java @@ -14,7 +14,6 @@ import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter; import org.lfenergy.compas.sct.commons.scl.sstation.VoltageLevelAdapter; - /** * A representation of the {@link SubstationService SubstationService}. *

diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapter.java index 333584ce1..0bd5a4661 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapter.java @@ -58,6 +58,11 @@ public boolean amChildElementRef() { return currentElem == parentAdapter.getCurrentElem().getCommunication(); } + @Override + protected String elementXPath() { + return "Communication"; + } + /** * Add Subnetwork node in Communication one. * For that : diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapter.java index 36ca4c3b0..3f4a076c3 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapter.java @@ -6,8 +6,8 @@ import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TConnectedAP; -import org.lfenergy.compas.scl2007b4.model.TPrivate; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.Optional; @@ -45,6 +45,13 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getConnectedAP().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("ConnectedAP[%s and %s]", + Utils.xpathAttributeFilter("apName", currentElem.isSetApName() ? currentElem.getApName() : null), + Utils.xpathAttributeFilter("iedName", currentElem.isSetIedName() ? currentElem.getApName() : null)); + } + /** * Returns the value of the iedName attribute. * @return the value of the iedName attribute. diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/SubNetworkAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/SubNetworkAdapter.java index 5a6333eef..efe7a9838 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/SubNetworkAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/SubNetworkAdapter.java @@ -9,6 +9,7 @@ import org.lfenergy.compas.scl2007b4.model.TSubNetwork; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.List; import java.util.Objects; @@ -48,6 +49,12 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getSubNetwork().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("SubNetwork[%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null)); + } + /** * Create a Connected Access Point for this subnetwork.
*

diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DAAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DAAdapter.java index 925eec136..a07d04571 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DAAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DAAdapter.java @@ -8,6 +8,7 @@ import org.lfenergy.compas.scl2007b4.model.TDA; import org.lfenergy.compas.sct.commons.dto.DaTypeName; import org.lfenergy.compas.sct.commons.exception.ScdException; +import org.lfenergy.compas.sct.commons.util.Utils; /** * A representation of the model object {@link org.lfenergy.compas.scl2007b4.model.TDA DA}. @@ -57,6 +58,13 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getSDOOrDA().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("DA[name=%s and type=%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null), + Utils.xpathAttributeFilter("type", currentElem.isSetType() ? currentElem.getType() : null)); + } + /** * Updates DA Type Name * @param daTypeName DA Type Name to update diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapter.java index 0402fa774..32c02403f 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapter.java @@ -14,6 +14,7 @@ import org.lfenergy.compas.sct.commons.dto.DaTypeName; import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate; import org.lfenergy.compas.sct.commons.exception.ScdException; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.ArrayList; import java.util.List; @@ -154,6 +155,12 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getDAType().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("DAType[%s]", + Utils.xpathAttributeFilter("id", currentElem.isSetId() ? currentElem.getId() : null)); + } + /** * Gets all BDAs from current DAType * @return list of linked BDA as BDAAdapter object @@ -390,5 +397,11 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getBDA().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("BDA[name=%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null)); + } + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOAdapter.java index 711a39f97..75fbb6445 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOAdapter.java @@ -6,6 +6,7 @@ import org.lfenergy.compas.scl2007b4.model.TDO; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.Optional; @@ -53,6 +54,13 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getDO().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("DO[name=%s and type=%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null), + Utils.xpathAttributeFilter("type", currentElem.isSetType() ? currentElem.getType() : null)); + } + /** * Gets linked DataTypeTemplateAdapter as parent * @return DataTypeTemplateAdapter object diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapter.java index 3f7fd8aa9..a2e675e29 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapter.java @@ -11,6 +11,7 @@ import org.lfenergy.compas.sct.commons.dto.DoTypeName; import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate; import org.lfenergy.compas.sct.commons.exception.ScdException; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.*; import java.util.stream.Collectors; @@ -183,6 +184,13 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getDOType().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("DOType[%s]", + Utils.xpathAttributeFilter("id", currentElem.isSetId() ? currentElem.getId() : null)); + } + + /** * Checks if current DOType contains DA * @param da DA name diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateAdapter.java index 488781267..587f1062c 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateAdapter.java @@ -13,7 +13,6 @@ import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; -import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter; import java.util.*; import java.util.stream.Collectors; @@ -90,6 +89,12 @@ protected boolean amChildElementRef() { return currentElem == parentAdapter.getCurrentElem().getDataTypeTemplates(); } + @Override + protected String elementXPath() { + return "DataTypeTemplates"; + } + + /** * Gets LNodeType from DataTypeTemplate by ID in LNodeTypeAdapter * @param id LNodeType ID diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/EnumTypeAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/EnumTypeAdapter.java index d184ab835..f05d80635 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/EnumTypeAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/EnumTypeAdapter.java @@ -7,6 +7,7 @@ import org.lfenergy.compas.scl2007b4.model.TEnumType; import org.lfenergy.compas.scl2007b4.model.TEnumVal; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.List; import java.util.Objects; @@ -53,6 +54,12 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getEnumType().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("EnumType[%s]", + Utils.xpathAttributeFilter("id", currentElem.isSetId() ? currentElem.getId() : null)); + } + /** * Compares current EnumType and given EnumType * @param tEnumType EnumType to compare with diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java index 6d25c83e3..92d2878c8 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java @@ -15,6 +15,7 @@ import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.ArrayList; import java.util.List; @@ -71,6 +72,13 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getLNodeType().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("LNodeType[id=%s and lnClass=%s]", + Utils.xpathAttributeFilter("id", currentElem.isSetId() ? currentElem.getId() : null), + Utils.xpathAttributeFilter("lnClass", currentElem.isSetLnClass() ? currentElem.getLnClass() : null)); + } + /** * Compares current LNodeType and given LNodeType * @param tlNodeType LNodeType to compare with diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/header/HeaderAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/header/HeaderAdapter.java index 3b1bee252..e3d96ef2a 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/header/HeaderAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/header/HeaderAdapter.java @@ -9,6 +9,7 @@ import org.lfenergy.compas.scl2007b4.model.TPrivate; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.ArrayList; import java.util.Date; @@ -55,6 +56,14 @@ protected boolean amChildElementRef() { return currentElem == parentAdapter.getCurrentElem().getHeader(); } + @Override + protected String elementXPath() { + return String.format("Header[%s and %s and %s]", + Utils.xpathAttributeFilter("id", currentElem.isSetId() ? currentElem.getId() : null), + Utils.xpathAttributeFilter("version", currentElem.isSetVersion() ? currentElem.getVersion() : null), + Utils.xpathAttributeFilter("revision", currentElem.isSetRevision() ? currentElem.getRevision() : null)); + } + /** * @param who input * @param what input diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java index 0c1b52255..c22ffa730 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java @@ -14,6 +14,7 @@ import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter; +import org.lfenergy.compas.sct.commons.scl.dtt.EnumTypeAdapter; import org.lfenergy.compas.sct.commons.scl.dtt.LNodeTypeAdapter; import java.util.*; @@ -90,6 +91,24 @@ public static LNAdapterBuilder builder(){ public abstract String getLNInst(); public abstract String getPrefix(); + /** + * Returns sets of enum value for given ResumedDataTemplate object + * @param enumType enum Type + * @return Enum value list + */ + public Set getEnumValue(String enumType) { + Optional enumTypeAdapter = parentAdapter + .getParentAdapter().getParentAdapter().getDataTypeTemplateAdapter() + .getEnumTypeAdapterById(enumType); + + if(enumTypeAdapter.isEmpty()){ + return new HashSet<>(); + } + return enumTypeAdapter.get().getCurrentElem().getEnumVal() + .stream().map(TEnumVal::getValue) + .collect(Collectors.toSet()); + } + /** * Add given ControlBlock to LNode * @param controlBlock ControlBlock to add diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java index 54414d7b9..35a546c09 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java @@ -10,6 +10,7 @@ import org.lfenergy.compas.scl2007b4.model.TSDI; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; /** @@ -56,6 +57,12 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getDOI().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("DOI[name=%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null)); + } + /** * Gets SDI by name from current DOI * @param sName name of SDI to get @@ -161,5 +168,11 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getSDIOrDAI().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("DAI[name=%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null)); + } + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapter.java index 6d3c5455a..fd84454af 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapter.java @@ -15,6 +15,7 @@ import org.lfenergy.compas.sct.commons.scl.ObjectReference; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.*; import java.util.stream.Collectors; @@ -99,6 +100,11 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getIED().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("IED[%s]", Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null)); + } + /** * Sets IED name in current IED * @param iedName new name to set diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapter.java index c2f6fa0ea..a037accc3 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapter.java @@ -14,6 +14,7 @@ import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.*; import java.util.stream.Collectors; @@ -75,6 +76,11 @@ protected boolean amChildElementRef() { .anyMatch(tlDevice -> currentElem.getInst().equals(tlDevice.getInst())); } + @Override + protected String elementXPath() { + return String.format("LDevice[%s]", Utils.xpathAttributeFilter("inst", currentElem.isSetInst() ? currentElem.getInst() : null)); + } + /** * Updates LDevice name by combining IED name and LDevice ldInst value * @throws ScdException throws when renaming LDevice and new name has more than 33 caracteres diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LN0Adapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LN0Adapter.java index a443250fc..3ca80cb93 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LN0Adapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LN0Adapter.java @@ -5,15 +5,17 @@ package org.lfenergy.compas.sct.commons.scl.ied; -import org.lfenergy.compas.scl2007b4.model.LN0; -import org.lfenergy.compas.scl2007b4.model.TLLN0Enum; -import org.lfenergy.compas.scl2007b4.model.TServiceType; -import org.lfenergy.compas.sct.commons.dto.ExtRefInfo; -import org.lfenergy.compas.sct.commons.dto.ExtRefSignalInfo; -import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate; +import org.lfenergy.compas.scl2007b4.model.*; +import org.lfenergy.compas.sct.commons.dto.*; +import org.lfenergy.compas.sct.commons.scl.LDeviceActivation; import org.lfenergy.compas.sct.commons.scl.ObjectReference; +import org.lfenergy.compas.sct.commons.scl.PrivateService; +import org.lfenergy.compas.sct.commons.util.Utils; +import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * A representation of the model object @@ -83,6 +85,13 @@ protected boolean amChildElementRef() { return currentElem == parentAdapter.getCurrentElem().getLN0(); } + @Override + protected String elementXPath() { + return String.format("LN[lnClass=LLN0 and %s and %s]", + Utils.xpathAttributeFilter("inst", currentElem.isSetInst() ? currentElem.getInst() : null), + Utils.xpathAttributeFilter("lnType", currentElem.isSetLnType() ? currentElem.getLnType() : null)); + } + /** * Gets current LN0 class type * @return LN0.class @@ -138,4 +147,109 @@ public void removeAllControlBlocksAndDatasets() { currentElem.unsetGSEControl(); currentElem.unsetSampledValueControl(); } + + /** + * Construct ResumedDataTemplate object with DO and DA attributes + * @param doName The value of the name attribute of DO object + * @param daTypeName DaTypeName object + * @return ResumedDataTemplate + */ + private ResumedDataTemplate getResumedDataTemplate(String doName, DaTypeName daTypeName) { + ResumedDataTemplate filter = new ResumedDataTemplate(); + filter.setLnClass(getLNClass()); + filter.setLnInst(getLNInst()); + filter.setPrefix(getPrefix()); + filter.setLnType(getLnType()); + filter.setDoName(new DoTypeName(doName)); + filter.setDaName(daTypeName); + return filter; + } + + /** + * Verify and update LDevice status in parent Node + * @param lDeviceActivation LDeviceActivation which compute LDevice status + * @return Set of Errors + */ + public List checkAndUpdateLDeviceStatus(LDeviceActivation lDeviceActivation) { + List errors = new ArrayList<>(); + lDeviceActivation.getErrorMessages().clear(); + final String iedName = getParentAdapter().getParentAdapter().getName(); + final String ldInst = getParentAdapter().getInst(); + final String behaviourDO = "Beh"; + final String targetDO = "Mod"; + final String targetDA = "stVal"; + DaTypeName daTypeName = new DaTypeName(); + daTypeName.setName(targetDA); + daTypeName.setBType(TPredefinedBasicTypeEnum.ENUM); + daTypeName.setFc(TFCEnum.ST); + ResumedDataTemplate daiBehFilter = getResumedDataTemplate(behaviourDO, daTypeName); + List daiBehList = getDAI(daiBehFilter, false); + if (daiBehList.isEmpty()) { + buildErrorMessage(errors, getXPath(), + "The IED@%s/LDevice@%s doesn't have a DO @name='Beh' OR its associated DA@fc='ST' AND DA@name='stVal'", + iedName, ldInst); + return errors; + } + Set enumValues = getEnumValue(daiBehList.get(0).getDaName().getType()); + List compasLDevicePrivateList = PrivateService.getCompasPrivates(getParentAdapter().getCurrentElem(), TCompasLDevice.class); + if (compasLDevicePrivateList.isEmpty()) { + buildErrorMessage(errors, getXPath(), + "The IED@%s/LDevice@%s doesn't have a Private compas:LDevice.", + iedName, ldInst); + return errors; + } + if (!compasLDevicePrivateList.get(0).isSetLDeviceStatus()) { + buildErrorMessage(errors, getXPath(), + "The IED@%s/LDevice@%s Private compas:LDevice doesn't have the attribute 'LDeviceStatus'", + iedName, ldInst); + return errors; + } + TCompasLDeviceStatus compasLDeviceStatus = compasLDevicePrivateList.get(0).getLDeviceStatus(); + DaTypeName modTypeName = new DaTypeName(); + daTypeName.setName(targetDA); + ResumedDataTemplate daiModFilter = getResumedDataTemplate(targetDO, modTypeName); + List daiModList = getDAI(daiModFilter, false); + if (daiModList.isEmpty()) { + buildErrorMessage(errors, getXPath(), + "The IED@%s/LDevice@%s doesn't have a DO @name='Mod'", + iedName, ldInst); + return errors; + } + ResumedDataTemplate daiMod = daiModList.get(0); + String initialValue = daiMod.getDaName().getDaiValues().isEmpty() ? "" : daiMod.getDaName().getDaiValues().values().toArray()[0].toString(); + lDeviceActivation.setResumedDataTemplate(daiMod); + lDeviceActivation.checkLDeviceActivationStatus(iedName, ldInst, compasLDeviceStatus, enumValues); + if(lDeviceActivation.isUpdatable()){ + if(!initialValue.equals(lDeviceActivation.getResumedDataTemplate().getDaName().getDaiValues().values().toArray()[0])) { + updateDAI(lDeviceActivation.getResumedDataTemplate()); + } + }else { + List errorDescriptionList = lDeviceActivation.getErrorMessages() + .stream() + .map(errorMessage -> SclReport.ErrorDescription.builder() + .xpath(getXPath()) + .message(errorMessage) + .build()) + .collect(Collectors.toList()); + errors.addAll(errorDescriptionList); + } + return errors; + } + + /** + * Update ErrorDescription list of SclReport object with given xpath and message + * @param errors input parameter + * @param xpath input parameter + * @param message input parameter + * @param iedName input parameter + * @param ldInst input parameter + */ + private void buildErrorMessage(List errors, String xpath, String message, String iedName, String ldInst) { + String msg = String.format(message, iedName, ldInst); + errors.add(SclReport.ErrorDescription.builder() + .message(msg) + .xpath(xpath) + .build()); + } + } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapter.java index 90bc1b5e5..b79ebeb24 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapter.java @@ -10,6 +10,7 @@ import org.lfenergy.compas.sct.commons.dto.ExtRefSignalInfo; import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate; import org.lfenergy.compas.sct.commons.scl.ObjectReference; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.List; @@ -113,6 +114,7 @@ public String getPrefix() { return currentElem.getPrefix(); } + /** * Check if node is child of the reference node * @return link parent child existence @@ -123,4 +125,12 @@ protected boolean amChildElementRef() { // as there's no equals method in TLN return parentAdapter.getCurrentElem().getLN().contains(currentElem); } + + @Override + protected String elementXPath() { + return String.format("LN[%s and %s and %s]", + Utils.xpathAttributeFilter("lnClass", currentElem.isSetLnClass() ? currentElem.getLnClass() : null), + Utils.xpathAttributeFilter("inst", currentElem.isSetInst() ? currentElem.getInst() : null), + Utils.xpathAttributeFilter("lnType", currentElem.isSetLnType() ? currentElem.getLnType() : null)); + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/RootSDIAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/RootSDIAdapter.java index d447610ca..3e7282e4b 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/RootSDIAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/RootSDIAdapter.java @@ -8,6 +8,7 @@ import org.lfenergy.compas.scl2007b4.model.TSDI; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; /** @@ -52,6 +53,13 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getSDIOrDAI().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("SDI[name=%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null)); + } + + /** * Gets in current root SDI specific SDI by its name * @param name name of SDI to get @@ -152,5 +160,11 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getSDIOrDAI().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("DAI[name=%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null)); + } + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/SDIAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/SDIAdapter.java index 46399ddf3..1194680a1 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/SDIAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/SDIAdapter.java @@ -8,6 +8,7 @@ import org.lfenergy.compas.scl2007b4.model.TSDI; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; +import org.lfenergy.compas.sct.commons.util.Utils; import java.util.Objects; @@ -57,6 +58,12 @@ protected boolean amChildElementRef() { return SDIAdapter.class.cast(parentAdapter).getCurrentElem().getSDIOrDAI().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("SDI[name=%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null)); + } + /** * Gets in current SDI specific SDI by its name * @param sName name of SDI to get @@ -162,5 +169,10 @@ protected boolean amChildElementRef() { return parentAdapter.getCurrentElem().getSDIOrDAI().contains(currentElem); } + @Override + protected String elementXPath() { + return String.format("DAI[name=%s]", + Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null)); + } } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/BayAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/BayAdapter.java index a8ad47551..cb805f7f5 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/BayAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/BayAdapter.java @@ -97,4 +97,5 @@ public Stream streamFunctionAdapters(){ } return currentElem.getFunction().stream().map(tFunction -> new FunctionAdapter(this, tFunction)); } + } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/SubstationAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/SubstationAdapter.java index 1b68bc99f..a3ee0b701 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/SubstationAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/SubstationAdapter.java @@ -4,13 +4,17 @@ package org.lfenergy.compas.sct.commons.scl.sstation; +import org.apache.commons.lang3.tuple.Pair; +import org.lfenergy.compas.scl2007b4.model.TLLN0Enum; import org.lfenergy.compas.scl2007b4.model.TSubstation; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.util.Utils; +import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -115,4 +119,19 @@ public Stream streamVoltageLevelAdapters() { return currentElem.getVoltageLevel().stream().map(tVoltageLevel -> new VoltageLevelAdapter(this, tVoltageLevel)); } + /** + * Gets a pair of IedName and LDevice inst from Substation LNodes for given LN type object + * @param isLN0 filter for LN type + * @return a pair of Ied name and LDevice inst attributes + */ + public List> getLDevicesFromLNode(boolean isLN0) { + return streamVoltageLevelAdapters() + .flatMap(VoltageLevelAdapter::streamBayAdapters) + .flatMap(BayAdapter::streamFunctionAdapters) + .flatMap(functionAdapter -> functionAdapter.getCurrentElem().getLNode().stream()) + .filter(tlNode -> !isLN0 || tlNode.getLnClass().contains(TLLN0Enum.LLN_0.value())) + .map(tlNode -> Pair.of(tlNode.getIedName(), tlNode.getLdInst())) + .collect(Collectors.toList()); + } + } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/STValEnum.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/STValEnum.java new file mode 100644 index 000000000..3b1559172 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/STValEnum.java @@ -0,0 +1,21 @@ +/* + * // SPDX-FileCopyrightText: 2022 RTE FRANCE + * // + * // SPDX-License-Identifier: Apache-2.0 + */ + +package org.lfenergy.compas.sct.commons.util; + +/** + * A representation of a specific object TDAI name that have attribute name STVal. + * + * @see org.lfenergy.compas.scl2007b4.model.TPredefinedBasicTypeEnum + */ +public enum STValEnum { + ON("on"), + OFF("off"); + public final String value; + STValEnum(String value) { + this.value = value; + } +} \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/LDeviceActivationTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/LDeviceActivationTest.java new file mode 100644 index 000000000..3e0796a7c --- /dev/null +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/LDeviceActivationTest.java @@ -0,0 +1,135 @@ +// SPDX-FileCopyrightText: 2022 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.scl; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.lfenergy.compas.scl2007b4.model.TCompasLDeviceStatus; +import org.lfenergy.compas.sct.commons.dto.DaTypeName; +import org.lfenergy.compas.sct.commons.dto.DoTypeName; +import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class LDeviceActivationTest { + + @ParameterizedTest + @ValueSource(strings = {"ACTIVE", "UNTESTED"}) + void checkLDeviceActivationStatus_shouldReturnNoError_when_LDeviceStatusACTIVE_Or_UNTESTED_And_ValidEnum_And_LDeviceReferencedINLNode(String lDeviceStatus) { + // Given + List> iedNameLdInstList = List.of(Pair.of("iedName1", "ldInst1")); + ResumedDataTemplate rdt = new ResumedDataTemplate(); + rdt.setLnClass("LN0"); + rdt.setDoName(new DoTypeName("doName")); + DaTypeName daTypeName = new DaTypeName("daName"); + daTypeName.setDaiValues(Map.of(0L, "off")); + rdt.setDaName(daTypeName); + LDeviceActivation lDeviceActivation = new LDeviceActivation(iedNameLdInstList); + lDeviceActivation.setResumedDataTemplate(rdt); + // When + lDeviceActivation.checkLDeviceActivationStatus("iedName1", "ldInst1", TCompasLDeviceStatus.fromValue(lDeviceStatus), Set.of("on")); + // Then + assertThat(lDeviceActivation.isUpdatable()).isTrue(); + assertThat(lDeviceActivation.getErrorMessages()).isEmpty(); + assertThat(lDeviceActivation.getResumedDataTemplate().getDaName().getDaiValues().values().toArray()[0].toString()) + .hasToString("on"); + } + + @ParameterizedTest + @ValueSource(strings = {"ACTIVE", "UNTESTED"}) + void checkLDeviceActivationStatus_shouldReturnNoError_when_LDeviceStatusACTIVE_Or_UNTESTED_And_NoValidEnum_And_LDeviceReferencedINLNode(String lDeviceStatus) { + // Given + List> iedNameLdInstList = List.of(Pair.of("iedName1", "ldInst1")); + ResumedDataTemplate rdt = new ResumedDataTemplate(); + rdt.setLnClass("LN0"); + rdt.setDoName(new DoTypeName("doName")); + DaTypeName daTypeName = new DaTypeName("daName"); + daTypeName.setDaiValues(Map.of(0L, "off")); + rdt.setDaName(daTypeName); + LDeviceActivation lDeviceActivation = new LDeviceActivation(iedNameLdInstList); + lDeviceActivation.setResumedDataTemplate(rdt); + // When + lDeviceActivation.checkLDeviceActivationStatus("iedName1", "ldInst1", TCompasLDeviceStatus.valueOf(lDeviceStatus), Set.of("off")); + // Then + assertThat(lDeviceActivation.isUpdatable()).isFalse(); + assertThat(lDeviceActivation.getErrorMessages()).containsExactly( + "Unexpected error: The IED@iedName1/LDevice@ldInst1 cannot be set to 'on' but has been selected into SSD: this case should not occur."); + assertThat(lDeviceActivation.getResumedDataTemplate().getDaName().getDaiValues().values().toArray()[0].toString()) + .hasToString("off"); + } + + @ParameterizedTest + @ValueSource(strings = {"ACTIVE", "UNTESTED"}) + void checkLDeviceActivationStatus_shouldReturnNoError_when_LDeviceStatusACTIVE_Or_UNTESTED_And_ValidEnum_And_NotLDeviceReferencedINLNode(String lDeviceStatus) { + // Given + List> iedNameLdInstList = List.of(); + ResumedDataTemplate rdt = new ResumedDataTemplate(); + rdt.setLnClass("LN0"); + rdt.setDoName(new DoTypeName("doName")); + DaTypeName daTypeName = new DaTypeName("daName"); + daTypeName.setDaiValues(Map.of(0L, "off")); + rdt.setDaName(daTypeName); + LDeviceActivation lDeviceActivation = new LDeviceActivation(iedNameLdInstList); + lDeviceActivation.setResumedDataTemplate(rdt); + // When + lDeviceActivation.checkLDeviceActivationStatus("iedName1", "ldInst2", TCompasLDeviceStatus.valueOf(lDeviceStatus), Set.of("on", "off")); + // Then + assertThat(lDeviceActivation.isUpdatable()).isTrue(); + assertThat(lDeviceActivation.getErrorMessages()).isEmpty(); + assertThat(lDeviceActivation.getResumedDataTemplate().getDaName().getDaiValues().values().toArray()[0].toString()) + .hasToString("off"); + } + + + @Test + void checkLDeviceActivationStatus_shouldReturnNoError_when_LDeviceStatusINACTIVE_And_ValidEnum_And_NotLDeviceReferencedINLNode() { + // Given + List> iedNameLdInstList = List.of(); + ResumedDataTemplate rdt = new ResumedDataTemplate(); + rdt.setLnClass("LN0"); + rdt.setDoName(new DoTypeName("doName")); + DaTypeName daTypeName = new DaTypeName("daName"); + daTypeName.setDaiValues(Map.of(0L, "on")); + rdt.setDaName(daTypeName); + LDeviceActivation lDeviceActivation = new LDeviceActivation(iedNameLdInstList); + lDeviceActivation.setResumedDataTemplate(rdt); + // When + lDeviceActivation.checkLDeviceActivationStatus("iedName1", "ldInst1", TCompasLDeviceStatus.INACTIVE, Set.of("on", "off")); + // Then + assertThat(lDeviceActivation.isUpdatable()).isTrue(); + assertThat(lDeviceActivation.getErrorMessages()).isEmpty(); + assertThat(lDeviceActivation.getResumedDataTemplate().getDaName().getDaiValues().values().toArray()[0].toString()) + .hasToString("off"); + } + @Test + void checkLDeviceActivationStatus_shouldReturnError_when_LDeviceStatusINACTIVE_And_ValidEnum_And_LDeviceReferencedINLNode() { + // Given + List> iedNameLdInstList = List.of(Pair.of("iedName1", "ldInst1")); + ResumedDataTemplate rdt = new ResumedDataTemplate(); + rdt.setLnClass("LN0"); + rdt.setDoName(new DoTypeName("doName")); + DaTypeName daTypeName = new DaTypeName("daName"); + daTypeName.setDaiValues(Map.of(0L, "on")); + rdt.setDaName(daTypeName); + LDeviceActivation lDeviceActivation = new LDeviceActivation(iedNameLdInstList); + lDeviceActivation.setResumedDataTemplate(rdt); + // When + lDeviceActivation.checkLDeviceActivationStatus("iedName1", "ldInst1", TCompasLDeviceStatus.INACTIVE, Set.of("on", "off")); + // Then + assertThat(lDeviceActivation.isUpdatable()).isFalse(); + assertThat(lDeviceActivation.getErrorMessages()).containsExactly( + "Unexpected error: The IED@iedName1/LDevice@ldInst1 is not qualified into STD but has been selected into SSD: this case should not occur."); + assertThat(lDeviceActivation.getResumedDataTemplate().getDaName().getDaiValues().values().toArray()[0].toString()) + .hasToString("on"); + } + + +} \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java index 571891ae9..6acba5073 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java @@ -16,10 +16,13 @@ import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.DynamicTest.dynamicTest; import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDa; import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDo; import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable; +import static org.lfenergy.compas.sct.commons.testhelpers.marshaller.SclTestMarshaller.createWrapper; import static org.lfenergy.compas.sct.commons.util.PrivateEnum.COMPAS_SCL_FILE_TYPE; class SclServiceTest { @@ -701,4 +704,259 @@ void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_srcXXX_attributes_o assertIsMarshallable(scl); } + + @Test + void updateLDeviceStatus_shouldReturnReportWithError_WhenMissingDOBeh() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_KO_MissingBeh.scd"); + String before = createWrapper().marshall(scl); + // When + SclReport sclReport = SclService.updateLDeviceStatus(scl); + String after = createWrapper().marshall(sclReport.getScdFile().getCurrentElem()); + // Then + assertFalse(sclReport.isSuccess()); + assertThat(sclReport.getErrorDescriptionList()) + .hasSize(1) + .extracting(SclReport.ErrorDescription::getMessage) + .containsExactly( + "The IED@IedName1/LDevice@LDSUIED doesn't have a DO @name='Beh' OR its associated DA@fc='ST' AND DA@name='stVal'"); + assertEquals(before, after); + } + @Test + void updateLDeviceStatus_shouldReturnReportWithError_WhenMissingLDevicePrivate() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivate.scd"); + assertTrue(getLDeviceStatusValue(scl, "IedName1", "LDSUIED").isPresent()); + assertEquals("off", getLDeviceStatusValue(scl, "IedName1", "LDSUIED").get().getValue()); + // When + SclReport sclReport = SclService.updateLDeviceStatus(scl); + // Then + assertFalse(sclReport.isSuccess()); + assertThat(sclReport.getErrorDescriptionList()) + .hasSize(1) + .containsExactly(SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName1\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType1\"]") + .message("The IED@IedName1/LDevice@LDSUIED doesn't have a Private compas:LDevice.") + .build()); + assertEquals("off", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName1", "LDSUIED").get().getValue()); + } + + @Test + void updateLDeviceStatus_shouldReturnReportWithError_WhenMissingLDevicePrivateAttribute() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivateAttribute.scd"); + assertTrue(getLDeviceStatusValue(scl, "IedName1", "LDSUIED").isPresent()); + assertEquals("off", getLDeviceStatusValue(scl, "IedName1", "LDSUIED").get().getValue()); + // When + SclReport sclReport = SclService.updateLDeviceStatus(scl); + // Then + assertFalse(sclReport.isSuccess()); + assertThat(sclReport.getErrorDescriptionList()) + .hasSize(1) + .containsExactly(SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName1\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType1\"]") + .message("The IED@IedName1/LDevice@LDSUIED Private compas:LDevice doesn't have the attribute 'LDeviceStatus'") + .build()); + assertEquals("off", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName1", "LDSUIED").get().getValue()); + } + + @Test + void updateLDeviceStatus_shouldReturnReportWithError_WhenMissingDOMod() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_KO_MissingMod.scd"); + assertTrue(getLDeviceStatusValue(scl, "IedName1", "LDSUIED").isPresent()); + assertEquals("off", getLDeviceStatusValue(scl, "IedName1", "LDSUIED").get().getValue()); + // When + SclReport sclReport = SclService.updateLDeviceStatus(scl); + // Then + assertFalse(sclReport.isSuccess()); + assertThat(sclReport.getErrorDescriptionList()) + .hasSize(1) + .containsExactly(SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName1\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType1\"]") + .message("The IED@IedName1/LDevice@LDSUIED doesn't have a DO @name='Mod'") + .build()); + assertEquals( "off",getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName1", "LDSUIED").get().getValue()); + } + + @Test + void updateLDeviceStatus_shouldReturnReportWithError_WhenAllLDeviceActive() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_LD_STATUS_ACTIVE.scd"); + assertEquals("off", getLDeviceStatusValue(scl, "IedName1", "LDSUIED").get().getValue()); + assertEquals("on", getLDeviceStatusValue(scl, "IedName2", "LDSUIED").get().getValue()); + assertFalse(getLDeviceStatusValue(scl, "IedName3", "LDSUIED").isPresent()); + // When + SclReport sclReport = SclService.updateLDeviceStatus(scl); + // Then + assertFalse(sclReport.isSuccess()); + assertThat(sclReport.getErrorDescriptionList()) + .hasSize(3) + .contains(SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName1\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType1\"]") + .message("Unexpected error: The IED@IedName1/LDevice@LDSUIED cannot be set to 'off' but has not been selected into SSD: this case should not occur.") + .build(), + SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName2\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType2\"]") + .message("Unexpected error: The IED@IedName2/LDevice@LDSUIED cannot be set to 'on' but has been selected into SSD: this case should not occur.") + .build(), + SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName3\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType3\"]") + .message("Unexpected error: The IED@IedName3/LDevice@LDSUIED cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'.") + .build()); + assertEquals("off", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName1", "LDSUIED").get().getValue()); + assertEquals("on", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName2", "LDSUIED").get().getValue()); + assertFalse(getLDeviceStatusValue(scl, "IedName3", "LDSUIED").isPresent()); + } + + + @Test + void updateLDeviceStatus_shouldReturnReportWithError_WhenAllLDeviceUntested() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_LD_STATUS_UNTESTED.scd"); + assertEquals("off", getLDeviceStatusValue(scl, "IedName1", "LDSUIED").get().getValue()); + assertEquals("on", getLDeviceStatusValue(scl, "IedName2", "LDSUIED").get().getValue()); + assertFalse(getLDeviceStatusValue(scl, "IedName3", "LDSUIED").isPresent()); + // When + SclReport sclReport = SclService.updateLDeviceStatus(scl); + // Then + assertFalse(sclReport.isSuccess()); + assertThat(sclReport.getErrorDescriptionList()) + .hasSize(3) + .contains(SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName1\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType1\"]") + .message("Unexpected error: The IED@IedName1/LDevice@LDSUIED cannot be set to 'off' but has not been selected into SSD: this case should not occur.") + .build(), + SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName2\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType2\"]") + .message("Unexpected error: The IED@IedName2/LDevice@LDSUIED cannot be set to 'on' but has been selected into SSD: this case should not occur.") + .build(), + SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName3\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType3\"]") + .message("Unexpected error: The IED@IedName3/LDevice@LDSUIED cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'.") + .build()); + assertEquals("off", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName1", "LDSUIED").get().getValue()); + assertEquals("on", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName2", "LDSUIED").get().getValue()); + assertFalse(getLDeviceStatusValue(scl, "IedName3", "LDSUIED").isPresent()); + } + + @Test + void updateLDeviceStatus_shouldReturnReportWithError_WhenAllLDeviceInactive_Test1() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test1_LD_STATUS_INACTIVE.scd"); + assertEquals("off", getLDeviceStatusValue(scl, "IedName1", "LDSUIED").get().getValue()); + assertEquals("on", getLDeviceStatusValue(scl, "IedName2", "LDSUIED").get().getValue()); + assertFalse(getLDeviceStatusValue(scl, "IedName3", "LDSUIED").isPresent()); + // When + SclReport sclReport = SclService.updateLDeviceStatus(scl); + // Then + assertFalse(sclReport.isSuccess()); + assertThat(sclReport.getErrorDescriptionList()) + .hasSize(3) + .contains(SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName1\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType1\"]") + .message("Unexpected error: The IED@IedName1/LDevice@LDSUIED is not qualified into STD but has been selected into SSD: this case should not occur.") + .build(), + SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName2\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType2\"]") + .message("Unexpected error: The IED@IedName2/LDevice@LDSUIED cannot be set to 'on' but has been selected into SSD: this case should not occur.") + .build(), + SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName3\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType3\"]") + .message("Unexpected error: The IED@IedName3/LDevice@LDSUIED cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'.") + .build()); + assertEquals("off", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName1", "LDSUIED").get().getValue()); + assertEquals("on", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName2", "LDSUIED").get().getValue()); + assertFalse(getLDeviceStatusValue(scl, "IedName3", "LDSUIED").isPresent()); + } + + @Test + void updateLDeviceStatus_shouldReturnReportWithError_WhenAllLDeviceInactive_Test2() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test2_LD_STATUS_INACTIVE.scd"); + assertEquals("off", getLDeviceStatusValue(scl, "IedName1", "LDSUIED").get().getValue()); + assertEquals("on", getLDeviceStatusValue(scl, "IedName2", "LDSUIED").get().getValue()); + assertFalse(getLDeviceStatusValue(scl, "IedName3", "LDSUIED").isPresent()); + // When + SclReport sclReport = SclService.updateLDeviceStatus(scl); + // Then + assertFalse(sclReport.isSuccess()); + assertThat(sclReport.getErrorDescriptionList()) + .hasSize(2) + .contains(SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName1\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType1\"]") + .message("Unexpected error: The IED@IedName1/LDevice@LDSUIED cannot be set to 'off' but has not been selected into SSD: this case should not occur.") + .build(), + SclReport.ErrorDescription.builder() + .xpath("/SCL/IED[@name=\"IedName2\"]/LDevice[@inst=\"LDSUIED\"]/LN[lnClass=LLN0 and @inst=\"\" and @lnType=\"LNType2\"]") + .message("Unexpected error: The IED@IedName2/LDevice@LDSUIED is not qualified into STD but has been selected into SSD: this case should not occur.") + .build()); + assertEquals("off", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName1", "LDSUIED").get().getValue()); + assertEquals("on", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName2", "LDSUIED").get().getValue()); + assertTrue(getLDeviceStatusValue(scl, "IedName3", "LDSUIED").isPresent()); + assertEquals("off", getLDeviceStatusValue(scl, "IedName3", "LDSUIED").get().getValue()); + } + + + @Test + void updateLDeviceStatus_shouldReturnUpdatedFile() throws Exception { + // Given + SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_Template.scd"); + assertTrue(getLDeviceStatusValue(givenScl, "IedName1", "LDSUIED").isPresent()); + assertEquals("off", getLDeviceStatusValue(givenScl, "IedName1", "LDSUIED").get().getValue()); + + assertTrue(getLDeviceStatusValue(givenScl, "IedName2", "LDSUIED").isPresent()); + assertEquals("on", getLDeviceStatusValue(givenScl, "IedName2", "LDSUIED").get().getValue()); + + assertFalse(getLDeviceStatusValue(givenScl, "IedName3", "LDSUIED").isPresent()); + + // When + SclReport sclReport = SclService.updateLDeviceStatus(givenScl); + // Then + assertTrue(sclReport.isSuccess()); + assertTrue(getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName1", "LDSUIED").isPresent()); + assertEquals("on", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName1", "LDSUIED").get().getValue()); + + assertTrue(getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName2", "LDSUIED").isPresent()); + assertEquals("off", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName2", "LDSUIED").get().getValue()); + + assertTrue(getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName3", "LDSUIED").isPresent()); + assertEquals("off", getLDeviceStatusValue(sclReport.getScdFile().getCurrentElem(), "IedName3", "LDSUIED").get().getValue()); + } + + @Test + void updateLDeviceStatus_shouldReturnError_when_DaiNotUpdatable() throws Exception { + // Given + SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_Dai_Not_Updatable.scd"); + assertTrue(getLDeviceStatusValue(givenScl, "IedName1", "LDSUIED").isPresent()); + assertEquals("off", getLDeviceStatusValue(givenScl, "IedName1", "LDSUIED").get().getValue()); + assertTrue(getLDeviceStatusValue(givenScl, "IedName2", "LDSUIED").isPresent()); + assertEquals("on", getLDeviceStatusValue(givenScl, "IedName2", "LDSUIED").get().getValue()); + assertFalse(getLDeviceStatusValue(givenScl, "IedName3", "LDSUIED").isPresent()); + + // When + // Then + assertThatCode(() -> SclService.updateLDeviceStatus(givenScl)) + .isInstanceOf(ScdException.class) + .hasMessage("DAI (Mod -stVal) cannot be updated"); + } + + + private Optional getLDeviceStatusValue(SCL scl, String iedName, String ldInst){ + SclRootAdapter sclRootAdapter = new SclRootAdapter(scl); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); + Optional lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst); + LN0Adapter ln0Adapter = lDeviceAdapter.get().getLN0Adapter(); + Optional doiAdapter = ln0Adapter.getDOIAdapters().stream() + .filter(doiAdapter1 -> doiAdapter1.getCurrentElem().getName().equals("Mod")) + .findFirst(); + if(doiAdapter.isEmpty()) return Optional.empty(); + return doiAdapter.get().getCurrentElem().getSDIOrDAI().stream() + .filter(tUnNaming -> tUnNaming.getClass().equals(TDAI.class)) + .map(TDAI.class::cast) + .filter(tdai -> tdai.getName().equals("stVal")) + .map(tdai -> tdai.getVal().get(0)) + .findFirst(); + } + } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SubstationServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SubstationServiceTest.java index 16d46ef35..17c045dad 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SubstationServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SubstationServiceTest.java @@ -4,12 +4,15 @@ package org.lfenergy.compas.sct.commons.scl; +import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.Test; import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TSubstation; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; +import java.util.List; + import static org.junit.jupiter.api.Assertions.*; import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable; diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapterTest.java index d5d70b0a1..3115a3f19 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/CommunicationAdapterTest.java @@ -9,6 +9,7 @@ import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class CommunicationAdapterTest { @@ -92,4 +93,15 @@ void addPrivate() { communicationAdapter.addPrivate(tPrivate); assertEquals(1, communicationAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void elementXPath() { + // Given + CommunicationAdapter communicationAdapter = new CommunicationAdapter(null,new TCommunication()); + // When + String result = communicationAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("Communication"); + } + } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapterTest.java index b71d8790d..cb292b9fe 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/ConnectedAPAdapterTest.java @@ -4,7 +4,6 @@ package org.lfenergy.compas.sct.commons.scl.com; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.lfenergy.compas.scl2007b4.model.SCL; @@ -17,8 +16,8 @@ import java.util.Optional; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; -import static org.assertj.core.api.Assertions.*; class ConnectedAPAdapterTest { @@ -90,4 +89,21 @@ void testCopyAddressAndPhysConnFromIcd_withEmptyIcd() { assertThat(connectedAPAdapter.getCurrentElem().getPhysConn()).isEmpty(); assertThat(connectedAPAdapter.getCurrentElem().getGSE()).isEmpty(); } + + @Test + void elementXPath() { + // Given + TConnectedAP tConnectedAP = new TConnectedAP(); + tConnectedAP.setApName(DTO.HOLDER_IED_NAME); + tConnectedAP.setIedName(DTO.AP_NAME); + ConnectedAPAdapter connectedAPAdapter = new ConnectedAPAdapter(null, new TConnectedAP()); + ConnectedAPAdapter namedConnectedAPAdapter = new ConnectedAPAdapter(null, tConnectedAP); + // When + String elementXPath = connectedAPAdapter.elementXPath(); + String namedElementXPath = namedConnectedAPAdapter.elementXPath(); + // Then + assertThat(elementXPath).isEqualTo("ConnectedAP[not(@apName) and not(@iedName)]"); + assertThat(namedElementXPath).isEqualTo("ConnectedAP[@apName=\"IED_NAME\" and @iedName=\"IED_NAME\"]"); + } + } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/SubNetworkAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/SubNetworkAdapterTest.java index ffd2fe4ad..198ee6df1 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/SubNetworkAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/com/SubNetworkAdapterTest.java @@ -12,6 +12,7 @@ import org.lfenergy.compas.sct.commons.dto.DTO; import org.lfenergy.compas.sct.commons.exception.ScdException; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class SubNetworkAdapterTest { @@ -74,4 +75,21 @@ void addPrivate() { subNetworkAdapter.addPrivate(tPrivate); assertEquals(1, subNetworkAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void elementXPath() { + // Given + TSubNetwork tSubNetwork = new TSubNetwork(); + tSubNetwork.setName("sName"); + tSubNetwork.setType("sType"); + SubNetworkAdapter subNetworkAdapter = new SubNetworkAdapter(null, new TSubNetwork()); + SubNetworkAdapter namedSubNetworkAdapter = new SubNetworkAdapter(null, tSubNetwork); + // When + String elementXPath = subNetworkAdapter.elementXPath(); + String namedElementXPath = namedSubNetworkAdapter.elementXPath(); + // Then + assertThat(elementXPath).isEqualTo("SubNetwork[not(@name)]"); + assertThat(namedElementXPath).isEqualTo("SubNetwork[@name=\"sName\"]"); + } + } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/BDAAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/BDAAdapterTest.java index 3ea61b167..3a26b19ca 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/BDAAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/BDAAdapterTest.java @@ -11,6 +11,7 @@ import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class BDAAdapterTest extends AbstractDTTLevel { @@ -102,4 +103,16 @@ void addPrivate() { bdaAdapter.addPrivate(tPrivate); assertEquals(1, bdaAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void elementXPath() { + // Given + init(); + DATypeAdapter.BDAAdapter bdaAdapter = new DATypeAdapter.BDAAdapter(sclElementAdapter,sclElement); + // When + String result = bdaAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("BDA[name=not(@name)]"); + } + } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DAAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DAAdapterTest.java index aebfad53c..8a87a8f0f 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DAAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DAAdapterTest.java @@ -12,6 +12,7 @@ import org.lfenergy.compas.sct.commons.dto.DaTypeName; import org.lfenergy.compas.sct.commons.exception.ScdException; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class DAAdapterTest { @@ -77,4 +78,16 @@ void addPrivate() throws Exception { daAdapter.addPrivate(tPrivate); assertEquals(1, daAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void elementXPath() throws Exception { + // Given + DataTypeTemplateAdapter dttAdapter = AbstractDTTLevel.initDttAdapterFromFile(AbstractDTTLevel.SCD_DTT); + DOTypeAdapter doTypeAdapter = dttAdapter.getDOTypeAdapters().get(0); + DAAdapter daAdapter = assertDoesNotThrow(() -> doTypeAdapter.getDAAdapterByName("dataNs").get()); + // When + String result = daAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("DA[name=@name=\"dataNs\" and type=not(@type)]"); + } } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapterTest.java index 5f40825a7..dc2483b95 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DATypeAdapterTest.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class DATypeAdapterTest extends AbstractDTTLevel { @@ -153,4 +154,15 @@ void addPrivate() throws Exception { daTypeAdapter.addPrivate(tPrivate); assertEquals(2, daTypeAdapter.getCurrentElem().getPrivate().size()); } + @Test + void elementXPath() throws Exception { + // Given + DataTypeTemplateAdapter dttAdapter = AbstractDTTLevel.initDttAdapterFromFile(AbstractDTTLevel.SCD_DTT); + DATypeAdapter daTypeAdapter = assertDoesNotThrow(() ->dttAdapter.getDATypeAdapterById("DA1").get()); + // When + String result = daTypeAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("DAType[@id=\"DA1\"]"); + } + } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOAdapterTest.java new file mode 100644 index 000000000..ddf07d47a --- /dev/null +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOAdapterTest.java @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2022 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.scl.dtt; + +import org.junit.jupiter.api.Test; +import org.lfenergy.compas.scl2007b4.model.TDO; +import org.lfenergy.compas.scl2007b4.model.TLNodeType; +import org.mockito.Mockito; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class DOAdapterTest { + + @Test + void elementXPath() { + // Given + LNodeTypeAdapter lNodeAdapter = Mockito.mock(LNodeTypeAdapter.class); + TLNodeType tlNodeType = Mockito.mock(TLNodeType.class); + Mockito.when(lNodeAdapter.getParentAdapter()).thenReturn(null); + Mockito.when(lNodeAdapter.getCurrentElem()).thenReturn(tlNodeType); + + TDO tdo = new TDO(); + tdo.setName("doName"); + Mockito.when(tlNodeType.getDO()).thenReturn(List.of(tdo)); + DOAdapter doAdapter = new DOAdapter(lNodeAdapter, tdo); + // When + String result = doAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("DO[name=@name=\"doName\" and type=not(@type)]"); + } +} \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapterTest.java index 843bd9684..589c5ef4f 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DOTypeAdapterTest.java @@ -14,6 +14,7 @@ import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class DOTypeAdapterTest extends AbstractDTTLevel { @@ -171,4 +172,17 @@ void addPrivate() throws Exception { doTypeAdapter.addPrivate(tPrivate); assertEquals(1, doTypeAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void elementXPath() throws Exception { + // Given + DataTypeTemplateAdapter dttAdapter = AbstractDTTLevel.initDttAdapterFromFile( + AbstractDTTLevel.SCD_DTT_DIFF_CONTENT_SAME_ID + ); + DOTypeAdapter doTypeAdapter = assertDoesNotThrow(() -> dttAdapter.getDOTypeAdapterById("DO1").get()); + // When + String result = doTypeAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("DOType[@id=\"DO1\"]"); + } } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateAdapterTest.java index 5fca85bf4..cc3aed22b 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateAdapterTest.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.Optional; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class DataTypeTemplateAdapterTest { @@ -369,4 +370,15 @@ void addPrivate() throws Exception { tPrivate.setSource("Private Source"); assertThrows(UnsupportedOperationException.class, () -> dttAdapter.addPrivate(tPrivate)); } + + @Test + void elementXPath() throws Exception { + // Given + DataTypeTemplateAdapter dttAdapter = AbstractDTTLevel.initDttAdapterFromFile(AbstractDTTLevel.SCD_DTT_DIFF_CONTENT_SAME_ID); + // When + String result = dttAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("DataTypeTemplates"); + } + } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/EnumTypeAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/EnumTypeAdapterTest.java index 1df3fa817..1f0efcb27 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/EnumTypeAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/EnumTypeAdapterTest.java @@ -12,6 +12,7 @@ import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class EnumTypeAdapterTest extends AbstractDTTLevel { @@ -73,4 +74,18 @@ void addPrivate() { enumTypeAdapter.addPrivate(tPrivate); assertEquals(1, enumTypeAdapter.getCurrentElem().getPrivate().size()); } + + + @Test + void elementXPath() { + // Given + init(); + EnumTypeAdapter enumTypeAdapter = assertDoesNotThrow( + () -> new EnumTypeAdapter(sclElementAdapter,sclElement) + ); + // When + String result = enumTypeAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("EnumType[@id=\"ID\"]"); + } } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapterTest.java index 3e61b66db..f5408bb63 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapterTest.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class LNodeTypeAdapterTest extends AbstractDTTLevel { @@ -196,4 +197,16 @@ void addPrivate() throws Exception { lNodeTypeAdapter.addPrivate(tPrivate); assertEquals(2, lNodeTypeAdapter.getCurrentElem().getPrivate().size()); } + + + @Test + void elementXPath() throws Exception { + // Given + DataTypeTemplateAdapter dttAdapter = AbstractDTTLevel.initDttAdapterFromFile(AbstractDTTLevel.SCD_DTT); + LNodeTypeAdapter lNodeTypeAdapter = assertDoesNotThrow(() ->dttAdapter.getLNodeTypeAdapterById("LN1").get()); + // When + String result = lNodeTypeAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("LNodeType[id=@id=\"LN1\" and lnClass=@lnClass=\"PIOC\"]"); + } } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/header/HeaderAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/header/HeaderAdapterTest.java index 7c7597891..232032197 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/header/HeaderAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/header/HeaderAdapterTest.java @@ -11,6 +11,7 @@ import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class HeaderAdapterTest { @@ -58,7 +59,7 @@ void testAddHistoryItem() throws ScdException { } @Test - void addPrivate() throws Exception { + void addPrivate() { SclRootAdapter sclRootAdapter = new SclRootAdapter( "hID","hVersion","hRevision" ); @@ -67,6 +68,23 @@ void addPrivate() throws Exception { tPrivate.setType("Private Type"); tPrivate.setSource("Private Source"); assertThrows(UnsupportedOperationException.class, () -> hAdapter.addPrivate(tPrivate)); + } + @Test + void elementXPath() { + // Given + THeader tHeader = new THeader(); + tHeader.setId("hID"); + tHeader.setVersion("hVersion"); + tHeader.setRevision("hRevision"); + HeaderAdapter headerAdapter = new HeaderAdapter(null, new THeader()); + HeaderAdapter namedHeaderAdapter = new HeaderAdapter(null, tHeader); + // When + String elementXPathResult = headerAdapter.elementXPath(); + String namedElementXPathResult = namedHeaderAdapter.elementXPath(); + // Then + assertThat(elementXPathResult).isEqualTo("Header[not(@id) and not(@version) and not(@revision)]"); + assertThat(namedElementXPathResult).isEqualTo("Header[@id=\"hID\" and @version=\"hVersion\" and @revision=\"hRevision\"]"); } + } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DAITrackerTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DAITrackerTest.java index c3de7b4a6..3f6fa1ad2 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DAITrackerTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DAITrackerTest.java @@ -16,6 +16,7 @@ import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class DAITrackerTest { @@ -176,4 +177,5 @@ void testGetDaiNumericValue() { daTypeName.setBType(TPredefinedBasicTypeEnum.FLOAT_32); assertDoesNotThrow(()->daiTracker.getDaiNumericValue(daTypeName,13.0)); } + } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapterTest.java index d848c7199..7bd23c7bc 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapterTest.java @@ -17,6 +17,7 @@ import java.util.HashMap; import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class DOIAdapterTest { @@ -156,4 +157,30 @@ void addPrivate() { daiAdapter.addPrivate(tPrivate); assertEquals(1, daiAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void elementXPath_doi() { + // Given + TDOI tdoi = new TDOI(); + tdoi.setName("doName"); + DOIAdapter doiAdapter = new DOIAdapter(null,new TDOI()); + DOIAdapter namedDoiAdapter = new DOIAdapter(null,tdoi); + // When + String elementXPathResult = doiAdapter.elementXPath(); + String namedElementXPathResult = namedDoiAdapter.elementXPath(); + // Then + assertThat(elementXPathResult).isEqualTo("DOI[name=not(@name)]"); + assertThat(namedElementXPathResult).isEqualTo("DOI[name=@name=\"doName\"]"); + } + + @Test + void elementXPath_dai() { + // Given + DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do","da"); + // When + String result = daiAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("DAI[name=@name=\"da\"]"); + } + } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java index b75e19ff6..cd9277ef4 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java @@ -13,6 +13,7 @@ import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.ObjectReference; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.scl.com.SubNetworkAdapter; import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; import org.mockito.Mockito; @@ -20,6 +21,7 @@ import java.util.List; import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable; @@ -244,4 +246,21 @@ void addPrivate() { iAdapter.addPrivate(tPrivate); assertEquals(1, iAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void elementXPath() { + // Given + SclRootAdapter sclRootAdapter = Mockito.mock(SclRootAdapter.class); + SCL scl = Mockito.mock(SCL.class); + Mockito.when(sclRootAdapter.getCurrentElem()).thenReturn(scl); + TIED tied = new TIED(); + tied.setName("iedName"); + Mockito.when(scl.getIED()).thenReturn(List.of(tied)); + IEDAdapter iAdapter = new IEDAdapter(sclRootAdapter, tied); + // When + String result = iAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("IED[@name=\"iedName\"]"); + } + } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapterTest.java index b311d60f0..7f3e325f6 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LDeviceAdapterTest.java @@ -7,6 +7,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.lfenergy.compas.scl2007b4.model.SCL; +import org.lfenergy.compas.scl2007b4.model.TLDevice; import org.lfenergy.compas.scl2007b4.model.TLLN0Enum; import org.lfenergy.compas.scl2007b4.model.TPrivate; import org.lfenergy.compas.sct.commons.dto.DTO; @@ -19,6 +20,7 @@ import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class LDeviceAdapterTest { @@ -100,4 +102,19 @@ void addPrivate() { lDeviceAdapter.addPrivate(tPrivate); assertEquals(1, lDeviceAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void elementXPath() { + // Given + TLDevice tlDevice = new TLDevice(); + tlDevice.setInst("ldInst"); + LDeviceAdapter lDeviceAdapter = new LDeviceAdapter(null, new TLDevice()); + LDeviceAdapter namedLDeviceAdapter = new LDeviceAdapter(null, tlDevice); + // When + String elementXPathResult = lDeviceAdapter.elementXPath(); + String namedElementXPathResult = namedLDeviceAdapter.elementXPath(); + // Then + assertThat(elementXPathResult).isEqualTo("LDevice[not(@inst)]"); + assertThat(namedElementXPathResult).isEqualTo("LDevice[@inst=\"ldInst\"]"); + } } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java index 5b05181e3..ebfc629e6 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java @@ -14,7 +14,9 @@ import org.mockito.Mockito; import java.util.List; +import java.util.Set; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class LN0AdapterTest { @@ -325,4 +327,64 @@ void addPrivate() { lnAdapter.addPrivate(tPrivate); assertEquals(1, lnAdapter.getCurrentElem().getPrivate().size()); } + + + @Test + void testGetDAI() throws Exception { + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef")); + LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED").get()); + LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter(); + ResumedDataTemplate filter = new ResumedDataTemplate(); + filter.setLnClass(ln0Adapter.getLNClass()); + filter.setLnInst(ln0Adapter.getLNInst()); + filter.setPrefix(ln0Adapter.getPrefix()); + filter.setLnType(ln0Adapter.getLnType()); + filter.setDoName(new DoTypeName("Beh")); + DaTypeName daTypeName = new DaTypeName(); + daTypeName.setName("stVal"); + daTypeName.setBType(TPredefinedBasicTypeEnum.ENUM); + daTypeName.setFc(TFCEnum.ST); + filter.setDaName(daTypeName); + var rDtts = ln0Adapter.getDAI(filter,false); + assertFalse(rDtts.isEmpty()); + assertEquals(1,rDtts.size()); + assertNotNull(rDtts.get(0).getDaName().getType()); + } + + @Test + void getEnumValue() throws Exception { + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef")); + LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED").get()); + LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter(); + ResumedDataTemplate filter = new ResumedDataTemplate(); + filter.setLnClass(ln0Adapter.getLNClass()); + filter.setLnInst(ln0Adapter.getLNInst()); + filter.setPrefix(ln0Adapter.getPrefix()); + filter.setLnType(ln0Adapter.getLnType()); + filter.setDoName(new DoTypeName("Beh")); + DaTypeName daTypeName = new DaTypeName(); + daTypeName.setName("stVal"); + daTypeName.setBType(TPredefinedBasicTypeEnum.ENUM); + daTypeName.setFc(TFCEnum.ST); + daTypeName.setType("BehaviourModeKind"); + filter.setDaName(daTypeName); + Set enumValues = ln0Adapter.getEnumValue(filter.getType()); + assertEquals(5, enumValues.size()); + } + + @Test + void elementXPath() { + // Given + LN0 tln = new LN0(); + tln.getLnClass().add(TLLN0Enum.LLN_0.value()); + LN0Adapter lnAdapter = new LN0Adapter(null,tln); + // When + String result = lnAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("LN[lnClass=LLN0 and not(@inst) and not(@lnType)]"); + } } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java index 544550871..e5f38aaee 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java @@ -16,6 +16,7 @@ import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class LNAdapterTest { @@ -318,4 +319,15 @@ void addPrivate() throws Exception { assertEquals(1, lnAdapter.getCurrentElem().getPrivate().size()); } + @Test + void elementXPath() { + // Given + TLN tln = new TLN(); + LNAdapter lnAdapter = initLNAdapter(tln); + // When + String result = lnAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("LN[@lnClass=\"LN_CLASS_H\" and @inst=\"1\" and @lnType=\"LN_TYPE\"]"); + } + } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/RootSDIAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/RootSDIAdapterTest.java index f68ea2a32..8411f2772 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/RootSDIAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/RootSDIAdapterTest.java @@ -11,6 +11,7 @@ import org.lfenergy.compas.scl2007b4.model.TSDI; import org.lfenergy.compas.sct.commons.exception.ScdException; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class RootSDIAdapterTest { @@ -69,4 +70,34 @@ void addPrivate() { rootSDIAdapter.addPrivate(tPrivate); assertEquals(1, rootSDIAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void elementXPath_sdi() { + // Given + TSDI tsdi = new TSDI(); + tsdi.setName("sdo1"); + RootSDIAdapter rootSDIAdapter = new RootSDIAdapter(null,tsdi); + // When + String result = rootSDIAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("SDI[name=@name=\"sdo1\"]"); + } + + @Test + void elementXPath_dai() { + // Given + TSDI tsdi = new TSDI(); + tsdi.setName("sdo1"); + RootSDIAdapter rootSDIAdapter = new RootSDIAdapter(null,tsdi); + + TDAI tdai = new TDAI(); + tdai.setName("angRef"); + tsdi.getSDIOrDAI().add(tdai); + RootSDIAdapter.DAIAdapter daiAdapter = assertDoesNotThrow(() -> new RootSDIAdapter.DAIAdapter(rootSDIAdapter,tdai)); + // When + String result = daiAdapter.elementXPath(); + // Then + assertThat(result).isEqualTo("DAI[name=@name=\"angRef\"]"); + } + } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/SDIAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/SDIAdapterTest.java index 809c36336..4af7db7b1 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/SDIAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/SDIAdapterTest.java @@ -10,6 +10,7 @@ import org.lfenergy.compas.scl2007b4.model.TSDI; import org.lfenergy.compas.sct.commons.exception.ScdException; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class SDIAdapterTest { @@ -72,4 +73,19 @@ void addPrivate() { assertEquals(1, sdiAdapter.getCurrentElem().getPrivate().size()); } + @Test + void elementXPath() { + // Given + TSDI tsdi = new TSDI(); + tsdi.setName("sdo1"); + SDIAdapter sdiAdapter = new SDIAdapter(null,new TSDI()); + SDIAdapter namedSDIAdapter = new SDIAdapter(null,tsdi); + // When + String sdiAdapterResult = sdiAdapter.elementXPath(); + String namedSdiAdapterResult = namedSDIAdapter.elementXPath(); + // Then + assertThat(sdiAdapterResult).isEqualTo("SDI[name=not(@name)]"); + assertThat(namedSdiAdapterResult).isEqualTo("SDI[name=@name=\"sdo1\"]"); + } + } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/sstation/SubstationAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/sstation/SubstationAdapterTest.java index a827f4dfc..12a088c25 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/sstation/SubstationAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/sstation/SubstationAdapterTest.java @@ -4,13 +4,18 @@ package org.lfenergy.compas.sct.commons.scl.sstation; +import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TPrivate; import org.lfenergy.compas.scl2007b4.model.TSubstation; import org.lfenergy.compas.scl2007b4.model.TVoltageLevel; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; + +import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -72,4 +77,29 @@ void addPrivate() { ssAdapter.addPrivate(tPrivate); assertEquals(1, ssAdapter.getCurrentElem().getPrivate().size()); } + + @Test + void getLDevicesFromLNode_test1_withoutLN0() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/scd-with-substation-lnode.xml"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scl); + SubstationAdapter substationAdapter = sclRootAdapter.getSubstationAdapter(); + // When + List> iedNameLdInstList = substationAdapter.getLDevicesFromLNode(false); + // Then + assertEquals(2, iedNameLdInstList.size()); + } + + @Test + void getLDevicesFromLNode_test2_withLN0() throws Exception { + // Given + SCL scl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_Template.scd"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scl); + SubstationAdapter substationAdapter = sclRootAdapter.getSubstationAdapter(); + // When + List> iedNameLdInstList = substationAdapter.getLDevicesFromLNode(true); + // Then + assertEquals(1, iedNameLdInstList.size()); + } + } \ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test1_LD_STATUS_INACTIVE.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test1_LD_STATUS_INACTIVE.scd new file mode 100644 index 000000000..b6f2124f7 --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test1_LD_STATUS_INACTIVE.scd @@ -0,0 +1,224 @@ + + + + + + + SCD + +

+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+ +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+ +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + on + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + blocked + test + test/blocked + + + off + blocked + test + test/blocked + + + blocked + test + test/blocked + + + \ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test2_LD_STATUS_INACTIVE.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test2_LD_STATUS_INACTIVE.scd new file mode 100644 index 000000000..f94cd1956 --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test2_LD_STATUS_INACTIVE.scd @@ -0,0 +1,222 @@ + + + + + + + SCD + +
+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+ +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+ +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + on + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + blocked + test + test/blocked + + + on + off + blocked + test + test/blocked + + + on + off + blocked + test + test/blocked + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_Dai_Not_Updatable.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_Dai_Not_Updatable.scd new file mode 100644 index 000000000..1de3c1de7 --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_Dai_Not_Updatable.scd @@ -0,0 +1,223 @@ + + + + + + + SCD + +
+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+ +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+ +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + on + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + off + blocked + test + test/blocked + + + on + off + blocked + test + test/blocked + + + on + off + blocked + test + test/blocked + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingBeh.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingBeh.scd new file mode 100644 index 000000000..068f2cf7f --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingBeh.scd @@ -0,0 +1,114 @@ + + + + + + + SCD + +
+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + + + + + + + + + + + + + blocked + test + test/blocked + off + on + + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivate.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivate.scd new file mode 100644 index 000000000..48877c0b5 --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivate.scd @@ -0,0 +1,112 @@ + + + + + + + SCD + +
+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + + + + + + + + + + + + + + blocked + test + test/blocked + off + on + + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivateAttribute.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivateAttribute.scd new file mode 100644 index 000000000..8ab10e71c --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingLDevicePrivateAttribute.scd @@ -0,0 +1,115 @@ + + + + + + + SCD + +
+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + + + + + + + + + + + + + + blocked + test + test/blocked + off + on + + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingMod.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingMod.scd new file mode 100644 index 000000000..f6d2f2979 --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_KO_MissingMod.scd @@ -0,0 +1,114 @@ + + + + + + + SCD + +
+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + + + + + + + + + + + + + blocked + test + test/blocked + off + on + + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_LD_STATUS_ACTIVE.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_LD_STATUS_ACTIVE.scd new file mode 100644 index 000000000..0823597c2 --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_LD_STATUS_ACTIVE.scd @@ -0,0 +1,219 @@ + + + + + + + SCD + +
+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+ +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+ +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + on + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + blocked + test + test/blocked + + + off + blocked + test + test/blocked + + + blocked + test + test/blocked + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_LD_STATUS_UNTESTED.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_LD_STATUS_UNTESTED.scd new file mode 100644 index 000000000..6f2cb7e9d --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_LD_STATUS_UNTESTED.scd @@ -0,0 +1,219 @@ + + + + + + + SCD + +
+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+ +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+ +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + on + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + blocked + test + test/blocked + + + off + blocked + test + test/blocked + + + blocked + test + test/blocked + + +
\ No newline at end of file diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_Template.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_Template.scd new file mode 100644 index 000000000..140e2390d --- /dev/null +++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue68_Test_Template.scd @@ -0,0 +1,223 @@ + + + + + + + SCD + +
+ + + +
+ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + +
+

00000001

+
+
+ +
+

00000001

+
+
+
+ + +
+

Adresse IP du serveur Syslog

+
+
+ +
+

Adresse IP du serveur Syslog

+
+
+
+
+ + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + off + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + on + + + + + + + + + + + SAMU + SAMU + + + + + + + + + + + + + + + + + 01.00.000 + + + 01.00.000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + off + blocked + test + test/blocked + + + on + off + blocked + test + test/blocked + + + on + off + blocked + test + test/blocked + + +
\ No newline at end of file