diff --git a/pom.xml b/pom.xml
index 33081daef..9fddeaa9d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,6 +39,7 @@
0.9.1
0.0.4
3.4.1
+ 3.2.1
@@ -156,6 +157,20 @@
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ ${maven-source-plugin.version}
+
+
+ attach-sources
+ verify
+
+ jar-no-fork
+
+
+
+
diff --git a/sct-app/pom.xml b/sct-app/pom.xml
index b87bea880..1a2857890 100644
--- a/sct-app/pom.xml
+++ b/sct-app/pom.xml
@@ -126,6 +126,10 @@
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
-
\ No newline at end of file
+
diff --git a/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java b/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java
index 699994cf2..2c35abd29 100644
--- a/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java
+++ b/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java
@@ -5,7 +5,6 @@
package org.lfenergy.compas.sct.app;
import lombok.NonNull;
-import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.sct.commons.dto.HeaderDTO;
@@ -26,7 +25,6 @@
* {@link SclAutomationService#createSCD(SCL, HeaderDTO, Set) Adds all elements under the SCL object from given SSD and STD files}
*
*/
-@Slf4j
public class SclAutomationService {
/**
diff --git a/sct-app/src/main/resources/logback.xml b/sct-app/src/main/resources/logback.xml
deleted file mode 100644
index 9674fe7e4..000000000
--- a/sct-app/src/main/resources/logback.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
- %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sct-commons/pom.xml b/sct-commons/pom.xml
index f47ecc126..ea046ce9f 100644
--- a/sct-commons/pom.xml
+++ b/sct-commons/pom.xml
@@ -218,7 +218,10 @@
-
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataTypeName.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataTypeName.java
index c8f23e8ae..123e5e1ee 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataTypeName.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataTypeName.java
@@ -9,7 +9,6 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
@@ -43,7 +42,6 @@
*/
@Getter
@Setter
-@Slf4j
@NoArgsConstructor
@EqualsAndHashCode
public class DataTypeName {
@@ -58,7 +56,7 @@ public class DataTypeName {
public DataTypeName(String dataName){
if(dataName == null) return;
String[] tokens = dataName.split("\\.");
- name = tokens[0];
+ this.name = tokens[0];
if(tokens.length > 1){
structNames.addAll(List.of(tokens).subList(1, tokens.length));
}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefBindingInfo.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefBindingInfo.java
index 6bef42b5c..2c1bf56a1 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefBindingInfo.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefBindingInfo.java
@@ -12,6 +12,7 @@
import org.lfenergy.compas.scl2007b4.model.TLLN0Enum;
import org.lfenergy.compas.scl2007b4.model.TServiceType;
+import java.util.Comparator;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -39,8 +40,12 @@
@Getter
@Setter
@NoArgsConstructor
-public class ExtRefBindingInfo {
+public class ExtRefBindingInfo implements Comparable {
+ public static final Comparator EXT_REF_BINDING_INFO_COMPARATOR = Comparator.comparing(ExtRefBindingInfo::getIedName)
+ .thenComparing(ExtRefBindingInfo::getLdInst)
+ .thenComparing(ExtRefBindingInfo::getLnClass)
+ .thenComparing(ExtRefBindingInfo::getLnInst);
private String iedName;
private String ldInst;
private String prefix;
@@ -53,23 +58,24 @@ public class ExtRefBindingInfo {
/**
* Constructor
+ *
* @param tExtRef input
*/
- public ExtRefBindingInfo(TExtRef tExtRef){
+ public ExtRefBindingInfo(TExtRef tExtRef) {
iedName = tExtRef.getIedName();
ldInst = tExtRef.getLdInst();
prefix = tExtRef.getPrefix();
- if(!tExtRef.getLnClass().isEmpty()) {
+ if (!tExtRef.getLnClass().isEmpty()) {
this.lnClass = tExtRef.getLnClass().get(0);
}
lnInst = tExtRef.getLnInst();
- if(tExtRef.getDoName() != null) {
+ if (tExtRef.getDoName() != null) {
doName = new DoTypeName(tExtRef.getDoName());
}
- if(tExtRef.getDaName() != null) {
+ if (tExtRef.getDaName() != null) {
daName = new DaTypeName(tExtRef.getDaName());
}
- if(tExtRef.getServiceType() != null) {
+ if (tExtRef.getServiceType() != null) {
serviceType = tExtRef.getServiceType();
}
}
@@ -100,33 +106,35 @@ public int hashCode() {
/**
* Check validity of ExtRef binding information
+ *
* @return validity state
*/
public boolean isValid() {
final String validationRegex = DaTypeName.VALIDATION_REGEX;
String doRef = doName == null ? "" : doName.toString();
- Pattern pattern = Pattern.compile(validationRegex,Pattern.MULTILINE);
+ Pattern pattern = Pattern.compile(validationRegex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(doRef);
matcher.find();
- if(!StringUtils.isBlank(doRef) && doRef.length() != matcher.end()){
+ if (!StringUtils.isBlank(doRef) && doRef.length() != matcher.end()) {
return false;
}
return !StringUtils.isBlank(iedName) &&
!StringUtils.isBlank(ldInst) &&
!StringUtils.isBlank(lnClass) &&
- (TLLN0Enum.LLN_0.value().equals(lnClass) || !StringUtils.isBlank(lnInst)) ;
+ (TLLN0Enum.LLN_0.value().equals(lnClass) || !StringUtils.isBlank(lnInst));
}
/**
* Check dependency between ExtRef binding information and ExtRef
+ *
* @param tExtRef object containing ExtRef data's'
* @return dependency state
*/
- public boolean isWrappedIn(TExtRef tExtRef){
- return Objects.equals(iedName,tExtRef.getIedName()) &&
- Objects.equals(ldInst,tExtRef.getLdInst()) &&
+ public boolean isWrappedIn(TExtRef tExtRef) {
+ return Objects.equals(iedName, tExtRef.getIedName()) &&
+ Objects.equals(ldInst, tExtRef.getLdInst()) &&
Objects.equals(prefix, tExtRef.getPrefix()) &&
Objects.equals(lnInst, tExtRef.getLnInst()) &&
tExtRef.getLnClass().contains(lnClass) &&
@@ -135,9 +143,10 @@ public boolean isWrappedIn(TExtRef tExtRef){
/**
* Check nullability of ExtRef binding information
- * @return nullability state
+ *
+ * @return nullability state
*/
- public boolean isNull(){
+ public boolean isNull() {
return iedName == null &&
ldInst == null &&
prefix == null &&
@@ -149,11 +158,18 @@ public boolean isNull(){
}
/**
- * Convert to string
- * @return ExtRef binding information formatted to string
+ * Define the way to compare 2 objects ExtRefBindingInfo in order to allow sorting items
+ *
+ * @param o the object to be compared.
+ * @return the comparaison's result (a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second)
*/
+ public int compareTo(ExtRefBindingInfo o) {
+ return EXT_REF_BINDING_INFO_COMPARATOR.compare(this, o);
+ }
+
@Override
public String toString() {
+ String sType = serviceType != null ? serviceType.value() : null;
return "ExtRefBindingInfo{" +
"iedName='" + iedName + '\'' +
", ldInst='" + ldInst + '\'' +
@@ -161,7 +177,8 @@ public String toString() {
", lnClass='" + lnClass + '\'' +
", lnInst='" + lnInst + '\'' +
", lnType='" + lnType + '\'' +
- ", serviceType=" + serviceType.value() +
+ ", serviceType=" + sType +
'}';
+
}
}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfo.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfo.java
index 185897b69..595bfcc06 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfo.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfo.java
@@ -5,10 +5,7 @@
package org.lfenergy.compas.sct.commons.dto;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.NonNull;
-import lombok.Setter;
+import lombok.*;
import org.apache.commons.lang3.StringUtils;
import org.lfenergy.compas.scl2007b4.model.TExtRef;
import org.lfenergy.compas.scl2007b4.model.TFCDA;
@@ -38,6 +35,7 @@
@Getter
@Setter
@NoArgsConstructor
+@AllArgsConstructor
public class ExtRefInfo extends LNodeMetaDataEmbedder{
private ExtRefSignalInfo signalInfo;
@@ -82,9 +80,10 @@ public static ExtRefInfo from(TExtRef tExtRef, String iedName, String ldInst,
* @param tfcda FCDA data object
* @return match state
*/
+ //TODO this method should be checked, return if parameter tested are not present in FCDA even if two object are different
public boolean matchFCDA(@NonNull TFCDA tfcda){
boolean returnValue = true;
- if(AbstractLNAdapter.isNull(tfcda)) {
+ if(AbstractLNAdapter.isFCDANull(tfcda)) {
returnValue = false;
}
@@ -118,4 +117,25 @@ public boolean matchFCDA(@NonNull TFCDA tfcda){
}
return returnValue;
}
+ /**
+ * Check matching between FCDA and ExtRef information (for external binding)
+ * Check is done for parameter lDInst(mandatory), lNClass(mandatory), lNInst, prefix doName as pDO(mandatory) and daName as pDA
+ * present in ExtRef and FCDA
+ * @param tfcda FCDA data to check compatibilities with ExtRef
+ * @return true if ExtRef matches FCDA for parameters ahead false otherwise
+ */
+ public boolean checkMatchingFCDA(@NonNull TFCDA tfcda){
+ if(bindingInfo == null || signalInfo == null) return false;
+ FCDAInfo fcdaInfo = new FCDAInfo(tfcda);
+ FCDAInfo fcdaOfBinding = FCDAInfo.builder()
+ .ldInst(bindingInfo.getLdInst())
+ .lnClass(bindingInfo.getLnClass())
+ .lnInst(bindingInfo.getLnInst())
+ .prefix(bindingInfo.getPrefix())
+ .doName(new DoTypeName(signalInfo.getPDO()))
+ .daName(new DaTypeName(signalInfo.getPDA()))
+ .build();
+ return fcdaInfo.checkFCDACompatibilitiesForBinding(fcdaOfBinding);
+ }
+
}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/FCDAInfo.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/FCDAInfo.java
index f156e7596..921e43424 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/FCDAInfo.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/FCDAInfo.java
@@ -5,13 +5,15 @@
package org.lfenergy.compas.sct.commons.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
+import lombok.*;
import org.apache.commons.lang3.StringUtils;
import org.lfenergy.compas.scl2007b4.model.TFCDA;
import org.lfenergy.compas.scl2007b4.model.TFCEnum;
+import java.util.Objects;
+
+import static org.lfenergy.compas.sct.commons.util.Utils.equalsOrBothBlank;
+
/**
* A representation of the model object FCDA .
*
@@ -33,7 +35,9 @@
*/
@Getter
@Setter
+@AllArgsConstructor
@NoArgsConstructor
+@Builder
public class FCDAInfo {
private String dataSet;
@@ -53,7 +57,11 @@ public class FCDAInfo {
* @param tfcda input
*/
public FCDAInfo(String dataSet, TFCDA tfcda) {
+ this(tfcda);
this.dataSet = dataSet;
+ }
+
+ public FCDAInfo(TFCDA tfcda) {
fc = tfcda.getFc();
ldInst = tfcda.getLdInst();
prefix = tfcda.getPrefix();
@@ -106,4 +114,18 @@ public TFCDA getFCDA(){
public boolean isValid() {
return doName != null && doName.isDefined();
}
+
+ /**
+ * Checks if two FCDAInfo object match for ldInst, lnInst, lnClass, lnPrefix doName and daName for search of binding control blocks
+ * @param fcdaInfo FCDA to copare with
+ * @return true if FCDAs match for binding, otherwise false
+ */
+ public boolean checkFCDACompatibilitiesForBinding(FCDAInfo fcdaInfo) {
+ return equalsOrBothBlank(getLdInst(), fcdaInfo.getLdInst())
+ && equalsOrBothBlank(getPrefix(), fcdaInfo.getPrefix())
+ && equalsOrBothBlank(getLnClass(), fcdaInfo.getLnClass())
+ && equalsOrBothBlank(getLnInst(), fcdaInfo.getLnInst())
+ && Objects.equals(getDoName(), fcdaInfo.getDoName())
+ && Objects.equals(getDaName(), fcdaInfo.getDaName());
+ }
}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/IedDTO.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/IedDTO.java
index 95d624b57..b3f2128fe 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/IedDTO.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/IedDTO.java
@@ -7,10 +7,8 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
-import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter;
import java.util.HashSet;
-import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -52,8 +50,7 @@ public IedDTO(String name){
public static IedDTO from(IEDAdapter iedAdapter, LogicalNodeOptions options) {
IedDTO iedDTO = new IedDTO();
iedDTO.name = iedAdapter.getName();
- List lDeviceAdapters = iedAdapter.getLDeviceAdapters();
- iedDTO.lDevices = lDeviceAdapters.stream()
+ iedDTO.lDevices = iedAdapter.streamLDeviceAdapters()
.map(lDeviceAdapter -> LDeviceDTO.from(lDeviceAdapter,options))
.collect(Collectors.toUnmodifiableSet());
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 c0022cb1d..04cfdabad 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
@@ -10,6 +10,10 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
+
+import static org.lfenergy.compas.sct.commons.util.CommonConstants.MOD_DO_NAME;
+import static org.lfenergy.compas.sct.commons.util.CommonConstants.STVAL;
/**
@@ -64,10 +68,18 @@ public static ResumedDataTemplate copyFrom(ResumedDataTemplate dtt){
/**
* Checks if DA/DO is updatable
- * @return Updatable state
+ * @return true if updatable, false otherwise
*/
public boolean isUpdatable(){
- return daName.isDefined() && daName.isUpdatable();
+ return isDOModDAstVal() || daName.isDefined() && daName.isUpdatable();
+ }
+
+ /**
+ * Checks if DO is Mod and DA is stVal
+ * @return true if DO is "Mod" and DA is "stVal", false otherwise
+ */
+ private boolean isDOModDAstVal(){
+ return doName.getName().equals(MOD_DO_NAME) && daName.getName().equals(STVAL);
}
@JsonIgnore
@@ -329,4 +341,16 @@ public ResumedDataTemplate setVal(String daiValue) {
this.setDaiValues(List.of(newDaiVal));
return this;
}
+
+ /**
+ * Retrieve value of the DAI, if present. If multiples values are found,
+ * the value with the lowest index is returned.
+ * @return Return the DAI value with the lowest key from getDaName().getdaiValues() map,
+ * or empty Optional if this DAI has no value.
+ */
+ public Optional findFirstValue() {
+ return getDaName().getDaiValues().keySet().stream()
+ .min(Long::compareTo)
+ .map(key -> getDaName().getDaiValues().get(key));
+ }
}
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
index 7a62b4bf0..05103dc8d 100644
--- 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
@@ -12,6 +12,9 @@
import java.util.ArrayList;
import java.util.List;
+/**
+ * Report of services which work on the SCD.
+ */
@AllArgsConstructor
@NoArgsConstructor
@Setter
@@ -19,22 +22,22 @@
@Builder
public class SclReport {
+ /**
+ * The SCD on which errors were encountered
+ */
private SclRootAdapter sclRootAdapter;
- private List errorDescriptionList = new ArrayList<>();
+ /**
+ * List of errors
+ */
+ private List sclReportItems = new ArrayList<>();
+ /**
+ *
+ * @return true the service succeeded, false otherwise
+ */
public boolean isSuccess() {
- return errorDescriptionList.isEmpty();
+ return sclReportItems.stream().noneMatch(SclReportItem::isFatal);
}
- @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/dto/SclReportItem.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SclReportItem.java
new file mode 100644
index 000000000..84d8cd057
--- /dev/null
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SclReportItem.java
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: 2022 RTE FRANCE
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package org.lfenergy.compas.sct.commons.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+
+@Getter
+@EqualsAndHashCode
+@AllArgsConstructor
+public final class SclReportItem {
+ private final String xpath;
+ private final String message;
+ private final boolean isFatal;
+
+ public static SclReportItem fatal(String xpath, String message) {
+ return new SclReportItem(xpath, message, true);
+ }
+
+ public static SclReportItem warning(String xpath, String message) {
+ return new SclReportItem(xpath, message, false);
+ }
+
+}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java
new file mode 100644
index 000000000..cc715f875
--- /dev/null
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java
@@ -0,0 +1,99 @@
+// SPDX-FileCopyrightText: 2022 RTE FRANCE
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package org.lfenergy.compas.sct.commons.scl;
+
+import lombok.experimental.UtilityClass;
+import org.apache.commons.lang3.StringUtils;
+import org.lfenergy.compas.scl2007b4.model.SCL;
+import org.lfenergy.compas.scl2007b4.model.TCompasICDHeader;
+import org.lfenergy.compas.scl2007b4.model.TIED;
+import org.lfenergy.compas.sct.commons.dto.SclReport;
+import org.lfenergy.compas.sct.commons.dto.SclReportItem;
+import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
+import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter;
+import org.lfenergy.compas.sct.commons.scl.ied.LN0Adapter;
+import org.lfenergy.compas.sct.commons.util.PrivateEnum;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@UtilityClass
+public class ExtRefService {
+
+ /**
+ * Updates iedName attribute of all ExtRefs in the Scd.
+ *
+ * @return list of encountered errors
+ */
+ public static SclReport updateAllExtRefIedNames(SCL scd) {
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ List iedErrors = validateIed(sclRootAdapter);
+ if (!iedErrors.isEmpty()) {
+ return new SclReport(sclRootAdapter, iedErrors);
+ }
+ Map icdSystemVersionToIed = sclRootAdapter.streamIEDAdapters()
+ .collect(Collectors.toMap(
+ iedAdapter -> PrivateService.extractCompasPrivate(iedAdapter.getCurrentElem(), TCompasICDHeader.class)
+ .map(TCompasICDHeader::getICDSystemVersionUUID)
+ .orElseThrow(), // Value presence is checked by method validateIed called above
+ Function.identity()
+ ));
+
+ List extRefErrors = sclRootAdapter.streamIEDAdapters()
+ .flatMap(IEDAdapter::streamLDeviceAdapters)
+ .filter(LDeviceAdapter::hasLN0)
+ .map(LDeviceAdapter::getLN0Adapter)
+ .filter(LN0Adapter::hasInputs)
+ .map(LN0Adapter::getInputsAdapter)
+ .map(inputsAdapter -> inputsAdapter.updateAllExtRefIedNames(icdSystemVersionToIed))
+ .flatMap(List::stream).collect(Collectors.toList());
+
+ return new SclReport(sclRootAdapter, extRefErrors);
+ }
+
+ private static List validateIed(SclRootAdapter sclRootAdapter) {
+ List iedErrors = new ArrayList<>(checkIedCompasIcdHeaderAttributes(sclRootAdapter));
+ iedErrors.addAll(checkIedUnityOfIcdSystemVersionUuid(sclRootAdapter));
+ return iedErrors;
+ }
+
+ private static List checkIedCompasIcdHeaderAttributes(SclRootAdapter sclRootAdapter) {
+ return sclRootAdapter.streamIEDAdapters()
+ .map(iedAdapter -> {
+ Optional compasPrivate = PrivateService.extractCompasPrivate(iedAdapter.getCurrentElem(), TCompasICDHeader.class);
+ if (compasPrivate.isEmpty()) {
+ return iedAdapter.buildFatalReportItem(String.format("IED has no Private %s element", PrivateEnum.COMPAS_ICDHEADER.getPrivateType()));
+ }
+ if (StringUtils.isBlank(compasPrivate.get().getICDSystemVersionUUID())
+ || StringUtils.isBlank(compasPrivate.get().getIEDName())) {
+ return iedAdapter.buildFatalReportItem(String.format("IED private %s as no icdSystemVersionUUID or iedName attribute",
+ PrivateEnum.COMPAS_ICDHEADER.getPrivateType()));
+ }
+ return null;
+ }
+ ).filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+ private static List checkIedUnityOfIcdSystemVersionUuid(SclRootAdapter sclRootAdapter) {
+ Map> systemVersionToIedList = sclRootAdapter.getCurrentElem().getIED().stream()
+ .collect(Collectors.groupingBy(ied -> PrivateService.extractCompasPrivate(ied, TCompasICDHeader.class)
+ .map(TCompasICDHeader::getICDSystemVersionUUID)
+ .orElse("")));
+
+ return systemVersionToIedList.entrySet().stream()
+ .filter(entry -> StringUtils.isNotBlank(entry.getKey()))
+ .filter(entry -> entry.getValue().size() > 1)
+ .map(entry -> SclReportItem.fatal(entry.getValue().stream()
+ .map(tied -> new IEDAdapter(sclRootAdapter, tied))
+ .map(IEDAdapter::getXPath)
+ .collect(Collectors.joining(", ")),
+ "/IED/Private/compas:ICDHeader[@ICDSystemVersionUUID] must be unique" +
+ " but the same ICDSystemVersionUUID was found on several IED."))
+ .collect(Collectors.toList());
+ }
+
+}
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
index 59dc6db7e..4691c650a 100644
--- 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
@@ -8,7 +8,7 @@
import lombok.Setter;
import org.apache.commons.lang3.tuple.Pair;
import org.lfenergy.compas.scl2007b4.model.TCompasLDeviceStatus;
-import org.lfenergy.compas.sct.commons.util.STValEnum;
+import org.lfenergy.compas.sct.commons.util.LDeviceStatus;
import java.util.List;
import java.util.Set;
@@ -38,15 +38,15 @@ public LDeviceActivation(List> iedNameLdInstList) {
* @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)) {
+ if (!enumValues.contains(LDeviceStatus.ON) && !enumValues.contains(LDeviceStatus.OFF)) {
errorMessage = "The LDevice cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'.";
}
- if (!enumValues.contains(STValEnum.ON.value) && enumValues.contains(STValEnum.OFF.value)) {
+ if (!enumValues.contains(LDeviceStatus.ON) && enumValues.contains(LDeviceStatus.OFF)) {
if (isDeclaredInSubstation(iedName, ldInst)) {
errorMessage = "The LDevice cannot be set to 'on' but has been selected into SSD.";
} else {
isUpdatable = true;
- newVal = STValEnum.OFF.value;
+ newVal = LDeviceStatus.OFF;
}
}
if(compasLDeviceStatus.equals(TCompasLDeviceStatus.ACTIVE) ||
@@ -65,20 +65,20 @@ public void checkLDeviceActivationStatus(String iedName, String ldInst, TCompasL
* @param enumValues enum values
*/
private void checkAuthorisationToActivateLDevice(String iedName, String ldInst, Set enumValues) {
- if (!enumValues.contains(STValEnum.OFF.value) && enumValues.contains(STValEnum.ON.value)) {
+ if (!enumValues.contains(LDeviceStatus.OFF) && enumValues.contains(LDeviceStatus.ON)) {
if (isDeclaredInSubstation(iedName, ldInst)) {
isUpdatable = true;
- newVal = STValEnum.ON.value;
+ newVal = LDeviceStatus.ON;
} else {
errorMessage = "The LDevice cannot be set to 'off' but has not been selected into SSD.";
}
}
- if (enumValues.contains(STValEnum.ON.value) && enumValues.contains(STValEnum.OFF.value)) {
+ if (enumValues.contains(LDeviceStatus.ON) && enumValues.contains(LDeviceStatus.OFF)) {
isUpdatable = true;
if (isDeclaredInSubstation(iedName, ldInst)) {
- newVal = STValEnum.ON.value;
+ newVal = LDeviceStatus.ON;
} else {
- newVal = STValEnum.OFF.value;
+ newVal = LDeviceStatus.OFF;
}
}
@@ -91,19 +91,19 @@ private void checkAuthorisationToActivateLDevice(String iedName, String ldInst,
* @param enumValues enum values
*/
private void checkAuthorisationToDeactivateLDevice(String iedName, String ldInst, Set enumValues) {
- if (!enumValues.contains(STValEnum.OFF.value) && enumValues.contains(STValEnum.ON.value)) {
+ if (!enumValues.contains(LDeviceStatus.OFF) && enumValues.contains(LDeviceStatus.ON)) {
if (isDeclaredInSubstation(iedName, ldInst)) {
errorMessage = "The LDevice is not qualified into STD but has been selected into SSD.";
} else {
errorMessage = "The LDevice cannot be set to 'off' but has not been selected into SSD.";
}
}
- if (enumValues.contains(STValEnum.ON.value) && enumValues.contains(STValEnum.OFF.value)) {
+ if (enumValues.contains(LDeviceStatus.ON) && enumValues.contains(LDeviceStatus.OFF)) {
if (isDeclaredInSubstation(iedName, ldInst)) {
errorMessage = "The LDevice is not qualified into STD but has been selected into SSD.";
} else {
isUpdatable = true;
- newVal = STValEnum.OFF.value;
+ newVal = LDeviceStatus.OFF;
}
}
}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/PrivateService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/PrivateService.java
index af6b633d8..aea8bd9c1 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/PrivateService.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/PrivateService.java
@@ -5,7 +5,6 @@
package org.lfenergy.compas.sct.commons.scl;
import lombok.NonNull;
-import lombok.extern.slf4j.Slf4j;
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.util.PrivateEnum;
@@ -24,19 +23,18 @@
* The following features are supported:
*
*
- * {@link PrivateService#getCompasPrivate(TPrivate, Class)
+ * {@link PrivateService#extractCompasPrivate(TPrivate, Class)
* Returns the value of the TPrivate reference object By class type }
*
- * {@link PrivateService#getCompasPrivates(TBaseElement, Class)
+ * {@link PrivateService#extractCompasPrivates(TBaseElement, Class)
* Returns the value of the TPrivate containment reference list from given TBaseElement By class type }
*
- * {@link PrivateService#getCompasPrivates(List, Class)
+ * {@link PrivateService#extractCompasPrivates(List, Class)
* Returns the value of the TPrivate containment reference list from given TPrivate elements By class type }
*
*
* @see org.lfenergy.compas.scl2007b4.model.TPrivate
*/
-@Slf4j
public final class PrivateService {
private PrivateService() {
@@ -46,14 +44,14 @@ private PrivateService() {
private static final ObjectFactory objectFactory = new ObjectFactory();
/**
- * Converts each item of given list of Private to list of Private element of type compasClass
- * @param tPrivates list of private to convert
- * @param compasClass type in which Privates should be
- * @return list of formatted Private
- * @param Inference parameter stands for wanted type of Privates
+ * Extract compas element of class compasClass nested in private elements.
+ * @param tPrivates list of privates to look in
+ * @param compasClass class of privates to extract
+ * @return list of compas objects nested in the privates.
+ * @param Inference parameter stands for class compasClass
* @throws ScdException throws when inconsistency between types
*/
- public static List getCompasPrivates(List tPrivates, Class compasClass) throws ScdException {
+ public static List extractCompasPrivates(List tPrivates, Class compasClass) throws ScdException {
PrivateEnum privateEnum = PrivateEnum.fromClass(compasClass);
List compasElements = tPrivates.stream().filter(tPrivate -> privateEnum.getPrivateType().equals(tPrivate.getType()))
.map(TAnyContentFromOtherNamespace::getContent).flatMap(List::stream)
@@ -75,30 +73,31 @@ public static List getCompasPrivates(List tPrivates, Class c
}
/**
- * Converts all Private of given TBaseElement of type compasClass given as parameter
- * @param baseElement TBaseElement contenting Privates
- * @param compasClass type in which Privates should be given
- * @return list of formatted Private
- * @param Inference parameter stands for wanted type of Privates
+ * Extract compas elements of class compasClass nested in private elements of the given baseElement.
+ * @param baseElement element where to look for privates
+ * @param compasClass class of privates to extract
+ * @return list of compas objects nested in the privates.
+ * @param Inference parameter stands for class compasClass
* @throws ScdException throws when inconsistency between types
*/
- public static List getCompasPrivates(TBaseElement baseElement, Class compasClass) throws ScdException {
+ public static List extractCompasPrivates(TBaseElement baseElement, Class compasClass) throws ScdException {
if (!baseElement.isSetPrivate()) {
return Collections.emptyList();
}
- return getCompasPrivates(baseElement.getPrivate(), compasClass);
+ return extractCompasPrivates(baseElement.getPrivate(), compasClass);
}
/**
- * Converts Private of type compasClass given as parameter
- * @param tPrivate Private to check if is in wanted type
- * @param compasClass type in which Privates should be given
- * @return optional of formatted Private
- * @param Inference parameter stands for wanted type of Private
- * @throws ScdException throws when inconsistency between types
+ * Extract a single compas element of class compasClass nested in a private element.
+ * Throws an exception when there are more than 1 compas element of given compasClass nested inside the private element.
+ * @param tPrivate private where to look in
+ * @param compasClass class of privates to extract
+ * @return list of compas objects nested in the privates.
+ * @param Inference parameter stands for class compasClass
+ * @throws ScdException throws when inconsistency between types, or when more than 1 compas element is found
*/
- public static Optional getCompasPrivate(TPrivate tPrivate, Class compasClass) throws ScdException {
- List compasPrivates = getCompasPrivates(Collections.singletonList(tPrivate), compasClass);
+ public static Optional extractCompasPrivate(TPrivate tPrivate, Class compasClass) throws ScdException {
+ List compasPrivates = extractCompasPrivates(Collections.singletonList(tPrivate), compasClass);
if (compasPrivates.size() > 1) {
throw new ScdException(String.format("Expecting maximum 1 element of type %s in private %s, but got %d",
compasClass.getName(), tPrivate.getType(), compasPrivates.size()));
@@ -109,20 +108,41 @@ public static Optional getCompasPrivate(TPrivate tPrivate, Class compa
return Optional.of(compasPrivates.get(0));
}
+ /**
+ * Extract a single compas element of class compasClass nested in private elements of a given baseElement.
+ * Throws an exception when there are more than 1 compas element of given compasClass nested inside privates of the baseElement.
+ * @param baseElement element where to look for privates
+ * @param compasClass class of privates to extract
+ * @return list of compas objects nested in the privates.
+ * @param Inference parameter stands for class compasClass
+ * @throws ScdException throws when inconsistency between types, or when more than 1 compas element is found
+ */
+ public static Optional extractCompasPrivate(TBaseElement baseElement, Class compasClass) throws ScdException {
+ List compasPrivates = extractCompasPrivates(baseElement, compasClass);
+ if (compasPrivates.size() > 1) {
+ throw new ScdException(String.format("Expecting maximum 1 private of type %s with 1 element, but found %d",
+ PrivateEnum.fromClass(compasClass).getPrivateType(), compasPrivates.size()));
+ }
+ if (compasPrivates.isEmpty()) {
+ return Optional.empty();
+ }
+ return Optional.of(compasPrivates.get(0));
+ }
+
/**
* Gets Private CompasICDHeader from Private
* @param tPrivate Private contenting object to get as CompasICDHeader
* @return content of th Private as optional of TCompasICDHeader object
* @throws ScdException throws when inconsistency between types
*/
- public static Optional getCompasICDHeader(TPrivate tPrivate) throws ScdException {
- return getCompasPrivate(tPrivate, TCompasICDHeader.class);
+ public static Optional extractCompasICDHeader(TPrivate tPrivate) throws ScdException {
+ return extractCompasPrivate(tPrivate, TCompasICDHeader.class);
}
/**
- * Removes specified Private from TBaseElement Privates
- * @param baseElement BaseElement contenting Privates
- * @param privateEnum enum type of Private to remove
+ * Removes all privates of type privateEnum from baseElement
+ * @param baseElement baseElement containing privates
+ * @param privateEnum enum type of private to remove
*/
public static void removePrivates(TBaseElement baseElement, @NonNull PrivateEnum privateEnum) {
if (baseElement.isSetPrivate()) {
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 1939dc07a..47c07085f 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
@@ -7,6 +7,8 @@
import lombok.Getter;
import org.lfenergy.compas.scl2007b4.model.TBaseElement;
import org.lfenergy.compas.scl2007b4.model.TPrivate;
+import org.lfenergy.compas.sct.commons.dto.SclReportItem;
+
/**
* A representation of the model object
* {@link SclElementAdapter SclElementAdapter} .
@@ -115,4 +117,12 @@ public String getXPath(){
return parentXpath + "/" + elementXPath();
}
+ /**
+ * builds message with message content and currentElement xpath
+ * @param message message
+ * @return error description with message and current element xpath
+ */
+ public SclReportItem buildFatalReportItem(String message){
+ return SclReportItem.fatal(getXPath(), message);
+ }
}
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 4371d0abb..fd064e433 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
@@ -17,9 +17,7 @@
import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* A representation of the model object
@@ -33,7 +31,7 @@
* {@link SclRootAdapter#getHeaderAdapter Returns the value of the HeaderAdapter reference object }
* {@link SclRootAdapter#getSubstationAdapter(String) Returns the value of the SubstationAdapter reference object By nme }
* {@link SclRootAdapter#getCommunicationAdapter(boolean) Returns or Adds the value of the CommunicationAdapter reference object }
- * {@link SclRootAdapter#getIEDAdapters() Returns the value of the IEDAdapter containment reference list }
+ * {@link SclRootAdapter#streamIEDAdapters() Returns the value of the IEDAdapter containment reference list }
* {@link SclRootAdapter#getIEDAdapterByName(String) Returns the value of the IEDAdapter reference object By name }
* {@link SclRootAdapter#getDataTypeTemplateAdapter() Returns the value of the DataTypeTemplateAdapter containment reference list }
*
@@ -265,12 +263,11 @@ public CommunicationAdapter getCommunicationAdapter(boolean createIfNotExists) t
/**
* Gets all IEDs from SCL
- * @return list of IEDAdapter object as IEDs of SCL
+ * @return Stream of IEDAdapter object as IEDs of SCL
*/
- public List getIEDAdapters() {
+ public Stream streamIEDAdapters() {
return currentElem.getIED().stream()
- .map(tied -> new IEDAdapter(this,tied))
- .collect(Collectors.toList());
+ .map(tied -> new IEDAdapter(this, tied));
}
/**
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 1c8f4246f..f9dc830c5 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
@@ -69,6 +69,7 @@
*
*
*
+ *
* @see org.lfenergy.compas.sct.commons.scl.header.HeaderAdapter
* @see org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter
* @see org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter
@@ -88,8 +89,9 @@ private SclService() {
/**
* Initialise SCD file with Header and Private SCLFileType
- * @param hId optional SCL Header ID, if empty random UUID will be created
- * @param hVersion SCL Header Version
+ *
+ * @param hId optional SCL Header ID, if empty random UUID will be created
+ * @param hVersion SCL Header Version
* @param hRevision SCL Header Revision
* @return SclRootAdapter object as SCD file
* @throws ScdException throws when inconsistenc in SCL file
@@ -103,10 +105,11 @@ public static SclRootAdapter initScl(Optional hId, String hVersion, String
/**
* Adds new HistoryItem in SCL file
- * @param scd SCL file in which new History should be added
- * @param who Who realize the action
+ *
+ * @param scd SCL file in which new History should be added
+ * @param who Who realize the action
* @param what What kind of action is realized
- * @param why Why this action is done
+ * @param why Why this action is done
* @return SclRootAdapter object as SCD file
*/
public static SclRootAdapter addHistoryItem(SCL scd, String who, String what, String why) {
@@ -118,7 +121,8 @@ public static SclRootAdapter addHistoryItem(SCL scd, String who, String what, St
/**
* Updates Header of SCL file
- * @param scd SCL file in which Header should be updated
+ *
+ * @param scd SCL file in which Header should be updated
* @param headerDTO Header new values
* @return SclRootAdapter object as SCD file
*/
@@ -152,9 +156,10 @@ public static SclRootAdapter updateHeader(@NonNull SCL scd, @NonNull HeaderDTO h
/**
* Adds IED in SCL file (Related DataTypeTemplate of SCL is updated also)
- * @param scd SCL file in which IED should be added
+ *
+ * @param scd SCL file in which IED should be added
* @param iedName name of IED to add in SCL
- * @param icd ICD containing IED to add and related DataTypeTemplate
+ * @param icd ICD containing IED to add and related DataTypeTemplate
* @return IEDAdapter as added IED
* @throws ScdException throws when inconsistency between IED to add and SCL file content
*/
@@ -165,9 +170,10 @@ public static IEDAdapter addIED(SCL scd, String iedName, SCL icd) throws ScdExce
/**
* Adds new SubNetworks in SCL file from ICD file
- * @param scd SCL file in which SubNetworks should be added
+ *
+ * @param scd SCL file in which SubNetworks should be added
* @param subNetworks list of SubNetworks DTO contenting SubNetwork and ConnectedAp parameter names
- * @param icd ICD file from which SubNetworks functional data are copied from
+ * @param icd ICD file from which SubNetworks functional data are copied from
* @return optional of CommunicationAdapter object as Communication node of SCL file.
* Calling getParentAdapter() will give SCL file
* @throws ScdException throws when no Communication in SCL and createIfNotExists == false
@@ -188,8 +194,7 @@ public static Optional addSubnetworks(SCL scd, Set subNetworkAdapter = communicationAdapter.getSubnetworkByName(snName);
if (subNetworkAdapter.isPresent()) {
- ConnectedAPAdapter connectedAPAdapter = subNetworkAdapter.get()
- .getConnectedAPAdapter(iedName, apName);
+ ConnectedAPAdapter connectedAPAdapter = subNetworkAdapter.get().getConnectedAPAdapter(iedName, apName);
connectedAPAdapter.copyAddressAndPhysConnFromIcd(icd);
}
@@ -202,6 +207,7 @@ public static Optional addSubnetworks(SCL scd, SetSubNetworkDTO from SCL
* @throws ScdException throws when no Communication in SCL and createIfNotExists == false
@@ -209,17 +215,17 @@ public static Optional addSubnetworks(SCL scd, Set getSubnetwork(SCL scd) throws ScdException {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
CommunicationAdapter communicationAdapter = sclRootAdapter.getCommunicationAdapter(false);
- return communicationAdapter.getSubNetworkAdapters()
- .stream()
+ return communicationAdapter.getSubNetworkAdapters().stream()
.map(SubNetworkDTO::from)
.collect(Collectors.toList());
}
/**
* Gets all ExtRef from specific IED/LDevice in SCL file
- * @param scd SCL file in which ExtRefs should be found
+ *
+ * @param scd SCL file in which ExtRefs should be found
* @param iedName name of IED in which LDevice is localized
- * @param ldInst LdInst of LDevice in which all ExtRefs should be found
+ * @param ldInst LdInst of LDevice in which all ExtRefs should be found
* @return list of ExtRefInfo from specified parameter SCL/IED/LDevice
* @throws ScdException throws when unknown specified IED or LDevice
*/
@@ -228,32 +234,28 @@ public static List getExtRefInfo(SCL scd, String iedName, String ldI
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
- .orElseThrow(
- () -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))
- );
+ .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
return lDeviceAdapter.getExtRefInfo();
}
/**
* Gets all possible ExtRefs to bind in SCL file with given ExtRef (signalInfo ) in SCL file
- * @param scd SCL file in which ExtRefs should be found
- * @param iedName name of IED in which LDevice is localized
- * @param ldInst ldInst of LDevice in which LN is localized
- * @param lnClass lnClass of LN in which ExtRef signal to find binders is localized
- * @param lnInst lnInst of LN in which ExtRef signal to find binders is localized
- * @param prefix prefix of LN in which ExtRef signal to find binders is localized
+ *
+ * @param scd SCL file in which ExtRefs should be found
+ * @param iedName name of IED in which LDevice is localized
+ * @param ldInst ldInst of LDevice in which LN is localized
+ * @param lnClass lnClass of LN in which ExtRef signal to find binders is localized
+ * @param lnInst lnInst of LN in which ExtRef signal to find binders is localized
+ * @param prefix prefix of LN in which ExtRef signal to find binders is localized
* @param signalInfo ExtRef signal for which we should find possible binders in SCL file binders
- * @return list of ExtRefBindingInfo object (containing binding data for each LNode in current SCL file)
+ * @return list of ExtRefBindingInfo object (containing binding data for each LNode in current SCL file) sorted by {@link ExtRefBindingInfo#compareTo(ExtRefBindingInfo) compareTo} method.
* @throws ScdException throws when ExtRef contains inconsistency data
*/
- public static List getExtRefBinders(SCL scd, String iedName, String ldInst,
- String lnClass, String lnInst, String prefix, ExtRefSignalInfo signalInfo) throws ScdException {
+ public static List getExtRefBinders(SCL scd, String iedName, String ldInst, String lnClass, String lnInst, String prefix, ExtRefSignalInfo signalInfo) throws ScdException {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
- .orElseThrow(
- () -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))
- );
+ .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
AbstractLNAdapter> abstractLNAdapter = AbstractLNAdapter.builder()
.withLDeviceAdapter(lDeviceAdapter)
.withLnClass(lnClass)
@@ -263,19 +265,21 @@ public static List getExtRefBinders(SCL scd, String iedName,
// check for signal existence
// The below throws exception if the signal doesn't exist
+ //TODO: create method which purpose is only ckecking instead of this one
abstractLNAdapter.getExtRefsBySignalInfo(signalInfo);
// find potential binders for the signalInfo
- List potentialBinders = new ArrayList<>();
- for (IEDAdapter iedA : sclRootAdapter.getIEDAdapters()) {
- potentialBinders.addAll(iedA.getExtRefBinders(signalInfo));
- }
- return potentialBinders;
+ return sclRootAdapter.streamIEDAdapters()
+ .map(iedAdapter1 -> iedAdapter1.getExtRefBinders(signalInfo))
+ .flatMap(Collection::stream)
+ .sorted()
+ .collect(Collectors.toList());
}
/**
* Updates ExtRef binding data related to given ExtRef (extRefInfo ) in given SCL file
- * @param scd SCL file in which ExtRef to update should be found
+ *
+ * @param scd SCL file in which ExtRef to update should be found
* @param extRefInfo ExtRef signal for which we should find possible binders in SCL file
* @throws ScdException throws when mandatory data of ExtRef are missing
*/
@@ -288,13 +292,7 @@ public static void updateExtRefBinders(SCL scd, ExtRefInfo extRefInfo) throws Sc
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
- .orElseThrow(
- () -> new ScdException(
- String.format(
- UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName
- )
- )
- );
+ .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
AbstractLNAdapter> abstractLNAdapter = AbstractLNAdapter.builder()
.withLDeviceAdapter(lDeviceAdapter)
@@ -308,7 +306,8 @@ public static void updateExtRefBinders(SCL scd, ExtRefInfo extRefInfo) throws Sc
/**
* Gets all Control Blocks related to extRefInfo in given SCL file
- * @param scd SCL file in which ControlBlocks should be found
+ *
+ * @param scd SCL file in which ControlBlocks should be found
* @param extRefInfo ExtRef signal for which we should find related ControlBlocks
* @return list of ControlBlock object as ControlBlocks of LNode specified in extRefInfo
* @throws ScdException throws when mandatory data of ExtRef are missing
@@ -329,43 +328,26 @@ public static List> getExtRefSourceInfo(SCL scd, ExtRefInfo extR
throw new ScdException("Internal binding can't have control block");
}
- String ldInst = extRefInfo.getHolderLDInst();
- String lnClass = extRefInfo.getHolderLnClass();
- String lnInst = extRefInfo.getHolderLnInst();
- String prefix = extRefInfo.getHolderLnPrefix();
- // Check holder (IED,LD,LN) exists
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
- IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
- LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
- .orElseThrow(
- () -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))
- );
- AbstractLNAdapter> abstractLNAdapter = AbstractLNAdapter.builder()
- .withLDeviceAdapter(lDeviceAdapter)
- .withLnClass(lnClass)
- .withLnInst(lnInst)
- .withLnPrefix(prefix)
- .build();
-
- abstractLNAdapter.checkExtRefInfoCoherence(extRefInfo);
// Get CBs
IEDAdapter srcIEDAdapter = sclRootAdapter.getIEDAdapterByName(bindingInfo.getIedName());
LDeviceAdapter srcLDeviceAdapter = srcIEDAdapter.getLDeviceAdapterByLdInst(extRefInfo.getBindingInfo().getLdInst())
.orElseThrow();
- AbstractLNAdapter> srcLnAdapter = AbstractLNAdapter.builder()
- .withLDeviceAdapter(srcLDeviceAdapter)
- .withLnClass(extRefInfo.getBindingInfo().getLnClass())
- .withLnInst(extRefInfo.getBindingInfo().getLnInst())
- .withLnPrefix(extRefInfo.getBindingInfo().getPrefix())
- .build();
- return srcLnAdapter.getControlSetByExtRefInfo(extRefInfo);
+ List> aLNAdapters = srcLDeviceAdapter.getLNAdaptersInclundigLN0();
+
+ return aLNAdapters.stream()
+ .map(abstractLNAdapter1 -> abstractLNAdapter1.getControlBlocksForMatchingFCDA(extRefInfo))
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+
}
/**
* Updates ExtRef source binding data's based on given data in extRefInfo
- * @param scd SCL file in which ExtRef source data's to update should be found
+ *
+ * @param scd SCL file in which ExtRef source data's to update should be found
* @param extRefInfo new data for ExtRef source binding data
* @return TExtRef object as update ExtRef with new source binding data
* @throws ScdException throws when mandatory data of ExtRef are missing
@@ -396,9 +378,7 @@ public static TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
- .orElseThrow(
- () -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))
- );
+ .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
var anLNAdapter = AbstractLNAdapter.builder()
.withLDeviceAdapter(lDeviceAdapter)
.withLnClass(lnClass)
@@ -411,34 +391,33 @@ public static TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws
/**
* Gets a list of summarized DataTypeTemplate for DataAttribute DA (updatable or not) related to the one given
* in rDtt
- * @param scd SCL file in which DataTypeTemplate of DAIs should be found
- * @param iedName name of IED in which DAs are localized
- * @param ldInst ldInst of LDevice in which DAIs are localized
- * @param rDtt reference summarized DataTypeTemplate related to IED DAIs
+ *
+ * @param scd SCL file in which DataTypeTemplate of DAIs should be found
+ * @param iedName name of IED in which DAs are localized
+ * @param ldInst ldInst of LDevice in which DAIs are localized
+ * @param rDtt reference summarized DataTypeTemplate related to IED DAIs
* @param updatable true to retrieve DataTypeTemplate's related to only updatable DAIs, false to retrieve all
* @return List of resumed DataTypeTemplate for DataAttribute (updatable or not)
* @throws ScdException SCD illegal arguments exception, missing mandatory data
*/
- public static Set getDAI(SCL scd, String iedName, String ldInst,
- ResumedDataTemplate rDtt, boolean updatable) throws ScdException {
+ public static Set getDAI(SCL scd, String iedName, String ldInst, ResumedDataTemplate rDtt, boolean updatable) throws ScdException {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iedAdapter = new IEDAdapter(sclRootAdapter, iedName);
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
- .orElseThrow(
- () -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))
- );
+ .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
return lDeviceAdapter.getDAI(rDtt, updatable);
}
/**
* Updates DAI based on given data in rDtt
- * @param scd SCL file in which DataTypeTemplate of DAI should be found
+ *
+ * @param scd SCL file in which DataTypeTemplate of DAI should be found
* @param iedName name of IED in which DAI is localized
- * @param ldInst ldInst of LDevice in which DAI is localized
- * @param rDtt reference summarized DataTypeTemplate related to DAI to update
+ * @param ldInst ldInst of LDevice in which DAI is localized
+ * @param rDtt reference summarized DataTypeTemplate related to DAI to update
* @throws ScdException when inconsistency are found in th SCL's
- * DataTypeTemplate. Which should normally not happens.
+ * DataTypeTemplate. Which should normally not happens.
*/
public static void updateDAI(SCL scd, String iedName, String ldInst, ResumedDataTemplate rDtt) throws ScdException {
long startTime = System.nanoTime();
@@ -457,9 +436,7 @@ public static void updateDAI(SCL scd, String iedName, String ldInst, ResumedData
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
- .orElseThrow(
- () -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))
- );
+ .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
AbstractLNAdapter> lnAdapter = AbstractLNAdapter.builder()
.withLDeviceAdapter(lDeviceAdapter)
@@ -478,7 +455,8 @@ public static void updateDAI(SCL scd, String iedName, String ldInst, ResumedData
/**
* Gets EnumTypes values of ID idEnum from DataTypeTemplate of SCL file
- * @param scd SCL file in which EnumType should be found
+ *
+ * @param scd SCL file in which EnumType should be found
* @param idEnum ID of EnumType for which values are retrieved
* @return list of couple EnumType value and it's order
* @throws ScdException throws when unkonown EnumType
@@ -506,21 +484,21 @@ public static Set> getEnumTypeElements(SCL scd, String idE
* import /IED /DataTypeTemplate from that STD file and update IEDName of /IED in SCD file
* import connectedAP and rename ConnectedAP/@iedName in Communication node in SCD file
*
+ *
* @param scdRootAdapter adapter object related to SCL file in which content of STD files are imported
- * @param stds list of STD files contenting datas to import into SCD
- * @param comMap couple of Subnetwork name and possible corresponding ConnectAP names
+ * @param stds list of STD files contenting datas to import into SCD
+ * @param comMap couple of Subnetwork name and possible corresponding ConnectAP names
* @return updated SCD file as SclRootAdapter
* @throws ScdException throws when inconsistency between Substation of SCL content and gien STD files as :
- *
- * ICD_SYSTEM_VERSION_UUID in IED/Private of STD is not present in COMPAS-ICDHeader in Substation/../LNode of SCL
- * There are several STD files corresponding to ICD_SYSTEM_VERSION_UUID of COMPAS-ICDHeader in Substation/../LNode of SCL
- * There is no STD file found corresponding to COMPAS-ICDHeader in Substation/../LNode of SCL
- * COMPAS-ICDHeader is not the same in Substation/../LNode of SCL and in IED/Private of STD
- * COMPAS_ICDHEADER in Substation/../LNode of SCL not found in IED/Private of STD
- *
+ *
+ * ICD_SYSTEM_VERSION_UUID in IED/Private of STD is not present in COMPAS-ICDHeader in Substation/../LNode of SCL
+ * There are several STD files corresponding to ICD_SYSTEM_VERSION_UUID of COMPAS-ICDHeader in Substation/../LNode of SCL
+ * There is no STD file found corresponding to COMPAS-ICDHeader in Substation/../LNode of SCL
+ * COMPAS-ICDHeader is not the same in Substation/../LNode of SCL and in IED/Private of STD
+ * COMPAS_ICDHEADER in Substation/../LNode of SCL not found in IED/Private of STD
+ *
*/
- public static SclRootAdapter importSTDElementsInSCD(@NonNull SclRootAdapter scdRootAdapter, Set stds,
- Map, List> comMap) throws ScdException {
+ public static SclRootAdapter importSTDElementsInSCD(@NonNull SclRootAdapter scdRootAdapter, Set stds, Map, List> comMap) throws ScdException {
//Check SCD and STD compatibilities
Map>> mapICDSystemVersionUuidAndSTDFile = createMapICDSystemVersionUuidAndSTDFile(stds);
@@ -531,8 +509,8 @@ public static SclRootAdapter importSTDElementsInSCD(@NonNull SclRootAdapter scdR
for (Map.Entry entry : mapIEDNameAndPrivate.entrySet()) {
String iedName = entry.getKey();
TPrivate tPrivate = entry.getValue();
- String icdSysVerUuid = PrivateService.getCompasICDHeader(tPrivate).map(TCompasICDHeader::getICDSystemVersionUUID).orElseThrow(
- () -> new ScdException(ICD_SYSTEM_VERSION_UUID + " is not present in COMPAS-ICDHeader in LNode")
+ String icdSysVerUuid = PrivateService.extractCompasICDHeader(tPrivate).map(TCompasICDHeader::getICDSystemVersionUUID)
+ .orElseThrow(() -> new ScdException(ICD_SYSTEM_VERSION_UUID + " is not present in COMPAS-ICDHeader in LNode")
);
if (!mapICDSystemVersionUuidAndSTDFile.containsKey(icdSysVerUuid))
@@ -557,10 +535,11 @@ public static SclRootAdapter importSTDElementsInSCD(@NonNull SclRootAdapter scdR
/**
* Checks SCD and STD compatibilities by checking if there is at least one ICD_SYSTEM_VERSION_UUID in
- * Substation/../LNode/Private COMPAS-ICDHeader of SCL not present in IED/Private COMPAS-ICDHeader of STD
+ * Substation/../LNode/Private COMPAS-ICDHeader of SCL not present in IED/Private COMPAS-ICDHeader of STD
+ *
* @param mapICDSystemVersionUuidAndSTDFile map of ICD_SYSTEM_VERSION_UUID and list of corresponding STD
* @throws ScdException throws when there are several STD files corresponding to ICD_SYSTEM_VERSION_UUID
- * from Substation/../LNode/Private COMPAS-ICDHeader of SCL
+ * from Substation/../LNode/Private COMPAS-ICDHeader of SCL
*/
private static void checkSTDCorrespondanceWithLNodeCompasICDHeader(Map>> mapICDSystemVersionUuidAndSTDFile) throws ScdException {
for (Pair> pairOfPrivateAndSTDs : mapICDSystemVersionUuidAndSTDFile.values()) {
@@ -573,20 +552,22 @@ private static void checkSTDCorrespondanceWithLNodeCompasICDHeader(Map optionalCompasICDHeader = PrivateService.getCompasICDHeader(key);
- return HEADER_ID + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getHeaderId).orElse(null) +
- HEADER_VERSION + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getHeaderVersion).orElse(null) +
- HEADER_REVISION + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getHeaderRevision).orElse(null) +
- "and " + ICD_SYSTEM_VERSION_UUID + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getICDSystemVersionUUID).orElse(null);
+ Optional optionalCompasICDHeader = PrivateService.extractCompasICDHeader(key);
+ return HEADER_ID + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getHeaderId).orElse(null) + " " +
+ HEADER_VERSION + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getHeaderVersion).orElse(null) + " " +
+ HEADER_REVISION + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getHeaderRevision).orElse(null) +
+ " and " + ICD_SYSTEM_VERSION_UUID + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getICDSystemVersionUUID).orElse(null);
}
/**
* Creates map of IEDName and related Private for all Privates COMPAS-ICDHeader in /Substation of SCL
+ *
* @param scdRootAdapter SCL file in which Private should be found
* @return map of Private and its IEDName parameter
*/
@@ -598,12 +579,14 @@ private static Map createMapIEDNameAndPrivate(SclRootAdapter s
.map(TLNode::getPrivate).flatMap(Collection::stream)
.filter(tPrivate ->
tPrivate.getType().equals(COMPAS_ICDHEADER.getPrivateType())
- && PrivateService.getCompasICDHeader(tPrivate).isPresent() && PrivateService.getCompasICDHeader(tPrivate).get().getIEDName() != null)
- .collect(Collectors.toMap(tPrivate -> PrivateService.getCompasICDHeader(tPrivate).get().getIEDName(), Function.identity()));
+ && PrivateService.extractCompasICDHeader(tPrivate).isPresent()
+ && PrivateService.extractCompasICDHeader(tPrivate).get().getIEDName() != null)
+ .collect(Collectors.toMap(tPrivate -> PrivateService.extractCompasICDHeader(tPrivate).get().getIEDName(), Function.identity()));
}
/**
* Sorts in map of ICD_SYSTEM_VERSION_UUID and related Private coupled with all corresponding STD for all given STD
+ *
* @param stds list of STD to short
* @return map of ICD_SYSTEM_VERSION_UUID attribute in IED/Private:COMPAS-ICDHeader and related Private coupled with
* all corresponding STD
@@ -611,7 +594,7 @@ private static Map createMapIEDNameAndPrivate(SclRootAdapter s
private static Map>> createMapICDSystemVersionUuidAndSTDFile(Set stds) {
Map>> stringSCLMap = new HashMap<>();
stds.forEach(std -> std.getIED().forEach(ied -> ied.getPrivate().forEach(tp ->
- PrivateService.getCompasICDHeader(tp).map(TCompasICDHeader::getICDSystemVersionUUID).ifPresent(icdSysVer -> {
+ PrivateService.extractCompasICDHeader(tp).map(TCompasICDHeader::getICDSystemVersionUUID).ifPresent(icdSysVer -> {
Pair> pair = stringSCLMap.get(icdSysVer);
List list = pair != null ? pair.getRight() : new ArrayList<>();
list.add(std);
@@ -623,16 +606,17 @@ private static Map>> createMapICDSystemVersionU
/**
* Compares if two Private:COMPAS-ICDHeader have all attributes equal except IEDNane, BayLabel and IEDinstance
+ *
* @param iedPrivate Private of IED from STD to compare
* @param scdPrivate Private of LNode fro SCD to compare
* @return Boolean value of check result
* @throws ScdException throws when Private is not COMPAS_ICDHEADER one
*/
private static boolean comparePrivateCompasICDHeaders(TPrivate iedPrivate, TPrivate scdPrivate) throws ScdException {
- TCompasICDHeader iedCompasICDHeader = PrivateService.getCompasICDHeader(iedPrivate).orElseThrow(
- () -> new ScdException(COMPAS_ICDHEADER + "not found in IED Private "));
- TCompasICDHeader scdCompasICDHeader = PrivateService.getCompasICDHeader(scdPrivate).orElseThrow(
- () -> new ScdException(COMPAS_ICDHEADER + "not found in LNode Private "));
+ TCompasICDHeader iedCompasICDHeader = PrivateService.extractCompasICDHeader(iedPrivate)
+ .orElseThrow(() -> new ScdException(COMPAS_ICDHEADER + "not found in IED Private "));
+ TCompasICDHeader scdCompasICDHeader = PrivateService.extractCompasICDHeader(scdPrivate)
+ .orElseThrow(() -> new ScdException(COMPAS_ICDHEADER + "not found in LNode Private "));
return iedCompasICDHeader.getIEDType().equals(scdCompasICDHeader.getIEDType())
&& iedCompasICDHeader.getICDSystemVersionUUID().equals(scdCompasICDHeader.getICDSystemVersionUUID())
&& iedCompasICDHeader.getVendorName().equals(scdCompasICDHeader.getVendorName())
@@ -647,25 +631,27 @@ private static boolean comparePrivateCompasICDHeaders(TPrivate iedPrivate, TPriv
/**
* Copy Private COMPAS_ICDHEADER from LNode of SCD into Private COMPAS_ICDHEADER from IED of STD
- * @param stdPrivate Private of IED from STD in which to copy new data
+ *
+ * @param stdPrivate Private of IED from STD in which to copy new data
* @param lNodePrivate Private of IED from STD from which new data are taken
* @throws ScdException throws when Private is not COMPAS_ICDHEADER one
*/
private static void copyCompasICDHeaderFromLNodePrivateIntoSTDPrivate(TPrivate stdPrivate, TPrivate lNodePrivate) throws ScdException {
- TCompasICDHeader lNodeCompasICDHeader = PrivateService.getCompasICDHeader(lNodePrivate).orElseThrow(
- () -> new ScdException(COMPAS_ICDHEADER + " not found in LNode Private "));
+ TCompasICDHeader lNodeCompasICDHeader = PrivateService.extractCompasICDHeader(lNodePrivate)
+ .orElseThrow(() -> new ScdException(COMPAS_ICDHEADER + " not found in LNode Private "));
stdPrivate.getContent().clear();
stdPrivate.getContent().add(objectFactory.createICDHeader(lNodeCompasICDHeader));
}
/**
* Removes all ControlBlocks and DataSets for all LNs in SCL
+ *
* @param scl SCL file for which ControlBlocks and DataSets should be deleted
*/
public static void removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(final SCL scl) {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scl);
- List lDeviceAdapters = sclRootAdapter.getIEDAdapters().stream()
- .map(IEDAdapter::getLDeviceAdapters).flatMap(List::stream).collect(Collectors.toList());
+ List lDeviceAdapters = sclRootAdapter.streamIEDAdapters()
+ .flatMap(IEDAdapter::streamLDeviceAdapters).collect(Collectors.toList());
// LN0
lDeviceAdapters.stream()
@@ -681,8 +667,9 @@ 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
*/
@@ -690,18 +677,15 @@ public static SclReport updateLDeviceStatus(SCL scd) {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
SubstationAdapter substationAdapter = sclRootAdapter.getSubstationAdapter();
final List> iedNameLdInstList = substationAdapter.getIedAndLDeviceNamesForLN0FromLNode();
- List errors = sclRootAdapter.getIEDAdapters().stream()
- .map(IEDAdapter::getLDeviceAdapters)
- .flatMap(Collection::stream)
+ List errors = sclRootAdapter.streamIEDAdapters()
+ .flatMap(IEDAdapter::streamLDeviceAdapters)
.map(LDeviceAdapter::getLN0Adapter)
- .map(ln0Adapter -> ln0Adapter.checkAndUpdateLDeviceStatus(iedNameLdInstList))
- .reduce(new ArrayList<>(),(sclReportErrors, partialSclReportErrors) -> {
- sclReportErrors.addAll(partialSclReportErrors);
- return sclReportErrors;
- });
+ .map(ln0Adapter -> ln0Adapter.updateLDeviceStatus(iedNameLdInstList))
+ .flatMap(Optional::stream)
+ .collect(Collectors.toList());
SclReport sclReport = new SclReport();
- sclReport.getErrorDescriptionList().addAll(errors);
+ sclReport.getSclReportItems().addAll(errors);
sclReport.setSclRootAdapter(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 8316d957a..ab7cd032e 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
@@ -5,7 +5,6 @@
package org.lfenergy.compas.sct.commons.scl;
import lombok.NonNull;
-import lombok.extern.slf4j.Slf4j;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.scl2007b4.model.TBay;
import org.lfenergy.compas.scl2007b4.model.TSubstation;
@@ -31,7 +30,6 @@
* @see org.lfenergy.compas.sct.commons.scl.sstation.LNodeAdapter
* @see org.lfenergy.compas.sct.commons.scl.PrivateService
*/
-@Slf4j
public final class SubstationService {
/**
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 67428e237..0d4f4c91a 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
@@ -5,7 +5,6 @@
package org.lfenergy.compas.sct.commons.scl.dtt;
import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.lfenergy.compas.scl2007b4.model.TBDA;
import org.lfenergy.compas.scl2007b4.model.TDAType;
@@ -52,7 +51,6 @@
*
*
*/
-@Slf4j
public class DATypeAdapter extends AbstractDataTypeAdapter{
/**
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 a2e675e29..c2afb9ef7 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
@@ -4,7 +4,6 @@
package org.lfenergy.compas.sct.commons.scl.dtt;
-import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.dto.DaTypeName;
@@ -52,7 +51,6 @@
*
*
*/
-@Slf4j
public class DOTypeAdapter extends AbstractDataTypeAdapter {
/**
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 1138fa98e..09dc91098 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
@@ -67,6 +67,7 @@
* LDName = "name" attribute of IEDName element + "inst" attribute of LDevice element
* LNName = "prefix" + "lnClass" + "lnInst"
*
+ *
* @see org.lfenergy.compas.scl2007b4.model.TAnyLN
*/
@Getter
@@ -76,32 +77,37 @@ public abstract class AbstractLNAdapter extends SclElementAdap
/**
* Constructor
+ *
* @param parentAdapter Parent container reference
- * @param currentElem Current reference
+ * @param currentElem Current reference
*/
protected AbstractLNAdapter(LDeviceAdapter parentAdapter, T currentElem) {
super(parentAdapter, currentElem);
}
- public static LNAdapterBuilder builder(){
+
+ public static LNAdapterBuilder builder() {
return new LNAdapterBuilder();
}
protected abstract Class getElementClassType();
+
public abstract String getLNClass() ;
+
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 getEnumValues(String enumType) {
- Optional enumTypeAdapter = parentAdapter
- .getParentAdapter().getParentAdapter().getDataTypeTemplateAdapter()
+ Optional enumTypeAdapter = getDataTypeTemplateAdapter()
.getEnumTypeAdapterById(enumType);
- if(enumTypeAdapter.isEmpty()){
+ if (enumTypeAdapter.isEmpty()) {
return Collections.emptySet();
}
return enumTypeAdapter.get().getCurrentElem().getEnumVal()
@@ -111,23 +117,24 @@ public Set getEnumValues(String enumType) {
/**
* Add given ControlBlock to LNode
+ *
* @param controlBlock ControlBlock to add
* @throws ScdException throws when the ControlBlock type is unknown
*/
protected void addControlBlock(ControlBlock> controlBlock) throws ScdException {
- switch (controlBlock.getServiceType() ) {
+ switch (controlBlock.getServiceType()) {
case REPORT:
currentElem.getReportControl().add(controlBlock.createControlBlock());
break;
case GOOSE:
- if(isLN0()) {
- ((LN0)currentElem).getGSEControl().add(controlBlock.createControlBlock());
+ if (isLN0()) {
+ ((LN0) currentElem).getGSEControl().add(controlBlock.createControlBlock());
}
break;
case SMV:
- if(isLN0()) {
- ((LN0)currentElem).getSampledValueControl().add(controlBlock.createControlBlock());
+ if (isLN0()) {
+ ((LN0) currentElem).getSampledValueControl().add(controlBlock.createControlBlock());
}
break;
default:
@@ -136,46 +143,48 @@ protected void addControlBlock(ControlBlock> controlBlock) throws ScdException
}
}
- public Optional findDataSetByRef(String dataSetRef) {
+ public Optional findDataSetByRef(String dataSetRef) {
return currentElem.getDataSet()
.stream()
- .filter(tDataSet -> Objects.equals(tDataSet.getName(),dataSetRef))
+ .filter(tDataSet -> Objects.equals(tDataSet.getName(), dataSetRef))
.findFirst();
}
public DOIAdapter getDOIAdapterByName(String doiName) throws ScdException {
- String iedName = parentAdapter.getParentAdapter().getName();
+ String iedName = getCurrentIed().getName();
String ldInst = parentAdapter.getInst();
return currentElem.getDOI()
.stream()
.filter(tdoi -> tdoi.getName().equals(doiName))
.findFirst()
- .map(tdoi -> new DOIAdapter(this,tdoi))
+ .map(tdoi -> new DOIAdapter(this, tdoi))
.orElseThrow(
() -> new ScdException(
- String.format( "Unknown DOI(%s) in %s%s/%s%s%s",
+ String.format("Unknown DOI(%s) in %s%s/%s%s%s",
doiName, iedName, ldInst, getPrefix(), getLNClass(), getLNInst()
)
)
);
}
+
public List getDOIAdapters() {
return currentElem.getDOI()
.stream()
- .map(tdoi -> new DOIAdapter(this,tdoi))
+ .map(tdoi -> new DOIAdapter(this, tdoi))
.collect(Collectors.toList());
}
- boolean isLN0(){
+ boolean isLN0() {
return getElementClassType() == LN0.class;
}
- public String getLnType(){
+ public String getLnType() {
return currentElem.getLnType();
}
/**
* Gets all ExtRefs
+ *
* @return list of LNode ExtRefs elements
*/
public List getExtRefs() {
@@ -184,11 +193,12 @@ public List getExtRefs() {
/**
* Gets all ExtRefs matches specified ExtRef info
+ *
* @param filter ExtRef filter value
* @return list of TExtRef
*/
public List getExtRefs(ExtRefSignalInfo filter) {
- if(!hasInputs()){
+ if (!hasInputs()) {
return new ArrayList<>();
}
@@ -199,20 +209,25 @@ public List getExtRefs(ExtRefSignalInfo filter) {
.stream()
.filter(tExtRef ->
((filter.getDesc() == null && tExtRef.getDesc().isEmpty())
- || Objects.equals(filter.getDesc(),tExtRef.getDesc()) ) &&
- Objects.equals(filter.getPDO(),tExtRef.getPDO()) &&
- Objects.equals(filter.getPDA(),tExtRef.getPDA()) &&
- Objects.equals(filter.getIntAddr(),tExtRef.getIntAddr()) &&
- Objects.equals(filter.getPServT(),tExtRef.getPServT()))
+ || Objects.equals(filter.getDesc(), tExtRef.getDesc())) &&
+ Objects.equals(filter.getPDO(), tExtRef.getPDO()) &&
+ Objects.equals(filter.getPDA(), tExtRef.getPDA()) &&
+ Objects.equals(filter.getIntAddr(), tExtRef.getIntAddr()) &&
+ Objects.equals(filter.getPServT(), tExtRef.getPServT()))
.collect(Collectors.toList());
}
+ /**
+ * Check whether the LN has an Inputs node
+ * @return true if the LN has an Inputs node
+ */
public boolean hasInputs() {
- return currentElem.getInputs() != null;
+ return currentElem.isSetInputs();
}
/**
* Gets all ExtRefs matches specified ExtRef info without PDA attribute
+ *
* @param signalInfo ExtRef filter value
* @return list of TExtRef
*/
@@ -224,12 +239,12 @@ public List getExtRefsBySignalInfo(ExtRefSignalInfo signalInfo) {
if (signalInfo == null) {
return currentElem.getInputs().getExtRef();
}
- if(!signalInfo.isValid()){
+ if (!signalInfo.isValid()) {
throw new IllegalArgumentException("Invalid or missing attributes in ExtRef signal info");
}
return currentElem.getInputs().getExtRef()
.stream()
- .filter(tExtRef -> Objects.equals(signalInfo.getDesc(), tExtRef.getDesc()) &&
+ .filter(tExtRef -> Objects.equals(signalInfo.getDesc(), tExtRef.getDesc()) &&
Objects.equals(tExtRef.getPDO(), signalInfo.getPDO()) &&
Objects.equals(signalInfo.getIntAddr(), tExtRef.getIntAddr()) &&
Objects.equals(signalInfo.getPServT(), tExtRef.getPServT())
@@ -239,27 +254,28 @@ public List getExtRefsBySignalInfo(ExtRefSignalInfo signalInfo) {
/**
* Update LNode ExtRefs data with ExtRefInfo data
+ *
* @param extRefInfo contains new data for LNode ExtREf update
* @throws ScdException throws when mandatory data are missing
*/
public void updateExtRefBinders(ExtRefInfo extRefInfo) throws ScdException {
- if(extRefInfo.getBindingInfo() == null || !extRefInfo.getBindingInfo().isValid()){
- throw new ScdException("ExtRef mandatory binding data are missing");
+ if (extRefInfo.getBindingInfo() == null || !extRefInfo.getBindingInfo().isValid()) {
+ throw new ScdException("ExtRef mandatory binding data are missing");
}
String iedName = extRefInfo.getHolderIEDName();
String ldInst = extRefInfo.getHolderLDInst();
ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo();
List tExtRefs = this.getExtRefs(signalInfo);
- if(tExtRefs.isEmpty()){
+ if (tExtRefs.isEmpty()) {
String msg = String.format("Unknown ExtRef [pDO(%s),intAddr(%s)] in %s/%s.%s",
- signalInfo.getPDO(), signalInfo.getIntAddr(), iedName, ldInst,getLNClass());
+ signalInfo.getPDO(), signalInfo.getIntAddr(), iedName, ldInst, getLNClass());
throw new ScdException(msg);
}
- if(tExtRefs.size() != 1){
+ if (tExtRefs.size() != 1) {
log.warn("More the one desc for ExtRef [pDO({}),intAddr({})] in {}{}/{}",
- signalInfo.getPDO(), signalInfo.getIntAddr(), iedName, ldInst,getLNClass());
+ signalInfo.getPDO(), signalInfo.getIntAddr(), iedName, ldInst, getLNClass());
}
TExtRef extRef = tExtRefs.get(0);
// update ExtRef with binding info
@@ -268,31 +284,32 @@ public void updateExtRefBinders(ExtRefInfo extRefInfo) throws ScdException {
/**
* Updates ExtRef with data from ExtRefInfo
- * @param extRef ExtRef to update
+ *
+ * @param extRef ExtRef to update
* @param extRefInfo contains new data for LNode ExtREf update
*/
protected void updateExtRefBindingInfo(TExtRef extRef, ExtRefInfo extRefInfo) {
//update binding info
ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo();
boolean isSrcReset = false;
- if(bindingInfo != null && bindingInfo.isValid()){
+ if (bindingInfo != null && bindingInfo.isValid()) {
extRef.setIedName(bindingInfo.getIedName());
extRef.setLdInst(bindingInfo.getLdInst());
extRef.setLnInst(bindingInfo.getLnInst());
extRef.getLnClass().clear();
extRef.getLnClass().add(bindingInfo.getLnClass());
- if(bindingInfo.getServiceType() == null && extRefInfo.getSignalInfo() != null){
+ if (bindingInfo.getServiceType() == null && extRefInfo.getSignalInfo() != null) {
bindingInfo.setServiceType(extRefInfo.getSignalInfo().getPServT());
}
extRef.setServiceType(bindingInfo.getServiceType());
extRef.setDaName(null);
- if(bindingInfo.getDaName() != null && bindingInfo.getDaName().isDefined()) {
+ if (bindingInfo.getDaName() != null && bindingInfo.getDaName().isDefined()) {
extRef.setDaName(bindingInfo.getDaName().toString());
}
extRef.setDoName(null);
- if(bindingInfo.getDoName() != null && bindingInfo.getDoName().isDefined()) {
+ if (bindingInfo.getDoName() != null && bindingInfo.getDoName().isDefined()) {
extRef.setDoName(bindingInfo.getDoName().toString());
}
@@ -303,9 +320,9 @@ protected void updateExtRefBindingInfo(TExtRef extRef, ExtRefInfo extRefInfo) {
}
//
ExtRefSourceInfo sourceInfo = extRefInfo.getSourceInfo();
- if(sourceInfo != null && isSrcReset){
+ if (sourceInfo != null && isSrcReset) {
extRef.setSrcLNInst(sourceInfo.getSrcLNInst());
- if(sourceInfo.getSrcLNClass() != null) {
+ if (sourceInfo.getSrcLNClass() != null) {
extRef.getSrcLNClass().add(sourceInfo.getSrcLNClass());
}
extRef.setSrcLDInst(sourceInfo.getSrcLDInst());
@@ -316,17 +333,35 @@ protected void updateExtRefBindingInfo(TExtRef extRef, ExtRefInfo extRefInfo) {
/**
* Gets Control Blocks of LN specified in extRefInfo
+ *
* @param extRefInfo ExtRef signal data for which Control Blocks should be found
* @return list of ControlBlock object as ControlBlocks of LNode
*/
public List> getControlSetByExtRefInfo(ExtRefInfo extRefInfo) {
List tDataSets = this.getDataSet(extRefInfo);
+ return getControlBlocks(tDataSets, extRefInfo.getBindingInfo().getServiceType());
+ }
+ public List> getControlSet(ExtRefInfo extRefInfo) {
+ List tDataSets = this.getDataSetMatchingExtRefInfo(extRefInfo);
return getControlBlocks(tDataSets,extRefInfo.getBindingInfo().getServiceType());
}
+
+ /**
+ * Gets Control Blocks matching FCDA compatible with specified in extRefInfo
+ *
+ * @param extRefInfo ExtRef signal data for which Control Blocks should be found (contain binding info to match with FCDA)
+ * @return list of ControlBlock object as ControlBlocks of LNode matching FCDA and ExtRef
+ */
+ public List> getControlBlocksForMatchingFCDA(@NonNull ExtRefInfo extRefInfo) {
+ List tDataSets = this.getDataSetMatchingExtRefInfo(extRefInfo);
+ return getControlBlocks(tDataSets, extRefInfo.getBindingInfo().getServiceType());
+ }
+
/**
* Gets all Control Blocks from LNode for specified Service Type (GOOSE, SMV and REPORT) and Data Sets
- * @param tDataSets Data Sets for which Control Blocks are needed
+ *
+ * @param tDataSets Data Sets for which Control Blocks are needed
* @param serviceType Service Type of Control Blocks needed
* @return list of ControlBlock objects
*/
@@ -336,13 +371,13 @@ protected List> getControlBlocks(List tDataSets, TServ
LNodeMetaData metaData = LNodeMetaData.from(this);
- for(TDataSet tDataSet : tDataSets){
- if(isLN0() && (serviceType == null || serviceType == TServiceType.GOOSE)) {
- tControls = this.lookUpControlBlocksByDataSetRef(tDataSet.getName(),TGSEControl.class);
+ for (TDataSet tDataSet : tDataSets) {
+ if (isLN0() && (serviceType == null || serviceType == TServiceType.GOOSE)) {
+ tControls = this.lookUpControlBlocksByDataSetRef(tDataSet.getName(), TGSEControl.class);
controlBlocks.addAll(
tControls.stream()
.map(tgseControl -> {
- var g = new GooseControlBlock((TGSEControl)tgseControl);
+ var g = new GooseControlBlock((TGSEControl) tgseControl);
g.setMetaData(metaData);
return g;
})
@@ -350,9 +385,9 @@ protected List> getControlBlocks(List tDataSets, TServ
);
}
- if(isLN0() && (serviceType == null || serviceType == TServiceType.SMV)) {
+ if (isLN0() && (serviceType == null || serviceType == TServiceType.SMV)) {
- tControls = this.lookUpControlBlocksByDataSetRef(tDataSet.getName(),TSampledValueControl.class);
+ tControls = this.lookUpControlBlocksByDataSetRef(tDataSet.getName(), TSampledValueControl.class);
controlBlocks.addAll(
tControls.stream()
.map(sampledValueControl -> {
@@ -364,8 +399,8 @@ protected List> getControlBlocks(List tDataSets, TServ
);
}
- if(serviceType == null || serviceType == TServiceType.REPORT) {
- tControls = this.lookUpControlBlocksByDataSetRef(tDataSet.getName(),TReportControl.class);
+ if (serviceType == null || serviceType == TServiceType.REPORT) {
+ tControls = this.lookUpControlBlocksByDataSetRef(tDataSet.getName(), TReportControl.class);
controlBlocks.addAll(
tControls.stream()
.map(reportControl -> {
@@ -382,18 +417,19 @@ protected List> getControlBlocks(List tDataSets, TServ
/**
* Gets Control Blocks for specified Data Set reference
+ *
* @param dataSetRef Data Set for which Control Blocks are needed
- * @param cls class type of Control Block (GOOSE, SMV and REPORT)
+ * @param cls class type of Control Block (GOOSE, SMV and REPORT)
+ * @param inference type
* @return List of Control Blocks corresponding to cls
- * @param inference type
*/
- protected List extends TControl> lookUpControlBlocksByDataSetRef(@NonNull String dataSetRef, Class cls){
+ protected List extends TControl> lookUpControlBlocksByDataSetRef(@NonNull String dataSetRef, Class cls) {
List extends TControl> ls = new ArrayList<>();
if (TGSEControl.class.equals(cls) && isLN0()) {
ls = ((LN0) currentElem).getGSEControl();
- } else if(TSampledValueControl.class.equals(cls) && isLN0()){
- ls = ((LN0) currentElem).getSampledValueControl();
- } else if(TReportControl.class.equals(cls)){
+ } else if (TSampledValueControl.class.equals(cls) && isLN0()) {
+ ls = ((LN0) currentElem).getSampledValueControl();
+ } else if (TReportControl.class.equals(cls)) {
ls = currentElem.getReportControl();
}
@@ -405,39 +441,42 @@ protected List extends TControl> lookUpControlBlocksByDataSetRef(@NonNull
/**
* Checks if FCDA is null
+ *
* @param tfcda FCDA to check
* @return Boolean value of check result
*/
- public static boolean isNull(TFCDA tfcda){
+ //TODO check method should be checked, why nullability is checked only for this parameters
+ public static boolean isFCDANull(TFCDA tfcda){
return Objects.isNull(tfcda.getLdInst()) &&
tfcda.getLnClass().isEmpty() &&
- Objects.isNull(tfcda.getFc()) ;
+ Objects.isNull(tfcda.getFc());
}
/**
* Checks if specified Control Block is present in LNode
+ *
* @param controlBlock Control Block to check
* @return Boolean value of check result
*/
public boolean hasControlBlock(ControlBlock extends ControlBlock> controlBlock) {
- switch (controlBlock.getServiceType()){
+ switch (controlBlock.getServiceType()) {
case REPORT:
return currentElem.getReportControl().stream()
.anyMatch(control -> control.getName().equals(controlBlock.getName()));
case GOOSE:
- return isLN0() && ((LN0)currentElem).getGSEControl().stream()
+ return isLN0() && ((LN0) currentElem).getGSEControl().stream()
.anyMatch(control -> control.getName().equals(controlBlock.getName()));
case SMV:
- return isLN0() && ((LN0)currentElem).getSampledValueControl().stream()
+ return isLN0() && ((LN0) currentElem).getSampledValueControl().stream()
.anyMatch(reportControl -> reportControl.getName().equals(controlBlock.getName()));
default:
return false;
}
}
- public List getDataSet(ExtRefInfo filter){
+ public List getDataSet(ExtRefInfo filter) {
if (filter == null || filter.getSignalInfo() == null || filter.getBindingInfo() == null) {
return currentElem.getDataSet();
}
@@ -451,8 +490,24 @@ public List getDataSet(ExtRefInfo filter){
.collect(Collectors.toList());
}
+ /**
+ * retrieves all DataSets for which at least one FCDA mathches with data given in ExtRefInfo for external binding
+ * @param filter contains data for external binding which should match with FCDAs values
+ * @return list of Data for which at least one FCDA mathches with filter datas
+ */
+ public List getDataSetMatchingExtRefInfo(ExtRefInfo filter){
+ return currentElem.getDataSet()
+ .stream()
+ .filter(tDataSet -> tDataSet.getFCDA()
+ .stream()
+ .anyMatch(filter::checkMatchingFCDA)
+ )
+ .collect(Collectors.toList());
+ }
+
/**
* Updates ExtRef source binding data's based on given data in extRefInfo
+ *
* @param extRefInfo new data for ExtRef source binding data
* @return TExtRef object as update ExtRef with new source binding data
* @throws ScdException throws when mandatory data of ExtRef are missing
@@ -462,11 +517,12 @@ public TExtRef updateExtRefSource(ExtRefInfo extRefInfo) throws ScdException {
ExtRefSourceInfo sourceInfo = extRefInfo.getSourceInfo();
ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo();
- if(signalInfo == null || bindingInfo == null || sourceInfo == null){
+ if (signalInfo == null || bindingInfo == null || sourceInfo == null) {
throw new IllegalArgumentException("ExtRef information (signal, binding, source) are missing");
}
+
TExtRef extRef = checkExtRefInfoCoherence(extRefInfo);
- updateExtRefBindingInfo(extRef,extRefInfo);
+ updateExtRefBindingInfo(extRef, extRefInfo);
return extRef;
}
@@ -476,22 +532,22 @@ public TExtRef updateExtRefSource(ExtRefInfo extRefInfo) throws ScdException {
* This method look up the TExtRef that matches the signal info in this LNode. Then verify the coherence
* between the ExtRef's binding info and the given binding info. If the ExtRef info contains a source information (
* ControlBlock info),it verifies that the CB and dataset it points to, exists within and existing binder IED.
+ *
* @param extRefInfo ExtRef information (signal, binding and source info)
* @return TExtRef that matches the signal info
* @throws IllegalArgumentException when no given signal info
- * @throws ScdException throws exception if
- *
- * given signal info or it doesn't match any TExtRef in this LNode
- * the given binding info doesn't match the found TExtRef's binding info.
- * the given binding info doesn't refer to an exiting IED, LDevice and LNode in the SCL
- * given source info references unknown control block
- *
+ * @throws ScdException throws exception if
+ *
+ * given signal info or it doesn't match any TExtRef in this LNode
+ * the given binding info doesn't match the found TExtRef's binding info.
+ * the given binding info doesn't refer to an exiting IED, LDevice and LNode in the SCL
+ * given source info references unknown control block
+ *
*/
public TExtRef checkExtRefInfoCoherence(@NonNull ExtRefInfo extRefInfo) throws ScdException {
-
ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo();
ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo();
- if(signalInfo == null ) {
+ if (signalInfo == null) {
log.error("Coherence checking needs at least a signal info");
throw new IllegalArgumentException("Coherence checking needs at least a signal info");
}
@@ -499,20 +555,20 @@ public TExtRef checkExtRefInfoCoherence(@NonNull ExtRefInfo extRefInfo) throws S
String holderIedName = extRefInfo.getHolderIEDName(); // parent (IED) of parent (LD) can be used here
String holderLdInst = extRefInfo.getHolderLDInst(); // parent (LD) can be use here
List extRefs = getExtRefs(signalInfo);
- if(extRefs.isEmpty()){
+ if (extRefs.isEmpty()) {
String msg = String.format("Unknown TExtRef with signal info [pDO(%s),intAddr(%s)] in %s%s/%s%s%s",
signalInfo.getPDO(), signalInfo.getIntAddr(), holderIedName, holderLdInst,
- getPrefix(),getLNClass(),getLNInst());
+ getPrefix(), getLNClass(), getLNInst());
log.error(msg);
throw new ScdException(msg);
}
TExtRef extRef = extRefs.get(0); // to be refined : what's the criteria for ExtRef's uniqueness
- if(bindingInfo == null){
+ if (bindingInfo == null) {
return extRef;
}
- if(!bindingInfo.isWrappedIn(extRef)){
+ if (!bindingInfo.isWrappedIn(extRef)) {
String msg = "No relation between binding info and the matched TExtRef";
log.error(msg);
throw new ScdException(msg);
@@ -523,12 +579,12 @@ public TExtRef checkExtRefInfoCoherence(@NonNull ExtRefInfo extRefInfo) throws S
String binderLnClass = bindingInfo.getLnClass();
String binderLnInst = bindingInfo.getLnInst();
String binderLnPrefix = bindingInfo.getPrefix();
+
IEDAdapter binderIEDAdapter;
- if(!binderIedName.equals( parentAdapter.getParentAdapter().getName())){ // external binding
- SclRootAdapter sclRootAdapter = parentAdapter.getParentAdapter().getParentAdapter();
- binderIEDAdapter = sclRootAdapter.getIEDAdapterByName(binderIedName);
+ if(!binderIedName.equals( getCurrentIed().getName())){ // external binding
+ binderIEDAdapter = getCurrentScd().getIEDAdapterByName(binderIedName);
} else {
- binderIEDAdapter = parentAdapter.getParentAdapter();
+ binderIEDAdapter = getCurrentIed();
}
LDeviceAdapter binderLDAdapter = binderIEDAdapter.getLDeviceAdapterByLdInst(binderLdInst)
.orElseThrow(
@@ -543,13 +599,14 @@ public TExtRef checkExtRefInfoCoherence(@NonNull ExtRefInfo extRefInfo) throws S
.withLnPrefix(binderLnPrefix)
.build();
+ boolean isCoherent;
ExtRefSourceInfo sourceInfo = extRefInfo.getSourceInfo();
- if(sourceInfo == null || sourceInfo.isNull()) { // to be refined : what to do here functionally ?
+ if (sourceInfo == null || sourceInfo.isNull()) { // to be refined : what to do here functionally ?
return extRef;
}
List> cbs = anLNAdapter.getControlSetByExtRefInfo(extRefInfo);
- boolean isCoherent = !cbs.isEmpty() && cbs.stream()
+ isCoherent = !cbs.isEmpty() && cbs.stream()
.anyMatch(controlBlock -> controlBlock.getName().equals(sourceInfo.getSrcCBName()));
if(!isCoherent){
String msg = String.format("Unknown control block %s in %s%s/%s%s%s",
@@ -562,32 +619,33 @@ public TExtRef checkExtRefInfoCoherence(@NonNull ExtRefInfo extRefInfo) throws S
return extRef;
}
+
/**
* Returns a list of resumed DataTypeTemplate for DataAttribute (updatable or not)
- * @param rDtt reference resumed DataTypeTemplate (used as filter)
+ *
+ * @param rDtt reference resumed DataTypeTemplate (used as filter)
* @param updatableOnly true to retrieve DataTypeTemplate's related to only updatable DAI, false to retrieve all
* @return List of resumed DataTypeTemplate for DataAttribute (updatable or not)
* @throws ScdException SCD illegal arguments exception
*/
public List getDAI(ResumedDataTemplate rDtt, boolean updatableOnly) throws ScdException {
String lnType = currentElem.getLnType();
- if(!StringUtils.isBlank(rDtt.getLnType())){
+ if (!StringUtils.isBlank(rDtt.getLnType())) {
lnType = rDtt.getLnType();
}
// get resumedDTT from DataTypeTemplate (it might be overridden in the DAI)
- SclRootAdapter sclRootAdapter = parentAdapter.getParentAdapter().getParentAdapter();
- DataTypeTemplateAdapter dttAdapter = sclRootAdapter.getDataTypeTemplateAdapter();
+ DataTypeTemplateAdapter dttAdapter = getDataTypeTemplateAdapter();
LNodeTypeAdapter lNodeTypeAdapter = dttAdapter.getLNodeTypeAdapterById(lnType)
.orElseThrow(
() -> new ScdException(
- String.format("Corrupted SCD : lnType missing for LN : %s%s", getLNClass(),getLNInst())
+ String.format("Corrupted SCD : lnType missing for LN : %s%s", getLNClass(), getLNInst())
)
);
List resumedDTTs = lNodeTypeAdapter.getResumedDTTs(rDtt);
resumedDTTs.forEach(this::overrideAttributesFromDAI);
- if (updatableOnly){
+ if (updatableOnly) {
return resumedDTTs.stream().filter(ResumedDataTemplate::isUpdatable).collect(Collectors.toList());
} else {
return resumedDTTs;
@@ -596,6 +654,7 @@ public List getDAI(ResumedDataTemplate rDtt, boolean updata
/**
* Update given ResumedDataTemplate DAI datas from LNode
+ *
* @param rDtt summarized Data Type Template object to update DAI datas
*/
protected void overrideAttributesFromDAI(final ResumedDataTemplate rDtt) {
@@ -611,7 +670,7 @@ protected void overrideAttributesFromDAI(final ResumedDataTemplate rDtt) {
} else {
rDtt.setValImport(false);
log.warn("Inconsistency in the SCD file - DAI {} with fc={} must have a sGroup attribute",
- rDtt.getObjRef(getCurrentIED().getName(), parentAdapter.getInst()), rDtt.getDaName().getFc());
+ rDtt.getObjRef(getCurrentIed().getName(), parentAdapter.getInst()), rDtt.getDaName().getFc());
}
} else if (tdai.isSetValImport()) {
rDtt.setValImport(tdai.isValImport());
@@ -621,25 +680,44 @@ protected void overrideAttributesFromDAI(final ResumedDataTemplate rDtt) {
/**
* Checks if linked IED as parent has Setting Group set
+ *
* @return Boolean value of check result
*/
private boolean iedHasConfSG() {
- IEDAdapter iedAdapter = getCurrentIED();
+ IEDAdapter iedAdapter = getCurrentIed();
return iedAdapter.isSettingConfig(this.parentAdapter.getInst());
}
/**
* Gets linked IED as parent
+ *
* @return IEDAdapter object
*/
- private IEDAdapter getCurrentIED() {
+ private IEDAdapter getCurrentIed() {
LDeviceAdapter lDeviceAdapter = this.parentAdapter;
return lDeviceAdapter.getParentAdapter();
}
+ /**
+ * Gets root Scd
+ * @return SclRootAdapter object
+ */
+ protected SclRootAdapter getCurrentScd() {
+ return getCurrentIed().getParentAdapter();
+ }
+
+ /**
+ * Gets SCL DataTypeTemplate
+ * @return DataTypeTemplateAdapter object
+ */
+ public DataTypeTemplateAdapter getDataTypeTemplateAdapter() {
+ return getCurrentScd().getDataTypeTemplateAdapter();
+ }
+
/**
* Checks fro DAI if Setting Group value is set correctly
+ *
* @param tdai DAI for which check is done
* @return Boolean value of check result
*/
@@ -650,14 +728,15 @@ private boolean hasSgGroup(TDAI tdai) {
/**
* Search for DAI that match the given defined-DO (do.sdo1[.sdo2 ...sdo_n]) and defined-DA (da.bda1[.bda2...bda_n])
* where 'sdo_n' points to a DOType that contains 'da'
+ *
* @param doTypeName defined-DO (do.sdo1[.sdo2 ...sdo_n])
* @param daTypeName defined-DA (da.bda1[.bda2...bda_n])
* @return Optional of DAIAdapter for the matched DAI
*/
- protected Optional findMatch(DoTypeName doTypeName, DaTypeName daTypeName){
- DAITracker daiTracker = new DAITracker(this,doTypeName,daTypeName);
+ protected Optional findMatch(DoTypeName doTypeName, DaTypeName daTypeName) {
+ DAITracker daiTracker = new DAITracker(this, doTypeName, daTypeName);
DAITracker.MatchResult matchResult = daiTracker.search();
- if(matchResult != DAITracker.MatchResult.FULL_MATCH){
+ if (matchResult != DAITracker.MatchResult.FULL_MATCH) {
return Optional.empty();
}
return Optional.of(daiTracker.getBdaiOrDaiAdapter());
@@ -667,35 +746,36 @@ protected Optional findMatch(DoTypeName doTypeName, DaTypeName daT
* Updates DAI (in LNode section) after checking updatability with summarized Data Type Template given information and LNode
* Summarized Data Type Temple and LNode helps to check updatability. rDtt gives DAI which should be found in LNode,
* that LNode gives LNodeType localized in DataTypeTemplate section and contains DOType in which the DAI is localized.
+ *
* @param rDtt summarized Data Type Temple containing new DO and DA data's
* @throws ScdException when inconsistency are found in th SCL's
- * DataTypeTemplate. Which should normally not happens.
+ * DataTypeTemplate. Which should normally not happens.
*/
public void updateDAI(@NonNull ResumedDataTemplate rDtt) throws ScdException {
- if(!rDtt.isDoNameDefined() || !rDtt.isDaNameDefined()){
+ if (!rDtt.isDoNameDefined() || !rDtt.isDaNameDefined()) {
throw new ScdException("Cannot update undefined DAI");
}
DoTypeName doTypeName = rDtt.getDoName();
DaTypeName daTypeName = rDtt.getDaName();
- DAITracker daiTracker = new DAITracker(this,doTypeName,daTypeName);
+ DAITracker daiTracker = new DAITracker(this, doTypeName, daTypeName);
DAITracker.MatchResult matchResult = daiTracker.search();
AbstractDAIAdapter> daiAdapter = null;
IDataParentAdapter doiOrSdoiAdapter;
- if(matchResult == DAITracker.MatchResult.FULL_MATCH){
+ if (matchResult == DAITracker.MatchResult.FULL_MATCH) {
// update
daiAdapter = (AbstractDAIAdapter) daiTracker.getBdaiOrDaiAdapter();
- if((daiAdapter.isValImport() != null && daiAdapter.isValImport()) ||
- (daiAdapter.isValImport() == null && rDtt.isUpdatable()) ) {
+ if ((daiAdapter.isValImport() != null && daiAdapter.isValImport()) ||
+ (daiAdapter.isValImport() == null && rDtt.isUpdatable())) {
daiAdapter.update(daTypeName.getDaiValues());
return;
- } else{
- throw new ScdException(String.format("DAI (%s -%s) cannot be updated",doTypeName,daTypeName));
+ } else {
+ throw new ScdException(String.format("DAI (%s -%s) cannot be updated", doTypeName, daTypeName));
}
}
- if(rDtt.isUpdatable()) {
+ if (rDtt.isUpdatable()) {
doiOrSdoiAdapter = daiTracker.getDoiOrSdoiAdapter();
int idx = daiTracker.getIndexDoType();
int doSz = doTypeName.getStructNames().size();
@@ -715,23 +795,23 @@ public void updateDAI(@NonNull ResumedDataTemplate rDtt) throws ScdException {
IDataParentAdapter daiOrBdaiAdapter = daiTracker.getDoiOrSdoiAdapter();
idx = daiTracker.getIndexDaType();
int daSz = daTypeName.getStructNames().size();
- if(idx <= -1 ){
+ if (idx <= -1) {
idx = 0;
- } else if(idx == daSz - 1){
+ } else if (idx == daSz - 1) {
idx = daSz;
}
- for(int i = idx; i < daSz; ++i){
+ for (int i = idx; i < daSz; ++i) {
String bdaName = daTypeName.getStructNames().get(i);
- if(idx == 0){
+ if (idx == 0) {
daiOrBdaiAdapter = doiOrSdoiAdapter.addSDOI(daTypeName.getName());
- } else if(i == daSz -1){
+ } else if (i == daSz - 1) {
daiAdapter = daiOrBdaiAdapter.addDAI(bdaName, rDtt.isUpdatable());
} else {
daiOrBdaiAdapter = daiOrBdaiAdapter.addSDOI(bdaName);
}
}
- if(daiAdapter == null){
- daiAdapter = doiOrSdoiAdapter.addDAI(daTypeName.getName(),rDtt.isUpdatable());
+ if (daiAdapter == null) {
+ daiAdapter = doiOrSdoiAdapter.addDAI(daTypeName.getName(), rDtt.isUpdatable());
}
daiAdapter.update(daTypeName.getDaiValues());
@@ -740,6 +820,7 @@ public void updateDAI(@NonNull ResumedDataTemplate rDtt) throws ScdException {
/**
* Adds DO in LNode
+ *
* @param name DOI name
* @return added DOIAdapter object
*/
@@ -748,13 +829,13 @@ protected DOIAdapter addDOI(String name) {
tdoi.setName(name);
currentElem.getDOI().add(tdoi);
- return new DOIAdapter(this,tdoi);
+ return new DOIAdapter(this, tdoi);
}
public String getLNodeName() {
StringBuilder stringBuilder = new StringBuilder();
- if(TLLN0Enum.LLN_0.value().equals(getLNClass())){
+ if (TLLN0Enum.LLN_0.value().equals(getLNClass())) {
stringBuilder.append(TLLN0Enum.LLN_0.value());
} else {
stringBuilder.append(getPrefix())
@@ -767,13 +848,13 @@ public String getLNodeName() {
/**
* Checks given reference matches with DataSet or ReportControl or DataTypeTemplate element for calling LNode
* in SCL file
+ *
* @param objRef reference to compare with LNode datas
* @return Boolean value of check result
*/
public boolean matches(ObjectReference objRef) {
String dataAttribute = objRef.getDataAttributes();
- SclRootAdapter sclRootAdapter = parentAdapter.getParentAdapter().getParentAdapter();
- DataTypeTemplateAdapter dttAdapter = sclRootAdapter.getDataTypeTemplateAdapter();
+ DataTypeTemplateAdapter dttAdapter = getDataTypeTemplateAdapter();
LNodeTypeAdapter lNodeTypeAdapter = dttAdapter.getLNodeTypeAdapterById(getLnType())
.orElseThrow(
() -> new AssertionError(
@@ -792,16 +873,18 @@ public boolean matches(ObjectReference objRef) {
/**
* Checks if given attibrute corresponds to DataSet or ReportControl in LNode
+ *
* @param dataAttribute attribute to check
* @return Boolean value of check result
*/
- protected boolean matchesDataAttributes(String dataAttribute){
- return currentElem.getDataSet().stream().anyMatch(tDataSet -> tDataSet.getName().equals(dataAttribute)) ||
+ protected boolean matchesDataAttributes(String dataAttribute) {
+ return currentElem.getDataSet().stream().anyMatch(tDataSet -> tDataSet.getName().equals(dataAttribute)) ||
currentElem.getReportControl().stream().anyMatch(rptCtl -> rptCtl.getName().equals(dataAttribute));
}
/**
* Gets Data Set in LNode by its name
+ *
* @param dataSetRef Data Set name
* @return optional of DataSetInfo
*/
@@ -815,6 +898,7 @@ public Optional getDataSetByRef(String dataSetRef) {
/**
* Adds Data Set to LNode Data Sets
+ *
* @param dataSetInfo data's of Data Set to add
*/
public void addDataSet(DataSetInfo dataSetInfo) {
@@ -827,33 +911,30 @@ public void addDataSet(DataSetInfo dataSetInfo) {
}
- public DataTypeTemplateAdapter getDataTypeTemplateAdapter() {
- return parentAdapter.getParentAdapter().getParentAdapter().getDataTypeTemplateAdapter();
- }
-
/**
* Gets DAI values for specified DA in summaraized Data Type Template
+ *
* @param rDtt summaraized Data Type Template containing DA datas
* @return map of Setting Group and it's VAL
*/
public Map getDAIValues(ResumedDataTemplate rDtt) {
- DAITracker daiTracker = new DAITracker(this,rDtt.getDoName(),rDtt.getDaName());
+ DAITracker daiTracker = new DAITracker(this, rDtt.getDoName(), rDtt.getDaName());
DAITracker.MatchResult matchResult = daiTracker.search();
- if(matchResult != DAITracker.MatchResult.FULL_MATCH){
+ if (matchResult != DAITracker.MatchResult.FULL_MATCH) {
return new HashMap<>();
}
List tVals;
IDataAdapter daiAdapter = daiTracker.getBdaiOrDaiAdapter();
- if(daiAdapter.getClass().equals(SDIAdapter.DAIAdapter.class)){
- tVals = ((RootSDIAdapter.DAIAdapter)daiAdapter).getCurrentElem().getVal();
- } else if(daiAdapter.getClass().equals(RootSDIAdapter.DAIAdapter.class)){
- tVals = ((RootSDIAdapter.DAIAdapter)daiAdapter).getCurrentElem().getVal();
+ if (daiAdapter.getClass().equals(SDIAdapter.DAIAdapter.class)) {
+ tVals = ((RootSDIAdapter.DAIAdapter) daiAdapter).getCurrentElem().getVal();
+ } else if (daiAdapter.getClass().equals(RootSDIAdapter.DAIAdapter.class)) {
+ tVals = ((RootSDIAdapter.DAIAdapter) daiAdapter).getCurrentElem().getVal();
} else {
- tVals = ((DOIAdapter.DAIAdapter)daiAdapter).getCurrentElem().getVal();
+ tVals = ((DOIAdapter.DAIAdapter) daiAdapter).getCurrentElem().getVal();
}
- Map res = new HashMap<>();
- tVals.forEach( tVal -> res.put(
+ Map res = new HashMap<>();
+ tVals.forEach(tVal -> res.put(
tVal.isSetSGroup() ? tVal.getSGroup() : 0L, tVal.getValue())
);
@@ -878,9 +959,10 @@ public void removeAllExtRefSourceBindings() {
/**
* Removes specified ExtRef Source binding data's
+ *
* @param tExtRef ExtRef Source for which binding data's should be removed
*/
- private void removeExtRefSourceBinding(final TExtRef tExtRef){
+ private void removeExtRefSourceBinding(final TExtRef tExtRef) {
tExtRef.setSrcCBName(null);
tExtRef.setSrcLDInst(null);
tExtRef.setSrcPrefix(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 fd84454af..7985aa0bc 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
@@ -5,7 +5,7 @@
package org.lfenergy.compas.sct.commons.scl.ied;
import lombok.NonNull;
-import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.dto.ControlBlock;
import org.lfenergy.compas.sct.commons.dto.DataSetInfo;
@@ -17,8 +17,12 @@
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
import org.lfenergy.compas.sct.commons.util.Utils;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* A representation of the model object
@@ -29,7 +33,7 @@
*
* Adapter
*
- * {@link IEDAdapter#getLDeviceAdapters Returns the value of the LDeviceAdapter containment reference list }
+ * {@link IEDAdapter#streamLDeviceAdapters LDeviceAdapters Returns the value of the LDeviceAdapter containment reference list }
* {@link IEDAdapter#getLDeviceAdapterByLdInst Returns the value of the LDeviceAdapter reference object By LDevice Inst }
*
* Principal functions
@@ -56,7 +60,6 @@
* @see org.lfenergy.compas.scl2007b4.model.TSettingGroups
* @see Issue !3 (Add new IEDs)
*/
-@Slf4j
public class IEDAdapter extends SclElementAdapter {
/**
@@ -114,17 +117,28 @@ public void setIEDName(String iedName) {
}
/**
- * Gets all LDevices linked to current IED
- * @return list of LDeviceAdapter
+ * Gets All LDevice from current IED as LDeviceAdapter
+ * @return Stream of LDeviceAdapter object
*/
- public List getLDeviceAdapters(){
- return currentElem.getAccessPoint()
- .stream()
- .filter(tAccessPoint -> tAccessPoint.getServer() != null)
- .map(tAccessPoint -> tAccessPoint.getServer().getLDevice())
- .flatMap(Collection::stream)
- .map(tlDevice -> new LDeviceAdapter(this,tlDevice))
- .collect(Collectors.toList());
+ public Stream streamLDeviceAdapters() {
+ return streamLDevices()
+ .map(tlDevice -> new LDeviceAdapter(this, tlDevice));
+ }
+
+ /**
+ * Gets All LDevice from current IED
+ * @return Stream of TLDevice object
+ */
+ private Stream streamLDevices() {
+ if (!currentElem.isSetAccessPoint()){
+ return Stream.empty();
+ }
+ return currentElem.getAccessPoint().stream()
+ .map(TAccessPoint::getServer)
+ .filter(Objects::nonNull)
+ .filter(TServer::isSetLDevice)
+ .map(TServer::getLDevice)
+ .flatMap(List::stream);
}
/**
@@ -132,15 +146,11 @@ public List getLDeviceAdapters(){
* @param ldInst ldInst value of LDevice to get
* @return optional of LDeviceAdapter object
*/
- public Optional getLDeviceAdapterByLdInst(String ldInst){
- return currentElem.getAccessPoint()
- .stream()
- .filter(tAccessPoint -> tAccessPoint.getServer() != null)
- .map(tAccessPoint -> tAccessPoint.getServer().getLDevice())
- .flatMap(Collection::stream)
- .filter(tlDevice -> Objects.equals(ldInst,tlDevice.getInst()))
- .map(tlDevice -> new LDeviceAdapter(this,tlDevice))
- .findFirst();
+ public Optional getLDeviceAdapterByLdInst(String ldInst) {
+ return streamLDevices()
+ .filter(tlDevice -> Utils.equalsOrBothBlank(tlDevice.getInst(), ldInst))
+ .findFirst()
+ .map(tlDevice -> new LDeviceAdapter(this, tlDevice));
}
/**
@@ -152,22 +162,20 @@ public Optional getLDeviceAdapterByLdInst(String ldInst){
*/
public void updateLDeviceNodesType(Map pairOldNewId) throws ScdException {
// renaming ldName
- for(LDeviceAdapter lDeviceAdapter : getLDeviceAdapters()) {
+ streamLDeviceAdapters().forEach(lDeviceAdapter -> {
lDeviceAdapter.updateLDName();
String lnType = lDeviceAdapter.getCurrentElem().getLN0().getLnType();
- if(pairOldNewId.containsKey(lnType)){
+ if (pairOldNewId.containsKey(lnType)) {
lDeviceAdapter.getCurrentElem().getLN0().setLnType(pairOldNewId.get(lnType));
}
lDeviceAdapter.getCurrentElem()
- .getLN()
- .stream()
- .forEach(tln -> {
- if(pairOldNewId.containsKey(tln.getLnType())) {
- tln.setLnType(pairOldNewId.get(tln.getLnType()));
- }
- });
-
- }
+ .getLN()
+ .forEach(tln -> {
+ if (pairOldNewId.containsKey(tln.getLnType())) {
+ tln.setLnType(pairOldNewId.get(tln.getLnType()));
+ }
+ });
+ });
}
/**
@@ -193,20 +201,16 @@ public String getName(){
* @return Boolean value of check result
*/
public boolean matches(ObjectReference objRef){
- if(!objRef.getLdName().startsWith(getName())) {
+ if (StringUtils.isBlank(getName())
+ || !objRef.getLdName().startsWith(getName())) {
return false;
}
- Optional opLD = currentElem.getAccessPoint()
- .stream()
- .filter(tAccessPoint -> tAccessPoint.getServer() != null)
- .map(tAccessPoint -> tAccessPoint.getServer().getLDevice())
- .flatMap(Collection::stream)
- .filter(tlDevice -> objRef.getLdName().equals(getName() + tlDevice.getInst()))
- .findFirst();
+ String ldInst = objRef.getLdName().substring(getName().length());
+ Optional opLD = getLDeviceAdapterByLdInst(ldInst);
if(opLD.isEmpty()) {
return false;
}
- LDeviceAdapter lDeviceAdapter = new LDeviceAdapter(this,opLD.get());
+ LDeviceAdapter lDeviceAdapter = opLD.get();
if(TLLN0Enum.LLN_0.value().equals(objRef.getLNodeName())) {
return lDeviceAdapter.getLN0Adapter().matches(objRef);
}
@@ -238,12 +242,9 @@ public List getExtRefBinders(@NonNull ExtRefSignalInfo signal
if(!signalInfo.isValid()){
throw new ScdException("Invalid ExtRef signal (pDO,pDA or intAddr))");
}
- List potentialBinders = new ArrayList<>();
- List lDeviceAdapters = getLDeviceAdapters();
- for (LDeviceAdapter lDeviceAdapter : lDeviceAdapters) {
- potentialBinders.addAll(lDeviceAdapter.getExtRefBinders(signalInfo));
- }
- return potentialBinders;
+ return streamLDeviceAdapters()
+ .map(lDeviceAdapter -> lDeviceAdapter.getExtRefBinders(signalInfo)).flatMap(List::stream)
+ .collect(Collectors.toList());
}
/**
@@ -350,7 +351,7 @@ public ControlBlock extends ControlBlock> createControlBlock(ControlBlock ex
controlBlock.validateSecurityEnabledValue(this);
controlBlock.validateDestination(this.parentAdapter);
- LDeviceAdapter lDeviceAdapter =getLDeviceAdapterByLdInst(controlBlock.getHolderLDInst()).orElseThrow();
+ LDeviceAdapter lDeviceAdapter = getLDeviceAdapterByLdInst(controlBlock.getHolderLDInst()).orElseThrow();
AbstractLNAdapter> lnAdapter = AbstractLNAdapter.builder()
.withLDeviceAdapter(lDeviceAdapter)
.withLnClass(controlBlock.getHolderLnClass())
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapter.java
new file mode 100644
index 000000000..8cb5f1a43
--- /dev/null
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapter.java
@@ -0,0 +1,244 @@
+// SPDX-FileCopyrightText: 2021 RTE FRANCE
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package org.lfenergy.compas.sct.commons.scl.ied;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.lfenergy.compas.scl2007b4.model.*;
+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 org.lfenergy.compas.sct.commons.dto.SclReportItem;
+import org.lfenergy.compas.sct.commons.scl.PrivateService;
+import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
+import org.lfenergy.compas.sct.commons.util.Utils;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.lfenergy.compas.sct.commons.util.LDeviceStatus.OFF;
+import static org.lfenergy.compas.sct.commons.util.LDeviceStatus.ON;
+
+/**
+ * A representation of the model object
+ * {@link InputsAdapter InputsAdapter} .
+ *
+ * @See TInputs
+ * @See TExtRef
+ * @see LN0Adapter
+ * @see AbstractLNAdapter
+ */
+@Slf4j
+public class InputsAdapter extends SclElementAdapter {
+
+ public static final String MESSAGE_NO_MATCHING_COMPAS_FLOW = "The signal ExtRef has no matching compas:Flow Private";
+ public static final String MESSAGE_TOO_MANY_MATCHING_COMPAS_FLOWS = "The signal ExtRef has more than one matching compas:Flow Private";
+
+ /**
+ * Constructor
+ *
+ * @param parentAdapter Parent container reference
+ * @param tInputs Current reference
+ */
+ public InputsAdapter(LN0Adapter parentAdapter, TInputs tInputs) {
+ super(parentAdapter, tInputs);
+ }
+
+ /**
+ * Check if current element is a child of the parent element
+ *
+ * @return true if the currentElem is part of the parentAdapter children
+ */
+ @Override
+ protected boolean amChildElementRef() {
+ return currentElem == parentAdapter.getCurrentElem().getInputs();
+ }
+
+ @Override
+ protected String elementXPath() {
+ return "Inputs";
+ }
+
+ /**
+ * Update iedName of all ExtRefs in this "Inputs" element.
+ *
+ * @return list of encountered errors
+ */
+ public List updateAllExtRefIedNames(Map icdSystemVersionToIed) {
+ Optional optionalLDeviceStatus = getLDeviceAdapter().getLDeviceStatus();
+ if (optionalLDeviceStatus.isEmpty()) {
+ return List.of(getLDeviceAdapter().buildFatalReportItem("The LDevice status is undefined"));
+ }
+ String lDeviceStatus = optionalLDeviceStatus.get();
+ switch (lDeviceStatus) {
+ case ON:
+ List compasFlows = PrivateService.extractCompasPrivates(currentElem, TCompasFlow.class);
+ return getExtRefs().stream()
+ .filter(tExtRef -> StringUtils.isNotBlank(tExtRef.getIedName()) && StringUtils.isNotBlank(tExtRef.getDesc()))
+ .map(extRef ->
+ updateExtRefIedName(extRef, compasFlows, icdSystemVersionToIed.get(extRef.getIedName())))
+ .flatMap(Optional::stream)
+ .collect(Collectors.toList());
+ case OFF:
+ getExtRefs().forEach(this::clearBinding);
+ return Collections.emptyList();
+ default:
+ return List.of(getLDeviceAdapter()
+ .buildFatalReportItem("The LDevice status is neither \"on\" nor \"off\""));
+ }
+ }
+
+ /**
+ * Find matching CompasFlow private and set ExtRef iedName accordingly
+ *
+ * @param extRef extRef whose iedName will be updated
+ * @param allCompasFlows list of all CompasFlow private in this Inputs
+ * @return Error if ExtRef could not be updated
+ */
+ private Optional updateExtRefIedName(TExtRef extRef, final List allCompasFlows, IEDAdapter sourceIed) {
+ List matchingCompasFlows = getMatchingCompasFlows(extRef, allCompasFlows);
+ if (!singleMatch(matchingCompasFlows)) {
+ return fatalReportItem(extRef,
+ matchingCompasFlows.isEmpty() ? MESSAGE_NO_MATCHING_COMPAS_FLOW : MESSAGE_TOO_MANY_MATCHING_COMPAS_FLOWS);
+ }
+ TCompasFlow compasFlow = matchingCompasFlows.get(0);
+ if (compasFlow.getFlowStatus() == TCompasFlowStatus.INACTIVE) {
+ clearBinding(extRef);
+ return Optional.empty();
+ }
+ Optional sourceValidationError = validateExtRefSource(extRef, sourceIed);
+ if (sourceValidationError.isPresent()) {
+ clearBinding(extRef);
+ return sourceValidationError;
+ }
+ String sourceIedName = PrivateService.extractCompasPrivate(sourceIed.getCurrentElem(), TCompasICDHeader.class)
+ .map(TCompasICDHeader::getIEDName).orElse("");
+ extRef.setIedName(sourceIedName);
+ compasFlow.setExtRefiedName(sourceIedName);
+ log.debug(String.format("extRef.desc=%s, iedName=%s%n", extRef.getDesc(), sourceIedName));
+ return Optional.empty();
+ }
+
+ /**
+ * List all ExtRefs in this Inputs
+ *
+ * @return list of ExtRefs. List is modifiable.
+ */
+ private List getExtRefs() {
+ if (!currentElem.isSetExtRef()) {
+ return Collections.emptyList();
+ }
+ return currentElem.getExtRef();
+ }
+
+ private Optional validateExtRefSource(TExtRef extRef, IEDAdapter sourceIed) {
+ if (sourceIed == null) {
+ return warningReportItem(extRef, "The signal ExtRef iedName does not match any " +
+ "IED/Private/compas:ICDHeader@ICDSystemVersionUUID");
+ }
+ Optional optionalSourceLDevice = sourceIed.getLDeviceAdapterByLdInst(extRef.getLdInst());
+ if (optionalSourceLDevice.isEmpty()) {
+ return warningReportItem(extRef, String.format("The signal ExtRef ExtRefldinst does not match any " +
+ "LDevice with same inst attribute in source IED %s", sourceIed.getXPath()));
+ }
+ LDeviceAdapter sourceLDevice = optionalSourceLDevice.get();
+ if (!hasMatchingLN(extRef, sourceLDevice)) {
+ return warningReportItem(extRef, String.format("The signal ExtRef ExtRefldinst does not match any " +
+ "LDevice with same inst attribute in source IED %s", sourceIed.getXPath()));
+ }
+ Optional optionalLDeviceStatus = sourceLDevice.getLDeviceStatus();
+ if (optionalLDeviceStatus.isEmpty()) {
+ return fatalReportItem(extRef, String.format("The signal ExtRef source LDevice %s status is undefined",
+ sourceLDevice.getXPath()));
+
+ } else if (OFF.equals(optionalLDeviceStatus.get())) {
+ return warningReportItem(extRef, String.format("The signal ExtRef source LDevice %s status is off",
+ sourceLDevice.getXPath()));
+ }
+ return Optional.empty();
+ }
+
+ private boolean hasMatchingLN(TExtRef extRef, LDeviceAdapter lDeviceAdapter) {
+ String extRefLnClass = extRef.getLnClass().stream().findFirst().orElse("");
+ ResumedDataTemplate filter = ResumedDataTemplate.builder()
+ .lnClass(extRefLnClass)
+ .prefix(extRef.getPrefix())
+ .lnInst(extRef.getLnInst())
+ .doName(new DoTypeName(extRef.getDoName()))
+ .daName(new DaTypeName(extRef.getDaName()))
+ .build();
+ return !lDeviceAdapter.getDAI(filter, false).isEmpty();
+ }
+
+ private boolean singleMatch(List matchingCompasFlows) {
+ return matchingCompasFlows.size() == 1;
+ }
+
+ private void clearBinding(TExtRef extRef) {
+ extRef.setIedName(null);
+ extRef.setLdInst(null);
+ extRef.setPrefix(null);
+ extRef.setLnInst(null);
+ extRef.setDoName(null);
+ extRef.setDaName(null);
+ extRef.setServiceType(null);
+ extRef.setSrcLDInst(null);
+ extRef.setSrcPrefix(null);
+ extRef.setSrcLNInst(null);
+ extRef.setSrcCBName(null);
+ extRef.unsetLnClass();
+ extRef.unsetSrcLNClass();
+ }
+
+ private Optional warningReportItem(TExtRef extRef, String message) {
+ return Optional.of(SclReportItem.warning(extRefXPath(extRef.getDesc()), message));
+ }
+
+ private Optional fatalReportItem(TExtRef extRef, String message) {
+ return Optional.of(SclReportItem.fatal(extRefXPath(extRef.getDesc()), message));
+ }
+
+ private String extRefXPath(String extRefDesc) {
+ return getXPath() + String.format("/ExtRef[%s]",
+ Utils.xpathAttributeFilter("desc", extRefDesc));
+ }
+
+ /**
+ * Find CompasFlows that match given ExtRef
+ *
+ * @param extRef extRef to match
+ * @param compasFlows list of all CompasFlow in which to search
+ * @return list of matching CompasFlows
+ */
+ private List getMatchingCompasFlows(TExtRef extRef, List compasFlows) {
+ return compasFlows.stream().filter(compasFlow -> isMatchingExtRef(compasFlow, extRef)).collect(Collectors.toList());
+ }
+
+ /**
+ * Check if extRef matches CompasFlow
+ *
+ * @param compasFlow compasFlow
+ * @param extRef extRef
+ * @return true if all required attributes matches. Note that empty string, whitespaces only string and null values are considered as matching
+ * (missing attributes matches attribute with empty string value or whitespaces only). Return false otherwise.
+ */
+ private boolean isMatchingExtRef(TCompasFlow compasFlow, TExtRef extRef) {
+ String extRefLnClass = extRef.isSetLnClass() ? extRef.getLnClass().get(0) : null;
+ return Utils.equalsOrBothBlank(compasFlow.getDataStreamKey(), extRef.getDesc())
+ && Utils.equalsOrBothBlank(compasFlow.getExtRefiedName(), extRef.getIedName())
+ && Utils.equalsOrBothBlank(compasFlow.getExtRefldinst(), extRef.getLdInst())
+ && Utils.equalsOrBothBlank(compasFlow.getExtRefprefix(), extRef.getPrefix())
+ && Utils.equalsOrBothBlank(compasFlow.getExtReflnClass(), extRefLnClass)
+ && Utils.equalsOrBothBlank(compasFlow.getExtReflnInst(), extRef.getLnInst());
+ }
+
+ private LDeviceAdapter getLDeviceAdapter() {
+ return parentAdapter.getParentAdapter();
+ }
+}
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 a037accc3..6fa771a32 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
@@ -7,9 +7,10 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
+import org.lfenergy.compas.scl2007b4.model.TAccessPoint;
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.scl2007b4.model.TServer;
import org.lfenergy.compas.sct.commons.dto.*;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
@@ -28,7 +29,7 @@
*
* Adapter
*
- * {@link LDeviceAdapter#getLNAdapters Returns the value of the LNAdapter containment reference list }
+ * {@link LDeviceAdapter#streamLnAdapters Returns the value of the LNAdapter containment reference list }
* {@link LDeviceAdapter#getLN0Adapter Returns the value of the LN0Adapter containment reference list }
* {@link LDeviceAdapter#getLNAdapter Returns the value of the LNAdapter reference object By LNClass, inst and prefix }
*
@@ -70,8 +71,10 @@ public LDeviceAdapter(IEDAdapter parentAdapter, TLDevice currentElem) {
protected boolean amChildElementRef() {
return parentAdapter.getCurrentElem().getAccessPoint()
.stream()
- .filter(tAccessPoint -> tAccessPoint.getServer() != null)
- .map(tAccessPoint -> tAccessPoint.getServer().getLDevice())
+ .map(TAccessPoint::getServer)
+ .filter(Objects::nonNull)
+ .filter(TServer::isSetLDevice)
+ .map(TServer::getLDevice)
.flatMap(Collection::stream)
.anyMatch(tlDevice -> currentElem.getInst().equals(tlDevice.getInst()));
}
@@ -81,6 +84,15 @@ protected String elementXPath() {
return String.format("LDevice[%s]", Utils.xpathAttributeFilter("inst", currentElem.isSetInst() ? currentElem.getInst() : null));
}
+ @Override
+ public String getXPath() {
+ if (parentAdapter != null){
+ return parentAdapter.getXPath() + "/AccessPoint/Server/" + elementXPath();
+ } else {
+ return super.getXPath();
+ }
+ }
+
/**
* 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
@@ -118,6 +130,14 @@ public LN0Adapter getLN0Adapter(){
return new LN0Adapter(this, currentElem.getLN0());
}
+ /**
+ * Checks if LDevice has an LN0 node
+ * @return true if lDevice has a LN0 node, false otherwise
+ */
+ public boolean hasLN0(){
+ return currentElem.isSetLN0();
+ }
+
/**
* Gets current LDevice LNodes (except LN0)
* @return list of LNAdapter object
@@ -140,11 +160,9 @@ public List getLNAdapters(){
public LNAdapter getLNAdapter(String lnClass, String lnInst, String prefix) throws ScdException {
return currentElem.getLN()
.stream()
- .filter(tln -> tln.getLnClass().contains(lnClass) &&
- tln.getInst().equals(lnInst) &&
- ( (prefix == null && tln.getPrefix().isEmpty()) ||
- prefix.equals(tln.getPrefix()))
- )
+ .filter(tln -> tln.getLnClass().contains(lnClass)
+ && tln.getInst().equals(lnInst)
+ && Utils.equalsOrBothBlank(prefix, tln.getPrefix()))
.map(tln -> new LNAdapter(this,tln))
.findFirst()
.orElseThrow(
@@ -166,9 +184,7 @@ public List getExtRefBinders(ExtRefSignalInfo signalInfo) {
DataTypeTemplateAdapter dttAdapter = parentAdapter.getParentAdapter().getDataTypeTemplateAdapter();
List potentialBinders = new ArrayList<>();
- List> lnAdapters = new ArrayList<>();
- lnAdapters.add(getLN0Adapter());
- lnAdapters.addAll(getLNAdapters());
+ List> lnAdapters = getLNAdaptersInclundigLN0();
for(AbstractLNAdapter> lnAdapter : lnAdapters) {
String lnType = lnAdapter.getLnType();
try {
@@ -193,9 +209,7 @@ public List getExtRefBinders(ExtRefSignalInfo signalInfo) {
*/
public List getExtRefInfo() {
List extRefInfos = new ArrayList<>();
- List> lnAdapters = new ArrayList<>();
- lnAdapters.add(getLN0Adapter());
- lnAdapters.addAll(getLNAdapters());
+ List> lnAdapters = getLNAdaptersInclundigLN0();
LogicalNodeOptions logicalNodeOptions = new LogicalNodeOptions();
logicalNodeOptions.setWithExtRef(true);
for(AbstractLNAdapter> lnAdapter : lnAdapters) {
@@ -206,17 +220,16 @@ public List getExtRefInfo() {
}
/**
- * Gets a list of summarized DataTypeTemplate for DataAttribute DAIs (updatable or not)
+ * Gets a list of summarized DataTypeTemplate for DataAttribute DAIs (updatableOnly or not)
* @param rDtt reference resumed DataTypeTemplate (used as filter)
- * @param updatable true to retrieve only updatable DAIs, false to retrieve all DAIs
- * @return List of ResumedDataTemplate (updatable or not)
+ * @param updatableOnly true to retrieve only updatableOnly DAIs, false to retrieve all DAIs
+ * @return List of ResumedDataTemplate (updatableOnly or not)
* @throws ScdException SCD illegal arguments exception
*/
- public Set getDAI(ResumedDataTemplate rDtt, boolean updatable) throws ScdException {
+ public Set getDAI(ResumedDataTemplate rDtt, boolean updatableOnly) throws ScdException {
List> lnAdapters = new ArrayList<>();
if(StringUtils.isBlank(rDtt.getLnClass())){
- lnAdapters.add(getLN0Adapter());
- lnAdapters.addAll(getLNAdapters());
+ lnAdapters = getLNAdaptersInclundigLN0();
} else if(rDtt.getLnClass().equals(TLLN0Enum.LLN_0.value())){
lnAdapters.add(getLN0Adapter());
} else {
@@ -230,10 +243,28 @@ public Set getDAI(ResumedDataTemplate rDtt, boolean updatab
filter.setLnInst(lnAdapter.getLNInst());
filter.setPrefix(lnAdapter.getPrefix());
filter.setLnType(lnAdapter.getLnType());
- resumedDataTemplateSet.addAll(lnAdapter.getDAI(filter, updatable));
+ resumedDataTemplateSet.addAll(lnAdapter.getDAI(filter, updatableOnly));
}
return resumedDataTemplateSet;
}
+
+ public Optional getLDeviceStatus() {
+ if (!hasLN0()){
+ return Optional.empty();
+ }
+ return getLN0Adapter().getLDeviceStatus();
+ }
+
+ /**
+ * Gets all LN of LDevice including LN0
+ * @return list of all LN of LDevice
+ */
+ public List> getLNAdaptersInclundigLN0() {
+ List> aLNAdapters = new ArrayList<>();
+ aLNAdapters.add(getLN0Adapter());
+ aLNAdapters.addAll(getLNAdapters());
+ return aLNAdapters;
+ }
}
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 92deae202..0983b28ba 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
@@ -11,10 +11,9 @@
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.Optional;
import java.util.Set;
import static org.lfenergy.compas.sct.commons.util.CommonConstants.*;
@@ -69,6 +68,10 @@
*/
public class LN0Adapter extends AbstractLNAdapter {
+ public static final DoTypeName MOD_DO_TYPE_NAME = new DoTypeName(MOD_DO_NAME);
+ public static final DaTypeName STVAL_DA_TYPE_NAME = new DaTypeName(STVAL);
+ public static final DoTypeName BEHAVIOUR_DO_TYPE_NAME = new DoTypeName(BEHAVIOUR_DO_NAME);
+ public static final DaTypeName BEHAVIOUR_DA_TYPE_NAME = getDaTypeNameForBeh();
/**
* Constructor
* @param parentAdapter Parent container reference
@@ -89,11 +92,10 @@ protected boolean amChildElementRef() {
@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));
+ return "LN0";
}
+
/**
* Gets current LN0 class type
* @return LN0.class
@@ -129,6 +131,14 @@ public String getPrefix() {
return "";
}
+ /**
+ * Gets Inputs node as an adapter
+ * @return an InputsAdapter
+ */
+ public InputsAdapter getInputsAdapter(){
+ return new InputsAdapter(this, currentElem.getInputs());
+ }
+
/** Checks if given attibrute corresponds to DataSet or ReportControl or SMVControl or GSEControl in current LN0
* @param dataAttribute attribute to check
* @return Boolean value of check result
@@ -152,17 +162,18 @@ public void removeAllControlBlocksAndDatasets() {
/**
* Construct ResumedDataTemplate object with DO and DA attributes
- * @param doName The value of the name attribute of DO object
+ *
+ * @param doTypeName DoTypeName object
* @param daTypeName DaTypeName object
* @return ResumedDataTemplate
*/
- private ResumedDataTemplate getResumedDataTemplate(String doName, DaTypeName daTypeName) {
+ private ResumedDataTemplate createDaiFilter(DoTypeName doTypeName, DaTypeName daTypeName) {
ResumedDataTemplate filter = new ResumedDataTemplate();
filter.setLnClass(getLNClass());
filter.setLnInst(getLNInst());
filter.setPrefix(getPrefix());
filter.setLnType(getLnType());
- filter.setDoName(new DoTypeName(doName));
+ filter.setDoName(doTypeName);
filter.setDaName(daTypeName);
return filter;
}
@@ -172,42 +183,30 @@ private ResumedDataTemplate getResumedDataTemplate(String doName, DaTypeName daT
* @param iedNameLDeviceInstList pair of Ied name and LDevice inst attributes
* @return Set of Errors
*/
- public List checkAndUpdateLDeviceStatus(List> iedNameLDeviceInstList) {
- List errors = new ArrayList<>();
+ public Optional updateLDeviceStatus(List> iedNameLDeviceInstList) {
LDeviceActivation lDeviceActivation = new LDeviceActivation(iedNameLDeviceInstList);
final String iedName = getParentAdapter().getParentAdapter().getName();
final String ldInst = getParentAdapter().getInst();
- DaTypeName daTypeNameBeh = new DaTypeName();
- daTypeNameBeh.setName(STVAL);
- daTypeNameBeh.setBType(TPredefinedBasicTypeEnum.ENUM);
- daTypeNameBeh.setFc(TFCEnum.ST);
- ResumedDataTemplate daiBehFilter = getResumedDataTemplate(BEHAVIOUR_DO_NAME, daTypeNameBeh);
- List daiBehList = getDAI(daiBehFilter, false);
+ ResumedDataTemplate daiBehFilter = createDaiFilter(BEHAVIOUR_DO_TYPE_NAME, BEHAVIOUR_DA_TYPE_NAME);
+ List daiBehList = getDAI(daiBehFilter, false);
if (daiBehList.isEmpty()) {
- errors.add(buildErrorDescriptionMessage("The LDevice doesn't have a DO @name='Beh' OR its associated DA@fc='ST' AND DA@name='stVal'"));
- return errors;
+ return Optional.of(buildFatalReportItem("The LDevice doesn't have a DO @name='Beh' OR its associated DA@fc='ST' AND DA@name='stVal'"));
}
Set enumValues = getEnumValues(daiBehList.get(0).getDaName().getType());
- List compasLDevicePrivateList = PrivateService.getCompasPrivates(getParentAdapter().getCurrentElem(), TCompasLDevice.class);
+ List compasLDevicePrivateList = PrivateService.extractCompasPrivates(getParentAdapter().getCurrentElem(), TCompasLDevice.class);
if (compasLDevicePrivateList.isEmpty()) {
- errors.add(buildErrorDescriptionMessage("The LDevice doesn't have a Private compas:LDevice."));
- return errors;
+ return Optional.of(buildFatalReportItem("The LDevice doesn't have a Private compas:LDevice."));
}
if (!compasLDevicePrivateList.get(0).isSetLDeviceStatus()) {
- errors.add(buildErrorDescriptionMessage("The Private compas:LDevice doesn't have the attribute 'LDeviceStatus'"));
- return errors;
+ return Optional.of(buildFatalReportItem("The Private compas:LDevice doesn't have the attribute 'LDeviceStatus'"));
}
TCompasLDeviceStatus compasLDeviceStatus = compasLDevicePrivateList.get(0).getLDeviceStatus();
- DaTypeName daTypeNameMod = new DaTypeName();
- daTypeNameMod.setName(STVAL);
- ResumedDataTemplate daiModFilter = getResumedDataTemplate(MOD_DO_NAME, daTypeNameMod);
- List daiModList = getDAI(daiModFilter, false);
- if (daiModList.isEmpty()) {
- errors.add(buildErrorDescriptionMessage("The LDevice doesn't have a DO @name='Mod'"));
- return errors;
+ Optional optionalModStVal = getDaiModStVal();
+ if (optionalModStVal.isEmpty()) {
+ return Optional.of(buildFatalReportItem("The LDevice doesn't have a DO @name='Mod'"));
}
- ResumedDataTemplate newDaModToSetInLN0 = daiModList.get(0);
- String initialValue = newDaModToSetInLN0.getDaName().getDaiValues().isEmpty() ? "" : newDaModToSetInLN0.getDaName().getDaiValues().values().toArray()[0].toString();
+ ResumedDataTemplate newDaModToSetInLN0 = optionalModStVal.get();
+ String initialValue = newDaModToSetInLN0.findFirstValue().orElse("");
lDeviceActivation.checkLDeviceActivationStatus(iedName, ldInst, compasLDeviceStatus, enumValues);
if(lDeviceActivation.isUpdatable()){
if(!initialValue.equals(lDeviceActivation.getNewVal())) {
@@ -216,18 +215,28 @@ public List checkAndUpdateLDeviceStatus(List getLDeviceStatus() {
+ return getDaiModStVal()
+ .flatMap(ResumedDataTemplate::findFirstValue);
}
+ private Optional getDaiModStVal() {
+ ResumedDataTemplate daiModFilter = createDaiFilter(MOD_DO_TYPE_NAME, STVAL_DA_TYPE_NAME);
+ return getDAI(daiModFilter, false).stream()
+ .findFirst();
+ }
+
+ private static DaTypeName getDaTypeNameForBeh() {
+ DaTypeName daTypeNameBeh = new DaTypeName();
+ daTypeNameBeh.setName(STVAL);
+ daTypeNameBeh.setBType(TPredefinedBasicTypeEnum.ENUM);
+ daTypeNameBeh.setFc(TFCEnum.ST);
+ return daTypeNameBeh;
+ }
}
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 b6fbe737d..6f56952ee 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
@@ -59,7 +59,6 @@ protected String elementXPath() {
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
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/LDeviceStatus.java
similarity index 54%
rename from sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/STValEnum.java
rename to sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/LDeviceStatus.java
index 3b1559172..dcc392540 100644
--- 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/LDeviceStatus.java
@@ -6,16 +6,14 @@
package org.lfenergy.compas.sct.commons.util;
+import lombok.experimental.UtilityClass;
+
/**
* 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
+@UtilityClass
+public class LDeviceStatus {
+ public static final String ON = "on";
+ public static final String OFF = "off";
+}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java
index f9346c2e1..fe6b24a01 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java
@@ -4,7 +4,7 @@
package org.lfenergy.compas.sct.commons.util;
-import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
import java.util.Collection;
import java.util.Objects;
@@ -12,7 +12,6 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;
-@Slf4j
public final class Utils {
public static final String LEAVING_PREFIX = "<<< Leaving: ::";
@@ -119,4 +118,18 @@ public static String xpathAttributeFilter(String name, Collection value)
return xpathAttributeFilter(name, value.stream().filter(Objects::nonNull).collect(Collectors.joining(" ")));
}
}
+
+ /**
+ * Checks if strings are equals or both blank.
+ * Blank means : null, empty string or whitespaces only string.
+ * @param s1 first string
+ * @param s2 seconde string
+ * @return true if strings are equals or both blank, false otherwise
+ *
+ * @see org.apache.commons.lang3.StringUtils#isBlank(CharSequence)
+ */
+ public static boolean equalsOrBothBlank(String s1, String s2){
+ return Objects.equals(s1, s2)
+ || (StringUtils.isBlank(s1) && StringUtils.isBlank(s2));
+ }
}
diff --git a/sct-commons/src/main/resources/logback.xml b/sct-commons/src/main/resources/logback.xml
deleted file mode 100644
index 6fbe71477..000000000
--- a/sct-commons/src/main/resources/logback.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
- %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java
index 2ff372b10..194be6745 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java
@@ -18,7 +18,8 @@ public class DTO {
/* ConnectedAPDTO */
/*-----------------------------------------------*/
public static final String AP_NAME = "AP_NAME";
- public static ConnectedApDTO createCapDTO(){
+
+ public static ConnectedApDTO createCapDTO() {
ConnectedApDTO cap = new ConnectedApDTO();
cap.setApName(AP_NAME);
@@ -49,16 +50,16 @@ public static ConnectedApDTO createCapDTO(){
public static final String REMOTE_LN_CLASS = "LN_CLASS_R";
public static final String DA_NAME = P_DA;
public static final String DO_NAME = P_DO;
- public static final String REMOTE_LN_PREFIX = "PR_R";
+ public static final String REMOTE_LN_PREFIX = "LN_PREFIX_R";
public static final String SERVICE_TYPE = P_SERV_T;
- public static final String SRC_LD_INST= REMOTE_LD_INST;
- public static final String SRC_LN_INST= REMOTE_LN_INST;
- public static final String SRC_LN_CLASS= REMOTE_LN_CLASS;
- public static final String SRC_PREFIX = REMOTE_LN_PREFIX;
+ public static final String SRC_LD_INST = "LD_INST_S";
+ public static final String SRC_LN_INST = "2";
+ public static final String SRC_LN_CLASS = "LN_CLASS_S";
+ public static final String SRC_LN_PREFIX = "LN_PREFIX_S";
public static final String SRC_CB_NAME = "SRC_CB_NAME";
- public static TExtRef createExtRef(){
+ public static TExtRef createExtRef() {
TExtRef tExtRef = new TExtRef();
tExtRef.setDesc(DESC);
tExtRef.setPDA(P_DA);
@@ -79,14 +80,14 @@ public static TExtRef createExtRef(){
tExtRef.setSrcLDInst(SRC_LD_INST);
tExtRef.setSrcLNInst(SRC_LN_INST);
tExtRef.getSrcLNClass().add(SRC_LN_CLASS);
- tExtRef.setSrcPrefix(SRC_PREFIX);
+ tExtRef.setSrcPrefix(SRC_LN_PREFIX);
tExtRef.setSrcCBName(SRC_CB_NAME);
return tExtRef;
}
- public static ExtRefSignalInfo createExtRefSignalInfo(){
+ public static ExtRefSignalInfo createExtRefSignalInfo() {
ExtRefSignalInfo signalInfo = new ExtRefSignalInfo();
signalInfo.setDesc(DESC);
signalInfo.setPDA(P_DA);
@@ -98,7 +99,7 @@ public static ExtRefSignalInfo createExtRefSignalInfo(){
return signalInfo;
}
- public static ExtRefBindingInfo createExtRefBindingInfo(){
+ public static ExtRefBindingInfo createExtRefBindingInfo_Remote() {
ExtRefBindingInfo bindingInfo = new ExtRefBindingInfo();
bindingInfo.setIedName(REMOTE_IED_NAME);
bindingInfo.setLdInst(REMOTE_LD_INST);
@@ -112,28 +113,43 @@ public static ExtRefBindingInfo createExtRefBindingInfo(){
return bindingInfo;
}
- public static ExtRefSourceInfo createExtRefSourceInfo(){
+ public static ExtRefBindingInfo createExtRefBindingInfo_Source() {
+ ExtRefBindingInfo bindingInfo = new ExtRefBindingInfo();
+ bindingInfo.setIedName(HOLDER_IED_NAME);
+ bindingInfo.setLdInst(HOLDER_LD_INST);
+ bindingInfo.setLnInst(SRC_LN_INST);
+ bindingInfo.setLnClass(SRC_LN_CLASS);
+ bindingInfo.setDaName(new DaTypeName(DA_NAME));
+ bindingInfo.setDoName(new DoTypeName(DO_NAME));
+ bindingInfo.setPrefix(REMOTE_LN_PREFIX);
+ bindingInfo.setServiceType(TServiceType.fromValue(SERVICE_TYPE));
+
+ return bindingInfo;
+ }
+
+ public static ExtRefSourceInfo createExtRefSourceInfo() {
ExtRefSourceInfo sourceInfo = new ExtRefSourceInfo();
sourceInfo.setSrcLDInst(SRC_LD_INST);
sourceInfo.setSrcLNInst(SRC_LN_INST);
sourceInfo.setSrcLNClass(SRC_LN_CLASS);
- sourceInfo.setSrcPrefix(SRC_PREFIX);
+ sourceInfo.setSrcPrefix(SRC_LN_PREFIX);
sourceInfo.setSrcCBName(SRC_CB_NAME);
return sourceInfo;
}
- public static ExtRefInfo createExtRefInfo(){
+ public static ExtRefInfo createExtRefInfo() {
ExtRefInfo extRefInfo = new ExtRefInfo();
extRefInfo.setMetaData(createMetaDataInfo());
extRefInfo.setSourceInfo(DTO.createExtRefSourceInfo());
- extRefInfo.setBindingInfo(DTO.createExtRefBindingInfo());
+ extRefInfo.setBindingInfo(DTO.createExtRefBindingInfo_Remote());
extRefInfo.setSignalInfo(DTO.createExtRefSignalInfo());
return extRefInfo;
}
- public static LNodeMetaData createMetaDataInfo(){
+
+ public static LNodeMetaData createMetaDataInfo() {
LNodeMetaData metaData = new LNodeMetaData();
metaData.setIedName(HOLDER_IED_NAME);
metaData.setLdInst(HOLDER_LD_INST);
@@ -144,7 +160,6 @@ public static LNodeMetaData createMetaDataInfo(){
}
-
/*-----------------------------------------------*/
/* ResumedDataTemplate */
/*-----------------------------------------------*/
@@ -152,7 +167,8 @@ public static LNodeMetaData createMetaDataInfo(){
public static final String CDC = TPredefinedCDCEnum.WYE.value();
public static final String FC = TFCEnum.CF.value();
- public static ResumedDataTemplate createRTT(){
+
+ public static ResumedDataTemplate createRTT() {
ResumedDataTemplate rDTT = new ResumedDataTemplate();
rDTT.setLnType(LN_TYPE);
@@ -165,7 +181,7 @@ public static ResumedDataTemplate createRTT(){
return rDTT;
}
- public static ResumedDataTemplate createRTT(String prefix, String lnClass, String lnInst){
+ public static ResumedDataTemplate createRTT(String prefix, String lnClass, String lnInst) {
ResumedDataTemplate rDTT = new ResumedDataTemplate();
rDTT.setLnType(LN_TYPE);
@@ -208,7 +224,7 @@ public static TRptEnabled createTRptEnabled() {
return rptEnabled;
}
- public static TReportControl.OptFields createOptFields(){
+ public static TReportControl.OptFields createOptFields() {
TReportControl.OptFields optFields = new TReportControl.OptFields();
optFields.setBufOvfl(true);
optFields.setBufOvfl(true);
@@ -219,15 +235,16 @@ public static TReportControl.OptFields createOptFields(){
/*-----------------------------------------------*/
/* LNodeDTO */
/*-----------------------------------------------*/
- public static LNodeDTO createLNodeDTO(){
- return new LNodeDTO(HOLDER_LN_INST, HOLDER_LN_CLASS,null,LN_TYPE);
+ public static LNodeDTO createLNodeDTO() {
+ return new LNodeDTO(HOLDER_LN_INST, HOLDER_LN_CLASS, null, LN_TYPE);
}
/*-----------------------------------------------*/
/* LDeviceDTO */
/*-----------------------------------------------*/
public static final String LD_NAME = "LDPO";
- public static LDeviceDTO createLdDTO(){
+
+ public static LDeviceDTO createLdDTO() {
LDeviceDTO lDeviceDTO = new LDeviceDTO();
lDeviceDTO.setLdInst(HOLDER_LD_INST);
@@ -242,7 +259,7 @@ public static LDeviceDTO createLdDTO(){
/* IedDTO */
/*-----------------------------------------------*/
- public static IedDTO createIedDTO(){
+ public static IedDTO createIedDTO() {
IedDTO iedDTO = new IedDTO();
iedDTO.setName(HOLDER_IED_NAME);
@@ -254,7 +271,7 @@ public static IedDTO createIedDTO(){
/* FCDAInfo */
/*-----------------------------------------------*/
- public static TFCDA createFCDA(){
+ public static TFCDA createFCDA() {
TFCDA tfcda = new TFCDA();
tfcda.setDaName("da.bda");
tfcda.setDoName("do.sdo");
@@ -272,7 +289,8 @@ public static TFCDA createFCDA(){
/*-----------------------------------------------*/
public static final String NOW_STR = LocalDateTime.now().toString();
- public static HeaderDTO createHeaderDTO(UUID id){
+
+ public static HeaderDTO createHeaderDTO(UUID id) {
HeaderDTO headerDTO = new HeaderDTO();
headerDTO.setId(id);
headerDTO.setRevision("1.0");
@@ -281,7 +299,7 @@ public static HeaderDTO createHeaderDTO(UUID id){
return headerDTO;
}
- public static HeaderDTO.HistoryItem createHeaderItem(String now){
+ public static HeaderDTO.HistoryItem createHeaderItem(String now) {
HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem();
historyItem.setRevision("1.0");
historyItem.setVersion("1.0");
@@ -293,7 +311,5 @@ public static HeaderDTO.HistoryItem createHeaderItem(String now){
return historyItem;
}
- public static final Map, List> comMap = Map.of(
- Pair.of("RSPACE_PROCESS_NETWORK", SubNetworkDTO.SubnetworkType.MMS.toString()), Arrays.asList("PROCESS_AP", "TOTO_AP_GE"),
- Pair.of("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString()), Arrays.asList("ADMIN_AP","TATA_AP_EFFACEC"));
+ public static final Map, List> comMap = Map.of(Pair.of("RSPACE_PROCESS_NETWORK", SubNetworkDTO.SubnetworkType.MMS.toString()), Arrays.asList("PROCESS_AP", "TOTO_AP_GE"), Pair.of("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString()), Arrays.asList("ADMIN_AP", "TATA_AP_EFFACEC"));
}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DaTypeNameTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DaTypeNameTest.java
index bc7ddf010..4e399151b 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DaTypeNameTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DaTypeNameTest.java
@@ -5,9 +5,13 @@
package org.lfenergy.compas.sct.commons.dto;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.lfenergy.compas.scl2007b4.model.TFCEnum;
import java.util.Map;
+import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDa;
@@ -122,4 +126,37 @@ void testFrom() {
// then
assertThat(da2).isEqualTo(da1);
}
+
+ /**
+ * ListFcEnum = CF, DC, SG, SP, ST , SE
+ * Fc value should be in ListFcEnum to be considered as known
+ */
+ @Test
+ void isUpdatable_shouldReturnTrue_whenFcKnown_And_valImportIsTrue() {
+ // given
+ DaTypeName da1 = createDa("da1.bda1.bda2", TFCEnum.CF, true, Map.of(0L, "value"));
+ // when
+ boolean isDAUpdatable = da1.isUpdatable();
+ // then
+ assertThat(isDAUpdatable).isTrue();
+ }
+
+ @ParameterizedTest
+ @MethodSource("daParametersProvider")
+ void isUpdatable(String testName, TFCEnum fc, boolean valImport) {
+ // given
+ DaTypeName da1 = createDa("da1.bda1.bda2", fc, valImport, Map.of(0L, "value"));
+ // when
+ boolean isDAUpdatable = da1.isUpdatable();
+ // then
+ assertThat(isDAUpdatable).isFalse();
+ }
+
+ private static Stream daParametersProvider() {
+ return Stream.of(
+ Arguments.of("should return false when ", TFCEnum.MX, true),
+ Arguments.of("should return false when ",TFCEnum.CF, false)
+ );
+ }
+
}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefBindingInfoTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefBindingInfoTest.java
index 6157d3815..68024e00c 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefBindingInfoTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefBindingInfoTest.java
@@ -6,22 +6,22 @@
import org.junit.jupiter.api.Test;
import org.lfenergy.compas.scl2007b4.model.TExtRef;
-import org.lfenergy.compas.scl2007b4.model.TLLN0Enum;
import org.lfenergy.compas.scl2007b4.model.TServiceType;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
class ExtRefBindingInfoTest {
@Test
- void testConstruction(){
- ExtRefBindingInfo bindingInfo = DTO.createExtRefBindingInfo();
- ExtRefBindingInfo bindingInfo_bis = DTO.createExtRefBindingInfo();
+ void testConstruction() {
+ ExtRefBindingInfo bindingInfo = DTO.createExtRefBindingInfo_Remote();
+ ExtRefBindingInfo bindingInfo_bis = DTO.createExtRefBindingInfo_Remote();
ExtRefBindingInfo bindingInfo_ter = new ExtRefBindingInfo(DTO.createExtRef());
ExtRefBindingInfo bindingInfo_qt = new ExtRefBindingInfo();
- assertEquals(bindingInfo,bindingInfo_ter);
- assertEquals(bindingInfo,bindingInfo_bis);
+ assertEquals(bindingInfo, bindingInfo_ter);
+ assertEquals(bindingInfo, bindingInfo_bis);
assertNotEquals(null, bindingInfo);
assertNotEquals(bindingInfo, bindingInfo_qt);
bindingInfo_qt.setDaName(bindingInfo.getDaName());
@@ -51,8 +51,8 @@ void testConstruction(){
}
@Test
- void testIsValid(){
- ExtRefBindingInfo bindingInfo = DTO.createExtRefBindingInfo();
+ void testIsValid() {
+ ExtRefBindingInfo bindingInfo = DTO.createExtRefBindingInfo_Remote();
assertTrue(bindingInfo.isValid());
bindingInfo.setLnClass("PIOC");
bindingInfo.setLnInst("");
@@ -71,7 +71,7 @@ void testIsValid(){
}
@Test
- void testIsWrappedIn(){
+ void testIsWrappedIn() {
TExtRef extRef = DTO.createExtRef();
ExtRefBindingInfo bindingInfo = new ExtRefBindingInfo();
assertFalse(bindingInfo.isWrappedIn(extRef));
@@ -82,7 +82,7 @@ void testIsWrappedIn(){
bindingInfo.setLdInst(extRef.getLdInst());
assertFalse(bindingInfo.isWrappedIn(extRef));
- if(!extRef.getLnClass().isEmpty()) {
+ if (!extRef.getLnClass().isEmpty()) {
bindingInfo.setLnClass(extRef.getLnClass().get(0));
assertFalse(bindingInfo.isWrappedIn(extRef));
@@ -98,11 +98,50 @@ void testIsWrappedIn(){
}
@Test
- void testIsNull(){
+ void testIsNull() {
ExtRefBindingInfo bindingInfo = new ExtRefBindingInfo();
assertTrue(bindingInfo.isNull());
bindingInfo.setServiceType(TServiceType.REPORT);
assertFalse(bindingInfo.isNull());
}
+
+ @Test
+ void compareTo_should_return_0_when_ExtRefBindingInfo_the_same() {
+ // Given
+ ExtRefBindingInfo bindingInfo1 = DTO.createExtRefBindingInfo_Remote();
+ ExtRefBindingInfo bindingInfo2 = DTO.createExtRefBindingInfo_Remote();
+
+ // When
+ int result = bindingInfo1.compareTo(bindingInfo2);
+
+ // Then
+ assertThat(result).isZero();
+ }
+
+ @Test
+ void compareTo_should_return_positive_int_when_first_ExtRefBindingInfo_is_major_in_alphabetical_order() {
+ // Given
+ ExtRefBindingInfo bindingInfo1 = DTO.createExtRefBindingInfo_Remote();
+ ExtRefBindingInfo bindingInfo2 = DTO.createExtRefBindingInfo_Source();
+
+ // When
+ int result = bindingInfo1.compareTo(bindingInfo2);
+
+ // Then
+ assertThat(result).isPositive();
+ }
+
+ @Test
+ void compareTo_should_return_negative_int_when_first_ExtRefBindingInfo_is_minor_in_alphabetical_order() {
+ // Given
+ ExtRefBindingInfo bindingInfo1 = DTO.createExtRefBindingInfo_Source();
+ ExtRefBindingInfo bindingInfo2 = DTO.createExtRefBindingInfo_Remote();
+
+ // When
+ int result = bindingInfo1.compareTo(bindingInfo2);
+
+ // Then
+ assertThat(result).isNegative();
+ }
}
\ No newline at end of file
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfoTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfoTest.java
index c5e3598ab..fe3da128d 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfoTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfoTest.java
@@ -5,10 +5,16 @@
package org.lfenergy.compas.sct.commons.dto;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.lfenergy.compas.scl2007b4.model.TExtRef;
import org.lfenergy.compas.scl2007b4.model.TFCDA;
import org.lfenergy.compas.scl2007b4.model.TServiceType;
+import java.util.stream.Stream;
+
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
class ExtRefInfoTest {
@@ -86,10 +92,84 @@ void testMatchTFCDA(){
private ExtRefInfo createExtRef(){
ExtRefInfo extRefInfo = new ExtRefInfo();
extRefInfo.setSignalInfo(DTO.createExtRefSignalInfo());
- extRefInfo.setBindingInfo(DTO.createExtRefBindingInfo());
+ extRefInfo.setBindingInfo(DTO.createExtRefBindingInfo_Remote());
extRefInfo.setSourceInfo(DTO.createExtRefSourceInfo());
return extRefInfo;
}
+ @Test
+ void checkMatchingFCDA_shouldreturnTrue_whenContentMatch() {
+ //Given
+ ExtRefInfo extRefInfo = new ExtRefInfo();
+ extRefInfo.setBindingInfo(DTO.createExtRefBindingInfo_Remote());
+ extRefInfo.setSignalInfo(DTO.createExtRefSignalInfo());
+
+ TFCDA tfcda = new TFCDA();
+ tfcda.setLdInst(DTO.createExtRefBindingInfo_Remote().getLdInst());
+ tfcda.getLnClass().add(DTO.createExtRefBindingInfo_Remote().getLnClass());
+ tfcda.setLnInst(DTO.createExtRefBindingInfo_Remote().getLnInst());
+ tfcda.setPrefix(DTO.createExtRefBindingInfo_Remote().getPrefix());
+ tfcda.setDoName(DTO.createExtRefSignalInfo().getPDO());
+ tfcda.setDaName(DTO.createExtRefSignalInfo().getPDA());
+
+ //When Then
+ assertThat(extRefInfo.checkMatchingFCDA(tfcda)).isTrue();
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("provideIncompleteExtRefInfo")
+ void checkMatchingFCDA(String testCase, TFCDA fcda, ExtRefBindingInfo bindingInfo, ExtRefSignalInfo signalInfo) {
+ //Given
+ ExtRefInfo extRefInfo = new ExtRefInfo();
+ extRefInfo.setBindingInfo(bindingInfo);
+ extRefInfo.setSignalInfo(signalInfo);
+ //When Then
+ assertThat(extRefInfo.checkMatchingFCDA(fcda)).isFalse();
+ }
+
+
+ private static Stream provideIncompleteExtRefInfo() {
+
+ ExtRefBindingInfo bindingInfo = DTO.createExtRefBindingInfo_Remote();
+ ExtRefSignalInfo signalInfo = DTO.createExtRefSignalInfo();
+
+ ExtRefBindingInfo extRefBindingInfoLDInstNotMatch = DTO.createExtRefBindingInfo_Remote();
+ extRefBindingInfoLDInstNotMatch.setLdInst("ldInst");
+
+ ExtRefBindingInfo extRefBindingInfoLNClassNotMatch = DTO.createExtRefBindingInfo_Remote();
+ extRefBindingInfoLNClassNotMatch.setLnClass("lnClass");
+
+ ExtRefBindingInfo xtRefBindingInfoLNInstNotMatch = DTO.createExtRefBindingInfo_Remote();
+ xtRefBindingInfoLNInstNotMatch.setLnInst("5");
+
+ ExtRefBindingInfo ExtRefBindingInfoPrefixNotMatch = DTO.createExtRefBindingInfo_Remote();
+ ExtRefBindingInfoPrefixNotMatch.setPrefix("Pref");
+
+ ExtRefSignalInfo extRefSignalInfoDOnotMatch = DTO.createExtRefSignalInfo();
+ extRefSignalInfoDOnotMatch.setPDO("do");
+
+ ExtRefSignalInfo extRefSignalInfoDAnotMatch = DTO.createExtRefSignalInfo();
+ extRefSignalInfoDAnotMatch.setPDA("da");
+
+ TFCDA tfcda = new TFCDA();
+ tfcda.setLdInst(DTO.createExtRefBindingInfo_Remote().getLdInst());
+ tfcda.getLnClass().add(DTO.createExtRefBindingInfo_Remote().getLnClass());
+ tfcda.setLnInst(DTO.createExtRefBindingInfo_Remote().getLnInst());
+ tfcda.setPrefix(DTO.createExtRefBindingInfo_Remote().getPrefix());
+ tfcda.setDoName(DTO.createExtRefSignalInfo().getPDO());
+ tfcda.setDaName(DTO.createExtRefSignalInfo().getPDA());
+
+ return Stream.of(
+ Arguments.of("return false when binding and signal are null ", tfcda, null, null),
+ Arguments.of("return false when only signal is null ", tfcda, bindingInfo, null),
+ Arguments.of("return false when only binding is null ", tfcda, null, signalInfo),
+ Arguments.of("return false when ldInst not match ", tfcda, extRefBindingInfoLDInstNotMatch, signalInfo),
+ Arguments.of("return false when lnClass not match ", tfcda, extRefBindingInfoLNClassNotMatch, signalInfo),
+ Arguments.of("return false when lNInst not match ", tfcda, xtRefBindingInfoLNInstNotMatch, signalInfo),
+ Arguments.of("return false when prefix not match ", tfcda, ExtRefBindingInfoPrefixNotMatch, signalInfo),
+ Arguments.of("return false when pDO not match ",tfcda, bindingInfo, extRefSignalInfoDOnotMatch),
+ Arguments.of("return false when pDA not match ",tfcda, bindingInfo, extRefSignalInfoDAnotMatch)
+ );
+ }
}
\ No newline at end of file
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/FCDAInfoTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/FCDAInfoTest.java
index 7b7121466..1b730c708 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/FCDAInfoTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/FCDAInfoTest.java
@@ -5,10 +5,17 @@
package org.lfenergy.compas.sct.commons.dto;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.lfenergy.compas.scl2007b4.model.TFCDA;
import org.lfenergy.compas.scl2007b4.model.TFCEnum;
-import static org.junit.jupiter.api.Assertions.*;
+import java.util.stream.Stream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
class FCDAInfoTest {
@@ -50,4 +57,68 @@ void testConstructor(){
assertTrue(fcdaInfo1.isValid());
}
+
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("providerFCDAInfoObjects")
+ void checkFCDACompatibilitiesForBinding(String testCase, FCDAInfo fcdaInfo, FCDAInfo expectedFcdaInfo) {
+ assertThat(fcdaInfo.checkFCDACompatibilitiesForBinding(expectedFcdaInfo)).isFalse();
+ }
+
+ @Test
+ void checkFCDACompatibilitiesForBinding_shouldReturnTrue_whensameContent() {
+ //Given
+ TFCDA tfcda = new TFCDA();
+ tfcda.setLdInst(DTO.createExtRefBindingInfo_Remote().getLdInst());
+ tfcda.getLnClass().add(DTO.createExtRefBindingInfo_Remote().getLnClass());
+ tfcda.setLnInst(DTO.createExtRefBindingInfo_Remote().getLnInst());
+ tfcda.setDoName(DTO.createExtRefSignalInfo().getPDO());
+ tfcda.setDaName(DTO.createExtRefSignalInfo().getPDA());
+
+ FCDAInfo fcdaInfo = new FCDAInfo(tfcda);
+ FCDAInfo expectedFcdaInfo = new FCDAInfo(tfcda);
+ //When Then
+ assertThat(fcdaInfo.checkFCDACompatibilitiesForBinding(expectedFcdaInfo)).isTrue();
+ }
+
+ private static Stream providerFCDAInfoObjects(){
+
+ TFCDA tfcda = new TFCDA();
+ tfcda.setLdInst(DTO.createExtRefBindingInfo_Remote().getLdInst());
+ tfcda.getLnClass().add(DTO.createExtRefBindingInfo_Remote().getLnClass());
+ tfcda.setLnInst(DTO.createExtRefBindingInfo_Remote().getLnInst());
+ tfcda.setDoName(DTO.createExtRefSignalInfo().getPDO());
+ tfcda.setDaName(DTO.createExtRefSignalInfo().getPDA());
+
+ FCDAInfo fcdaInfo = new FCDAInfo(tfcda);
+
+ FCDAInfo expectedFcdaInfo = new FCDAInfo(tfcda);
+
+ FCDAInfo expectedLDInstNotMatch = new FCDAInfo(tfcda);
+ expectedLDInstNotMatch.setLdInst("LDCMDDJ");
+
+ FCDAInfo expectedLNClassNotMatch = new FCDAInfo(tfcda);
+ expectedLNClassNotMatch.setLnClass("CSWI");
+
+ FCDAInfo expectedLNInstNotMatch = new FCDAInfo(tfcda);
+ expectedLNInstNotMatch.setLnInst("5");
+
+ FCDAInfo expectedPrefixNotMatch = new FCDAInfo(tfcda);
+ expectedPrefixNotMatch.setPrefix("Prefix");
+
+ FCDAInfo expectedDONotMatch = new FCDAInfo(tfcda);
+ expectedDONotMatch.setDoName(new DoTypeName("do.do1"));
+
+ FCDAInfo expectedDANotMatch = new FCDAInfo(tfcda);
+ expectedDANotMatch.setDaName(new DaTypeName("da.bda.bda1"));
+
+ return Stream.of(
+ Arguments.of("return false when LdInst not match ", fcdaInfo, expectedLDInstNotMatch),
+ Arguments.of("return false when lnClass not match ", fcdaInfo, expectedLNClassNotMatch),
+ Arguments.of("return false when lnInst not match ", fcdaInfo, expectedLNInstNotMatch),
+ Arguments.of("return false when Prefix not match ", fcdaInfo, expectedPrefixNotMatch),
+ Arguments.of("return false when DO not match ", fcdaInfo, expectedDONotMatch),
+ Arguments.of("return false when DO not match ", fcdaInfo, expectedDANotMatch)
+
+ );
+ }
}
\ No newline at end of file
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LDeviceDTOTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LDeviceDTOTest.java
index 26b95816c..b020752f8 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LDeviceDTOTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LDeviceDTOTest.java
@@ -5,9 +5,6 @@
package org.lfenergy.compas.sct.commons.dto;
-import lombok.extern.slf4j.Slf4j;
-import static org.junit.jupiter.api.Assertions.*;
-
import org.junit.jupiter.api.Test;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
@@ -15,10 +12,10 @@
import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter;
import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
-
import java.util.Set;
-@Slf4j
+import static org.junit.jupiter.api.Assertions.*;
+
class LDeviceDTOTest {
@Test
@@ -56,4 +53,4 @@ void testFromLDAdapter() throws Exception {
LDeviceDTO lDeviceDTO = LDeviceDTO.from(lDeviceAdapter,null);
assertNotNull(lDeviceDTO);
}
-}
\ No newline at end of file
+}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ReportControlBlockTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ReportControlBlockTest.java
index 0b8256cc8..a2cc6bea8 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ReportControlBlockTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ReportControlBlockTest.java
@@ -5,16 +5,7 @@
package org.lfenergy.compas.sct.commons.dto;
import org.junit.jupiter.api.Test;
-import org.lfenergy.compas.scl2007b4.model.TClientLN;
-import org.lfenergy.compas.scl2007b4.model.TControlWithIEDName;
-import org.lfenergy.compas.scl2007b4.model.TPredefinedTypeOfSecurityEnum;
-import org.lfenergy.compas.scl2007b4.model.TReportControl;
-import org.lfenergy.compas.scl2007b4.model.TReportSettings;
-import org.lfenergy.compas.scl2007b4.model.TRptEnabled;
-import org.lfenergy.compas.scl2007b4.model.TServiceSettingsNoDynEnum;
-import org.lfenergy.compas.scl2007b4.model.TServiceType;
-import org.lfenergy.compas.scl2007b4.model.TServices;
-import org.lfenergy.compas.scl2007b4.model.TText;
+import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
@@ -27,12 +18,7 @@
import java.util.Optional;
import java.util.UUID;
-import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.*;
class ReportControlBlockTest {
@@ -234,4 +220,4 @@ private TReportControl.OptFields createOptFields(){
optFields.setDataRef(true);
return optFields;
}
-}
\ No newline at end of file
+}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplateTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplateTest.java
index 385eda9e6..691a82145 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplateTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplateTest.java
@@ -5,17 +5,27 @@
package org.lfenergy.compas.sct.commons.dto;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.lfenergy.compas.scl2007b4.model.TFCEnum;
import org.lfenergy.compas.scl2007b4.model.TPredefinedCDCEnum;
import org.lfenergy.compas.scl2007b4.model.TVal;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
+import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDa;
+import static org.lfenergy.compas.sct.commons.util.CommonConstants.MOD_DO_NAME;
+import static org.lfenergy.compas.sct.commons.util.CommonConstants.STVAL;
class ResumedDataTemplateTest {
+ public static final String CTL_MODEL = "ctlModel";
@Test
void testGetObjRef(){
String expected = "IEDLDTM/prelnclass1.do.sdo1.sdo2.da.bda1.bda2";
@@ -148,12 +158,95 @@ void testCopyFrom() {
assertThrows(IllegalArgumentException.class, () -> rDtt_t.setFc(TFCEnum.BL));
}
+ /**
+ * Known Fc = CF, DC, SG, SP, ST , SE
+ */
+ @ParameterizedTest
+ @MethodSource("daParametersProviderUpdatable")
+ void isUpdatable_case0(String testName, String daName, TFCEnum fc, boolean valImport) {
+ //Given
+ ResumedDataTemplate rDTT = new ResumedDataTemplate();
+ rDTT.setDoName(new DoTypeName(MOD_DO_NAME));
+ rDTT.setDaName(new DaTypeName(daName));
+ rDTT.setFc(fc);
+ rDTT.setValImport(valImport);
+ //When
+ boolean isRdttUpdatable = rDTT.isUpdatable();
+ // Then
+ assertThat(isRdttUpdatable).isTrue();
+ }
+
+ private static Stream daParametersProviderUpdatable() {
+ return Stream.of(
+ Arguments.of("should return true when Mod", STVAL, TFCEnum.CF, true),
+ Arguments.of("should return true when Mod", STVAL, TFCEnum.CF, false),
+ Arguments.of("should return true when Mod", STVAL, TFCEnum.MX, true),
+ Arguments.of("should return true when Mod", STVAL, TFCEnum.MX, false),
+ Arguments.of("should return true when Mod", STVAL, null, true),
+ Arguments.of("should return true when Mod", STVAL, null, false),
+ Arguments.of("should return true when Mod", CTL_MODEL, TFCEnum.CF, true)
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("daParametersProviderNotUpdatable")
+ void isUpdatable_case1(String testName, String daName, TFCEnum fc, boolean valImport) {
+ //Given
+ ResumedDataTemplate rDTT = new ResumedDataTemplate();
+ rDTT.setDoName(new DoTypeName(MOD_DO_NAME));
+ rDTT.setDaName(new DaTypeName(daName));
+ rDTT.setFc(fc);
+ rDTT.setValImport(valImport);
+ //When
+ boolean isRdttUpdatable = rDTT.isUpdatable();
+ // Then
+ assertThat(isRdttUpdatable).isFalse();
+ }
+
+ private static Stream daParametersProviderNotUpdatable() {
+ return Stream.of(
+ Arguments.of("should return false when Mod", CTL_MODEL, TFCEnum.CF, false),
+ Arguments.of("should return false when Mod", CTL_MODEL, TFCEnum.MX, true),
+ Arguments.of("should return false when Mod", CTL_MODEL, TFCEnum.MX, false),
+ Arguments.of("should return false when Mod", CTL_MODEL, null, true),
+ Arguments.of("should return false when Mod", CTL_MODEL, null, false)
+ );
+ }
+
@Test
- void testIsUpdatable(){
- ResumedDataTemplate rDtt = DTO.createRTT("pre","lnclass","1");
- assertTrue(rDtt.isUpdatable());
+ void findFirstValue_should_return_value(){
+ // Given
+ ResumedDataTemplate rDTT = new ResumedDataTemplate();
+ DaTypeName da1 = createDa("da1", TFCEnum.CF, true, Map.of(10L, "a value"));
+ rDTT.setDaName(da1);
+ // When
+ Optional firstValue = rDTT.findFirstValue();
+ // Then
+ assertThat(firstValue).hasValue("a value");
+ }
- rDtt.getDaName().setFc(TFCEnum.BL);
- assertFalse(rDtt.isUpdatable());
+ @Test
+ void findFirstValue_should_return_first_value(){
+ // Given
+ ResumedDataTemplate rDTT = new ResumedDataTemplate();
+ DaTypeName da1 = createDa("da1", TFCEnum.CF, true,
+ Map.of(1L, "value 1", 0L, "value 0"));
+ rDTT.setDaName(da1);
+ // When
+ Optional firstValue = rDTT.findFirstValue();
+ // Then
+ assertThat(firstValue).hasValue("value 0");
+ }
+
+ @Test
+ void findFirstValue_should_return_empty_optional(){
+ // Given
+ ResumedDataTemplate rDTT = new ResumedDataTemplate();
+ DaTypeName da1 = createDa("da1", TFCEnum.CF, true, Map.of());
+ rDTT.setDaName(da1);
+ // When
+ Optional firstValue = rDTT.findFirstValue();
+ // Then
+ assertThat(firstValue).isNotPresent();
}
}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ExtRefServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ExtRefServiceTest.java
new file mode 100644
index 000000000..617ebea50
--- /dev/null
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ExtRefServiceTest.java
@@ -0,0 +1,232 @@
+// SPDX-FileCopyrightText: 2021 RTE FRANCE
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package org.lfenergy.compas.sct.commons.scl;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.lfenergy.compas.scl2007b4.model.SCL;
+import org.lfenergy.compas.scl2007b4.model.TCompasFlow;
+import org.lfenergy.compas.scl2007b4.model.TExtRef;
+import org.lfenergy.compas.scl2007b4.model.TInputs;
+import org.lfenergy.compas.sct.commons.dto.SclReport;
+import org.lfenergy.compas.sct.commons.dto.SclReportItem;
+import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
+import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter;
+import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
+import org.opentest4j.AssertionFailedError;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class ExtRefServiceTest {
+
+ @Test
+ void updateAllExtRefIedNames_should_update_iedName_and_ExtRefiedName() throws Exception {
+ // Given : An ExtRef with a matching compas:Flow
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_success.xml");
+ // When
+ SclReport sclReport = ExtRefService.updateAllExtRefIedNames(scd);
+ // Then
+ TExtRef extRef = findExtRef(sclReport, "IED_NAME1", "LD_INST11", "STAT_LDSUIED_LPDO 1 Sortie_13_BOOLEAN_18_stVal_1");
+ assertThat(extRef.getIedName()).isEqualTo("IED_NAME2");
+
+ TInputs inputs = findLDeviceAdapter(sclReport, "IED_NAME1", "LD_INST11")
+ .getLN0Adapter()
+ .getCurrentElem()
+ .getInputs();
+ assertThat(PrivateService.extractCompasPrivate(inputs, TCompasFlow.class))
+ .map(TCompasFlow::getExtRefiedName)
+ .hasValue("IED_NAME2");
+ }
+
+ @Test
+ void updateAllExtRefIedNames_should_return_success_status() throws Exception {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_success.xml");
+ // When
+ SclReport sclReport = ExtRefService.updateAllExtRefIedNames(scd);
+ // Then
+ assertThat(sclReport.isSuccess())
+ .overridingErrorMessage(String.valueOf(sclReport.getSclReportItems()))
+ .isTrue();
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("updateAllExtRefIedNamesErrors")
+ void updateAllExtRefIedNames_should_report_errors(String testCase, SCL scl, SclReportItem... errors) {
+ // Given : scl parameter
+ // When
+ SclReport sclReport = ExtRefService.updateAllExtRefIedNames(scl);
+ // Then : the sclReport should report all errors described in the comments in the SCD file
+ assertThat(sclReport).isNotNull();
+ assertThat(sclReport.isSuccess()).isFalse();
+ assertThat(sclReport.getSclReportItems()).containsExactlyInAnyOrder(errors);
+ }
+
+ public static Stream updateAllExtRefIedNamesErrors() throws Exception {
+ return
+ Stream.of(Arguments.of(
+ "Errors on ExtRefs",
+ SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_with_extref_errors.xml"),
+ new SclReportItem[]{
+ SclReportItem.fatal(
+ "/SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST11\"]" +
+ "/LN0/Inputs/ExtRef[@desc=\"No matching compas:Flow\"]",
+ "The signal ExtRef has no matching compas:Flow Private"),
+ SclReportItem.fatal(
+ "/SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST11\"]" +
+ "/LN0/Inputs/ExtRef[@desc=\"Matching two compas:Flow\"]",
+ "The signal ExtRef has more than one matching compas:Flow Private"),
+ SclReportItem.fatal(
+ "/SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST13\"]",
+ "The LDevice status is neither \"on\" nor \"off\""),
+ SclReportItem.fatal(
+ "/SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST14\"]",
+ "The LDevice status is undefined"),
+ SclReportItem.warning(
+ "/SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST11\"]" +
+ "/LN0/Inputs/ExtRef[@desc=\"ExtRef does not match any ICDSystemVersionUUID\"]",
+ "The signal ExtRef iedName does not match any IED/Private/compas:ICDHeader@ICDSystemVersionUUID"),
+ SclReportItem.warning(
+ "/SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST11\"]" +
+ "/LN0/Inputs/ExtRef[@desc=\"ExtRefldinst does not match any LDevice inst in source IED\"]",
+ "The signal ExtRef ExtRefldinst does not match any LDevice with same inst attribute in source IED /SCL/IED[@name=\"IED_NAME2\"]"),
+ SclReportItem.warning(
+ "/SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST11\"]" +
+ "/LN0/Inputs/ExtRef[@desc=\"ExtRef does not match any LN is source LDevice\"]",
+ "The signal ExtRef ExtRefldinst does not match any LDevice with same inst attribute in source IED /SCL/IED[@name=\"IED_NAME2\"]"),
+ SclReportItem.warning(
+ "/SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST11\"]" +
+ "/LN0/Inputs/ExtRef[@desc=\"Source LDevice is off for this ExtRef\"]",
+ "The signal ExtRef source LDevice /SCL/IED[@name=\"IED_NAME2\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST22\"] status is off"),
+ SclReportItem.fatal(
+ "/SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST11\"]" +
+ "/LN0/Inputs/ExtRef[@desc=\"Source LDevice is undefined for this ExtRef\"]",
+ "The signal ExtRef source LDevice /SCL/IED[@name=\"IED_NAME2\"]/AccessPoint/Server/LDevice[@inst=\"LD_INST23\"] status is undefined")
+ }),
+ Arguments.of(
+ "Errors on IEDs",
+ SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_with_ied_errors.xml"),
+ new SclReportItem[]{
+ SclReportItem.fatal(
+ "/SCL/IED[@name=\"IED_NAME1\"], /SCL/IED[@name=\"IED_NAME2\"]",
+ "/IED/Private/compas:ICDHeader[@ICDSystemVersionUUID] must be unique but the same ICDSystemVersionUUID was found on several IED."),
+ SclReportItem.fatal("/SCL/IED[@name=\"IED_NAME3\"]", "IED has no Private COMPAS-ICDHeader element"),
+ SclReportItem.fatal("/SCL/IED[@name=\"IED_NAME4\"]", "IED private COMPAS-ICDHeader as no icdSystemVersionUUID or iedName attribute"),
+ SclReportItem.fatal("/SCL/IED[@name=\"IED_NAME5\"]", "IED private COMPAS-ICDHeader as no icdSystemVersionUUID or iedName attribute")
+ })
+ );
+ }
+
+ @Test
+ void updateAllExtRefIedNames_when_not_bindable_should_clear_binding() throws Exception {
+ // Given : see comments in SCD file
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_with_extref_errors.xml");
+ // When
+ SclReport sclReport = ExtRefService.updateAllExtRefIedNames(scd);
+ // Then
+ assertThatExtRefBindingInfoIsMissing(findExtRef(sclReport, "IED_NAME1", "LD_INST12", "ExtRef target LDevice status is off"));
+ assertThatExtRefBindingInfoIsMissing(findExtRef(sclReport, "IED_NAME1", "LD_INST11", "Match compas:Flow but FlowStatus is INACTIVE"));
+ assertThatExtRefBindingInfoIsMissing(findExtRef(sclReport, "IED_NAME1", "LD_INST11", "ExtRef does not match any ICDSystemVersionUUID"));
+ assertThatExtRefBindingInfoIsMissing(findExtRef(sclReport, "IED_NAME1", "LD_INST11", "ExtRefldinst does not match any LDevice inst in source IED"));
+ assertThatExtRefBindingInfoIsMissing(findExtRef(sclReport, "IED_NAME1", "LD_INST11", "ExtRef does not match any LN is source LDevice"));
+ assertThatExtRefBindingInfoIsMissing(findExtRef(sclReport, "IED_NAME1", "LD_INST11", "Source LDevice is off for this ExtRef"));
+ }
+
+ private void assertThatExtRefBindingInfoIsMissing(TExtRef extRef) {
+ assertThat(extRef.isSetIedName()).isFalse();
+ assertThat(extRef.isSetLdInst()).isFalse();
+ assertThat(extRef.isSetPrefix()).isFalse();
+ assertThat(extRef.isSetLnClass()).isFalse();
+ assertThat(extRef.isSetLnInst()).isFalse();
+ assertThat(extRef.isSetDoName()).isFalse();
+ assertThat(extRef.isSetDaName()).isFalse();
+ assertThat(extRef.isSetServiceType()).isFalse();
+ assertThat(extRef.isSetSrcLDInst()).isFalse();
+ assertThat(extRef.isSetPrefix()).isFalse();
+ assertThat(extRef.isSetSrcLNClass()).isFalse();
+ assertThat(extRef.isSetLnInst()).isFalse();
+ assertThat(extRef.isSetSrcCBName()).isFalse();
+ }
+
+ private TExtRef findExtRef(SclReport sclReport, String nameOfIED, String lDeviceInst, String extRefDesc) {
+ return findLDeviceAdapter(sclReport, nameOfIED, lDeviceInst)
+ .getLN0Adapter()
+ .getCurrentElem()
+ .getInputs()
+ .getExtRef().stream().filter(extRef -> extRefDesc.equals(extRef.getDesc()))
+ .findFirst().orElseThrow(
+ () -> new AssertionFailedError(String.format("ExtRef.des=%s not found in IED.name=%s,LDevice.inst=%s", extRefDesc, lDeviceInst, nameOfIED)));
+ }
+
+ private LDeviceAdapter findLDeviceAdapter(SclReport sclReport, String nameOfIED, String lDeviceInst) {
+ return sclReport.getSclRootAdapter()
+ .getIEDAdapterByName(nameOfIED)
+ .getLDeviceAdapterByLdInst(lDeviceInst)
+ .orElseThrow(() -> new AssertionFailedError(String.format("LDevice.inst=%s not found in IED.name=%s", lDeviceInst, nameOfIED)));
+ }
+
+ @Test
+ void updateAllExtRefIedNames_when_lDevice_off_should_remove_binding() throws Exception {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_with_extref_errors.xml");
+ // When
+ SclReport sclReport = ExtRefService.updateAllExtRefIedNames(scd);
+ // Then
+ assertThat(sclReport).isNotNull();
+ LDeviceAdapter lDeviceAdapter = getLDeviceByLdName("IED_NAME1LD_INST12", sclReport.getSclRootAdapter());
+ assertThat(lDeviceAdapter.getLDeviceStatus()).hasValue("off");
+ assertThat(lDeviceAdapter.getLN0Adapter().getInputsAdapter().getCurrentElem().getExtRef())
+ .allSatisfy(this::assertExtRefIsNotBound);
+ }
+
+ @Test
+ void updateAllExtRefIedNames_when_FlowStatus_INACTIVE_should_remove_binding() throws Exception {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_with_extref_errors.xml");
+ // When
+ SclReport sclReport = ExtRefService.updateAllExtRefIedNames(scd);
+ // Then
+ assertThat(sclReport).isNotNull();
+ LDeviceAdapter lDeviceAdapter = getLDeviceByLdName("IED_NAME1LD_INST11", sclReport.getSclRootAdapter());
+ assertThat(lDeviceAdapter.getLDeviceStatus()).hasValue("on");
+ Optional optionalTExtRef = lDeviceAdapter.getCurrentElem().getLN0().getInputs().getExtRef().stream()
+ .filter(tExtRef -> "Match compas:Flow but FlowStatus is INACTIVE".equals(tExtRef.getDesc()))
+ .findFirst();
+ assertThat(optionalTExtRef).isPresent();
+ TExtRef extRef = optionalTExtRef.get();
+ assertExtRefIsNotBound(extRef);
+ }
+
+ private void assertExtRefIsNotBound(TExtRef extRef) {
+ assertThat(extRef.isSetIedName()).isFalse();
+ assertThat(extRef.isSetLdInst()).isFalse();
+ assertThat(extRef.isSetPrefix()).isFalse();
+ assertThat(extRef.isSetLnClass()).isFalse();
+ assertThat(extRef.isSetLnInst()).isFalse();
+ assertThat(extRef.isSetDoName()).isFalse();
+ assertThat(extRef.isSetDaName()).isFalse();
+ assertThat(extRef.isSetServiceType()).isFalse();
+ assertThat(extRef.isSetSrcLDInst()).isFalse();
+ assertThat(extRef.isSetSrcPrefix()).isFalse();
+ assertThat(extRef.isSetSrcLNClass()).isFalse();
+ assertThat(extRef.isSetSrcLNInst()).isFalse();
+ assertThat(extRef.isSetSrcCBName()).isFalse();
+ }
+
+ private LDeviceAdapter getLDeviceByLdName(String ldName, SclRootAdapter sclRootAdapter) {
+ Optional optionalLDeviceAdapter = sclRootAdapter.streamIEDAdapters()
+ .flatMap(IEDAdapter::streamLDeviceAdapters)
+ .filter(lDeviceAdapter -> ldName.equals(lDeviceAdapter.getLdName()))
+ .findFirst();
+ assertThat(optionalLDeviceAdapter).isPresent();
+ return optionalLDeviceAdapter.get();
+ }
+
+}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/PrivateServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/PrivateServiceTest.java
index e3213f04d..9d55cc596 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/PrivateServiceTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/PrivateServiceTest.java
@@ -56,10 +56,10 @@ void class_should_not_be_instantiable() {
}
@Test
- void getCompasPrivates_should_return_privates_value() {
+ void extractCompasPrivates_should_return_privates_value() {
// Given : setUp
// When
- List result = PrivateService.getCompasPrivates(List.of(privateSCD, privateICD),
+ List result = PrivateService.extractCompasPrivates(List.of(privateSCD, privateICD),
TCompasSclFileType.class);
//Then
assertThat(result)
@@ -68,42 +68,42 @@ void getCompasPrivates_should_return_privates_value() {
}
@Test
- void getCompasPrivates_when_no_privates_match_class_should_return_empty_list() {
+ void extractCompasPrivates_when_no_privates_match_class_should_return_empty_list() {
// Given : setUp
// When
- List result = PrivateService.getCompasPrivates(List.of(privateSCD), TCompasICDHeader.class);
+ List result = PrivateService.extractCompasPrivates(List.of(privateSCD), TCompasICDHeader.class);
//Then
assertThat(result).isEmpty();
}
@Test
- void getCompasPrivates_when_class_is_not_compas_class_should_throw_exception() {
+ void extractCompasPrivates_when_class_is_not_compas_class_should_throw_exception() {
// Given : setUp
List privates = List.of(privateSCD);
// When & Then
- assertThatThrownBy(() -> PrivateService.getCompasPrivates(privates, Object.class)).isInstanceOf(
+ assertThatThrownBy(() -> PrivateService.extractCompasPrivates(privates, Object.class)).isInstanceOf(
NoSuchElementException.class);
}
@Test
- void getCompasPrivates_when_content_not_match_private_type_should_throw_exception() {
+ void extractCompasPrivates_when_content_not_match_private_type_should_throw_exception() {
// Given : setUp
privateSCD.setType(PrivateEnum.COMPAS_BAY.getPrivateType());
Class> compasClass = PrivateEnum.COMPAS_BAY.getCompasClass();
List privates = List.of(privateSCD);
// When & Then
- assertThatThrownBy(() -> PrivateService.getCompasPrivates(privates, compasClass)).isInstanceOf(
+ assertThatThrownBy(() -> PrivateService.extractCompasPrivates(privates, compasClass)).isInstanceOf(
ScdException.class);
}
@Test
- void getCompasPrivates_on_base_element_should_return_privates_value() {
+ void extractCompasPrivates_on_base_element_should_return_privates_value() {
// Given : setUp
TBaseElement baseElement = new SCL();
baseElement.getPrivate().add(privateSCD);
baseElement.getPrivate().add(privateICD);
// When
- List result = PrivateService.getCompasPrivates(baseElement, TCompasSclFileType.class);
+ List result = PrivateService.extractCompasPrivates(baseElement, TCompasSclFileType.class);
// Then
assertThat(result)
.hasSize(2)
@@ -111,20 +111,20 @@ void getCompasPrivates_on_base_element_should_return_privates_value() {
}
@Test
- void getCompasPrivates_on_base_element_should_not_set_private() {
+ void extractCompasPrivates_on_base_element_should_not_set_private() {
// Given
TBaseElement baseElement = new SCL();
// When
- PrivateService.getCompasPrivates(baseElement, TCompasSclFileType.class);
+ PrivateService.extractCompasPrivates(baseElement, TCompasSclFileType.class);
// Then
assertThat(baseElement.isSetPrivate()).isFalse();
}
@Test
- void getCompasPrivate_should_return_private_value() {
+ void extractCompasPrivate_should_return_private_value() {
// Given : setUp
// When
- Optional result = PrivateService.getCompasPrivate(privateSCD,
+ Optional result = PrivateService.extractCompasPrivate(privateSCD,
TCompasSclFileType.class);
//Then
assertThat(result).isPresent()
@@ -132,34 +132,69 @@ void getCompasPrivate_should_return_private_value() {
}
@Test
- void getCompasPrivate_should_return_empty() {
+ void extractCompasPrivate_should_return_empty() {
// Given : setUp
// When
- Optional result = PrivateService.getCompasPrivate(privateSCD,
+ Optional result = PrivateService.extractCompasPrivate(privateSCD,
TCompasBay.class);
//Then
assertThat(result).isNotPresent();
}
@Test
- void getCompasPrivate_should_throw_exception() {
+ void extractCompasPrivate_should_throw_exception() {
// Given : setUp
privateSCD.getContent().add(objectFactory.createSclFileType(TCompasSclFileType.ICD));
Class> compasClass = PrivateEnum.COMPAS_SCL_FILE_TYPE.getCompasClass();
// When & Then
- assertThatThrownBy(() -> PrivateService.getCompasPrivate(privateSCD, compasClass)).isInstanceOf(
+ assertThatThrownBy(() -> PrivateService.extractCompasPrivate(privateSCD, compasClass)).isInstanceOf(
ScdException.class);
}
@Test
- void getCompasICDHeader_should_return_private_value() {
+ void extractCompasPrivate_on_base_element_should_return_private_value() {
+ // Given : setUp
+ TBaseElement baseElement = new SCL();
+ baseElement.getPrivate().add(privateSCD);
+ // When
+ Optional result = PrivateService.extractCompasPrivate(baseElement,
+ TCompasSclFileType.class);
+ //Then
+ assertThat(result).isPresent()
+ .hasValue(TCompasSclFileType.SCD);
+ }
+
+ @Test
+ void extractCompasPrivate_on_base_element_should_return_empty() {
+ // Given
+ TBaseElement baseElement = new SCL();
+ // When
+ Optional result = PrivateService.extractCompasPrivate(baseElement,
+ TCompasBay.class);
+ //Then
+ assertThat(result).isNotPresent();
+ }
+
+ @Test
+ void extractCompasPrivate_on_base_element_should_throw_exception() {
+ // Given : setUp
+ TBaseElement baseElement = new SCL();
+ baseElement.getPrivate().add(privateSCD);
+ baseElement.getPrivate().add(privateICD);
+ // When & Then
+ assertThatThrownBy(() -> PrivateService.extractCompasPrivate(baseElement, TCompasSclFileType.class)).isInstanceOf(
+ ScdException.class);
+ }
+
+ @Test
+ void extractCompasICDHeader_should_return_private_value() {
// Given
privateSCD = objectFactory.createTPrivate();
privateSCD.setType(PrivateEnum.COMPAS_ICDHEADER.getPrivateType());
TCompasICDHeader tCompasICDHeader = objectFactory.createTCompasICDHeader();
privateSCD.getContent().add(objectFactory.createICDHeader(tCompasICDHeader));
// When
- Optional optionalResult = PrivateService.getCompasICDHeader(privateSCD);
+ Optional optionalResult = PrivateService.extractCompasICDHeader(privateSCD);
//Then
assertThat(optionalResult).isPresent().get().matches(result -> result == tCompasICDHeader);
}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclRootAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclRootAdapterTest.java
index f83ab071b..0248ccdfc 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclRootAdapterTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclRootAdapterTest.java
@@ -4,7 +4,6 @@
package org.lfenergy.compas.sct.commons.scl;
-import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.scl2007b4.model.TPrivate;
@@ -16,7 +15,6 @@
import static org.junit.jupiter.api.Assertions.*;
import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable;
-@Slf4j
class SclRootAdapterTest {
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 6133cd298..f5984077b 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
@@ -21,7 +21,7 @@
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.*;
import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDa;
import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDo;
@@ -181,7 +181,7 @@ void testGetExtRefBinders() throws Exception {
"Do11.sdo11", "da11.bda111.bda112.bda113", "INT_ADDR11"
);
- List potentialBinders = assertDoesNotThrow(
+ assertDoesNotThrow(
() -> SclService.getExtRefBinders(
scd, "IED_NAME1", "LD_INST11", "LLN0", "", "", signalInfo
)
@@ -195,6 +195,34 @@ void testGetExtRefBinders() throws Exception {
);
}
+ @Test
+ void test_getExtRefBinders_should_return_sorted_list() throws Exception {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_binders_test.xml");
+
+ ExtRefSignalInfo signalInfo = createSignalInfo(
+ "Do11.sdo11", "da11.bda111.bda112.bda113", "INT_ADDR11"
+ );
+
+ // When
+ List potentialBinders = SclService.getExtRefBinders(scd, "IED_NAME1", "LD_INST11", "LLN0", "", "", signalInfo);
+
+ // Then
+ // Not so relevant because we get a single element list from the XML file
+ assertThat(potentialBinders)
+ .extracting(ExtRefBindingInfo::getIedName)
+ .containsExactly("IED_NAME1");
+ assertThat(potentialBinders)
+ .extracting(ExtRefBindingInfo::getLdInst)
+ .containsExactly("LD_INST12");
+ assertThat(potentialBinders)
+ .extracting(ExtRefBindingInfo::getLnClass)
+ .containsExactly("LLN0");
+ assertThat(potentialBinders)
+ .extracting(ExtRefBindingInfo::getLnInst)
+ .containsExactly("");
+ }
+
@Test
void testUpdateExtRefBinders() throws Exception {
SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION);
@@ -245,7 +273,8 @@ void testUpdateExtRefBinders() throws Exception {
}
@Test
- void testGetExtRefSourceInfo() throws Exception {
+ void getExtRefSourceInfo_shouldReturnEmptyList_whenExtRefMatchNoFCDA() throws Exception {
+ //Given
SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml");
String iedName = "IED_NAME2";
String ldInst = "LD_INST21";
@@ -263,49 +292,129 @@ void testGetExtRefSourceInfo() throws Exception {
extRefInfo.setHolderLDInst(ldInst);
extRefInfo.setHolderLnClass(lnClass);
- var controlBlocks = SclService.getExtRefSourceInfo(scd, extRefInfo);
- assertEquals(2, controlBlocks.size());
- controlBlocks.forEach(controlBlock -> assertTrue(
- controlBlock.getName().equals("goose1") || controlBlock.getName().equals("smv1")
- )
- );
+ //When
+ List> controlBlocks = SclService.getExtRefSourceInfo(scd, extRefInfo);
+
+ //Then
+ assertThat(controlBlocks).hasSize(0);
}
@Test
- void testUpdateExtRefSource() throws Exception {
+ void getExtRefSourceInfo_shouldReturnListOfControlBlocks_whenExtRefMatchFCDA() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/issue_175_scd_get_cbs_test.xml");
+ String iedName = "IED_NAME2";
+ String ldInst = "LD_INST21";
+ String lnClass = TLLN0Enum.LLN_0.value();
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iedAdapter.getLDeviceAdapterByLdInst(ldInst).get());
+ LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
+ List extRefs = ln0Adapter.getExtRefs(null);
+ assertFalse(extRefs.isEmpty());
+
+ ExtRefInfo extRefInfo = new ExtRefInfo(extRefs.get(0));
+
+ extRefInfo.setHolderIEDName(iedName);
+ extRefInfo.setHolderLDInst(ldInst);
+ extRefInfo.setHolderLnClass(lnClass);
+
+ //When
+ List> controlBlocks = SclService.getExtRefSourceInfo(scd, extRefInfo);
+
+ //Then
+ assertThat(controlBlocks).hasSize(1);
+ assertThat(controlBlocks.get(0).getName()).isEqualTo("goose2");
+ }
+
+ @Test
+ void updateExtRefSource_shouldThrowScdException_whenSignalInfoNullOrInvalid() throws Exception {
+ //Given
SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml");
ExtRefInfo extRefInfo = new ExtRefInfo();
extRefInfo.setHolderIEDName("IED_NAME2");
extRefInfo.setHolderLDInst("LD_INST21");
extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value());
- assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // signal = null
+ //When Then
+ assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // signal = null
extRefInfo.setSignalInfo(new ExtRefSignalInfo());
- assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // signal invalid
+ assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// signal invalid
+ }
- extRefInfo.getSignalInfo().setIntAddr("INT_ADDR21");
- extRefInfo.getSignalInfo().setPDA("da21.bda211.bda212.bda213");
- extRefInfo.getSignalInfo().setPDO("Do21.sdo21");
- assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // binding = null
+ @Test
+ void updateExtRefSource_shouldThrowScdException_whenBindingInfoNullOrInvalid() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml");
+ ExtRefInfo extRefInfo = new ExtRefInfo();
+ extRefInfo.setHolderIEDName("IED_NAME2");
+ extRefInfo.setHolderLDInst("LD_INST21");
+ extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value());
+
+ ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo();
+ extRefSignalInfo.setIntAddr("INT_ADDR21");
+ extRefSignalInfo.setPDA("da21.bda211.bda212.bda213");
+ extRefSignalInfo.setPDO("Do21.sdo21");
+ extRefInfo.setSignalInfo(extRefSignalInfo);
+ //When Then
+ assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // binding = null
extRefInfo.setBindingInfo(new ExtRefBindingInfo());
- assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // binding invalid
+ assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// binding invalid
+ }
+ @Test
+ void updateExtRefSource_shouldThrowScdException_whenBindingInternalBinding() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml");
+ ExtRefInfo extRefInfo = new ExtRefInfo();
+ extRefInfo.setHolderIEDName("IED_NAME2");
+ extRefInfo.setHolderLDInst("LD_INST21");
+ extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value());
+
+ ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo();
+ extRefSignalInfo.setIntAddr("INT_ADDR21");
+ extRefSignalInfo.setPDA("da21.bda211.bda212.bda213");
+ extRefSignalInfo.setPDO("Do21.sdo21");
+ extRefInfo.setSignalInfo(extRefSignalInfo);
+
+ ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo();
+ extRefBindingInfo.setIedName("IED_NAME2"); // internal binding
+ extRefBindingInfo.setLdInst("LD_INST12");
+ extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value());
+ extRefInfo.setBindingInfo(new ExtRefBindingInfo());
+ //When Then
+ assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // CB not allowed
+ }
+ @Test
+ void updateExtRefSource_shouldThrowScdException_whenBindingExternalBinding() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml");
+ ExtRefInfo extRefInfo = new ExtRefInfo();
+ extRefInfo.setHolderIEDName("IED_NAME2");
+ extRefInfo.setHolderLDInst("LD_INST21");
+ extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value());
- extRefInfo.getBindingInfo().setIedName("IED_NAME2"); // internal binding
- extRefInfo.getBindingInfo().setLdInst("LD_INST12");
- extRefInfo.getBindingInfo().setLnClass(TLLN0Enum.LLN_0.value());
- assertThrows(ScdException.class, () -> SclService.updateExtRefSource(scd, extRefInfo)); // CB not allowed
+ ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo();
+ extRefSignalInfo.setIntAddr("INT_ADDR21");
+ extRefSignalInfo.setPDA("da21.bda211.bda212.bda213");
+ extRefSignalInfo.setPDO("Do21.sdo21");
+ extRefInfo.setSignalInfo(extRefSignalInfo);
- extRefInfo.getBindingInfo().setIedName("IED_NAME1");
+ ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo();
+ extRefBindingInfo.setIedName("IED_NAME1");
+ extRefBindingInfo.setLdInst("LD_INST12");
+ extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value());
+ extRefInfo.setBindingInfo(extRefBindingInfo);
extRefInfo.setSourceInfo(new ExtRefSourceInfo());
extRefInfo.getSourceInfo().setSrcLDInst(extRefInfo.getBindingInfo().getLdInst());
extRefInfo.getSourceInfo().setSrcLNClass(extRefInfo.getBindingInfo().getLnClass());
extRefInfo.getSourceInfo().setSrcCBName("goose1");
+
+ //When Then
TExtRef extRef = assertDoesNotThrow(() -> SclService.updateExtRefSource(scd, extRefInfo));
assertEquals(extRefInfo.getSourceInfo().getSrcCBName(), extRef.getSrcCBName());
}
-
private ExtRefSignalInfo createSignalInfo(String pDO, String pDA, String intAddr) {
final String DESC = "DESC";
@@ -651,8 +760,7 @@ void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_D
SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl);
// Then
SclRootAdapter scdRootAdapter = new SclRootAdapter(scl);
- List lDevices = scdRootAdapter.getIEDAdapters().stream().map(IEDAdapter::getLDeviceAdapters)
- .flatMap(List::stream).collect(Collectors.toList());
+ List lDevices = scdRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters).collect(Collectors.toList());
List ln0s = lDevices.stream().map(LDeviceAdapter::getLN0Adapter).map(LN0Adapter::getCurrentElem).collect(Collectors.toList());
assertThat(ln0s)
.isNotEmpty()
@@ -672,9 +780,9 @@ void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_D
SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl);
// Then
SclRootAdapter scdRootAdapter = new SclRootAdapter(scl);
- List lDevices = scdRootAdapter.getIEDAdapters().stream().map(IEDAdapter::getLDeviceAdapters)
- .flatMap(List::stream).collect(Collectors.toList());
- List lns = lDevices.stream().map(LDeviceAdapter::getLNAdapters).flatMap(List::stream)
+ List