sclReportItems = sclRootAdapter.streamIEDAdapters()
+ .flatMap(IEDAdapter::streamLDeviceAdapters)
+ .map(LDeviceAdapter::getLN0Adapter)
+ .map(LN0Adapter::updateDoInRef)
+ .flatMap(List::stream)
+ .toList();
+ return new SclReport(sclRootAdapter, sclReportItems);
+ }
}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/package-info.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/package-info.java
index fbf637d8e..8b72f2343 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/package-info.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/com/package-info.java
@@ -3,9 +3,9 @@
// SPDX-License-Identifier: Apache-2.0
/**
- * scl.com is a group of services for operating on
+ * scl.com is a group of services for operating on
* {@link org.lfenergy.compas.scl2007b4.model.TCommunication Communication} object
- *
+ *
* @see org.lfenergy.compas.scl2007b4.model.TCommunication
* @see org.lfenergy.compas.scl2007b4.model.TSubNetwork
* @see org.lfenergy.compas.scl2007b4.model.TConnectedAP
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/package-info.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/package-info.java
index 81afa71b1..020d29d34 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/package-info.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/package-info.java
@@ -3,9 +3,9 @@
// SPDX-License-Identifier: Apache-2.0
/**
- * scl.dtt is a group of services for operating on
+ * scl.dtt is a group of services for operating on
* {@link org.lfenergy.compas.scl2007b4.model.TDataTypeTemplates DataTypeTemplates} object
- *
+ *
* @see org.lfenergy.compas.scl2007b4.model.TLNodeType
* @see org.lfenergy.compas.scl2007b4.model.TDOType
* @see org.lfenergy.compas.scl2007b4.model.TDAType
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/header/package-info.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/header/package-info.java
index 55eaf1e46..53782746e 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/header/package-info.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/header/package-info.java
@@ -3,9 +3,9 @@
// SPDX-License-Identifier: Apache-2.0
/**
- * scl.header is a group of services for operating on
+ * scl.header is a group of services for operating on
* {@link org.lfenergy.compas.scl2007b4.model.THeader Header} object
- *
+ *
* @see org.lfenergy.compas.scl2007b4.model.THeader
* @see org.lfenergy.compas.scl2007b4.model.THitem
* @see Issue !6
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractDAIAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractDAIAdapter.java
index d612a8cee..3d6e69e45 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractDAIAdapter.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractDAIAdapter.java
@@ -5,14 +5,14 @@
package org.lfenergy.compas.sct.commons.scl.ied;
import org.lfenergy.compas.scl2007b4.model.TDAI;
+import org.lfenergy.compas.scl2007b4.model.TDOI;
import org.lfenergy.compas.scl2007b4.model.TPrivate;
import org.lfenergy.compas.scl2007b4.model.TVal;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
+import org.lfenergy.compas.sct.commons.util.CommonConstants;
import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Stream;
/**
* A representation of the model object
@@ -35,20 +35,18 @@
* {@link AbstractDAIAdapter#addPrivate(TPrivate) Add TPrivate under this object}
*
* Checklist functions
- *
- * - {@link AbstractDAIAdapter#isValImport Check value Of valImport attribute}
- *
*
*
* @see org.lfenergy.compas.scl2007b4.model.TDAI
* @see Issue !70
*/
-public abstract class AbstractDAIAdapter extends SclElementAdapter
implements IDataAdapter{
+public abstract class AbstractDAIAdapter
extends SclElementAdapter
implements IDataAdapter {
/**
* Constructor
+ *
* @param parentAdapter Parent container reference
- * @param currentElem Current reference
+ * @param currentElem Current reference
*/
protected AbstractDAIAdapter(P parentAdapter, TDAI currentElem) {
super(parentAdapter, currentElem);
@@ -56,9 +54,10 @@ protected AbstractDAIAdapter(P parentAdapter, TDAI currentElem) {
/**
* Gets SDI from DAI by name
+ *
* @param sName SDI name
+ * @param expected class type
* @return IDataAdapter related object
- * @param expected class type
* @throws ScdException throws when specified SDI not present in DAI
*/
public S getStructuredDataAdapterByName(String sName) throws ScdException {
@@ -67,33 +66,34 @@ public S getStructuredDataAdapterByName(String sName) t
/**
* Gets DataAdapter by DAI
+ *
* @param sName DAI name
+ * @param expected class type
* @return IDataAdapter related object
- * @param expected class type
* @throws ScdException throws when specified DAI unknown
*/
- public S getDataAdapterByName(String sName) throws ScdException {
+ public S getDataAdapterByName(String sName) throws ScdException {
throw new UnsupportedOperationException("DAI doesn't have any DAI");
}
/**
* Sets ValImport value
+ *
* @param b value
*/
- public void setValImport(boolean b){
+ public void setValImport(boolean b) {
currentElem.setValImport(b);
}
- /**
- * Cheks ValImport boolean value
- * @return Boolean value of ValImport if define or null
- */
- public Boolean isValImport(){
- return currentElem.isSetValImport() ? currentElem.isValImport() : null;
+ private boolean isDOModDAstVal() {
+ if (parentAdapter.getCurrentElem() instanceof final TDOI tdoi) {
+ return currentElem.getName().equals(CommonConstants.STVAL) && tdoi.getName().equals(CommonConstants.MOD_DO_NAME);
+ }
+ return false;
}
public AbstractDAIAdapter extends SclElementAdapter> update(Map daiValues) throws ScdException {
- if(daiValues.size() > 1 && daiValues.containsKey(0L)){
+ if (daiValues.size() > 1 && daiValues.containsKey(0L)) {
update(0L, daiValues.get(0L)); // to be refined (with COMPAS TEAMS)
} else {
for (Map.Entry mapVal : daiValues.entrySet()) {
@@ -105,47 +105,55 @@ public AbstractDAIAdapter extends SclElementAdapter> update(Map
/**
* Updates DAI SGroup value
+ *
* @param sGroup SGroup to update
- * @param val value
+ * @param val value
* @throws ScdException throws when DAI for which SGroup should be updated is not updatable
*/
public void update(Long sGroup, String val) throws ScdException {
- if(currentElem.isSetValImport() && !currentElem.isValImport()){
+ if (!isDOModDAstVal() && currentElem.isSetValImport() && !currentElem.isValImport()) {
String msg = String.format(
- "DAI(%s) cannot be updated : valImport(false)",currentElem.getName()
+ "DAI(%s) cannot be updated : valImport(false) %s", currentElem.getName(), getXPath()
);
throw new ScdException(msg);
}
- Stream tValStream = currentElem.getVal().stream();
if (sGroup != null && sGroup != 0) {
- Optional tVal = tValStream.filter(tValElem -> tValElem.isSetSGroup() &&
- sGroup.equals(tValElem.getSGroup()))
- .findFirst();
- if(tVal.isPresent()){
- tVal.get().setValue(val);
- } else {
- TVal newTVal = new TVal();
- newTVal.setValue(val);
- newTVal.setSGroup(sGroup);
- currentElem.getVal().add(newTVal);
- }
+ updateSGroupVal(sGroup, val);
} else {
- Optional tVal = tValStream.findFirst();
- if(tVal.isPresent()){
- tVal.get().setValue(val);
- }else {
- TVal newTVal = new TVal();
- newTVal.setValue(val);
- currentElem.getVal().add(newTVal);
- }
+ updateVal(val);
}
}
- public IDataAdapter addDAI(String name){
+ private void updateSGroupVal(Long sGroup, String val) {
+ currentElem.getVal().stream()
+ .filter(tValElem -> tValElem.isSetSGroup() && sGroup.equals(tValElem.getSGroup()))
+ .findFirst()
+ .orElseGet(
+ () -> {
+ TVal newTVal = new TVal();
+ newTVal.setSGroup(sGroup);
+ currentElem.getVal().add(newTVal);
+ return newTVal;
+ })
+ .setValue(val);
+ }
+
+ public void updateVal(String s) {
+ currentElem.getVal().stream().findFirst()
+ .orElseGet(
+ () -> {
+ TVal newTVal = new TVal();
+ currentElem.getVal().add(newTVal);
+ return newTVal;
+ })
+ .setValue(s);
+ }
+
+ public IDataAdapter addDAI(String name) {
throw new UnsupportedOperationException("DAI cannot contain an SDI");
}
- public IDataAdapter addSDOI(String sdoName){
+ public IDataAdapter addSDOI(String sdoName) {
throw new UnsupportedOperationException("DAI cannot contain an DAI");
}
}
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 89ab101f5..bc79c4b94 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
@@ -705,46 +705,40 @@ public void updateDAI(@NonNull ResumedDataTemplate rDtt) throws ScdException {
DAITracker.MatchResult matchResult = daiTracker.search();
AbstractDAIAdapter> daiAdapter = null;
IDataParentAdapter doiOrSdoiAdapter;
- if (matchResult == DAITracker.MatchResult.FULL_MATCH) {
- // update
- daiAdapter = (AbstractDAIAdapter) daiTracker.getBdaiOrDaiAdapter();
- 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));
- }
- }
- if (rDtt.isUpdatable()) {
+ if (!rDtt.isUpdatable())
+ return;
+
+ if (rDtt.isUpdatable() && matchResult == DAITracker.MatchResult.FULL_MATCH) {
+ daiAdapter = (AbstractDAIAdapter) daiTracker.getBdaiOrDaiAdapter();
+ } else {
doiOrSdoiAdapter = daiTracker.getDoiOrSdoiAdapter();
- int idx = daiTracker.getIndexDoType();
+ int indexDoType = daiTracker.getIndexDoType();
int doSz = doTypeName.getStructNames().size();
if (matchResult == DAITracker.MatchResult.FAILED) {
doiOrSdoiAdapter = addDOI(doTypeName.getName());
- idx = 0;
- } else if (idx == -1) {
- idx = 0;
- } else if (idx == doSz - 1) {
- idx = doSz;
+ indexDoType = 0;
+ } else if (indexDoType == -1) {
+ indexDoType = 0;
+ } else if (indexDoType == doSz - 1) {
+ indexDoType = doSz;
}
- for (int i = idx; i < doSz; ++i) {
+ for (int i = indexDoType; i < doSz; ++i) {
String sdoName = doTypeName.getStructNames().get(i);
doiOrSdoiAdapter = doiOrSdoiAdapter.addSDOI(sdoName);
}
IDataParentAdapter daiOrBdaiAdapter = daiTracker.getDoiOrSdoiAdapter();
- idx = daiTracker.getIndexDaType();
+ int indexDaType = daiTracker.getIndexDaType();
int daSz = daTypeName.getStructNames().size();
- if (idx <= -1) {
- idx = 0;
- } else if (idx == daSz - 1) {
- idx = daSz;
+ if (indexDaType <= -1) {
+ indexDaType = 0;
+ } else if (indexDaType == daSz - 1) {
+ indexDaType = daSz;
}
- for (int i = idx; i < daSz; ++i) {
+ for (int i = indexDaType; i < daSz; ++i) {
String bdaName = daTypeName.getStructNames().get(i);
- if (idx == 0) {
+ if (indexDaType == 0) {
daiOrBdaiAdapter = doiOrSdoiAdapter.addSDOI(daTypeName.getName());
} else if (i == daSz - 1) {
daiAdapter = daiOrBdaiAdapter.addDAI(bdaName, rDtt.isUpdatable());
@@ -755,9 +749,8 @@ public void updateDAI(@NonNull ResumedDataTemplate rDtt) throws ScdException {
if (daiAdapter == null) {
daiAdapter = doiOrSdoiAdapter.addDAI(daTypeName.getName(), rDtt.isUpdatable());
}
-
- daiAdapter.update(daTypeName.getDaiValues());
}
+ daiAdapter.update(daTypeName.getDaiValues());
}
/**
@@ -961,14 +954,31 @@ public Optional findControlBlock(String name, ControlBlockE
public ControlBlockAdapter createControlBlockIfNotExists(String cbName, String id, String datSet, ControlBlockEnum controlBlockEnum) {
return findControlBlock(cbName, controlBlockEnum)
- .orElseGet(() -> addControlBlock(
- switch (controlBlockEnum) {
- case GSE -> new GooseControlBlock(cbName, id, datSet);
- case SAMPLED_VALUE -> new SMVControlBlock(cbName, id, datSet);
- case REPORT -> new ReportControlBlock(cbName, id, datSet);
- default -> throw new IllegalArgumentException("Unsupported ControlBlock Type " + controlBlockEnum);
- }
- )
- );
+ .orElseGet(() -> addControlBlock(
+ switch (controlBlockEnum) {
+ case GSE -> new GooseControlBlock(cbName, id, datSet);
+ case SAMPLED_VALUE -> new SMVControlBlock(cbName, id, datSet);
+ case REPORT -> new ReportControlBlock(cbName, id, datSet);
+ default -> throw new IllegalArgumentException("Unsupported ControlBlock Type " + controlBlockEnum);
+ }
+ )
+ );
+ }
+
+ /**
+ * Finds all FCDAs in DataSet of Control Block feeding ExtRef
+ * @param tExtRef Fed ExtRef
+ * @return list of all FCDA in DataSet of Control Block
+ */
+ public List getFCDAs(TExtRef tExtRef){
+ TControl tControl = getTControlsByType(ControlBlockEnum.from(tExtRef.getServiceType()).getControlBlockClass()).stream()
+ .filter(tCtrl -> tExtRef.getSrcCBName() != null && tExtRef.getSrcCBName().equals(tCtrl.getName()))
+ .findFirst().orElseThrow(() ->
+ new ScdException(String.format("Control Block %s not found in %s", tExtRef.getSrcCBName(), getXPath())));
+ return getCurrentElem().getDataSet().stream()
+ .filter(tDataSet -> tDataSet.getName().equals(tControl.getDatSet()))
+ .map(TDataSet::getFCDA)
+ .flatMap(Collection::stream)
+ .toList();
}
}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapter.java
new file mode 100644
index 000000000..4e12b6658
--- /dev/null
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapter.java
@@ -0,0 +1,340 @@
+/*
+ * // SPDX-FileCopyrightText: 2023 RTE FRANCE
+ * //
+ * // SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lfenergy.compas.sct.commons.scl.ied;
+
+import org.lfenergy.compas.scl2007b4.model.*;
+import org.lfenergy.compas.sct.commons.dto.SclReportItem;
+import org.lfenergy.compas.sct.commons.exception.ScdException;
+import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
+import org.lfenergy.compas.sct.commons.util.ServicesConfigEnum;
+import org.lfenergy.compas.sct.commons.util.Utils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * A representation of the model object
+ * {@link org.lfenergy.compas.scl2007b4.model.TAccessPoint AccessPoint}.
+ *
+ * The following features are supported:
+ *
+ *
+ * - Functions
+ *
+ * - {@link AccessPointAdapter#checkFCDALimitations Returns the value of the name attribute}
+ * - {@link AccessPointAdapter#checkControlsLimitation Returns the value of the Service object}
+ *
+ *
+ */
+
+public class AccessPointAdapter extends SclElementAdapter {
+
+ public static final long MAX_OCCURRENCE_NO_LIMIT_VALUE = -1L;
+ private static final String CLIENT_IED_NAME = "The Client IED ";
+
+ /**
+ * Constructor
+ *
+ * @param parentAdapter Parent container reference
+ * @param tAccessPoint Current reference
+ */
+ public AccessPointAdapter(IEDAdapter parentAdapter, TAccessPoint tAccessPoint) {
+ super(parentAdapter, tAccessPoint);
+ }
+
+ /**
+ * 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 parentAdapter.getCurrentElem().getAccessPoint().stream()
+ .anyMatch(tAccessPoint -> tAccessPoint.getName().equals(currentElem.getName()));
+ }
+
+ @Override
+ protected String elementXPath() {
+ return String.format("AccessPoint[%s]", Utils.xpathAttributeFilter("name", currentElem.isSetName() ? currentElem.getName() : null));
+ }
+
+ /**
+ * Gets all LDevice from AccessPoint
+ *
+ * @return Stream of LDeviceAdapter object as IEDs of SCL
+ */
+ private Stream streamLDeviceAdapters() {
+ if (!currentElem.isSetServer()) return Stream.empty();
+ return currentElem.getServer().getLDevice().stream()
+ .map(tlDevice -> new LDeviceAdapter(getParentAdapter(), tlDevice));
+ }
+
+ /**
+ * Checks FCDA number limitation into each LDevice of AccessPoint
+ *
+ * @return List of errors encountered for LDevices
+ */
+ public List checkFCDALimitations() {
+ long max = getMaxInstanceAuthorized(ServicesConfigEnum.FCDA);
+ if (currentElem.getServer() == null || max == MAX_OCCURRENCE_NO_LIMIT_VALUE) return Collections.emptyList();
+ return currentElem.getServer().getLDevice().stream()
+ .map(tlDevice -> new LDeviceAdapter(parentAdapter, tlDevice))
+ .map(lDeviceAdapter ->
+ lDeviceAdapter.getLNAdaptersIncludingLN0().stream()
+ .map(abstractLNAdapter -> abstractLNAdapter.getCurrentElem().getDataSet())
+ .flatMap(Collection::stream)
+ .filter(tDataSet -> tDataSet.getFCDA().size() > max)
+ .map(tDataSet -> SclReportItem.fatal(getXPath(), String.format("There are too much FCDA for the DataSet %S for the LDevice %S in IED %S",
+ tDataSet.getName(), lDeviceAdapter.getInst(), parentAdapter.getName()))).toList()
+ ).flatMap(Collection::stream).toList();
+ }
+
+ /**
+ * Checks if occurrences of specified tpe (DataSet, Controls) exceeds config limitation
+ *
+ * @param servicesConfigEnum type of element for which limitation is checked
+ * @param msg error message to display
+ * @return Optional of encountered error or empty
+ */
+ public Optional checkControlsLimitation(ServicesConfigEnum servicesConfigEnum, String msg) {
+ long max = getMaxInstanceAuthorized(servicesConfigEnum);
+ long value = getNumberOfItems(servicesConfigEnum);
+ return max == MAX_OCCURRENCE_NO_LIMIT_VALUE || value <= max ? Optional.empty() : Optional.of(SclReportItem.fatal(getXPath(), String.format("%s %s", msg, parentAdapter.getName())));
+ }
+
+ /**
+ * Counts all occurrence of Control into AccessPoint
+ *
+ * @param servicesConfigEnum type (GOOSE, Report, SampledValue, DataSet)
+ * @return number of occurrence
+ */
+ private long getNumberOfItems(ServicesConfigEnum servicesConfigEnum) {
+ if (!currentElem.isSetServer()) return 0L;
+ return currentElem.getServer().getLDevice().stream()
+ .map(tlDevice -> new LDeviceAdapter(parentAdapter, tlDevice))
+ .map(lDeviceAdapter -> {
+ List> list = new ArrayList<>();
+ if (servicesConfigEnum == ServicesConfigEnum.GSE || servicesConfigEnum == ServicesConfigEnum.SMV)
+ list.add(lDeviceAdapter.getLN0Adapter());
+ else list.addAll(lDeviceAdapter.getLNAdaptersIncludingLN0());
+ return list;
+ })
+ .flatMap(Collection::stream)
+ .map(abstractLNAdapter -> {
+ if (servicesConfigEnum == ServicesConfigEnum.DATASET) {
+ return abstractLNAdapter.getCurrentElem().getDataSet();
+ } else {
+ return abstractLNAdapter.getTControlsByType(getControlTypeClass(servicesConfigEnum));
+ }
+ })
+ .mapToLong(Collection::size).sum();
+ }
+
+ private Class extends TControl> getControlTypeClass(ServicesConfigEnum servicesConfigEnum) {
+ return switch (servicesConfigEnum) {
+ case REPORT -> TReportControl.class;
+ case GSE -> TGSEControl.class;
+ case SMV -> TSampledValueControl.class;
+ default -> throw new ScdException("Unknown Control Block Type: " + servicesConfigEnum);
+ };
+ }
+
+ /**
+ * Gets max number authorized in configuration of each element DataSets, FCDAs, Control Blocks) into an AccessPoint
+ *
+ * @param servicesConfigEnum element type
+ * @return max number authorized by config
+ */
+ private long getMaxInstanceAuthorized(ServicesConfigEnum servicesConfigEnum) {
+ if (currentElem.getServices() == null || currentElem.getServices().getConfDataSet() == null)
+ return MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ TServices tServices = currentElem.getServices();
+
+ return switch (servicesConfigEnum) {
+ case DATASET ->
+ tServices.getConfDataSet().isSetMax() ? tServices.getConfDataSet().getMax() : MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ case FCDA ->
+ tServices.getConfDataSet().isSetMaxAttributes() ? tServices.getConfDataSet().getMaxAttributes() : MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ case REPORT ->
+ tServices.getConfReportControl().isSetMax() ? tServices.getConfReportControl().getMax() : MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ case GSE -> tServices.getGOOSE().isSetMax() ? tServices.getGOOSE().getMax() : MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ case SMV -> tServices.getSMVsc().isSetMax() ? tServices.getSMVsc().getMax() : MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ };
+ }
+
+
+ /**
+ * Checks FCDA number limitation for binded IED
+ *
+ * @param msg message to display hen error occurred
+ * @return Optional of encountered error or empty
+ */
+ public Optional checkLimitationForBoundIEDFCDAs(List tExtRefs, String msg) {
+ long value = tExtRefs.stream()
+ .map(tExtRef -> {
+ IEDAdapter iedAdapter = getParentAdapter().getParentAdapter().getIEDAdapterByName(tExtRef.getIedName());
+ LDeviceAdapter lDeviceAdapter;
+ if (tExtRef.getSrcLDInst() != null) {
+ lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(tExtRef.getSrcLDInst());
+ } else {
+ lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(tExtRef.getLdInst());
+ }
+ AbstractLNAdapter> abstractLNAdapter;
+ if (!tExtRef.isSetSrcLNClass() || tExtRef.getSrcLNClass().contains(TLLN0Enum.LLN_0.value())) {
+ abstractLNAdapter = lDeviceAdapter.getLN0Adapter();
+ } else {
+ abstractLNAdapter = lDeviceAdapter.getLNAdapter(tExtRef.getSrcLNClass().get(0), tExtRef.getSrcLNInst(), tExtRef.getSrcPrefix());
+ }
+ return abstractLNAdapter.getFCDAs(tExtRef);
+ })
+ .flatMap(Collection::stream)
+ .toList()
+ .size();
+ long max;
+ if (currentElem.getServices() == null) {
+ max = AccessPointAdapter.MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ } else {
+ TClientServices tClientServices = currentElem.getServices().getClientServices();
+ max = tClientServices != null && tClientServices.isSetMaxAttributes() ? tClientServices.getMaxAttributes() : AccessPointAdapter.MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ }
+
+ return max == AccessPointAdapter.MAX_OCCURRENCE_NO_LIMIT_VALUE || value <= max ? Optional.empty() :
+ Optional.of(SclReportItem.fatal(getParentAdapter().getXPath(), msg));
+
+ }
+
+ /**
+ * @param sclReportItems
+ * @param tExtRefs
+ */
+ record ExtRefAnalyzeRecord(List sclReportItems, List tExtRefs) {
+ }
+
+ /**
+ * Returns all ExtRef of the AccessPoint which have SrcCBName set and ServiceType provided
+ *
+ * @return ExtRefAnalyzeRecord object containing Set of ExtRefs and errors list for ExtRefs with SrcCBName and without ServiceType provided
+ */
+ public ExtRefAnalyzeRecord getAllCoherentExtRefForAnalyze() {
+ List sclReportItems = new ArrayList<>();
+ List tExtRefList = new ArrayList<>();
+ streamLDeviceAdapters().map(lDeviceAdapter -> {
+ List extRefs = lDeviceAdapter.getLN0Adapter().getExtRefs().stream().filter(TExtRef::isSetSrcCBName).collect(Collectors.toCollection(ArrayList::new));
+ sclReportItems.addAll(checkExtRefWithoutServiceType(extRefs, lDeviceAdapter.getXPath()));
+ extRefs.removeIf(tExtRef -> !tExtRef.isSetServiceType());
+ return extRefs;
+ }).flatMap(Collection::stream).forEach(tExtRef -> {
+ if (tExtRefList.isEmpty())
+ tExtRefList.add(tExtRef);
+ else {
+ if (tExtRefList.stream().noneMatch(t -> isExtRefFeedBySameControlBlock(tExtRef, t)))
+ tExtRefList.add(tExtRef);
+ }
+ });
+ return new ExtRefAnalyzeRecord(sclReportItems, tExtRefList);
+ }
+
+ /**
+ * Checks all ExtRefs with SrcCBName and without ServiceType provided
+ *
+ * @param tExtRefs Set of ExtRefs to check
+ * @return errors list
+ */
+ private List checkExtRefWithoutServiceType(List tExtRefs, String xPath) {
+ return tExtRefs.stream()
+ .filter(tExtRef -> !tExtRef.isSetServiceType())
+ .map(tExtRef ->
+ SclReportItem.fatal(xPath, "ExtRef signal without ServiceType : " + tExtRef.getDesc()))
+ .toList();
+ }
+
+ /**
+ * Checks if two ExtRefs fed by same Control Block for SCL limits analyze
+ * Nota : this equality is only for checking limitation check
+ *
+ * @param t1 extref to compare
+ * @param t2 extref to compare
+ * @return true if the two ExtRef are fed by same Control Block, otherwise false
+ */
+ private static boolean isExtRefFeedBySameControlBlock(TExtRef t1, TExtRef t2) {
+ String srcLNClass1 = (t1.isSetSrcLNClass()) ? t1.getSrcLNClass().get(0) : TLLN0Enum.LLN_0.value();
+ String srcLNClass2 = (t2.isSetSrcLNClass()) ? t2.getSrcLNClass().get(0) : TLLN0Enum.LLN_0.value();
+ return Utils.equalsOrBothBlank(t1.getIedName(), t2.getIedName())
+ && Utils.equalsOrBothBlank(t1.getSrcLDInst(), t2.getSrcLDInst())
+ && srcLNClass1.equals(srcLNClass2)
+ && Utils.equalsOrBothBlank(t1.getSrcLNInst(), t2.getSrcLNInst())
+ && Utils.equalsOrBothBlank(t1.getSrcPrefix(), t2.getSrcPrefix())
+ && t1.getServiceType().equals(t2.getServiceType());
+ }
+
+ /**
+ * Checks Control Blocks (Report, Goose, SMV) number limitation for binded IED
+ *
+ * @return List of errors encountered
+ */
+ public List checkLimitationForBoundIEDControls(List tExtRefs) {
+ Map> extRefsByServiceType = tExtRefs.stream()
+ .filter(TExtRef::isSetServiceType)
+ .collect(Collectors.groupingBy(TExtRef::getServiceType, Collectors.toSet()));
+ return extRefsByServiceType.keySet().stream()
+ .map(tServiceType -> {
+ Set tExtRefSet = extRefsByServiceType.get(tServiceType);
+ return switch (tServiceType) {
+ case REPORT ->
+ checkLimitationForOneControlType(tExtRefSet, CLIENT_IED_NAME + getParentAdapter().getName() + " subscribes to too much REPORT Control Blocks.", ServicesConfigEnum.REPORT);
+ case GOOSE ->
+ checkLimitationForOneControlType(tExtRefSet, CLIENT_IED_NAME + getParentAdapter().getName() + " subscribes to too much GOOSE Control Blocks.", ServicesConfigEnum.GSE);
+ case SMV ->
+ checkLimitationForOneControlType(tExtRefSet, CLIENT_IED_NAME + getParentAdapter().getName() + " subscribes to too much SMV Control Blocks.", ServicesConfigEnum.SMV);
+ default -> throw new ScdException("Unsupported value: " + tServiceType);
+ };
+ }).flatMap(Optional::stream)
+ .toList();
+ }
+
+ /**
+ * Checks Control Block number limitation for binded IED
+ *
+ * @param tExtRefs list of ExtRefs referenced same ied
+ * @param msg message to display hen error occured
+ * @param servicesConfigEnum type of Control Block for which check is done
+ * @return Optional of encountered error or empty
+ */
+ private Optional checkLimitationForOneControlType(Set tExtRefs, String msg, ServicesConfigEnum servicesConfigEnum) {
+ long max = getMaxInstanceAuthorizedForBoundIED(servicesConfigEnum);
+ long value = tExtRefs.size();
+ return max == AccessPointAdapter.MAX_OCCURRENCE_NO_LIMIT_VALUE || value <= max ? Optional.empty() : Optional.of(SclReportItem.fatal(getParentAdapter().getXPath(), msg));
+ }
+
+ /**
+ * Gets max number authorized in configuration of each element ( DataSets, FCDAs, Control Blocks) into an AccessPoint
+ *
+ * @param servicesConfigEnum element type
+ * @return max number authorized by config
+ */
+ private long getMaxInstanceAuthorizedForBoundIED(ServicesConfigEnum servicesConfigEnum) {
+ if (currentElem.getServices() == null || currentElem.getServices().getClientServices() == null) {
+ return AccessPointAdapter.MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ }
+ TClientServices tClientServices = currentElem.getServices().getClientServices();
+ return switch (servicesConfigEnum) {
+ case FCDA ->
+ tClientServices.isSetMaxAttributes() ? tClientServices.getMaxAttributes() : AccessPointAdapter.MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ case REPORT ->
+ tClientServices.isSetMaxReports() ? tClientServices.getMaxReports() : AccessPointAdapter.MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ case GSE ->
+ tClientServices.isSetMaxGOOSE() ? tClientServices.getMaxGOOSE() : AccessPointAdapter.MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ case SMV ->
+ tClientServices.isSetMaxSMV() ? tClientServices.getMaxSMV() : AccessPointAdapter.MAX_OCCURRENCE_NO_LIMIT_VALUE;
+ default -> throw new ScdException("Unsupported value: " + servicesConfigEnum);
+ };
+
+ }
+
+
+}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java
index ecd34e231..a12c63ec4 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java
@@ -4,14 +4,19 @@
package org.lfenergy.compas.sct.commons.scl.ied;
-import org.lfenergy.compas.scl2007b4.model.TAnyLN;
-import org.lfenergy.compas.scl2007b4.model.TDAI;
-import org.lfenergy.compas.scl2007b4.model.TDOI;
-import org.lfenergy.compas.scl2007b4.model.TSDI;
+import org.lfenergy.compas.scl2007b4.model.*;
+import org.lfenergy.compas.sct.commons.dto.ExtrefTarget;
+import org.lfenergy.compas.sct.commons.dto.SclReportItem;
import org.lfenergy.compas.sct.commons.exception.ScdException;
+import org.lfenergy.compas.sct.commons.scl.ObjectReference;
import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
import org.lfenergy.compas.sct.commons.util.Utils;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
/**
* A representation of the model object
@@ -39,10 +44,18 @@
*/
public class DOIAdapter extends SclElementAdapter, TDOI> implements IDataParentAdapter {
+ protected static final String DA_NAME_SET_SRC_REF = "setSrcRef";
+ protected static final String DA_NAME_SET_SRC_CB = "setSrcCB";
+ protected static final String DA_NAME_SET_TST_REF = "setTstRef";
+ protected static final String DA_NAME_SET_TST_CB = "setTstCB";
+
+ private static final Comparator EXTREF_DESC_SUFFIX_COMPARATOR = Comparator.comparingInt(extRef -> extractDescSuffix(extRef.getDesc()));
+
/**
* Constructor
+ *
* @param parentAdapter Parent container reference
- * @param currentElem Current reference
+ * @param currentElem Current reference
*/
protected DOIAdapter(AbstractLNAdapter extends TAnyLN> parentAdapter, TDOI currentElem) {
super(parentAdapter, currentElem);
@@ -50,6 +63,7 @@ protected DOIAdapter(AbstractLNAdapter extends TAnyLN> parentAdapter, TDOI cur
/**
* Check if node is child of the reference node
+ *
* @return link parent child existence
*/
@Override
@@ -65,6 +79,7 @@ protected String elementXPath() {
/**
* Gets SDI by name from current DOI
+ *
* @param sName name of SDI to get
* @return RootSDIAdapter object
* @throws ScdException throws when specified name of SDI not present in current DOI
@@ -76,40 +91,52 @@ public RootSDIAdapter getStructuredDataAdapterByName(String sName) throws ScdExc
.filter(tUnNaming -> tUnNaming.getClass().equals(TSDI.class))
.map(TSDI.class::cast)
.filter(tsdi -> tsdi.getName().equals(sName))
- .map(tsdi -> new RootSDIAdapter(this,tsdi))
+ .map(tsdi -> new RootSDIAdapter(this, tsdi))
.findFirst()
.orElseThrow(
- ()-> new ScdException(
- String.format("Unknown SDI (%s) in DOI (%s)", sName, currentElem.getName())
- )
+ () -> new ScdException(
+ String.format("Unknown SDI (%s) in DOI (%s)", sName, currentElem.getName())
+ )
);
}
/**
* Gets DAI from current DOI
+ *
* @param daName name of DAI to get
* @return DAIAdapter object
* @throws ScdException throws when specified name of DAI not present in current DOI
*/
@Override
public DAIAdapter getDataAdapterByName(String daName) throws ScdException {
- return currentElem.getSDIOrDAI()
+ return findDataAdapterByName(daName)
+ .orElseThrow(
+ () -> new ScdException(
+ String.format("Unknown DAI (%s) in DOI (%s)", daName, currentElem.getName())
+ )
+ );
+ }
+
+ /**
+ * Given a DAI[name], returns an associated DAIAdapter
+ *
+ * @param daName name of DAI to get
+ * @return an Optional DAIAdapter if found, Optional.empty() otherwise
+ */
+ public Optional findDataAdapterByName(String daName) {
+ return currentElem.getSDIOrDAI()
.stream()
.filter(tUnNaming -> tUnNaming.getClass().equals(TDAI.class))
.map(TDAI.class::cast)
.filter(tdai -> tdai.getName().equals(daName))
- .map(tdai -> new DAIAdapter(this,tdai))
- .findFirst()
- .orElseThrow(
- ()-> new ScdException(
- String.format("Unknown DAI (%s) in DOI (%s)", daName, currentElem.getName())
- )
- );
+ .map(tdai -> new DAIAdapter(this, tdai))
+ .findFirst();
}
/**
* Adds DAI to current DOI
- * @param name name of DAI to add
+ *
+ * @param name name of DAI to add
* @param isUpdatable updatability state of DAI
* @return DAIAdapter object as added DAI
*/
@@ -119,11 +146,12 @@ public DAIAdapter addDAI(String name, boolean isUpdatable) {
tdai.setName(name);
tdai.setValImport(isUpdatable);
currentElem.getSDIOrDAI().add(tdai);
- return new DAIAdapter(this,tdai);
+ return new DAIAdapter(this, tdai);
}
/**
* Adds SDOI to SDI in current DOI
+ *
* @param sdoName name of SDOI to add
* @return RootSDIAdapter object as added SDOI
*/
@@ -132,7 +160,64 @@ public RootSDIAdapter addSDOI(String sdoName) {
TSDI tsdi = new TSDI();
tsdi.setName(sdoName);
currentElem.getSDIOrDAI().add(tsdi);
- return new RootSDIAdapter(this,tsdi);
+ return new RootSDIAdapter(this, tsdi);
+ }
+
+ /**
+ * Update the DAI/Val according to the ExtRef attributes.
+ * If the ExtRef.desc start with DAI[name='purpose']/Val and end with "_1" (nominal case):
+ * - DAI[name='setSrcRef']/Val is updated with ExtRef attributes concatenation
+ * - DAI[name='setSrcCB']/Val is updated with ExtRef attributes concatenation if ExtRef.srcCBName is present
+ * If the ExtRef.desc start with DAI[name='purpose']/Val and end with "_2" or greater (test case):
+ * - DAI[name='setTstRef']/Val is updated with ExtRef attributes concatenation
+ * - DAI[name='setTstCB']/Val is updated with ExtRef attributes concatenation if ExtRef.srcCBName is present
+ *
+ * @param tExtRefs all the ExtRefs contained in the current LDevice/LLN0
+ * @return a filled SclReportItem if an error occurs, empty SclReportItem otherwise
+ */
+ public Optional updateDaiFromExtRef(List tExtRefs) {
+ Optional tExtRefMinOptional = tExtRefs.stream().min(EXTREF_DESC_SUFFIX_COMPARATOR);
+
+ if (tExtRefMinOptional.isPresent() && extractDescSuffix(tExtRefMinOptional.get().getDesc()) == 1) {
+ TExtRef tExtRefMin = tExtRefMinOptional.get();
+ findDataAdapterByName(DA_NAME_SET_SRC_REF)
+ .orElse(addDAI(DA_NAME_SET_SRC_REF, true))
+ .updateVal(createInRefValNominalString(tExtRefMin));
+ if (tExtRefMin.isSetSrcCBName()) {
+ findDataAdapterByName(DA_NAME_SET_SRC_CB)
+ .orElse(addDAI(DA_NAME_SET_SRC_CB, true))
+ .updateVal(createInRefValTestString(tExtRefMin));
+ }
+
+ Optional tExtRefMaxOptional = tExtRefs.stream().max(Comparator.comparingInt(o -> Integer.parseInt(Objects.requireNonNull(Utils.extractField(o.getDesc(), "_", -1)))));
+ if (tExtRefMaxOptional.isPresent() && extractDescSuffix(tExtRefMaxOptional.get().getDesc()) > 1) {
+ TExtRef tExtRefMax = tExtRefMaxOptional.get();
+ findDataAdapterByName(DA_NAME_SET_TST_REF)
+ .orElse(addDAI(DA_NAME_SET_TST_REF, true))
+ .updateVal(createInRefValNominalString(tExtRefMax));
+ if (tExtRefMax.isSetSrcCBName()) {
+ findDataAdapterByName(DA_NAME_SET_TST_CB)
+ .orElse(addDAI(DA_NAME_SET_TST_CB, true))
+ .updateVal(createInRefValTestString(tExtRefMax));
+ }
+ }
+ } else {
+ return Optional.of(SclReportItem.warning(getXPath(), "The DOI %s can't be bound with an ExtRef".formatted(getXPath())));
+ }
+
+ return Optional.empty();
+ }
+
+ private static int extractDescSuffix(String desc) throws NumberFormatException {
+ return Integer.parseInt(Utils.extractField(desc, "_", -1));
+ }
+
+ private String createInRefValNominalString(TExtRef extRef) {
+ return new ObjectReference(extRef, ExtrefTarget.SRC_REF).getReference();
+ }
+
+ private String createInRefValTestString(TExtRef extRef) {
+ return new ObjectReference(extRef, ExtrefTarget.SRC_CB).getReference();
}
/**
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 542c9887a..df3934aac 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
@@ -9,17 +9,16 @@
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.dto.ExtRefBindingInfo;
import org.lfenergy.compas.sct.commons.dto.ExtRefSignalInfo;
+import org.lfenergy.compas.sct.commons.dto.SclReportItem;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.ObjectReference;
import org.lfenergy.compas.sct.commons.scl.PrivateService;
import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
+import org.lfenergy.compas.sct.commons.util.ServicesConfigEnum;
import org.lfenergy.compas.sct.commons.util.Utils;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
import java.util.stream.Stream;
/**
@@ -320,4 +319,48 @@ public Optional getPrivateHeader(String privateType) {
public Optional getPrivateCompasBay() {
return PrivateService.extractCompasPrivate(currentElem, TCompasBay.class);
}
+
+ /**
+ * Checks if Controls, DataSets and FCDAs of IED respect config limitation
+ * @return empty list if all IED respect limits, otherwise list of errors
+ */
+ public List checkDataGroupCoherence() {
+ return currentElem.getAccessPoint().stream()
+ .map(tAccessPoint -> {
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(this, tAccessPoint);
+ List sclReportItems = new ArrayList<>(accessPointAdapter.checkFCDALimitations());
+ accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.DATASET, "There are too much DataSets for the IED")
+ .ifPresent(sclReportItems::add);
+ accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.REPORT, "There are too much Report Control Blocks for the IED")
+ .ifPresent(sclReportItems::add);
+ accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.GSE, "There are too much GOOSE Control Blocks for the IED")
+ .ifPresent(sclReportItems::add);
+ accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.SMV, "There are too much SMV Control Blocks for the IED")
+ .ifPresent(sclReportItems::add);
+ return sclReportItems;
+ }).flatMap(Collection::stream)
+ .toList();
+ }
+
+ /**
+ * Checks if Controls and FCDAs of source IEDs respect config limitation
+ * @return empty list if all IED respect limits, otherwise list of errors
+ */
+ public List checkBindingDataGroupCoherence() {
+ return currentElem.getAccessPoint().stream()
+ .map(tAccessPoint -> {
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(this, tAccessPoint);
+ AccessPointAdapter.ExtRefAnalyzeRecord extRefAnalyzeRecord = accessPointAdapter.getAllCoherentExtRefForAnalyze();
+ List sclReportItems = new ArrayList<>(extRefAnalyzeRecord.sclReportItems());
+ accessPointAdapter.checkLimitationForBoundIEDFCDAs(extRefAnalyzeRecord.tExtRefs(), "There are too much FCDA for the Client IED " + getName())
+ .ifPresent(sclReportItems::add);
+ sclReportItems.addAll(accessPointAdapter.checkLimitationForBoundIEDControls(extRefAnalyzeRecord.tExtRefs()));
+ return sclReportItems;
+ }).flatMap(List::stream).toList();
+
+ }
+
+
+
+
}
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
index b2e5f33e2..0f0496fc1 100644
--- 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
@@ -420,4 +420,5 @@ private IEDAdapter getIedAdapter() {
private SclRootAdapter getSclRootAdapter() {
return getIedAdapter().getParentAdapter();
}
+
}
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 efc341581..e3399ad5d 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
@@ -61,6 +61,7 @@
* LDName = "name" attribute of IEDName element + "inst" attribute of LDevice element
* LNName = "prefix" + "lnClass" + "lnInst"
*
+ *
* @see org.lfenergy.compas.scl2007b4.model.TLN0
* @see org.lfenergy.compas.sct.commons.scl.ied.AbstractLNAdapter
*/
@@ -70,17 +71,22 @@ public class LN0Adapter extends AbstractLNAdapter {
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();
+ private static final String DAI_NAME_PURPOSE = "purpose";
+ private static final String INREF_PREFIX = "InRef";
+
/**
* Constructor
+ *
* @param parentAdapter Parent container reference
- * @param ln0 Current reference
+ * @param ln0 Current reference
*/
public LN0Adapter(LDeviceAdapter parentAdapter, LN0 ln0) {
- super(parentAdapter,ln0);
+ super(parentAdapter, ln0);
}
/**
* Check if node is child of the reference node
+ *
* @return link parent child existence
*/
@Override
@@ -96,6 +102,7 @@ protected String elementXPath() {
/**
* Gets current LN0 class type
+ *
* @return LN0.class
*/
@Override
@@ -105,6 +112,7 @@ protected Class getElementClassType() {
/**
* Gets LNClass enum value of current LNO
+ *
* @return LNClass value
*/
public String getLNClass() {
@@ -113,6 +121,7 @@ public String getLNClass() {
/**
* Gets LNInst value of current LN0
+ *
* @return ""
*/
@Override
@@ -122,6 +131,7 @@ public String getLNInst() {
/**
* Gets Prefix value of current LN0
+ *
* @return ""
*/
@Override
@@ -131,19 +141,22 @@ public String getPrefix() {
/**
* Gets Inputs node as an adapter
+ *
* @return an InputsAdapter
*/
- public InputsAdapter getInputsAdapter(){
+ 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
+ /**
+ * 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
*/
@Override
- protected boolean matchesDataAttributes(String dataAttribute){
- return super.matchesDataAttributes(dataAttribute) ||
+ protected boolean matchesDataAttributes(String dataAttribute) {
+ return super.matchesDataAttributes(dataAttribute) ||
currentElem.getSampledValueControl().stream().anyMatch(smp -> smp.getName().equals(dataAttribute)) ||
currentElem.getGSEControl().stream().anyMatch(gse -> gse.getName().equals(dataAttribute));
}
@@ -178,6 +191,7 @@ private ResumedDataTemplate createDaiFilter(DoTypeName doTypeName, DaTypeName da
/**
* Verify and update LDevice status in parent Node
+ *
* @param iedNameLDeviceInstList pair of Ied name and LDevice inst attributes
* @return Set of Errors
*/
@@ -186,7 +200,7 @@ public Optional updateLDeviceStatus(List> ie
final String iedName = getParentAdapter().getParentAdapter().getName();
final String ldInst = getParentAdapter().getInst();
ResumedDataTemplate daiBehFilter = createDaiFilter(BEHAVIOUR_DO_TYPE_NAME, BEHAVIOUR_DA_TYPE_NAME);
- List daiBehList = getDAI(daiBehFilter, false);
+ List daiBehList = getDAI(daiBehFilter, false);
if (daiBehList.isEmpty()) {
return Optional.of(buildFatalReportItem("The LDevice doesn't have a DO @name='Beh' OR its associated DA@fc='ST' AND DA@name='stVal'"));
}
@@ -206,13 +220,13 @@ public Optional updateLDeviceStatus(List> ie
ResumedDataTemplate newDaModToSetInLN0 = optionalModStVal.get();
String initialValue = newDaModToSetInLN0.findFirstValue().orElse("");
lDeviceActivation.checkLDeviceActivationStatus(iedName, ldInst, compasLDeviceStatus, enumValues);
- if(lDeviceActivation.isUpdatable()){
- if(!initialValue.equals(lDeviceActivation.getNewVal())) {
+ if (lDeviceActivation.isUpdatable()) {
+ if (!initialValue.equals(lDeviceActivation.getNewVal())) {
newDaModToSetInLN0.setVal(lDeviceActivation.getNewVal());
updateDAI(newDaModToSetInLN0);
}
- }else {
- if(lDeviceActivation.getErrorMessage() != null) {
+ } else {
+ if (lDeviceActivation.getErrorMessage() != null) {
return Optional.of(buildFatalReportItem(lDeviceActivation.getErrorMessage()));
}
}
@@ -221,13 +235,13 @@ public Optional updateLDeviceStatus(List> ie
public Optional getLDeviceStatus() {
return getDaiModStVal()
- .flatMap(ResumedDataTemplate::findFirstValue);
+ .flatMap(ResumedDataTemplate::findFirstValue);
}
private Optional getDaiModStVal() {
ResumedDataTemplate daiModFilter = createDaiFilter(MOD_DO_TYPE_NAME, STVAL_DA_TYPE_NAME);
return getDAI(daiModFilter, false).stream()
- .findFirst();
+ .findFirst();
}
private static DaTypeName getDaTypeNameForBeh() {
@@ -237,4 +251,28 @@ private static DaTypeName getDaTypeNameForBeh() {
daTypeNameBeh.setFc(TFCEnum.ST);
return daTypeNameBeh;
}
+
+ /**
+ * Update DAIs of DO InRef in all LN0 of the SCD using matching ExtRef information.
+ *
+ * @return A list of SclReport Objects that contain errors
+ */
+ public List updateDoInRef() {
+ return getDOIAdapters().stream()
+ .filter(doiAdapter -> doiAdapter.getCurrentElem().isSetName()
+ && doiAdapter.getCurrentElem().getName().startsWith(INREF_PREFIX)
+ && doiAdapter.findDataAdapterByName(DAI_NAME_PURPOSE).isPresent())
+ .map(doiAdapter -> doiAdapter.getDataAdapterByName(DAI_NAME_PURPOSE).getCurrentElem().getVal().stream()
+ .findFirst()
+ .map(tVal -> doiAdapter.updateDaiFromExtRef(getExtRefsByDesc(tVal.getValue())))
+ .orElse(Optional.of(SclReportItem.warning(getXPath(), "The DOI %s can't be bound with an ExtRef".formatted(getXPath())))))
+ .flatMap(Optional::stream)
+ .toList();
+ }
+
+ private List getExtRefsByDesc(String desc) {
+ return getExtRefs().stream()
+ .filter(tExtRef -> tExtRef.isSetDesc() && tExtRef.getDesc().contains(desc))
+ .toList();
+ }
}
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/package-info.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/package-info.java
index 5d8086435..5bbacdaba 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/package-info.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/package-info.java
@@ -3,9 +3,9 @@
// SPDX-License-Identifier: Apache-2.0
/**
- * scl.ied is a group of services for operating on
+ * scl.ied is a group of services for operating on
* {@link org.lfenergy.compas.scl2007b4.model.TIED IED} object
- *
+ *
* @see org.lfenergy.compas.scl2007b4.model.TAccessPoint
* @see org.lfenergy.compas.scl2007b4.model.TServices
* @see org.lfenergy.compas.scl2007b4.model.TLDevice
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/package-info.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/package-info.java
index 9385c8a5a..4529100aa 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/package-info.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/package-info.java
@@ -3,13 +3,13 @@
// SPDX-License-Identifier: Apache-2.0
/**
- * commons.scl is a group of services for operating on
+ * commons.scl is a group of services for operating on
* {@link org.lfenergy.compas.scl2007b4.model.THeader Header} ,
* {@link org.lfenergy.compas.scl2007b4.model.TSubstation Substation} ,
* {@link org.lfenergy.compas.scl2007b4.model.TCommunication Communication} ,
* {@link org.lfenergy.compas.scl2007b4.model.TIED IED} ,
* {@link org.lfenergy.compas.scl2007b4.model.TDataTypeTemplates DataTypeTemplates} objects
- *
+ *
* @see org.lfenergy.compas.scl2007b4.model.SCL
*/
package org.lfenergy.compas.sct.commons.scl;
\ No newline at end of file
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/package-info.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/package-info.java
index 2f3987594..45b2f2e0d 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/package-info.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/sstation/package-info.java
@@ -2,9 +2,9 @@
//
// SPDX-License-Identifier: Apache-2.0
/**
- * scl.sstation is a group of services for operating on
+ * scl.sstation is a group of services for operating on
* {@link org.lfenergy.compas.scl2007b4.model.TSubstation Substation} object
- *
+ *
* @see org.lfenergy.compas.scl2007b4.model.TVoltageLevel
* @see org.lfenergy.compas.scl2007b4.model.TFunction
* @see org.lfenergy.compas.scl2007b4.model.TBay
diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ServicesConfigEnum.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ServicesConfigEnum.java
new file mode 100644
index 000000000..cfa6755e0
--- /dev/null
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/ServicesConfigEnum.java
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2022 RTE FRANCE
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package org.lfenergy.compas.sct.commons.util;
+
+public enum ServicesConfigEnum {
+ GSE,
+ SMV,
+ REPORT,
+ DATASET,
+ FCDA;
+
+}
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 dc98feb9b..0fd7e179c 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
@@ -437,7 +437,7 @@ void createMapIEDNameAndPrivate_should_return_map_of_three_items() {
//When
SclRootAdapter sclRootAdapter = SclService.initScl(Optional.empty(), "hv", "hr");
sclRootAdapter.setCurrentElem(scl);
- Stream tPrivateStream = PrivateService.createMapIEDNameAndPrivate(sclRootAdapter);
+ Stream tPrivateStream = PrivateService.streamIcdHeaderPrivatesWithDistinctIEDName(sclRootAdapter);
//Then
assertThat(tPrivateStream.toList()).hasSize(3)
@@ -467,7 +467,7 @@ void createMapIEDNameAndPrivate_should_return_empty_map_when_no_compasicdheader_
//When
SclRootAdapter sclRootAdapter = SclService.initScl(Optional.empty(), "hv", "hr");
sclRootAdapter.setCurrentElem(scl);
- Stream tPrivateStream = PrivateService.createMapIEDNameAndPrivate(sclRootAdapter);
+ Stream tPrivateStream = PrivateService.streamIcdHeaderPrivatesWithDistinctIEDName(sclRootAdapter);
//Then
assertThat(tPrivateStream.toList()).isEmpty();
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 645615ced..94a38dcf4 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
@@ -9,6 +9,7 @@
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.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.dto.*;
@@ -133,7 +134,6 @@ void testAddSubnetworksWithoutImportingIcdAddressAndPhysConn() {
assertThat(marshalledScd).doesNotContain("", "PhysConn");
}
-
@Test
void testGetSubnetwork() {
SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION);
@@ -285,7 +285,7 @@ void getExtRefSourceInfo_shouldReturnEmptyList_whenExtRefMatchNoFCDA() {
extRefInfo.setHolderLnClass(lnClass);
//When
- List controlBlocks = SclService.getExtRefSourceInfo(scd, extRefInfo);
+ List controlBlocks = SclService.getExtRefSourceInfo(scd, extRefInfo);
//Then
assertThat(controlBlocks).isEmpty();
@@ -357,6 +357,7 @@ void updateExtRefSource_shouldThrowScdException_whenBindingInfoNullOrInvalid() {
assertThat(extRefInfo.getBindingInfo()).isNotNull();
assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// binding invalid
}
+
@Test
void updateExtRefSource_shouldThrowScdException_whenBindingInternalByIedName() {
//Given
@@ -434,6 +435,7 @@ void updateExtRefSource_shouldThrowScdException_whenSourceInfoNullOrInvalid() {
assertThat(extRefInfo.getSourceInfo()).isNotNull();
assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// signal invalid
}
+
@Test
void updateExtRefSource_shouldThrowScdException_whenBindingExternalBinding() {
//Given
@@ -751,7 +753,7 @@ void testImportSTDElementsInSCD() {
SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter scdRootAdapter = new SclRootAdapter(scd);
- SclRootAdapter expectedScdAdapter = assertDoesNotThrow( () -> SclService.importSTDElementsInSCD(
+ SclRootAdapter expectedScdAdapter = assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(
scdRootAdapter, Set.of(std), DTO.comMap));
assertThat(expectedScdAdapter.getCurrentElem().getIED()).hasSize(1);
assertThat(expectedScdAdapter.getCurrentElem().getDataTypeTemplates()).hasNoNullFieldsOrProperties();
@@ -767,13 +769,13 @@ void testImportSTDElementsInSCD_with_Multiple_STD() {
SCL std2 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_SITESITE1SCU2.xml");
SclRootAdapter scdRootAdapter = new SclRootAdapter(scd);
- SclRootAdapter expectedScdAdapter = assertDoesNotThrow( () -> SclService.importSTDElementsInSCD(
+ SclRootAdapter expectedScdAdapter = assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(
scdRootAdapter, Set.of(std0, std1, std2), DTO.comMap));
assertThat(expectedScdAdapter.getCurrentElem().getIED()).hasSize(3);
assertThat(expectedScdAdapter.getCurrentElem().getDataTypeTemplates()).hasNoNullFieldsOrProperties();
assertThat(expectedScdAdapter.getCurrentElem().getCommunication().getSubNetwork()).hasSize(2);
- assertThat(expectedScdAdapter.getCurrentElem().getCommunication().getSubNetwork().get(0).getConnectedAP()).hasSizeBetween(1,3);
- assertThat(expectedScdAdapter.getCurrentElem().getCommunication().getSubNetwork().get(1).getConnectedAP()).hasSizeBetween(1,3);
+ assertThat(expectedScdAdapter.getCurrentElem().getCommunication().getSubNetwork().get(0).getConnectedAP()).hasSizeBetween(1, 3);
+ assertThat(expectedScdAdapter.getCurrentElem().getCommunication().getSubNetwork().get(1).getConnectedAP()).hasSizeBetween(1, 3);
assertIsMarshallable(scd);
}
@@ -790,6 +792,17 @@ void testImportSTDElementsInSCD_Several_STD_Match_Compas_ICDHeader() {
assertIsMarshallable(scd);
}
+ @Test
+ void test_importSTDElementsInSCD_should_not_throw_exception_when_SCD_file_contains_same_ICDHeader_in_two_different_functions() {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd_with_same_compas_icd_header_in_different_functions.xml");
+ SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
+ SclRootAdapter scdRootAdapter = new SclRootAdapter(scd);
+ //When Then
+ assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(scdRootAdapter, Set.of(std), DTO.comMap));
+ assertIsMarshallable(scd);
+ }
+
@Test
void testImportSTDElementsInSCD_Compas_ICDHeader_Not_Match() {
//Given
@@ -798,7 +811,7 @@ void testImportSTDElementsInSCD_Compas_ICDHeader_Not_Match() {
SclRootAdapter scdRootAdapter = new SclRootAdapter(scd);
//When Then
Set stds = Set.of(std);
- assertThrows(ScdException.class, ()-> SclService.importSTDElementsInSCD(scdRootAdapter, stds, DTO.comMap));
+ assertThrows(ScdException.class, () -> SclService.importSTDElementsInSCD(scdRootAdapter, stds, DTO.comMap));
assertIsMarshallable(scd);
}
@@ -807,9 +820,9 @@ void testImportSTDElementsInSCD_No_STD_Match() {
//Given
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml");
SclRootAdapter scdRootAdapter = new SclRootAdapter(scd);
- //When Then
+ //When Then
Set stds = new HashSet<>();
- assertThrows(ScdException.class, ()-> SclService.importSTDElementsInSCD(scdRootAdapter, stds, DTO.comMap));
+ assertThrows(ScdException.class, () -> SclService.importSTDElementsInSCD(scdRootAdapter, stds, DTO.comMap));
assertIsMarshallable(scd);
}
@@ -891,10 +904,10 @@ private static Stream sclProviderMissingRequiredObjects() {
Tuple[] scl4Errors = new Tuple[]{Tuple.tuple("The LDevice doesn't have a DO @name='Mod'",
"/SCL/IED[@name=\"IedName1\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0")};
return Stream.of(
- Arguments.of("MissingDOBeh",scl1, scl1Errors),
- Arguments.of("MissingLDevicePrivate",scl2, scl2Errors),
- Arguments.of("MissingLDevicePrivateAttribute",scl3, scl3Errors),
- Arguments.of("MissingDOMod",scl4, scl4Errors)
+ Arguments.of("MissingDOBeh", scl1, scl1Errors),
+ Arguments.of("MissingLDevicePrivate", scl2, scl2Errors),
+ Arguments.of("MissingLDevicePrivateAttribute", scl3, scl3Errors),
+ Arguments.of("MissingDOMod", scl4, scl4Errors)
);
}
@@ -923,21 +936,21 @@ private static Stream sclProviderBasedLDeviceStatus() {
SCL scl2 = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_LD_STATUS_UNTESTED.scd");
SCL scl3 = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test1_LD_STATUS_INACTIVE.scd");
Tuple[] scl1Errors = new Tuple[]{Tuple.tuple("The LDevice cannot be set to 'off' but has not been selected into SSD.",
- "/SCL/IED[@name=\"IedName1\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"),
+ "/SCL/IED[@name=\"IedName1\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"),
Tuple.tuple("The LDevice cannot be set to 'on' but has been selected into SSD.",
"/SCL/IED[@name=\"IedName2\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"),
Tuple.tuple("The LDevice cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'.",
"/SCL/IED[@name=\"IedName3\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"
)};
Tuple[] scl2Errors = new Tuple[]{Tuple.tuple("The LDevice cannot be set to 'off' but has not been selected into SSD.",
- "/SCL/IED[@name=\"IedName1\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"),
+ "/SCL/IED[@name=\"IedName1\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"),
Tuple.tuple("The LDevice cannot be set to 'on' but has been selected into SSD.",
"/SCL/IED[@name=\"IedName2\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"),
Tuple.tuple("The LDevice cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'.",
"/SCL/IED[@name=\"IedName3\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"
)};
Tuple[] scl3Errors = new Tuple[]{Tuple.tuple("The LDevice is not qualified into STD but has been selected into SSD.",
- "/SCL/IED[@name=\"IedName1\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"),
+ "/SCL/IED[@name=\"IedName1\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"),
Tuple.tuple("The LDevice cannot be set to 'on' but has been selected into SSD.",
"/SCL/IED[@name=\"IedName2\"]/AccessPoint/Server/LDevice[@inst=\"LDSUIED\"]/LN0"),
Tuple.tuple("The LDevice cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'.",
@@ -1024,21 +1037,173 @@ void updateLDeviceStatus_shouldReturnUpdatedFile() {
assertEquals("off", getLDeviceStatusValue(sclReport.getSclRootAdapter().getCurrentElem(), "IedName3", "LDSUIED").get().getValue());
}
- private Optional getLDeviceStatusValue(SCL scl, String iedName, String ldInst){
+ @Test
+ void updateLDeviceStatus_shouldReturnUpdatedFile_when_DAI_Mod_DO_stVal_whatever_it_is_updatable_or_not() {
+ // Given
+ SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue_165_enhance_68_Test_Dai_Updatable.scd");
+ assertThat(getLDeviceStatusValue(givenScl, "IedName1", "LDSUIED"))
+ .map(TVal::getValue)
+ .hasValue("off");
+ assertThat(getLDeviceStatusValue(givenScl, "IedName2", "LDSUIED"))
+ .map(TVal::getValue)
+ .hasValue("on");
+ assertThat(getLDeviceStatusValue(givenScl, "IedName3", "LDSUIED"))
+ .map(TVal::getValue)
+ .isNotPresent();
+ assertThat(getLDeviceStatusValue(givenScl, "IedName4", "LDSUIED"))
+ .map(TVal::getValue)
+ .hasValue("on");
+ assertThat(getLDeviceStatusValue(givenScl, "IedName5", "LDSUIED"))
+ .map(TVal::getValue)
+ .hasValue("on");
+
+ // When
+ SclReport sclReport = SclService.updateLDeviceStatus(givenScl);
+
+ // Then
+ assertThat(sclReport.isSuccess()).isTrue();
+ assertThat(getLDeviceStatusValue(sclReport.getSclRootAdapter().getCurrentElem(), "IedName1", "LDSUIED"))
+ .map(TVal::getValue)
+ .hasValue("on");
+
+ assertThat(getLDeviceStatusValue(sclReport.getSclRootAdapter().getCurrentElem(), "IedName2", "LDSUIED"))
+ .map(TVal::getValue)
+ .hasValue("off");
+
+ assertThat(getLDeviceStatusValue(sclReport.getSclRootAdapter().getCurrentElem(), "IedName3", "LDSUIED"))
+ .map(TVal::getValue)
+ .hasValue("off");
+
+ assertThat(getLDeviceStatusValue(sclReport.getSclRootAdapter().getCurrentElem(), "IedName4", "LDSUIED"))
+ .map(TVal::getValue)
+ .hasValue("off");
+
+ assertThat(getLDeviceStatusValue(sclReport.getSclRootAdapter().getCurrentElem(), "IedName5", "LDSUIED"))
+ .map(TVal::getValue)
+ .hasValue("off");
+ }
+
+ private Optional getLDeviceStatusValue(SCL scl, String iedName, String ldInst) {
+ return getValFromDaiName(scl, iedName, ldInst, "Mod", "stVal");
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @CsvSource({
+ "Test update setSrcRef Value,LD_WITH_1_InRef,InRef2,setSrcRef,IED_NAME1LD_WITH_1_InRef/PRANCR1.Do11.sdo11",
+ "Test update setSrcCB Value,LD_WITH_1_InRef,InRef2,setSrcCB,IED_NAME1LD_WITH_1_InRef/prefixANCR1.GSE1",
+ "Test update setSrcRef Value,LD_WITH_3_InRef,InRef3,setSrcRef,IED_NAME1LD_WITH_3_InRef/PRANCR1.Do11.sdo11",
+ "Test update setSrcCB Value,LD_WITH_3_InRef,InRef3,setSrcCB,IED_NAME1LD_WITH_3_InRef/prefixANCR1.GSE1",
+ "Test update setTstRef Value,LD_WITH_3_InRef,InRef3,setTstRef,IED_NAME1LD_WITH_3_InRef/PRANCR1.Do11.sdo11",
+ "Test update setTstCB Value,LD_WITH_3_InRef,InRef3,setTstCB,IED_NAME1LD_WITH_3_InRef/prefixANCR3.GSE3"
+ })
+ void updateDoInRef_shouldReturnUpdatedFile(String testName, String ldInst, String doName, String daName, String expected) {
+ // Given
+ SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ok.xml");
+
+ // When
+ SclReport sclReport = SclService.updateDoInRef(givenScl);
+
+ // Then
+ assertThat(sclReport.isSuccess()).isTrue();
+ assertThat(getValFromDaiName(sclReport.getSclRootAdapter().getCurrentElem(), "IED_NAME1", ldInst, doName, daName)
+ .map(TVal::getValue))
+ .hasValue(expected);
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @CsvSource({
+ "Test with only 1 ExtRef should not update srcTstCB,LD_WITH_1_InRef,InRef2,setTstRef",
+ "Test with only 1 ExtRef should not update setTstCB Value,LD_WITH_1_InRef,InRef2,setTstCB"
+ })
+ void updateDoInRef_should_not_update_tst_DAI_When_only_1_ExtRef(String testName, String ldInst, String doName, String daName) {
+ // Given
+ SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ok.xml");
+
+ // When
+ SclReport sclReport = SclService.updateDoInRef(givenScl);
+
+ // Then
+ assertThat(sclReport.isSuccess()).isTrue();
+ assertThat(getValFromDaiName(sclReport.getSclRootAdapter().getCurrentElem(), "IED_NAME1", ldInst, doName, daName)).isNotPresent();
+ }
+
+ @Test
+ void updateDoInRef_shouldReturnReportWithError_when_ExtRef_not_coherent() {
+ // Given
+ SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ko.xml");
+
+ // When
+ SclReport sclReport = SclService.updateDoInRef(givenScl);
+
+ // Then
+ assertThat(sclReport.isSuccess()).isTrue();
+ assertThat(sclReport.getSclReportItems()).isNotEmpty();
+ assertThat(sclReport.getSclReportItems()).hasSize(4);
+ }
+
+ private Optional getValFromDaiName(SCL scl, String iedName, String ldInst, String doiName, String daiName) {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scl);
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
Optional lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst);
LN0Adapter ln0Adapter = lDeviceAdapter.get().getLN0Adapter();
Optional doiAdapter = ln0Adapter.getDOIAdapters().stream()
- .filter(doiAdapter1 -> doiAdapter1.getCurrentElem().getName().equals("Mod"))
+ .filter(doiAdapter1 -> doiAdapter1.getCurrentElem().getName().equals(doiName))
.findFirst();
- if(doiAdapter.isEmpty()) return Optional.empty();
- return doiAdapter.get().getCurrentElem().getSDIOrDAI().stream()
+ return doiAdapter.flatMap(adapter -> adapter.getCurrentElem().getSDIOrDAI().stream()
.filter(tUnNaming -> tUnNaming.getClass().equals(TDAI.class))
.map(TDAI.class::cast)
- .filter(tdai -> tdai.getName().equals("stVal"))
+ .filter(tdai -> tdai.getName().equals(daiName) && !tdai.getVal().isEmpty())
.map(tdai -> tdai.getVal().get(0))
- .findFirst();
+ .findFirst());
}
+ @Test
+ void analyzeDataGroups_should_success() {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter1 = sclRootAdapter.getIEDAdapterByName("IED_NAME1");
+ iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxAttributes(9L);
+ iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxGOOSE(3L);
+ iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxSMV(2L);
+ iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxReports(1L);
+ // When
+ SclReport sclReport = SclService.analyzeDataGroups(scd);
+ //Then
+ assertThat(sclReport.getSclReportItems()).isEmpty();
+
+ }
+
+ @Test
+ void analyzeDataGroups_should_return_errors_messages() {
+
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME2");
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfDataSet().setMaxAttributes(1L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfDataSet().setMax(3L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getSMVsc().setMax(1L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getGOOSE().setMax(2L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfReportControl().setMax(0L);
+ // When
+ SclReport sclReport = SclService.analyzeDataGroups(scd);
+ //Then
+ assertThat(sclReport.getSclReportItems()).hasSize(11)
+ .extracting(SclReportItem::getMessage)
+ .containsExactlyInAnyOrder(
+ "There are too much FCDA for the Client IED IED_NAME1",
+ "The Client IED IED_NAME1 subscribes to too much GOOSE Control Blocks.",
+ "The Client IED IED_NAME1 subscribes to too much REPORT Control Blocks.",
+ "The Client IED IED_NAME1 subscribes to too much SMV Control Blocks.",
+ "There are too much FCDA for the DataSet DATASET6 for the LDevice LD_INST21 in IED IED_NAME2",
+ "There are too much FCDA for the DataSet DATASET6 for the LDevice LD_INST22 in IED IED_NAME2",
+ "There are too much FCDA for the DataSet DATASET5 for the LDevice LD_INST22 in IED IED_NAME2",
+ "There are too much DataSets for the IED IED_NAME2",
+ "There are too much Report Control Blocks for the IED IED_NAME2",
+ "There are too much GOOSE Control Blocks for the IED IED_NAME2",
+ "There are too much SMV Control Blocks for the IED IED_NAME2");
+ }
+
+
}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapterTest.java
new file mode 100644
index 000000000..1ecfc9daf
--- /dev/null
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapterTest.java
@@ -0,0 +1,278 @@
+/*
+ * // SPDX-FileCopyrightText: 2023 RTE FRANCE
+ * //
+ * // SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lfenergy.compas.sct.commons.scl.ied;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.lfenergy.compas.scl2007b4.model.*;
+import org.lfenergy.compas.sct.commons.dto.DTO;
+import org.lfenergy.compas.sct.commons.dto.SclReportItem;
+import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
+import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
+import org.lfenergy.compas.sct.commons.util.ServicesConfigEnum;
+
+import java.util.List;
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class AccessPointAdapterTest {
+
+ @Test
+ void amChildElementRef() {
+ //Given
+ SclRootAdapter sclRootAdapter = new SclRootAdapter("hID","hVersion","hRevision");
+ TIED tied = new TIED();
+ tied.setName(DTO.HOLDER_IED_NAME);
+ TAccessPoint tAccessPoint = new TAccessPoint();
+ tAccessPoint.setName("AP_NAME");
+ tAccessPoint.setServices(new TServices());
+ tied.getAccessPoint().add(tAccessPoint);
+ sclRootAdapter.getCurrentElem().getIED().add(tied);
+ IEDAdapter iAdapter = sclRootAdapter.getIEDAdapterByName(DTO.HOLDER_IED_NAME);
+ //When
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(iAdapter, iAdapter.getCurrentElem().getAccessPoint().get(0));
+ //Then
+ assertThat(accessPointAdapter.amChildElementRef()).isTrue();
+ assertThat(accessPointAdapter.getCurrentElem().getServices()).isNotNull();
+ }
+
+ @ParameterizedTest
+ @CsvSource(value = {"AP_NAME;AccessPoint[@name=\"AP_NAME\"]", ";AccessPoint[not(@name)]"}
+ , delimiter = ';')
+ void elementXPath(String apName, String message) {
+ // Given
+ TAccessPoint tAccessPoint = new TAccessPoint();
+ tAccessPoint.setName(apName);
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(null, tAccessPoint);
+ // When
+ String elementXPathResult = accessPointAdapter.elementXPath();
+ // Then
+ assertThat(elementXPathResult).isEqualTo(message);
+ }
+
+ @Test
+ void getXPath() {
+ // Given
+ TIED tied = new TIED();
+ tied.setName("IED_NAME");
+ TAccessPoint tAccessPoint = new TAccessPoint();
+ tAccessPoint.setName("AP_NAME");
+ tied.getAccessPoint().add(tAccessPoint);
+ IEDAdapter iedAdapter = new IEDAdapter(null, tied);
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(iedAdapter, tAccessPoint);
+ // When
+ String elementXPathResult = accessPointAdapter.getXPath();
+ // Then
+ assertThat(elementXPathResult).isEqualTo("/IED[@name=\"IED_NAME\"]/AccessPoint[@name=\"AP_NAME\"]");
+ }
+
+ @Test
+ void checkFCDALimitations_should_succed_no_error_message() throws Exception {
+ //Given
+ AccessPointAdapter accessPointAdapter = provideAPForCheckLimitationForIED();
+ //When
+ List sclReportItems = accessPointAdapter.checkFCDALimitations();
+ //Then
+ assertThat(sclReportItems).isEmpty();
+ }
+
+ @Test
+ void checkFCDALimitations_should_fail_with_one_error_messages() throws Exception {
+ //Given
+ AccessPointAdapter accessPointAdapter = provideAPForCheckLimitationForIED();
+ accessPointAdapter.getCurrentElem().getServices().getConfDataSet().setMaxAttributes(2L);
+ //When
+ List sclReportItems = accessPointAdapter.checkFCDALimitations();
+ //Then
+ assertThat(sclReportItems).hasSize(1)
+ .extracting(SclReportItem::getMessage)
+ .containsExactlyInAnyOrder("There are too much FCDA for the DataSet DATASET6 for the LDevice LD_INST21 in IED IED_NAME");
+ }
+ @Test
+ void checkFCDALimitations_should_fail_with_four_error_messages() throws Exception {
+ //Given
+ AccessPointAdapter accessPointAdapter = provideAPForCheckLimitationForIED();
+ accessPointAdapter.getCurrentElem().getServices().getConfDataSet().setMaxAttributes(1L);
+ //When
+ List sclReportItems = accessPointAdapter.checkFCDALimitations();
+ //Then
+ assertThat(sclReportItems).hasSize(4)
+ .extracting(SclReportItem::getMessage)
+ .containsExactlyInAnyOrder("There are too much FCDA for the DataSet DATASET3 for the LDevice LD_INST21 in IED IED_NAME",
+ "There are too much FCDA for the DataSet DATASET6 for the LDevice LD_INST21 in IED IED_NAME",
+ "There are too much FCDA for the DataSet DATASET6 for the LDevice LD_INST22 in IED IED_NAME",
+ "There are too much FCDA for the DataSet DATASET5 for the LDevice LD_INST22 in IED IED_NAME");
+ }
+
+
+ @Test
+ void checkControlsLimitation_should_fail_for_dataset_with_one_error_messages() throws Exception {
+ //Given
+ AccessPointAdapter accessPointAdapter = provideAPForCheckLimitationForIED();
+ accessPointAdapter.getCurrentElem().getServices().getConfDataSet().setMax(5L);
+ String message = "Too much DataSet for";
+ //When
+ Optional sclReportItem = accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.DATASET,message);
+ //Then
+ assertThat(sclReportItem).isPresent()
+ .get().extracting(SclReportItem::getMessage).isEqualTo(message +" IED_NAME");
+ }
+
+ @Test
+ void checkControlsLimitation_should_fail_for_smv_with_one_error_messages() throws Exception {
+ //Given
+ AccessPointAdapter accessPointAdapter = provideAPForCheckLimitationForIED();
+ accessPointAdapter.getCurrentElem().getServices().getSMVsc().setMax(2L);
+ String message = "Too much SMV Control for";
+ //When
+ Optional sclReportItem = accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.SMV,message);
+ //Then
+ assertThat(sclReportItem).isPresent()
+ .get().extracting(SclReportItem::getMessage).isEqualTo(message +" IED_NAME");
+ }
+
+ @Test
+ void checkControlsLimitation_should_fail_for_goose_with_one_error_messages() throws Exception {
+ //Given
+ AccessPointAdapter accessPointAdapter = provideAPForCheckLimitationForIED();
+ accessPointAdapter.getCurrentElem().getServices().getGOOSE().setMax(2L);
+ String message = "Too much Goose Control for";
+ //When
+ Optional sclReportItem = accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.GSE,message);
+ //Then
+ assertThat(sclReportItem).isPresent()
+ .get().extracting(SclReportItem::getMessage).isEqualTo(message +" IED_NAME");
+ }
+
+ @Test
+ void checkControlsLimitation_should_fail_for_report_with_one_error_messages() throws Exception {
+ //Given
+ AccessPointAdapter accessPointAdapter = provideAPForCheckLimitationForIED();
+ accessPointAdapter.getCurrentElem().getServices().getConfReportControl().setMax(0L);
+ String message = "Too much Report Control for";
+ //When
+ Optional sclReportItem = accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.REPORT,message);
+ //Then
+ assertThat(sclReportItem).isPresent()
+ .get().extracting(SclReportItem::getMessage).isEqualTo(message +" IED_NAME");
+ }
+
+ public static AccessPointAdapter provideAPForCheckLimitationForIED() throws Exception {
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_ied_controls_dataset.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME");
+ return new AccessPointAdapter(iedAdapter, iedAdapter.getCurrentElem().getAccessPoint().get(0));
+ }
+
+ @Test
+ void checkLimitationForBindedIEDFCDAs_should_success_no_error() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1");
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxAttributes(11L);
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(iedAdapter, iedAdapter.getCurrentElem().getAccessPoint().get(0));
+ String message = "Too much FCDA";
+ List tExtRefs = accessPointAdapter.getAllCoherentExtRefForAnalyze().tExtRefs();
+ //When
+ Optional sclReportItem = accessPointAdapter.checkLimitationForBoundIEDFCDAs(tExtRefs, message);
+
+ //Then
+ assertThat(sclReportItem).isEmpty();
+ }
+
+ @Test
+ void checkLimitationForBindedIEDFCDAs_should_fail_one_error_message() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1");
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(iedAdapter, iedAdapter.getCurrentElem().getAccessPoint().get(0));
+ accessPointAdapter.getCurrentElem().getServices().getClientServices().setMaxAttributes(4L);
+ List tExtRefs = accessPointAdapter.getAllCoherentExtRefForAnalyze().tExtRefs();
+ String message = "Too much FCDA for IED_NAME1";
+
+ //When
+ Optional sclReportItem = accessPointAdapter.checkLimitationForBoundIEDFCDAs(tExtRefs, message);
+
+ //Then
+ assertThat(sclReportItem).isPresent()
+ .get()
+ .extracting(SclReportItem::getMessage)
+ .isEqualTo(message);
+ }
+
+ @Test
+ void checkLimitationForBindedIEDControls_should_fail_three_error_messages() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1");
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(iedAdapter, iedAdapter.getCurrentElem().getAccessPoint().get(0));
+ List tExtRefs = accessPointAdapter.getAllCoherentExtRefForAnalyze().tExtRefs();
+ //When
+ List sclReportItems = accessPointAdapter.checkLimitationForBoundIEDControls(tExtRefs);
+
+ //Then
+ assertThat(sclReportItems).hasSize(3)
+ .extracting(SclReportItem::getMessage)
+ .containsExactlyInAnyOrder("The Client IED IED_NAME1 subscribes to too much GOOSE Control Blocks.",
+ "The Client IED IED_NAME1 subscribes to too much SMV Control Blocks.",
+ "The Client IED IED_NAME1 subscribes to too much REPORT Control Blocks.");
+ }
+
+ @Test
+ void checkLimitationForBindedIEDControls_should_succed_no_error_message() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1");
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxAttributes(11L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxGOOSE(5L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxReports(2L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxSMV(2L);
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(iedAdapter, iedAdapter.getCurrentElem().getAccessPoint().get(0));
+ List tExtRefs = accessPointAdapter.getAllCoherentExtRefForAnalyze().tExtRefs();
+ //When
+ List sclReportItems = accessPointAdapter.checkLimitationForBoundIEDControls(tExtRefs);
+
+ //Then
+ assertThat(sclReportItems).isEmpty();
+ }
+
+ @Test
+ void getAllCoherentExtRefForAnalyze_succed() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1");
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(iedAdapter, iedAdapter.getCurrentElem().getAccessPoint().get(0));
+ //When
+ AccessPointAdapter.ExtRefAnalyzeRecord extRefAnalyzeRecord = accessPointAdapter.getAllCoherentExtRefForAnalyze();
+ //Then
+ assertThat(extRefAnalyzeRecord)
+ .extracting(AccessPointAdapter.ExtRefAnalyzeRecord::sclReportItems)
+ .asList().isEmpty();
+ }
+
+ @Test
+ void getAllCoherentExtRefForAnalyze_fail_with_one_error() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_coherent_extRefs.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1");
+ AccessPointAdapter accessPointAdapter = new AccessPointAdapter(iedAdapter, iedAdapter.getCurrentElem().getAccessPoint().get(0));
+ //When
+ AccessPointAdapter.ExtRefAnalyzeRecord extRefAnalyzeRecord = accessPointAdapter.getAllCoherentExtRefForAnalyze();
+ //Then
+ assertThat(extRefAnalyzeRecord)
+ .extracting(AccessPointAdapter.ExtRefAnalyzeRecord::sclReportItems)
+ .asList().hasSize(1);
+ }
+}
\ No newline at end of file
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapterTest.java
index 7873ff9a9..2058b81c5 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapterTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapterTest.java
@@ -9,15 +9,14 @@
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.SclReportItem;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
class DOIAdapterTest {
@@ -25,137 +24,154 @@ class DOIAdapterTest {
@Test
void testConstructor() {
LN0 ln0 = new LN0();
- LN0Adapter ln0Adapter = new LN0Adapter(null,ln0);
+ LN0Adapter ln0Adapter = new LN0Adapter(null, ln0);
TDOI tdoi = new TDOI();
tdoi.setName("Do");
ln0.getDOI().add(tdoi);
// test amChildElement
- DOIAdapter doiAdapter = assertDoesNotThrow(() -> new DOIAdapter(ln0Adapter,tdoi));
+ DOIAdapter doiAdapter = assertDoesNotThrow(() -> new DOIAdapter(ln0Adapter, tdoi));
// test tree map
TSDI tsdi = new TSDI();
tsdi.setName("sdo2");
tdoi.getSDIOrDAI().add(tsdi);
- assertDoesNotThrow(() -> doiAdapter.getStructuredDataAdapterByName("sdo2"));
- assertThrows(ScdException.class, () -> doiAdapter.getStructuredDataAdapterByName("sdo3"));
+ assertThatCode(() -> doiAdapter.getStructuredDataAdapterByName("sdo2")).doesNotThrowAnyException();
+ assertThatThrownBy(() -> doiAdapter.getStructuredDataAdapterByName("sdo3")).isInstanceOf(ScdException.class);
TDAI tdai = new TDAI();
tdai.setName("angRef");
tdoi.getSDIOrDAI().add(tdai);
- assertDoesNotThrow(() -> doiAdapter.getDataAdapterByName("angRef"));
- assertThrows(ScdException.class, () -> doiAdapter.getStructuredDataAdapterByName("bda"));
- assertThrows(ScdException.class, () -> doiAdapter.getDataAdapterByName("bda"));
+ assertThatCode(() -> doiAdapter.getDataAdapterByName("angRef")).doesNotThrowAnyException();
+ assertThatThrownBy(() -> doiAdapter.getStructuredDataAdapterByName("bda")).isInstanceOf(ScdException.class);
+ assertThatThrownBy(() -> doiAdapter.getDataAdapterByName("bda")).isInstanceOf(ScdException.class);
}
-
@Test
- void testInnerDAIAdapter(){
+ void testInnerDAIAdapter() {
+ // Given
final String TOTO = "toto";
- DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do","angRef");
- assertNull(daiAdapter.isValImport());
+ // When
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "angRef");
+
+ // Then
+ assertThat(daiAdapter.getCurrentElem().isSetValImport()).isFalse();
daiAdapter.setValImport(true);
- assertTrue(daiAdapter.isValImport());
+ assertThat(daiAdapter.getCurrentElem().isSetValImport()).isTrue();
// test tree map
- assertThrows(UnsupportedOperationException.class, () -> daiAdapter.getDataAdapterByName(TOTO));
- assertThrows(
- UnsupportedOperationException.class,
- () -> daiAdapter.getStructuredDataAdapterByName(TOTO)
- );
+ assertThatThrownBy(() -> daiAdapter.getDataAdapterByName(TOTO)).isInstanceOf(UnsupportedOperationException.class);
+ assertThatThrownBy(() -> daiAdapter.getStructuredDataAdapterByName(TOTO)).isInstanceOf(UnsupportedOperationException.class);
- assertThrows(UnsupportedOperationException.class, () -> daiAdapter.addDAI(TOTO));
- assertThrows(UnsupportedOperationException.class, () -> daiAdapter.addSDOI(TOTO));
+ assertThatThrownBy(() -> daiAdapter.addDAI(TOTO)).isInstanceOf(UnsupportedOperationException.class);
+ assertThatThrownBy(() -> daiAdapter.addSDOI(TOTO)).isInstanceOf(UnsupportedOperationException.class);
}
@Test
- void testInnerDAIAdapterTestUpdateWithMapAsArg(){
+ void testInnerDAIAdapterTestUpdateWithMapAsArg() {
+ // Given
final String TOTO = "toto";
- DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do","da");
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
daiAdapter.setValImport(true);
// update DAI val
- final Map vals = Collections.singletonMap(0L,TOTO);
- assertDoesNotThrow(() -> daiAdapter.update(vals));
- assertFalse(daiAdapter.getCurrentElem().getVal().isEmpty());
+ final Map vals = Collections.singletonMap(0L, TOTO);
+ assertThatCode(() -> daiAdapter.update(vals)).doesNotThrowAnyException();
+ assertThat(daiAdapter.getCurrentElem().getVal()).isNotEmpty();
TVal tVal = daiAdapter.getCurrentElem().getVal().get(0);
- assertFalse(tVal.isSetSGroup());
+ assertThat(tVal.isSetSGroup()).isFalse();
+
+ final Map vals2 = new HashMap<>();
+ vals2.put(1L, TOTO);
+ vals2.put(0L, TOTO);
- final Map vals2 = new HashMap<>();
- vals2.put(1L,TOTO);
- vals2.put(0L,TOTO);
- assertDoesNotThrow(() -> daiAdapter.update(vals2));
- assertFalse(daiAdapter.getCurrentElem().getVal().isEmpty());
+ // When Then
+ assertThatCode(() -> daiAdapter.update(vals2)).doesNotThrowAnyException();
+ assertThat(daiAdapter.getCurrentElem().getVal()).isNotEmpty();
tVal = daiAdapter.getCurrentElem().getVal().get(0);
- assertFalse(tVal.isSetSGroup());
+ assertThat(tVal.isSetSGroup()).isFalse();
}
@Test
- void testInnerDAIAdapterTestUpdate(){
+ void testInnerDAIAdapterTestUpdate() {
+ // Given
final String TOTO = "toto";
- DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do","da");
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
daiAdapter.setValImport(false);
- assertThrows(ScdException.class,() -> daiAdapter.update(0L,TOTO) );
+ assertThatThrownBy(() -> daiAdapter.update(0L, TOTO)).isInstanceOf(ScdException.class);
daiAdapter.setValImport(true);
- assertDoesNotThrow(() -> daiAdapter.update(0L,TOTO));
+ assertThatCode(() -> daiAdapter.update(0L, TOTO)).doesNotThrowAnyException();
+
+ final Map vals2 = new HashMap<>();
+ vals2.put(1L, TOTO);
+ vals2.put(2L, TOTO);
- final Map vals2 = new HashMap<>();
- vals2.put(1L,TOTO);
- vals2.put(2L,TOTO);
- assertDoesNotThrow(() -> daiAdapter.update(vals2));
- vals2.put(2L,TOTO + "1");
- assertDoesNotThrow(() -> daiAdapter.update(vals2));
+ // When Then
+ assertThatCode(() -> daiAdapter.update(vals2)).doesNotThrowAnyException();
+ vals2.put(2L, TOTO + "1");
+ assertThatCode(() -> daiAdapter.update(vals2)).doesNotThrowAnyException();
}
@Test
void testFindDeepestMatch() throws Exception {
+ // Given
SCL scd = SclTestMarshaller.getSCLFromFile("/ied-test-schema-conf/ied_unit_test.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED_NAME"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.findLDeviceAdapterByLdInst("LD_INS1").get());
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.findLDeviceAdapterByLdInst("LD_INS1").get());
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
- DOIAdapter doiAdapter = assertDoesNotThrow(()-> ln0Adapter.getDOIAdapterByName("Do"));
+ DOIAdapter doiAdapter = assertDoesNotThrow(() -> ln0Adapter.getDOIAdapterByName("Do"));
DoTypeName doTypeName = new DoTypeName("Do.sdo1.d");
DaTypeName daTypeName = new DaTypeName("antRef.bda1.bda2.bda3");
- Pair extends IDataAdapter,Integer> pair = doiAdapter.findDeepestMatch(
- doTypeName.getStructNames(),0,false
+ Pair extends IDataAdapter, Integer> pair = doiAdapter.findDeepestMatch(
+ doTypeName.getStructNames(), 0, false
);
SDIAdapter lastSDOIAdapter = (SDIAdapter) pair.getLeft();
- assertEquals(1,pair.getRight());
- assertNotNull(lastSDOIAdapter);
- assertEquals(SDIAdapter.class,lastSDOIAdapter.getClass());
+ assertThat(pair.getRight()).isEqualTo(1);
+ assertThat(lastSDOIAdapter)
+ .isNotNull()
+ .isInstanceOf(SDIAdapter.class);
SDIAdapter firstDAIAdapter = lastSDOIAdapter.getStructuredDataAdapterByName(daTypeName.getName());
+
+ // When
pair = firstDAIAdapter.findDeepestMatch(
- daTypeName.getStructNames(),0,true
+ daTypeName.getStructNames(), 0, true
);
- assertEquals(2,pair.getRight());
- assertNotNull(pair.getLeft());
- assertEquals(SDIAdapter.DAIAdapter.class,pair.getLeft().getClass());
+
+ // Then
+ assertThat(pair.getRight()).isEqualTo(2);
+ assertThat(pair.getLeft()).isNotNull();
+ assertThat(pair.getLeft()).isInstanceOf(SDIAdapter.DAIAdapter.class);
}
- private DOIAdapter.DAIAdapter initInnerDAIAdapter(String doName, String daName){
+ private DOIAdapter.DAIAdapter initInnerDAIAdapter(String doName, String daName) {
TDOI tdoi = new TDOI();
tdoi.setName(doName);
- DOIAdapter doiAdapter = new DOIAdapter(null,tdoi);
+ DOIAdapter doiAdapter = new DOIAdapter(null, tdoi);
TDAI tdai = new TDAI();
tdai.setName(daName);
tdoi.getSDIOrDAI().add(tdai);
- DOIAdapter.DAIAdapter daiAdapter = assertDoesNotThrow(() -> new DOIAdapter.DAIAdapter(doiAdapter,tdai));
+ DOIAdapter.DAIAdapter daiAdapter = assertDoesNotThrow(() -> new DOIAdapter.DAIAdapter(doiAdapter, tdai));
return daiAdapter;
}
@Test
void addPrivate() {
- DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do","da");
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
TPrivate tPrivate = new TPrivate();
tPrivate.setType("Private Type");
tPrivate.setSource("Private Source");
- assertTrue(daiAdapter.getCurrentElem().getPrivate().isEmpty());
+ assertThat(daiAdapter.getCurrentElem().getPrivate()).isEmpty();
+
+ // When
daiAdapter.addPrivate(tPrivate);
- assertEquals(1, daiAdapter.getCurrentElem().getPrivate().size());
+
+ // Then
+ assertThat(daiAdapter.getCurrentElem().getPrivate()).hasSize(1);
}
@Test
@@ -163,8 +179,8 @@ void elementXPath_doi() {
// Given
TDOI tdoi = new TDOI();
tdoi.setName("doName");
- DOIAdapter doiAdapter = new DOIAdapter(null,new TDOI());
- DOIAdapter namedDoiAdapter = new DOIAdapter(null,tdoi);
+ DOIAdapter doiAdapter = new DOIAdapter(null, new TDOI());
+ DOIAdapter namedDoiAdapter = new DOIAdapter(null, tdoi);
// When
String elementXPathResult = doiAdapter.elementXPath();
String namedElementXPathResult = namedDoiAdapter.elementXPath();
@@ -176,11 +192,311 @@ void elementXPath_doi() {
@Test
void elementXPath_dai() {
// Given
- DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do","da");
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
// When
String result = daiAdapter.elementXPath();
// Then
assertThat(result).isEqualTo("DAI[@name=\"da\"]");
}
+
+ @Test
+ void findDataAdapterByName_should_return_DAIAdapter_when_DA_name_exist() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+
+ // When
+ Optional result = doiAdapter.findDataAdapterByName("da");
+
+ // Then
+ assertThat(result)
+ .isPresent()
+ .map(daiAdapter1 -> daiAdapter1.getCurrentElem().getName())
+ .isEqualTo(Optional.of("da"));
+ }
+
+ @Test
+ void findDataAdapterByName_should_return_DAIAdapter_when_DA_name_dont_exist() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+
+ // When
+ Optional result = doiAdapter.findDataAdapterByName("wrong");
+
+ // Then
+ assertThat(result).isEmpty();
+ }
+
+ @Test
+ void updateDaiFromExtRef_should_update_setSrcXX_values_when_ExtRef_desc_suffix_ends_with_1() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+ TDAI daiSrcRef = new TDAI();
+ daiSrcRef.setName(DOIAdapter.DA_NAME_SET_SRC_REF);
+ TDAI daiSrcCb = new TDAI();
+ daiSrcCb.setName(DOIAdapter.DA_NAME_SET_SRC_CB);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcRef);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcCb);
+
+ TExtRef extRef1 = givenExtRef(1, true);
+
+ // When
+ Optional sclReportItems = doiAdapter.updateDaiFromExtRef(List.of(extRef1));
+
+ // Then
+ assertThat(sclReportItems).isEmpty();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF).get().getValue())
+ .isEqualTo("IED_NAME_1LD_INST_1/PREFIX_1ANCR1.DO_NAME_1");
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_CB).get().getValue())
+ .isEqualTo("IED_NAME_1LD_INST_1/SRC_PREFIX_1LLN0SRC_LN_INST_1.CB_NAME_1");
+ }
+
+ private static Optional getDaiValOfDoi(DOIAdapter doiAdapter, String daName) {
+ return doiAdapter.getDataAdapterByName(daName).getCurrentElem().getVal().stream().findFirst();
+ }
+
+ @Test
+ void updateDaiFromExtRef_should_update_setSrcRef_value_but_not_setSrcCB_when_ExtRef_dont_contains_CB() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+ TDAI daiSrcRef = new TDAI();
+ daiSrcRef.setName(DOIAdapter.DA_NAME_SET_SRC_REF);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcRef);
+
+ TExtRef extRef1 = givenExtRef(1, false);
+
+ // When
+ Optional sclReportItems = doiAdapter.updateDaiFromExtRef(List.of(extRef1));
+
+ // Then
+ assertThat(sclReportItems).isEmpty();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF)).isPresent();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF).get().getValue())
+ .isEqualTo("IED_NAME_1LD_INST_1/PREFIX_1ANCR1.DO_NAME_1");
+ assertThatThrownBy(() -> getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_CB)).isInstanceOf(ScdException.class);
+ }
+
+ @Test
+ void updateDaiFromExtRef_should_update_setSrcXX_and_setTstXX_values_when_ExtRef_desc_suffix_ends_with_1_and_3() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+ TDAI daiSrcRef = new TDAI();
+ daiSrcRef.setName(DOIAdapter.DA_NAME_SET_SRC_REF);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcRef);
+ TDAI daiSrcCb = new TDAI();
+ daiSrcCb.setName(DOIAdapter.DA_NAME_SET_SRC_CB);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcCb);
+ TDAI daiTstRef = new TDAI();
+ daiTstRef.setName(DOIAdapter.DA_NAME_SET_TST_REF);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiTstRef);
+ TDAI daiTstCb = new TDAI();
+ daiTstCb.setName(DOIAdapter.DA_NAME_SET_TST_CB);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiTstCb);
+
+ TExtRef extRef1 = givenExtRef(1, true);
+ TExtRef extRef3 = givenExtRef(3, true);
+
+ // When
+ Optional sclReportItems = doiAdapter.updateDaiFromExtRef(List.of(extRef1, extRef3));
+
+ // Then
+ assertThat(sclReportItems).isEmpty();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF).get().getValue())
+ .isEqualTo("IED_NAME_1LD_INST_1/PREFIX_1ANCR1.DO_NAME_1");
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_CB).get().getValue())
+ .isEqualTo("IED_NAME_1LD_INST_1/SRC_PREFIX_1LLN0SRC_LN_INST_1.CB_NAME_1");
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_TST_REF).get().getValue())
+ .isEqualTo("IED_NAME_3LD_INST_3/PREFIX_3ANCR3.DO_NAME_3");
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_TST_CB).get().getValue())
+ .isEqualTo("IED_NAME_3LD_INST_3/SRC_PREFIX_3LLN0SRC_LN_INST_3.CB_NAME_3");
+ }
+
+ private static TExtRef givenExtRef(int num, boolean withCbName) {
+ TExtRef extRef1 = new TExtRef();
+ extRef1.setIedName("IED_NAME_" + num);
+ extRef1.setDesc("ExtRef_desc_" + num);
+ extRef1.setLdInst("LD_INST_" + num);
+ extRef1.setSrcPrefix("SRC_PREFIX_" + num);
+ extRef1.setSrcLNInst("SRC_LN_INST_" + num);
+ extRef1.getLnClass().add("ANCR");
+ extRef1.setLnInst(Integer.toString(num));
+ extRef1.setPrefix("PREFIX_" + num);
+ extRef1.setDoName("DO_NAME_" + num);
+ if (withCbName) {
+ extRef1.setSrcCBName("CB_NAME_" + num);
+ }
+ return extRef1;
+ }
+
+ @Test
+ void updateDaiFromExtRef_should_update_only_setSrcRef_and_setTstRef_values_when_ExtRef_desc_suffix_ends_with_1_and_3_without_CB() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+ TDAI daiSrcRef = new TDAI();
+ daiSrcRef.setName(DOIAdapter.DA_NAME_SET_SRC_REF);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcRef);
+ TDAI daiSrcCb = new TDAI();
+ daiSrcCb.setName(DOIAdapter.DA_NAME_SET_SRC_CB);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcCb);
+ TDAI daiTstRef = new TDAI();
+ daiTstRef.setName(DOIAdapter.DA_NAME_SET_TST_REF);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiTstRef);
+ TDAI daiTstCb = new TDAI();
+ daiTstCb.setName(DOIAdapter.DA_NAME_SET_TST_CB);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiTstCb);
+
+ TExtRef extRef1 = givenExtRef(1, false);
+ TExtRef extRef3 = givenExtRef(3, false);
+
+ // When
+ Optional sclReportItems = doiAdapter.updateDaiFromExtRef(List.of(extRef1, extRef3));
+
+ // Then
+ assertThat(sclReportItems).isEmpty();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF)).isPresent();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF).get().getValue())
+ .isEqualTo("IED_NAME_1LD_INST_1/PREFIX_1ANCR1.DO_NAME_1");
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_CB))
+ .isNotPresent();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_TST_REF)).isPresent();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_TST_REF).get().getValue())
+ .isEqualTo("IED_NAME_3LD_INST_3/PREFIX_3ANCR3.DO_NAME_3");
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_TST_CB))
+ .isNotPresent();
+ }
+
+ @Test
+ void updateDaiFromExtRef_should_return_warning_report_when_none_ExtRef_endin_with_1() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+ TDAI daiSrcRef = new TDAI();
+ daiSrcRef.setName(DOIAdapter.DA_NAME_SET_SRC_REF);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcRef);
+
+ TExtRef extRef3 = givenExtRef(3, false);
+
+ // When
+ Optional sclReportItems = doiAdapter.updateDaiFromExtRef(List.of(extRef3));
+
+ // Then
+ assertThat(sclReportItems)
+ .isPresent()
+ .isNotEmpty();
+ assertThat(sclReportItems.get().getMessage())
+ .contains("can't be bound with an ExtRef");
+ assertThat(doiAdapter.getDataAdapterByName(DOIAdapter.DA_NAME_SET_SRC_REF)).isNotNull();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF)).isNotPresent();
+ }
+
+ @Test
+ void updateDaiFromExtRef_should_create_DAI_when_no_DAI_name_setSrcRef() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+
+ TExtRef extRef1 = givenExtRef(1, false);
+
+ // When
+ Optional sclReportItems = doiAdapter.updateDaiFromExtRef(List.of(extRef1));
+
+ // Then
+ assertThat(sclReportItems).isEmpty();
+ assertThat(doiAdapter.getDataAdapterByName(DOIAdapter.DA_NAME_SET_SRC_REF)).isNotNull();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF))
+ .isPresent()
+ .map(TVal::getValue)
+ .contains("IED_NAME_1LD_INST_1/PREFIX_1ANCR1.DO_NAME_1");
+ }
+
+ @Test
+ void updateDaiFromExtRef_should_return_filled_ReportItem_when_no_ExtRef_in_LNode() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+
+ // When
+ Optional sclReportItems = doiAdapter.updateDaiFromExtRef(List.of());
+
+ // Then
+ assertThat(sclReportItems)
+ .isPresent()
+ .isNotEmpty();
+ assertThat(sclReportItems.get().getMessage()).contains("can't be bound with an ExtRef");
+ }
+
+ @Test
+ void updateDaiFromExtRef_should_compose_correct_name_when_optional_ExtRef_attributes_are_missing() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+ TDAI daiSrcRef = new TDAI();
+ daiSrcRef.setName(DOIAdapter.DA_NAME_SET_SRC_REF);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcRef);
+ TDAI daiSrcCb = new TDAI();
+ daiSrcCb.setName(DOIAdapter.DA_NAME_SET_SRC_CB);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcCb);
+ TDAI daiTstRef = new TDAI();
+ daiTstRef.setName(DOIAdapter.DA_NAME_SET_TST_REF);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiTstRef);
+ TDAI daiTstCb = new TDAI();
+ daiTstCb.setName(DOIAdapter.DA_NAME_SET_TST_CB);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiTstCb);
+
+ TExtRef extRef1 = new TExtRef();
+ extRef1.setDesc("ExtRef_desc_1");
+ extRef1.setIedName("IED_NAME_1");
+ extRef1.setLdInst("LD_INST_1");
+ extRef1.getLnClass().add("LN_CLASS_1");
+ extRef1.setDoName("DO_NAME_1");
+ TExtRef extRef3 = new TExtRef();
+ extRef3.setDesc("ExtRef_desc_3");
+ extRef3.setIedName("IED_NAME_3");
+ extRef3.setLdInst("LD_INST_3");
+ extRef3.getLnClass().add("LN_CLASS_3");
+ extRef3.setDoName("DO_NAME_3");
+
+ // When
+ Optional sclReportItems = doiAdapter.updateDaiFromExtRef(List.of(extRef1, extRef3));
+
+ // Then
+ assertThat(sclReportItems).isEmpty();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF)).isPresent();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_REF).get().getValue())
+ .isEqualTo("IED_NAME_1LD_INST_1/LN_CLASS_1.DO_NAME_1");
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_SRC_CB))
+ .isNotPresent();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_TST_REF)).isPresent();
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_TST_REF).get().getValue())
+ .isEqualTo("IED_NAME_3LD_INST_3/LN_CLASS_3.DO_NAME_3");
+ assertThat(getDaiValOfDoi(doiAdapter, DOIAdapter.DA_NAME_SET_TST_CB))
+ .isNotPresent();
+ }
+
+ @Test
+ void updateDaiFromExtRef_should_throw_exception_when_ExtRef_desc_dont_end_with__1() {
+ // Given
+ DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
+ DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
+ TDAI daiSrcRef = new TDAI();
+ daiSrcRef.setName(DOIAdapter.DA_NAME_SET_SRC_REF);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcRef);
+ TDAI daiSrcCb = new TDAI();
+ daiSrcCb.setName(DOIAdapter.DA_NAME_SET_SRC_CB);
+ doiAdapter.getCurrentElem().getSDIOrDAI().add(daiSrcCb);
+
+ TExtRef extRef1 = new TExtRef();
+ extRef1.setDesc("ExtRefDesc");
+ List extRefList = List.of(extRef1);
+
+ // When Then
+ assertThatThrownBy(() -> doiAdapter.updateDaiFromExtRef(extRefList))
+ .isInstanceOf(NumberFormatException.class);
+ }
}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java
index 635d37bf1..88f867311 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java
@@ -5,12 +5,10 @@
package org.lfenergy.compas.sct.commons.scl.ied;
import org.junit.jupiter.api.Test;
-import org.lfenergy.compas.scl2007b4.model.SCL;
-import org.lfenergy.compas.scl2007b4.model.TIED;
-import org.lfenergy.compas.scl2007b4.model.TPrivate;
-import org.lfenergy.compas.scl2007b4.model.TServices;
+import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.dto.DTO;
import org.lfenergy.compas.sct.commons.dto.ExtRefSignalInfo;
+import org.lfenergy.compas.sct.commons.dto.SclReportItem;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.ObjectReference;
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
@@ -26,6 +24,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
class IEDAdapterTest {
@@ -174,8 +173,8 @@ void testMatches() {
@Test
void addPrivate() {
- SclRootAdapter sclRootAdapter = Mockito.mock(SclRootAdapter.class);
- SCL scl = Mockito.mock(SCL.class);
+ SclRootAdapter sclRootAdapter = mock(SclRootAdapter.class);
+ SCL scl = mock(SCL.class);
Mockito.when(sclRootAdapter.getCurrentElem()).thenReturn(scl);
TIED tied = new TIED();
Mockito.when(scl.getIED()).thenReturn(List.of(tied));
@@ -191,8 +190,8 @@ void addPrivate() {
@Test
void elementXPath() {
// Given
- SclRootAdapter sclRootAdapter = Mockito.mock(SclRootAdapter.class);
- SCL scl = Mockito.mock(SCL.class);
+ SclRootAdapter sclRootAdapter = mock(SclRootAdapter.class);
+ SCL scl = mock(SCL.class);
Mockito.when(sclRootAdapter.getCurrentElem()).thenReturn(scl);
TIED tied = new TIED();
tied.setName("iedName");
@@ -204,4 +203,77 @@ void elementXPath() {
assertThat(result).isEqualTo("IED[@name=\"iedName\"]");
}
+ @Test
+ void checkDataGroupCoherence_should_succed_no_error_message() throws Exception {
+ //Given
+ IEDAdapter iedAdapter = provideIEDForCheckLimitationForIED();
+ //When
+ List sclReportItems = iedAdapter.checkDataGroupCoherence();
+ //Then
+ assertThat(sclReportItems).isEmpty();
+ }
+
+ @Test
+ void checkDataGroupCoherence_should_fail_five_error_message() throws Exception {
+ //Given
+ IEDAdapter iedAdapter = provideIEDForCheckLimitationForIED();
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfDataSet().setMaxAttributes(2L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfDataSet().setMax(5L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getSMVsc().setMax(2L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getGOOSE().setMax(2L);
+ iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfReportControl().setMax(0L);
+ //When
+ List sclReportItems = iedAdapter.checkDataGroupCoherence();
+ //Then
+ assertThat(sclReportItems).hasSize(5)
+ .extracting(SclReportItem::getMessage)
+ .containsExactlyInAnyOrder("There are too much FCDA for the DataSet DATASET6 for the LDevice LD_INST21 in IED IED_NAME",
+ "There are too much DataSets for the IED IED_NAME",
+ "There are too much Report Control Blocks for the IED IED_NAME",
+ "There are too much GOOSE Control Blocks for the IED IED_NAME",
+ "There are too much SMV Control Blocks for the IED IED_NAME");
+ }
+
+ @Test
+ void checkBindingDataGroupCoherence_should_succed_no_error_message() throws Exception {
+ //Given
+ IEDAdapter iedAdapter = provideIEDForCheckLimitationForBindedIED();
+ TClientServices tClientServices = iedAdapter.getParentAdapter().getIEDAdapterByName("IED_NAME1").getCurrentElem().getAccessPoint().get(0).getServices().getClientServices();
+ tClientServices.setMaxAttributes(11L);
+ tClientServices.setMaxGOOSE(5L);
+ tClientServices.setMaxReports(2L);
+ tClientServices.setMaxSMV(2L);
+ //When
+ List sclReportItems = iedAdapter.checkBindingDataGroupCoherence();
+ //Then
+ assertThat(sclReportItems).isEmpty();
+ }
+
+ @Test
+ void checkBindingDataGroupCoherence_should_fail_five_error_message() throws Exception {
+ //Given
+ IEDAdapter iedAdapter = provideIEDForCheckLimitationForBindedIED();
+ //When
+ List sclReportItems = iedAdapter.checkBindingDataGroupCoherence();
+ //Then
+ assertThat(sclReportItems).hasSize(4)
+ .extracting(SclReportItem::getMessage)
+ .containsExactlyInAnyOrder("There are too much FCDA for the Client IED IED_NAME1",
+ "The Client IED IED_NAME1 subscribes to too much SMV Control Blocks.",
+ "The Client IED IED_NAME1 subscribes to too much REPORT Control Blocks.",
+ "The Client IED IED_NAME1 subscribes to too much GOOSE Control Blocks.");
+
+ }
+
+ public static IEDAdapter provideIEDForCheckLimitationForBindedIED() throws Exception {
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ return sclRootAdapter.getIEDAdapterByName("IED_NAME1");
+ }
+
+ public static IEDAdapter provideIEDForCheckLimitationForIED() throws Exception {
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_limitation_ied_controls_dataset.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ return sclRootAdapter.getIEDAdapterByName("IED_NAME");
+ }
}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapterTest.java
index 64be79b07..a23706f4d 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapterTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapterTest.java
@@ -5,6 +5,7 @@
package org.lfenergy.compas.sct.commons.scl.ied;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -14,6 +15,7 @@
import org.lfenergy.compas.sct.commons.testhelpers.FCDARecord;
import org.lfenergy.compas.sct.commons.testhelpers.MarshallerWrapper;
import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
+import org.mockito.junit.jupiter.MockitoExtension;
import org.opentest4j.AssertionFailedError;
import java.util.List;
@@ -25,6 +27,7 @@
import static org.junit.jupiter.api.Named.named;
import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.*;
+@ExtendWith(MockitoExtension.class)
class InputsAdapterTest {
@Test
@@ -255,5 +258,30 @@ private static InputsAdapter keepOnlyThisExtRef(SclRootAdapter sclRootAdapter, S
foundInputsAdapter.getCurrentElem().getExtRef().removeIf(Predicate.not(extref -> extRefDesc.equals(extref.getDesc())));
return foundInputsAdapter;
}
+ /* @Test
+ void checkSourceDataGroupCoherence_should_fail_one_error_messages() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_coherent_extRefs.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ InputsAdapter inputsAdapter = keepOnlyThisExtRef(sclRootAdapter, "a");
+ //When
+ List sclReportItems = inputsAdapter.checkSourceDataGroupCoherence();
+ //Then
+ assertThat(sclReportItems).hasSize(1)
+ .extracting(SclReportItem::getMessage)
+ .containsExactlyInAnyOrder("The Client IED IED_NAME1 subscribes to much GOOSE Control Blocks.");
+ }
+ @Test
+ void checkSourceDataGroupCoherence_should_succed_no_error_message() throws Exception {
+ //Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/limitation_cb_dataset_fcda/scd_check_coherent_extRefs.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ InputsAdapter inputsAdapter = keepOnlyThisExtRef(sclRootAdapter, "a");
+ sclRootAdapter.getIEDAdapterByName("IED_NAME1").getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxGOOSE(1L);
+ //When
+ List sclReportItems = inputsAdapter.checkSourceDataGroupCoherence();
+ //Then
+ assertThat(sclReportItems).isEmpty();
+ }*/
}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java
index 84b141887..e48d8d48e 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java
@@ -7,6 +7,7 @@
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.CsvSource;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.lfenergy.compas.scl2007b4.model.*;
@@ -29,6 +30,7 @@
import static org.junit.jupiter.api.Named.named;
import static org.lfenergy.compas.scl2007b4.model.TSampledValueControl.SmvOpts;
import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.findLn0;
+import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.getDaiValue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -46,11 +48,11 @@ void testAmChildElementRef() throws ScdException {
LN0 ln0 = new LN0();
ln0.setLnType("LT1");
when(tlDevice.getLN0()).thenReturn(ln0);
- LN0Adapter ln0Adapter = assertDoesNotThrow( () -> new LN0Adapter(lDeviceAdapter,ln0));
+ LN0Adapter ln0Adapter = assertDoesNotThrow(() -> new LN0Adapter(lDeviceAdapter, ln0));
- assertEquals(LN0.class,ln0Adapter.getElementClassType());
- assertEquals("LT1",ln0Adapter.getLnType());
- assertEquals(TLLN0Enum.LLN_0.value(),ln0Adapter.getLNClass());
+ assertEquals(LN0.class, ln0Adapter.getElementClassType());
+ assertEquals("LT1", ln0Adapter.getLnType());
+ assertEquals(TLLN0Enum.LLN_0.value(), ln0Adapter.getLNClass());
assertFalse(ln0Adapter.hasInputs());
ln0.setInputs(new TInputs());
assertTrue(ln0Adapter.hasInputs());
@@ -63,7 +65,7 @@ void testAmChildElementRef() throws ScdException {
assertTrue(ln0Adapter.getCurrentElem().getReportControl().isEmpty());
LN0 ln01 = new LN0();
- assertThrows(IllegalArgumentException.class, () -> new LN0Adapter(lDeviceAdapter, ln01));
+ assertThrows(IllegalArgumentException.class, () -> new LN0Adapter(lDeviceAdapter, ln01));
}
// AbstractLNAdapter class test
@@ -74,8 +76,9 @@ void containsFCDA() {
when(lDeviceAdapter.getCurrentElem()).thenReturn(tlDevice);
LN0 ln0 = new LN0();
when(tlDevice.getLN0()).thenReturn(ln0);
- assertDoesNotThrow( () -> new LN0Adapter(lDeviceAdapter,ln0));
+ assertDoesNotThrow(() -> new LN0Adapter(lDeviceAdapter, ln0));
}
+
@Test
void isExtRefExist_shouldThrowScdException_whenNoInputsInLN0() {
//Given
@@ -114,7 +117,7 @@ void isExtRefExist_shouldThrowScdException_whenSignalNotValid() {
@Test
- void isExtRefExist_shouldThrowScdException_whenSignalNull(){
+ void isExtRefExist_shouldThrowScdException_whenSignalNull() {
//Given
LDeviceAdapter lDeviceAdapter = mock(LDeviceAdapter.class);
TLDevice tlDevice = mock(TLDevice.class);
@@ -125,7 +128,7 @@ void isExtRefExist_shouldThrowScdException_whenSignalNull(){
tInputs.getExtRef().add(extRef);
ln0.setInputs(tInputs);
when(tlDevice.getLN0()).thenReturn(ln0);
- LN0Adapter ln0Adapter = assertDoesNotThrow( () -> new LN0Adapter(lDeviceAdapter,ln0));
+ LN0Adapter ln0Adapter = assertDoesNotThrow(() -> new LN0Adapter(lDeviceAdapter, ln0));
//When Then
assertThatThrownBy(() -> ln0Adapter.isExtRefExist(null))
.isInstanceOf(ScdException.class)
@@ -133,7 +136,7 @@ void isExtRefExist_shouldThrowScdException_whenSignalNull(){
}
@Test
- void isExtRefExist_shouldThrowScdException_whenNotExistInTargetLN(){
+ void isExtRefExist_shouldThrowScdException_whenNotExistInTargetLN() {
//Given
LDeviceAdapter lDeviceAdapter = mock(LDeviceAdapter.class);
TLDevice tlDevice = mock(TLDevice.class);
@@ -153,7 +156,7 @@ void isExtRefExist_shouldThrowScdException_whenNotExistInTargetLN(){
.hasMessage("ExtRef signal does not exist in target LN");
}
- @Test
+ @Test
void isExtRefExist_shouldNotThrowException_whenExtRefExist() {
//Given
LDeviceAdapter lDeviceAdapter = mock(LDeviceAdapter.class);
@@ -195,13 +198,13 @@ void isExtRefExist_shouldNotThrowException_whenExtRefExistWithPDA() {
}
@Test
- void testGetDataSetWith(){
+ void testGetDataSetWith() {
LDeviceAdapter lDeviceAdapter = mock(LDeviceAdapter.class);
TLDevice tlDevice = mock(TLDevice.class);
when(lDeviceAdapter.getCurrentElem()).thenReturn(tlDevice);
LN0 ln0 = new LN0();
when(tlDevice.getLN0()).thenReturn(ln0);
- LN0Adapter ln0Adapter = assertDoesNotThrow( () -> new LN0Adapter(lDeviceAdapter,ln0));
+ LN0Adapter ln0Adapter = assertDoesNotThrow(() -> new LN0Adapter(lDeviceAdapter, ln0));
TDataSet tDataSet = new TDataSet();
ln0.getDataSet().add(tDataSet);
@@ -223,7 +226,7 @@ void testGetDataSetWith(){
}
@Test
- void testGetControlBlocks(){
+ void testGetControlBlocks() {
LDeviceAdapter lDeviceAdapter = mock(LDeviceAdapter.class);
IEDAdapter iedAdapter = mock(IEDAdapter.class);
TLDevice tlDevice = mock(TLDevice.class);
@@ -232,7 +235,7 @@ void testGetControlBlocks(){
when(iedAdapter.getName()).thenReturn("IED_NAME");
LN0 ln0 = new LN0();
when(tlDevice.getLN0()).thenReturn(ln0);
- LN0Adapter ln0Adapter = assertDoesNotThrow( () -> new LN0Adapter(lDeviceAdapter,ln0));
+ LN0Adapter ln0Adapter = assertDoesNotThrow(() -> new LN0Adapter(lDeviceAdapter, ln0));
TGSEControl tgseControl = new TGSEControl();
tgseControl.setDatSet("GSE_REF");
TSampledValueControl tSampledValueControl = new TSampledValueControl();
@@ -246,7 +249,7 @@ void testGetControlBlocks(){
TDataSet tDataSetGSE = new TDataSet();
tDataSetGSE.setName(DTO.CB_DATASET_REF);
- List controlBlocks = ln0Adapter.getControlBlocks(List.of(tDataSetGSE),null);
+ List controlBlocks = ln0Adapter.getControlBlocks(List.of(tDataSetGSE), null);
assertTrue(controlBlocks.isEmpty());
tDataSetGSE.setName("GSE_REF");
@@ -257,18 +260,18 @@ void testGetControlBlocks(){
List tDataSets = List.of(tDataSetGSE, tDataSetSMV, tDataSetRPT);
- controlBlocks = ln0Adapter.getControlBlocks(tDataSets,TServiceType.REPORT);
+ controlBlocks = ln0Adapter.getControlBlocks(tDataSets, TServiceType.REPORT);
assertThat(controlBlocks).hasSize(1);
- controlBlocks = ln0Adapter.getControlBlocks(tDataSets,TServiceType.SMV);
+ controlBlocks = ln0Adapter.getControlBlocks(tDataSets, TServiceType.SMV);
assertThat(controlBlocks).hasSize(1);
- controlBlocks = ln0Adapter.getControlBlocks(tDataSets,TServiceType.GOOSE);
+ controlBlocks = ln0Adapter.getControlBlocks(tDataSets, TServiceType.GOOSE);
assertThat(controlBlocks).hasSize(1);
- controlBlocks = ln0Adapter.getControlBlocks(tDataSets,null);
+ controlBlocks = ln0Adapter.getControlBlocks(tDataSets, null);
assertThat(controlBlocks).hasSize(3);
}
@Test
- void testGetControlSetByBindingInfo(){
+ void testGetControlSetByBindingInfo() {
LN0 ln0 = new LN0();
LN0Adapter ln0Adapter = mock(LN0Adapter.class);
@@ -287,17 +290,17 @@ void testGetControlSetByBindingInfo(){
Mockito.doReturn(List.of(new ReportControlBlock("rpt", "rptID", "rptDatSet")))
.when(ln0Adapter).getControlBlocks(
- any(List.class), any(TServiceType.class));
+ any(List.class), any(TServiceType.class));
- List controlBlocks = ln0Adapter.getControlBlocksForMatchingFCDA(extRefBindingInfo);
+ List controlBlocks = ln0Adapter.getControlBlocksForMatchingFCDA(extRefBindingInfo);
assertFalse(controlBlocks.isEmpty());
- assertEquals(TServiceType.REPORT,controlBlocks.get(0).getServiceType());
+ assertEquals(TServiceType.REPORT, controlBlocks.get(0).getServiceType());
}
@Test
- void testGetDOIAdapters(){
+ void testGetDOIAdapters() {
LN0 ln0 = new LN0();
- LN0Adapter ln0Adapter = new LN0Adapter(null,ln0);
+ LN0Adapter ln0Adapter = new LN0Adapter(null, ln0);
TDOI tdoi = new TDOI();
tdoi.setName("Do");
@@ -307,7 +310,7 @@ void testGetDOIAdapters(){
}
@Test
- void testGetDOIAdapterByName(){
+ void testGetDOIAdapterByName() {
IEDAdapter iedAdapter = mock(IEDAdapter.class);
TIED tied = new TIED();
when(iedAdapter.getCurrentElem()).thenReturn(tied);
@@ -320,7 +323,7 @@ void testGetDOIAdapterByName(){
LN0 ln0 = new LN0();
tlDevice.setLN0(ln0);
- LN0Adapter ln0Adapter = new LN0Adapter(lDeviceAdapter,ln0);
+ LN0Adapter ln0Adapter = new LN0Adapter(lDeviceAdapter, ln0);
TDOI tdoi = new TDOI();
tdoi.setName("Do");
@@ -334,16 +337,16 @@ void testFindMatch() {
SCL scd = SclTestMarshaller.getSCLFromFile(SCD_IED_U_TEST);
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED_NAME"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.findLDeviceAdapterByLdInst("LD_INS1").get());
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.findLDeviceAdapterByLdInst("LD_INS1").get());
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
DoTypeName doTypeName = new DoTypeName("Do.sdo1.d");
DaTypeName daTypeName = new DaTypeName("antRef.bda1.bda2.bda3");
- AbstractDAIAdapter> daiAdapter = (AbstractDAIAdapter>) assertDoesNotThrow(() -> ln0Adapter.findMatch(doTypeName,daTypeName).get());
- assertEquals("bda3",daiAdapter.getCurrentElem().getName());
- assertEquals("Completed-diff",daiAdapter.getCurrentElem().getVal().get(0).getValue());
+ AbstractDAIAdapter> daiAdapter = (AbstractDAIAdapter>) assertDoesNotThrow(() -> ln0Adapter.findMatch(doTypeName, daTypeName).get());
+ assertEquals("bda3", daiAdapter.getCurrentElem().getName());
+ assertEquals("Completed-diff", daiAdapter.getCurrentElem().getVal().get(0).getValue());
DoTypeName doTypeName2 = new DoTypeName("Do.sdo1");
- assertFalse(ln0Adapter.findMatch(doTypeName2,daTypeName).isPresent());
+ assertFalse(ln0Adapter.findMatch(doTypeName2, daTypeName).isPresent());
}
@ParameterizedTest
@@ -399,7 +402,7 @@ void hasControlBlock_when_wrong_controlBlockEnum_should_return_false() {
void addPrivate() {
LN0 tln = new LN0();
tln.getLnClass().add(TLLN0Enum.LLN_0.value());
- LN0Adapter lnAdapter = new LN0Adapter(null,tln);
+ LN0Adapter lnAdapter = new LN0Adapter(null, tln);
TPrivate tPrivate = new TPrivate();
tPrivate.setType("Private Type");
tPrivate.setSource("Private Source");
@@ -415,7 +418,7 @@ void testGetDAI() {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.findLDeviceAdapterByLdInst("LDSUIED").get());
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.findLDeviceAdapterByLdInst("LDSUIED").get());
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
ResumedDataTemplate filter = new ResumedDataTemplate();
filter.setLnClass(ln0Adapter.getLNClass());
@@ -429,10 +432,10 @@ void testGetDAI() {
daTypeName.setFc(TFCEnum.ST);
filter.setDaName(daTypeName);
//When
- var rDtts = ln0Adapter.getDAI(filter,false);
+ var rDtts = ln0Adapter.getDAI(filter, false);
//Then
assertFalse(rDtts.isEmpty());
- assertEquals(1,rDtts.size());
+ assertEquals(1, rDtts.size());
assertNotNull(rDtts.get(0).getDaName().getType());
assertEquals("BehaviourModeKind", rDtts.get(0).getDaName().getType());
}
@@ -443,7 +446,7 @@ void getEnumValue_shouldReturnNothing_whenEnumUnknow() {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
//When
Set enumValues = ln0Adapter.getEnumValues("Behaviour");
@@ -457,7 +460,7 @@ void getEnumValue_shouldReturnEnumValues_whenEnumKnown() {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.findLDeviceAdapterByLdInst("LDSUIED").get());
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.findLDeviceAdapterByLdInst("LDSUIED").get());
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
//When
Set enumValues = ln0Adapter.getEnumValues("BehaviourModeKind");
@@ -473,7 +476,7 @@ void addControlBlock_should_add_ControlBlock(ControlBlock controlBlock) {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
ln0Adapter.createDataSetIfNotExists(controlBlock.getDataSetRef(), controlBlock.getControlBlockEnum());
int initialControlBlockCount = ln0Adapter.getTControlsByType(controlBlock.getControlBlockEnum().getControlBlockClass()).size();
@@ -489,7 +492,7 @@ void addControlBlock_should_add_ReportControlBlock() {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
ln0Adapter.createDataSetIfNotExists("rptDatSet", ControlBlockEnum.REPORT);
ReportControlBlock reportControlBlock = new ReportControlBlock("rpt", "rptID", "rptDatSet");
@@ -497,7 +500,7 @@ void addControlBlock_should_add_ReportControlBlock() {
//When
ln0Adapter.addControlBlock(reportControlBlock);
//Then
- assertThat(ln0Adapter.getCurrentElem().getReportControl()).hasSize(reportCBInitSize+1);
+ assertThat(ln0Adapter.getCurrentElem().getReportControl()).hasSize(reportCBInitSize + 1);
}
@Test
@@ -506,7 +509,7 @@ void addControlBlock_should_add_GooseControlBlock() {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
ln0Adapter.createDataSetIfNotExists("datSet", ControlBlockEnum.GSE);
GooseControlBlock gooseControlBlock = new GooseControlBlock("gse", "gseID", "datSet");
@@ -524,7 +527,7 @@ void addControlBlock_should_add_SMVControlBlock() {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
ln0Adapter.createDataSetIfNotExists("smvDatSet", ControlBlockEnum.SAMPLED_VALUE);
SMVControlBlock smvControlBlock = new SMVControlBlock("smv", "smvID", "smvDatSet");
@@ -532,7 +535,7 @@ void addControlBlock_should_add_SMVControlBlock() {
//When
ln0Adapter.addControlBlock(smvControlBlock);
//Then
- assertThat(ln0Adapter.getCurrentElem().getSampledValueControl()).hasSize(reportCBInitSize+1);
+ assertThat(ln0Adapter.getCurrentElem().getSampledValueControl()).hasSize(reportCBInitSize + 1);
}
@ParameterizedTest
@@ -542,14 +545,14 @@ void addControlBlock_when_accessPoint_does_not_have_capability_should_throw_exce
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
ln0Adapter.createDataSetIfNotExists("dataSet", ControlBlockEnum.REPORT);
ln0Adapter.getParentLDevice().getAccessPoint().setServices(new TServices());
//When & Then
assertThatThrownBy(() -> ln0Adapter.addControlBlock(controlBlock))
- .isInstanceOf(ScdException.class)
- .hasMessageContaining("because IED/AccessPoint does not have capability to create ControlBlock");
+ .isInstanceOf(ScdException.class)
+ .hasMessageContaining("because IED/AccessPoint does not have capability to create ControlBlock");
}
@ParameterizedTest
@@ -559,14 +562,14 @@ void addControlBlock_when_controlBlock_already_exists_should_throw_exception(Con
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
ln0Adapter.createDataSetIfNotExists("dataSet", ControlBlockEnum.REPORT);
ln0Adapter.addControlBlock(controlBlock);
//When & Then
assertThatThrownBy(() -> ln0Adapter.addControlBlock(controlBlock))
- .isInstanceOf(ScdException.class)
- .hasMessageContaining("because it already exists");
+ .isInstanceOf(ScdException.class)
+ .hasMessageContaining("because it already exists");
}
@ParameterizedTest
@@ -576,19 +579,19 @@ void addControlBlock_when_dataSet_does_not_exist_should_throw_exception(ControlB
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED4d4fe1a8cda64cf88a5ee4176a1a0eef"));
- LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(()-> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.getLDeviceAdapterByLdInst("LDSUIED"));
LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter();
//When & Then
assertThatThrownBy(() -> ln0Adapter.addControlBlock(controlBlock))
- .isInstanceOf(ScdException.class)
- .hasMessageContaining("because target DataSet dataSet does not exists");
+ .isInstanceOf(ScdException.class)
+ .hasMessageContaining("because target DataSet dataSet does not exists");
}
- private static Stream provideControlBlocks(){
+ private static Stream provideControlBlocks() {
return Stream.of(
- Arguments.of(named("ReportControlBlock", new ReportControlBlock("name", "id", "dataSet"))),
- Arguments.of(named("GooseControlBlock", new GooseControlBlock("name", "id", "dataSet"))),
- Arguments.of(named("SMVControlBlock", new SMVControlBlock("name", "id", "dataSet")))
+ Arguments.of(named("ReportControlBlock", new ReportControlBlock("name", "id", "dataSet"))),
+ Arguments.of(named("GooseControlBlock", new GooseControlBlock("name", "id", "dataSet"))),
+ Arguments.of(named("SMVControlBlock", new SMVControlBlock("name", "id", "dataSet")))
);
}
@@ -604,11 +607,11 @@ void getTControlsByType_should_return_LN0_list_of_controls_for_this_class(Class<
assertThat(controlList).isSameAs(getter.apply(ln0Adapter.getCurrentElem()));
}
- private static Stream provideGetTControlsByType(){
+ private static Stream provideGetTControlsByType() {
return Stream.of(
- Arguments.of(TGSEControl.class, (Function>) LN0::getGSEControl),
- Arguments.of(TSampledValueControl.class, (Function>) LN0::getSampledValueControl),
- Arguments.of(TReportControl.class, (Function>) LN0::getReportControl)
+ Arguments.of(TGSEControl.class, (Function>) LN0::getGSEControl),
+ Arguments.of(TSampledValueControl.class, (Function>) LN0::getSampledValueControl),
+ Arguments.of(TReportControl.class, (Function>) LN0::getReportControl)
);
}
@@ -617,7 +620,7 @@ void elementXPath() {
// Given
LN0 tln = new LN0();
tln.getLnClass().add(TLLN0Enum.LLN_0.value());
- LN0Adapter lnAdapter = new LN0Adapter(null,tln);
+ LN0Adapter lnAdapter = new LN0Adapter(null, tln);
// When
String result = lnAdapter.elementXPath();
// Then
@@ -630,18 +633,18 @@ void getLDeviceStatus_should_succeed() {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_with_extref_errors.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
Optional optionalLN0Adapter = sclRootAdapter.streamIEDAdapters()
- .flatMap(IEDAdapter::streamLDeviceAdapters)
- .filter(lDeviceAdapter -> "IED_NAME1LD_INST13".equals(lDeviceAdapter.getLdName()))
- .map(LDeviceAdapter::getLN0Adapter)
- .findFirst();
+ .flatMap(IEDAdapter::streamLDeviceAdapters)
+ .filter(lDeviceAdapter -> "IED_NAME1LD_INST13".equals(lDeviceAdapter.getLdName()))
+ .map(LDeviceAdapter::getLN0Adapter)
+ .findFirst();
assertThat(optionalLN0Adapter).isPresent();
LN0Adapter ln0Adapter = optionalLN0Adapter.get();
// When
Optional result = ln0Adapter.getLDeviceStatus();
// Then
assertThat(result)
- .isPresent()
- .hasValue("test");
+ .isPresent()
+ .hasValue("test");
}
@Test
@@ -656,8 +659,8 @@ void createDataSetIfNotExists_should_create_dataSet() {
assertThat(newDataSet.getCurrentElem().getName()).isEqualTo("newDataSet");
assertThat(newDataSet.getParentAdapter().getParentAdapter().getInst()).isEqualTo("LD_INST11");
assertThat(ln0.getCurrentElem().getDataSet())
- .map(TDataSet::getName)
- .containsExactly("newDataSet");
+ .map(TDataSet::getName)
+ .containsExactly("newDataSet");
}
@Test
@@ -670,8 +673,8 @@ void createDataSetIfNotExists_when_dataset_exists_should_not_create_dataset() {
DataSetAdapter newDataSet = ln0.createDataSetIfNotExists("existingDataSet", ControlBlockEnum.GSE);
// Then
assertThat(ln0.getCurrentElem().getDataSet()).hasSize(1)
- .map(TDataSet::getName)
- .containsExactly("existingDataSet");
+ .map(TDataSet::getName)
+ .containsExactly("existingDataSet");
assertThat(newDataSet.getCurrentElem().getName()).isEqualTo("existingDataSet");
assertThat(newDataSet.getParentAdapter().getParentAdapter().getInst()).isEqualTo("LD_INST12");
}
@@ -683,7 +686,7 @@ void createDataSetIfNotExists_when_ied_does_not_have_creation_capabilities_shoul
LN0Adapter ln0 = findLn0(new SclRootAdapter(scd), "IED_NAME2", "LD_INST21");
// When & Then
assertThatThrownBy(() -> ln0.createDataSetIfNotExists("existingDataSet", ControlBlockEnum.GSE))
- .isInstanceOf(ScdException.class);
+ .isInstanceOf(ScdException.class);
}
@Test
@@ -700,11 +703,11 @@ void createControlBlockIfNotExists_should_create_GSEControl() {
sourceLn0.createControlBlockIfNotExists(NEW_CB_NAME, NEW_CB_ID, NEW_DATASET_NAME, ControlBlockEnum.GSE);
// Then
assertThat(sourceLn0.getCurrentElem().getGSEControl())
- .hasSize(1)
- .first().extracting(TControl::getName, TGSEControl::getAppID, TControl::getDatSet,
- TGSEControl::getType, TGSEControl::isFixedOffs, TGSEControl::getSecurityEnable, TControlWithIEDName::getConfRev)
+ .hasSize(1)
+ .first().extracting(TControl::getName, TGSEControl::getAppID, TControl::getDatSet,
+ TGSEControl::getType, TGSEControl::isFixedOffs, TGSEControl::getSecurityEnable, TControlWithIEDName::getConfRev)
.containsExactly(NEW_CB_NAME, NEW_CB_ID, NEW_DATASET_NAME,
- TGSEControlTypeEnum.GOOSE, false, TPredefinedTypeOfSecurityEnum.NONE, 10000L);
+ TGSEControlTypeEnum.GOOSE, false, TPredefinedTypeOfSecurityEnum.NONE, 10000L);
}
@Test
@@ -721,18 +724,18 @@ void createControlBlockIfNotExists_should_create_SampledValueControl() {
sourceLn0.createControlBlockIfNotExists(NEW_CB_NAME, NEW_CB_ID, NEW_DATASET_NAME, ControlBlockEnum.SAMPLED_VALUE);
// Then
assertThat(sourceLn0.getCurrentElem().getSampledValueControl())
- .hasSize(1);
+ .hasSize(1);
TSampledValueControl tSampledValueControl = sourceLn0.getCurrentElem().getSampledValueControl().get(0);
assertThat(tSampledValueControl)
- .extracting(TControl::getName, TSampledValueControl::getSmvID, TControl::getDatSet,
- TSampledValueControl::isMulticast, TSampledValueControl::getSmpRate, TSampledValueControl::getNofASDU, TSampledValueControl::getSmpMod, TSampledValueControl::getSecurityEnable,
- TControlWithIEDName::getConfRev)
- .containsExactly(NEW_CB_NAME, NEW_CB_ID, NEW_DATASET_NAME,
- true, 4800L, 2L, TSmpMod.SMP_PER_SEC, TPredefinedTypeOfSecurityEnum.NONE, 10000L);
+ .extracting(TControl::getName, TSampledValueControl::getSmvID, TControl::getDatSet,
+ TSampledValueControl::isMulticast, TSampledValueControl::getSmpRate, TSampledValueControl::getNofASDU, TSampledValueControl::getSmpMod, TSampledValueControl::getSecurityEnable,
+ TControlWithIEDName::getConfRev)
+ .containsExactly(NEW_CB_NAME, NEW_CB_ID, NEW_DATASET_NAME,
+ true, 4800L, 2L, TSmpMod.SMP_PER_SEC, TPredefinedTypeOfSecurityEnum.NONE, 10000L);
assertThat(tSampledValueControl.getSmvOpts())
- .extracting(SmvOpts::isRefreshTime, SmvOpts::isSampleSynchronized, SmvOpts::isSampleRate, SmvOpts::isDataSet,
- SmvOpts::isSecurity, SmvOpts::isTimestamp)
- .containsExactly(false, true, true, false, false, false);
+ .extracting(SmvOpts::isRefreshTime, SmvOpts::isSampleSynchronized, SmvOpts::isSampleRate, SmvOpts::isDataSet,
+ SmvOpts::isSecurity, SmvOpts::isTimestamp)
+ .containsExactly(false, true, true, false, false, false);
}
@Test
@@ -750,25 +753,250 @@ void createControlBlockIfNotExists_should_create_ReportControl() {
sourceLn0.createControlBlockIfNotExists(NEW_CB_NAME, NEW_CB_ID, NEW_DATASET_NAME, ControlBlockEnum.REPORT);
// Then
assertThat(sourceLn0.getCurrentElem().getReportControl())
- .hasSize(1);
+ .hasSize(1);
TReportControl tReportControl = sourceLn0.getCurrentElem().getReportControl().get(0);
assertThat(tReportControl)
- .extracting(TControl::getName, TReportControl::getRptID, TControl::getDatSet,
- TReportControl::isBuffered, TReportControl::getBufTime, TReportControl::isIndexed, TControlWithTriggerOpt::getIntgPd, TReportControl::getConfRev)
- .containsExactly(NEW_CB_NAME, NEW_CB_ID, NEW_DATASET_NAME,
- true, 0L, true, 60000L, 1L);
+ .extracting(TControl::getName, TReportControl::getRptID, TControl::getDatSet,
+ TReportControl::isBuffered, TReportControl::getBufTime, TReportControl::isIndexed, TControlWithTriggerOpt::getIntgPd, TReportControl::getConfRev)
+ .containsExactly(NEW_CB_NAME, NEW_CB_ID, NEW_DATASET_NAME,
+ true, 0L, true, 60000L, 1L);
assertThat(tReportControl.getTrgOps())
- .extracting(TTrgOps::isDchg, TTrgOps::isQchg, TTrgOps::isPeriod, TTrgOps::isGi)
- .containsOnly(true);
+ .extracting(TTrgOps::isDchg, TTrgOps::isQchg, TTrgOps::isPeriod, TTrgOps::isGi)
+ .containsOnly(true);
assertThat(tReportControl.getTrgOps().isDupd()).isFalse();
assertThat(tReportControl.getOptFields())
- .extracting(TReportControl.OptFields::isSeqNum, TReportControl.OptFields::isTimeStamp, TReportControl.OptFields::isDataSet,
- TReportControl.OptFields::isReasonCode, TReportControl.OptFields::isDataRef, TReportControl.OptFields::isEntryID,
- TReportControl.OptFields::isConfigRef)
- .containsOnly(false);
+ .extracting(TReportControl.OptFields::isSeqNum, TReportControl.OptFields::isTimeStamp, TReportControl.OptFields::isDataSet,
+ TReportControl.OptFields::isReasonCode, TReportControl.OptFields::isDataRef, TReportControl.OptFields::isEntryID,
+ TReportControl.OptFields::isConfigRef)
+ .containsOnly(false);
assertThat(tReportControl.getOptFields().isBufOvfl()).isTrue();
}
+ @Test
+ void getFCDAs_should_return_list_of_FCDAs() {
+
+ TFCDA tfcda = new TFCDA();
+ tfcda.setFc(TFCEnum.CF);
+ TFCDA tfcda1 = new TFCDA();
+ tfcda1.setFc(TFCEnum.CF);
+ TFCDA tfcda2 = new TFCDA();
+ tfcda2.setFc(TFCEnum.CF);
+
+ TDataSet tDataSet1 = new TDataSet();
+ tDataSet1.setName("gse_dat_set");
+ tDataSet1.getFCDA().addAll(List.of(tfcda,tfcda1));
+
+ TDataSet tDataSet2 = new TDataSet();
+ tDataSet2.setName("smv_dat_set");
+ tDataSet2.getFCDA().add(tfcda2);
+
+ TGSEControl gseCB = new TGSEControl();
+ gseCB.setName("gse1");
+ gseCB.setDatSet("gse_dat_set");
+ TSampledValueControl smvCB = new TSampledValueControl();
+ smvCB.setName("smv1");
+ smvCB.setDatSet("smv_dat_set");
+
+ LN0 ln0 = new LN0();
+ ln0.getDataSet().addAll(List.of(tDataSet1, tDataSet2));
+ ln0.getGSEControl().add(gseCB);
+ ln0.getSampledValueControl().add(smvCB);
+ LN0Adapter ln0Adapter = new LN0Adapter(null, ln0);
+
+ TExtRef tExtRef = new TExtRef();
+ tExtRef.setSrcCBName("gse1");
+ tExtRef.setServiceType(TServiceType.GOOSE);
+
+ //When
+ List result = ln0Adapter.getFCDAs(tExtRef);
+
+ //Then
+ assertThat(result).hasSize(2)
+ .containsExactlyInAnyOrder(tfcda, tfcda1);
+
+ }
+
+ @Test
+ void getFCDAs_should_return_empty_list_of_FCDAs() {
+
+ TDataSet tDataSet2 = new TDataSet();
+ tDataSet2.setName("smv_dat_set");
+
+ TSampledValueControl smvCB = new TSampledValueControl();
+ smvCB.setName("smv1");
+ smvCB.setDatSet("smv_dat_set");
+
+ LN0 ln0 = new LN0();
+ ln0.getDataSet().add(tDataSet2);
+ ln0.getSampledValueControl().add(smvCB);
+ LN0Adapter ln0Adapter = new LN0Adapter(null, ln0);
+
+ TExtRef tExtRef = new TExtRef();
+ tExtRef.setSrcCBName("smv1");
+ tExtRef.setServiceType(TServiceType.SMV);
+
+ //When
+ List result = ln0Adapter.getFCDAs(tExtRef);
+
+ //Then
+ assertThat(result).isEmpty();
+
+ }
+
+ @Test
+ void getFCDAs_should_throw_Exception_when_DataSet_not_present() {
+
+ LN0 ln0 = new LN0();
+ LN0Adapter ln0Adapter = new LN0Adapter(null, ln0);
+
+ TExtRef tExtRef = new TExtRef();
+ tExtRef.setSrcCBName("smv1");
+ tExtRef.setServiceType(TServiceType.SMV);
+
+ //When Then
+ assertThatThrownBy(() -> ln0Adapter.getFCDAs(tExtRef))
+ .isInstanceOf(ScdException.class)
+ .hasMessage("Control Block smv1 not found in /LN0");
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @CsvSource({
+ "Case without InRef,LD_WITHOUT_InRef,InRef1",
+ "Case with no InRef finishing with _1,LD_WITH_1_Bad_InRef,InRef4",
+ "Case with several ExtRef desc finishing with _1,LD_WITH_2_InRef_same_SUFFIX,InRef5"
+ })
+ void updateDoInRef_should_return_error_message(String testName, String ldInst, String doiName) {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_test.xml");
+ LN0Adapter sourceLn0 = findLn0(new SclRootAdapter(scd), "IED_NAME1", ldInst);
+
+ // When
+ List sclReportItems = sourceLn0.updateDoInRef();
+
+ // Then
+ assertThat(sclReportItems).hasSize(1)
+ .extracting(SclReportItem::getMessage)
+ .containsExactly("The DOI /SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"" + ldInst + "\"]/LN0/DOI[@name=\"" + doiName + "\"] can't be bound with an ExtRef");
+ }
+
+ @Test
+ void updateDoInRef_should_return_error_message_when_no_Val_in_DAI_purpose() {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_test.xml");
+ LN0Adapter sourceLn0 = findLn0(new SclRootAdapter(scd), "IED_NAME1", "LD_Without_Val_in_DAI_purpose");
+
+ // When
+ List sclReportItems = sourceLn0.updateDoInRef();
+
+ // Then
+ assertThat(sclReportItems).hasSize(1)
+ .extracting(SclReportItem::getMessage)
+ .containsExactly("The DOI /SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"" + "LD_Without_Val_in_DAI_purpose" + "\"]/LN0 can't be bound with an ExtRef");
+ }
+
+ @Test
+ void updateDoInRef_should_not_treat_LN0_when_DAI_name_purpose_not_compliant() {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_test.xml");
+ LN0Adapter sourceLn0 = findLn0(new SclRootAdapter(scd), "IED_NAME1", "LD_Without_purpose");
+
+ // When
+ List sclReportItems = sourceLn0.updateDoInRef();
+
+ // Then
+ DOIAdapter.DAIAdapter finalSetSrcRef = sourceLn0.getDOIAdapterByName("InRef6").getDataAdapterByName(DOIAdapter.DA_NAME_SET_SRC_REF);
+ assertThat(finalSetSrcRef.getCurrentElem().isSetVal()).isFalse();
+ assertThat(sclReportItems).isEmpty();
+ }
+
+ @Test
+ void updateDoInRef_should_update_setSrcRef_and_not_setSrcCB_when_one_ExtRef_desc_matches() {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_test.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ LN0Adapter sourceLn0 = findLn0(sclRootAdapter, "IED_NAME1", "LD_WITH_1_InRef_without_cbName");
+ String doiNameInRef = "InRef7";
+ List daiValList = sourceLn0.getDOIAdapterByName(doiNameInRef).getDataAdapterByName(DOIAdapter.DA_NAME_SET_SRC_REF).getCurrentElem().getVal();
+ String originalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_SRC_CB);
+ String expectedSrcRef = "IED_NAME1LD_WITH_1_InRef/PRANCR1.Do11.sdo11";
+
+ assertThat(daiValList).isEmpty();
+
+ // When
+ List sclReportItems = sourceLn0.updateDoInRef();
+
+ // Then
+ String finalSetSrcRef = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_SRC_REF);
+ String finalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_SRC_CB);
+ assertThat(finalSetSrcRef)
+ .isNotBlank()
+ .isEqualTo(expectedSrcRef);
+ assertThat(finalSetSrcCB).isEqualTo(originalSetSrcCB);
+ assertThat(sclReportItems).isEmpty();
+ }
+
+ @Test
+ void updateDoInRef_should_update_setSrcRef_and_setSrcCB_when_one_ExtRef_desc_matches() {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_test.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ LN0Adapter sourceLn0 = findLn0(sclRootAdapter, "IED_NAME1", "LD_WITH_1_InRef");
+ String doiNameInRef = "InRef2";
+ String originalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_SRC_CB);
+ String expectedSrcRef = "IED_NAME1LD_WITH_1_InRef/PRANCR1.Do11.sdo11";
+ String expectedSrcCb = "IED_NAME1LD_WITH_1_InRef/prefixANCR1.GSE1";
+
+ // When
+ List sclReportItems = sourceLn0.updateDoInRef();
+
+ // Then
+ String finalSetSrcRef = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_SRC_REF);
+ String finalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_SRC_CB);
+ assertThat(finalSetSrcRef)
+ .isNotBlank()
+ .isEqualTo(expectedSrcRef);
+ assertThat(finalSetSrcCB)
+ .isNotEqualTo(originalSetSrcCB)
+ .isEqualTo(expectedSrcCb);
+ assertThat(sclReportItems).isEmpty();
+ }
+
+ @Test
+ void updateDoInRef_should_update_setSrcRef_and_setSrcCB_and_setTstRef_and_setTstCB_when_ExtRef_desc_matches() {
+ // Given
+ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_test.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ LN0Adapter sourceLn0 = findLn0(sclRootAdapter, "IED_NAME1", "LD_WITH_3_InRef");
+ String doiNameInRef = "InRef3";
+ String originalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_SRC_CB);
+ String expectedSrcRef = "IED_NAME1LD_WITH_3_InRef/PRANCR1.Do11.sdo11";
+ String expectedSrcCb = "IED_NAME1LD_WITH_3_InRef/prefixANCR1.GSE1";
+ String originalSetTstCB = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_TST_CB);
+ String expectedTstRef = "IED_NAME1LD_WITH_3_InRef/PRANCR1.Do11.sdo11";
+ String expectedTstCB = "IED_NAME1LD_WITH_3_InRef/prefixANCR3.GSE3";
+
+ // When
+ List sclReportItems = sourceLn0.updateDoInRef();
+ // Then
+
+ String finalSetSrcRef = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_SRC_REF);
+ String finalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_SRC_CB);
+ String finalSetTstRef = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_TST_REF);
+ String finalSetTstCB = getDaiValue(sourceLn0, doiNameInRef, DOIAdapter.DA_NAME_SET_TST_CB);
+ assertThat(finalSetSrcRef)
+ .isNotBlank()
+ .isEqualTo(expectedSrcRef);
+ assertThat(finalSetSrcCB)
+ .isNotEqualTo(originalSetSrcCB)
+ .isEqualTo(expectedSrcCb);
+ assertThat(finalSetTstRef)
+ .isNotBlank()
+ .isEqualTo(expectedTstRef);
+ assertThat(finalSetTstCB)
+ .isNotEqualTo(originalSetTstCB)
+ .isEqualTo(expectedTstCB);
+ assertThat(sclReportItems).isEmpty();
+ }
}
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java
index c0dc0e129..199b61e32 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java
@@ -4,6 +4,7 @@
package org.lfenergy.compas.sct.commons.scl.ied;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -20,8 +21,7 @@
import java.util.Optional;
import java.util.stream.Stream;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
class LNAdapterTest {
@@ -380,7 +380,7 @@ void testUpdateExtRefSource() {
assertThat(extRef.getSrcCBName()).isEqualTo(extRefInfo.getSourceInfo().getSrcCBName());
assertThat(extRef.getSrcLDInst()).isEqualTo(extRefInfo.getSourceInfo().getSrcLDInst());
- assertThat(extRef.getLnClass().contains(extRefInfo.getSourceInfo().getSrcLNClass())).isTrue();
+ assertThat(extRef.getLnClass()).contains(extRefInfo.getSourceInfo().getSrcLNClass());
}
@@ -434,7 +434,8 @@ void testGetLNodeName() {
}
@Test
- void testUpdateDAI() {
+ void updateDAI_should_throw_ScdException_when_ResumedDataTemplate_is_empty() {
+ // Given
ResumedDataTemplate rDtt = new ResumedDataTemplate();
SCL scd = SclTestMarshaller.getSCLFromFile("/ied-test-schema-conf/ied_unit_test.xml");
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
@@ -445,28 +446,138 @@ void testUpdateDAI() {
.withLnClass(TLLN0Enum.LLN_0.value())
.build();
- assertThrows(ScdException.class, () -> lnAdapter.updateDAI(rDtt));
+ // When Then
+ assertThatThrownBy(() -> lnAdapter.updateDAI(rDtt))
+ .isInstanceOf(ScdException.class)
+ .hasMessage("Cannot update undefined DAI");
+ }
+
+ @Test
+ void updateDAI_should_throw_ScdException_when_ResumedDataTemplate_DA_name_is_not_defined() {
+ // Given
+ ResumedDataTemplate rDtt = new ResumedDataTemplate();
+ SCL scd = SclTestMarshaller.getSCLFromFile("/ied-test-schema-conf/ied_unit_test.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED_NAME"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.findLDeviceAdapterByLdInst("LD_INS1").get());
+ AbstractLNAdapter> lnAdapter = AbstractLNAdapter.builder()
+ .withLDeviceAdapter(lDeviceAdapter)
+ .withLnClass(TLLN0Enum.LLN_0.value())
+ .build();
DoTypeName doTypeName = new DoTypeName("Do.sdo1.d");
rDtt.setDoName(doTypeName);
- assertThrows(ScdException.class, () -> lnAdapter.updateDAI(rDtt));
+
+ // When Then
+ assertThatThrownBy(() -> lnAdapter.updateDAI(rDtt))
+ .isInstanceOf(ScdException.class)
+ .hasMessage("Cannot update undefined DAI");
+ }
+
+ @Test
+ @Disabled(value = "Disable while bug #241 is not fixed")
+ /**
+ * @see Issue !241 (UpdateDAI Val does not produce subelements (SDI) as expected)
+ */
+ void updateDAI_should_not_update_DAI_Val_when_DTT_Fc_not_defined() {
+ // Given
+ ResumedDataTemplate rDtt = new ResumedDataTemplate();
+ SCL scd = SclTestMarshaller.getSCLFromFile("/ied-test-schema-conf/ied_unit_test.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED_NAME"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.findLDeviceAdapterByLdInst("LD_INS1").get());
+ LN0Adapter lnAdapter = (LN0Adapter) AbstractLNAdapter.builder()
+ .withLDeviceAdapter(lDeviceAdapter)
+ .withLnClass(TLLN0Enum.LLN_0.value())
+ .build();
+
+ rDtt.setDoName(new DoTypeName("Do.sdo1.d"));
rDtt.setDaName(new DaTypeName("antRef.bda1.bda2.bda3"));
TVal tVal = new TVal();
tVal.setValue("newValue");
rDtt.setDaiValues(List.of(tVal));
- assertDoesNotThrow(() -> lnAdapter.updateDAI(rDtt));
- lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.findLDeviceAdapterByLdInst("LD_INS2").get());
- AbstractLNAdapter> lnAdapter2 = AbstractLNAdapter.builder()
+ // When
+ lnAdapter.updateDAI(rDtt);
+
+ // Then
+ SDIAdapter.DAIAdapter daiAdapter = lnAdapter
+ .getDOIAdapterByName("Do")
+ .getStructuredDataAdapterByName("sdo1")
+ .getStructuredDataAdapterByName("d")
+ .getStructuredDataAdapterByName("bda1")
+ .getStructuredDataAdapterByName("bda2")
+ .getStructuredDataAdapterByName("bda3")
+ .getDataAdapterByName("antRef");
+
+ assertThat(daiAdapter.getCurrentElem().getVal().get(0).getValue()).isEqualTo("Completed-diff");
+
+ System.out.println(MarshallerWrapper.marshall(scd));
+ }
+
+ @Test
+ @Disabled(value = "Disable while bug #241 is not fixed")
+ /**
+ * @see Issue !241 (UpdateDAI Val does not produce subelements (SDI) as expected)
+ */
+ void updateDAI_should_update_DAI_values_when_data_updatable() {
+ // Given
+ ResumedDataTemplate rDtt = new ResumedDataTemplate();
+ SCL scd = SclTestMarshaller.getSCLFromFile("/ied-test-schema-conf/ied_unit_test.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED_NAME"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.findLDeviceAdapterByLdInst("LD_INS2").get());
+ LN0Adapter lnAdapter = (LN0Adapter) AbstractLNAdapter.builder()
.withLDeviceAdapter(lDeviceAdapter)
.withLnClass(TLLN0Enum.LLN_0.value())
.build();
+
+ rDtt.setDoName(new DoTypeName("Do.sdo1.d"));
+ rDtt.setDaName(new DaTypeName("antRef.bda1.bda2.bda3"));
+ TVal tVal = new TVal();
+ tVal.setValue("newValue");
rDtt.setValImport(true);
rDtt.setFc(TFCEnum.SE);
- assertTrue(rDtt.isUpdatable());
- assertDoesNotThrow(() -> lnAdapter2.updateDAI(rDtt));
+ assertThat(rDtt.isUpdatable()).isTrue();
+ rDtt.setDaiValues(List.of(tVal));
+
+ // When
+ lnAdapter.updateDAI(rDtt);
+
+ // Then
+ SDIAdapter.DAIAdapter daiAdapter = lnAdapter
+ .getDOIAdapterByName("Do")
+ .getStructuredDataAdapterByName("sdo1")
+ .getStructuredDataAdapterByName("d")
+ .getStructuredDataAdapterByName("antRef")
+ .getStructuredDataAdapterByName("bda1")
+ .getStructuredDataAdapterByName("bda2")
+ .getDataAdapterByName("bda3");
+
+ assertThat(daiAdapter.getCurrentElem().getVal().get(0).getValue()).isEqualTo("newValue");
System.out.println(MarshallerWrapper.marshall(scd));
+ }
+
+ @Test
+ void updateDAI_should_not_update_DAI_values_when_not_updatable() {
+ // Given
+ ResumedDataTemplate rDtt = new ResumedDataTemplate();
+ SCL scd = SclTestMarshaller.getSCLFromFile("/ied-test-schema-conf/ied_unit_test.xml");
+ SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
+ IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED_NAME"));
+ LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.findLDeviceAdapterByLdInst("LD_INS1").get());
+ LN0Adapter lnAdapter = (LN0Adapter) AbstractLNAdapter.builder()
+ .withLDeviceAdapter(lDeviceAdapter)
+ .withLnClass(TLLN0Enum.LLN_0.value())
+ .build();
+
+ rDtt.setDoName(new DoTypeName("Do.sdo1.d"));
+ rDtt.setDaName(new DaTypeName("antRef.bda1.bda2.bda3"));
+ rDtt.setValImport(false);
+ // When Then
+ assertThat(rDtt.isUpdatable()).isFalse();
+ assertThatCode(() -> lnAdapter.updateDAI(rDtt)).doesNotThrowAnyException();
}
@Test
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java
index 0e554cb54..71d3d110a 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java
@@ -156,4 +156,7 @@ public static Stream streamAllExtRef(SclRootAdapter sclRootAdapter) {
.flatMap(List::stream);
}
+ public static String getDaiValue(AbstractLNAdapter> ln, String doiName, String daiName) {
+ return ln.getDOIAdapterByName(doiName).getDataAdapterByName(daiName).getCurrentElem().getVal().get(0).getValue();
+ }
}
diff --git a/sct-commons/src/test/resources/limitation_cb_dataset_fcda/scd_check_coherent_extRefs.xml b/sct-commons/src/test/resources/limitation_cb_dataset_fcda/scd_check_coherent_extRefs.xml
new file mode 100644
index 000000000..e09b36fc2
--- /dev/null
+++ b/sct-commons/src/test/resources/limitation_cb_dataset_fcda/scd_check_coherent_extRefs.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sct-commons/src/test/resources/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml b/sct-commons/src/test/resources/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml
new file mode 100644
index 000000000..57382209d
--- /dev/null
+++ b/sct-commons/src/test/resources/limitation_cb_dataset_fcda/scd_check_limitation_binded_ied_controls_fcda.xml
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sct-commons/src/test/resources/limitation_cb_dataset_fcda/scd_check_limitation_ied_controls_dataset.xml b/sct-commons/src/test/resources/limitation_cb_dataset_fcda/scd_check_limitation_ied_controls_dataset.xml
new file mode 100644
index 000000000..6c8c046b7
--- /dev/null
+++ b/sct-commons/src/test/resources/limitation_cb_dataset_fcda/scd_check_limitation_ied_controls_dataset.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sct-commons/src/test/resources/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success_analyze.xml b/sct-commons/src/test/resources/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success_analyze.xml
new file mode 100644
index 000000000..4cd987c58
--- /dev/null
+++ b/sct-commons/src/test/resources/scd-extref-create-dataset-and-controlblocks/scd_create_dataset_and_controlblocks_success_analyze.xml
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ on
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ on
+
+
+
+
+
+
+
+
+
+
+ 5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ on
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ on
+ off
+ test
+
+
+
diff --git a/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd_with_same_compas_icd_header_in_different_functions.xml b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd_with_same_compas_icd_header_in_different_functions.xml
new file mode 100644
index 000000000..c2d4c04d1
--- /dev/null
+++ b/sct-commons/src/test/resources/scd-ied-dtt-com-import-stds/scd_with_same_compas_icd_header_in_different_functions.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ SCD
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sct-commons/src/test/resources/scd-refresh-lnode/issue_165_enhance_68_Test_Dai_Updatable.scd b/sct-commons/src/test/resources/scd-refresh-lnode/issue_165_enhance_68_Test_Dai_Updatable.scd
index 48c81222d..68a260d66 100644
--- a/sct-commons/src/test/resources/scd-refresh-lnode/issue_165_enhance_68_Test_Dai_Updatable.scd
+++ b/sct-commons/src/test/resources/scd-refresh-lnode/issue_165_enhance_68_Test_Dai_Updatable.scd
@@ -169,6 +169,80 @@
+
+ SAMU
+ SAMU
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 01.00.000
+
+
+ 01.00.000
+
+
+
+
+ on
+
+
+
+
+
+
+
+
+
+
+ SAMU
+ SAMU
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 01.00.000
+
+
+ 01.00.000
+
+
+
+
+ on
+
+
+
+
+
+
+
+
+
diff --git a/sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_issue_231_test_ko.xml b/sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_issue_231_test_ko.xml
new file mode 100644
index 000000000..7b81a7164
--- /dev/null
+++ b/sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_issue_231_test_ko.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LD_WITHOUT_InRef_DOI_InRef1
+
+
+
+
+
+
+
+
+
+
+ LD_WITH_1_Bad_InRef_DOI_InRef4
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LD_WITH_1_Bad_InRef_DOI_InRef5
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_issue_231_test_ok.xml b/sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_issue_231_test_ok.xml
new file mode 100644
index 000000000..9b15fc0b5
--- /dev/null
+++ b/sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_issue_231_test_ok.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LD_WITH_1_InRef_DOI_InRef2
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LD_WITH_3_InRef_DOI_InRef3
+
+
+
+ OLD_VAL
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_test.xml b/sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_test.xml
new file mode 100644
index 000000000..3a26f7493
--- /dev/null
+++ b/sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_test.xml
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LD_WITHOUT_InRef_DOI_InRef1
+
+
+
+
+
+
+
+
+
+
+ LD_WITH_1_InRef_DOI_InRef2
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LD_WITH_3_InRef_DOI_InRef3
+
+
+
+ OLD_VAL
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LD_WITH_1_Bad_InRef_DOI_InRef4
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LD_WITH_1_Bad_InRef_DOI_InRef5
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LD_WITH_1_InRef_without_cbName_DOI_InRef7
+
+
+
+ OLD_VAL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file