diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java
index 8debf101b..ae3f530af 100644
--- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java
+++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapter.java
@@ -18,10 +18,8 @@
import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
import org.lfenergy.compas.sct.commons.util.Utils;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
+import java.util.stream.Collectors;
/**
* A representation of the model object
@@ -41,7 +39,8 @@
*
{@link LNodeTypeAdapter#getDOTypeId Returns the value of the type attribute By DOType Id}
* {@link LNodeTypeAdapter#getId() Returns the value of the id attribute}
* {@link LNodeTypeAdapter#getLNClass Returns the value of the lnClass attribute}
- * {@link LNodeTypeAdapter#getDataAttributeRefs Returns DataAttributeRef list}
+ * {@link LNodeTypeAdapter#getDataAttributeRefs(DataAttributeRef)} Returns DataAttributeRef list}
+ * {@link LNodeTypeAdapter#getDataAttributeRefs(String)} Returns DataAttributeRef list}
*
* Checklist functions
*
@@ -52,13 +51,14 @@
*/
@Slf4j
public class LNodeTypeAdapter
- extends SclElementAdapter
- implements IDataTemplate,IDTTComparable {
+ extends SclElementAdapter
+ implements IDataTemplate, IDTTComparable {
/**
* Constructor
+ *
* @param parentAdapter Parent container reference
- * @param currentElem Current reference
+ * @param currentElem Current reference
*/
public LNodeTypeAdapter(DataTypeTemplateAdapter parentAdapter, TLNodeType currentElem) {
super(parentAdapter, currentElem);
@@ -66,6 +66,7 @@ public LNodeTypeAdapter(DataTypeTemplateAdapter parentAdapter, TLNodeType curren
/**
* Check if node is child of the reference node
+ *
* @return link parent child existence
*/
@Override
@@ -82,36 +83,37 @@ protected String elementXPath() {
/**
* Compares current LNodeType and given LNodeType
+ *
* @param tlNodeType LNodeType to compare with
* @return Boolean value of comparison result
*/
@Override
public boolean hasSameContentAs(TLNodeType tlNodeType) {
- if(!DataTypeTemplateAdapter.hasSamePrivates(currentElem,tlNodeType)){
+ if (!DataTypeTemplateAdapter.hasSamePrivates(currentElem, tlNodeType)) {
return false;
}
- if(Objects.equals(
+ if (Objects.equals(
currentElem.getLnClass().toArray(new String[0]),
tlNodeType.getLnClass().toArray(new String[0])
- ) || !Objects.equals(currentElem.getIedType(),tlNodeType.getIedType())){
+ ) || !Objects.equals(currentElem.getIedType(), tlNodeType.getIedType())) {
return false;
}
List thisTDOs = currentElem.getDO();
List inTDOs = tlNodeType.getDO();
- if(thisTDOs.size() != inTDOs.size()) {
+ if (thisTDOs.size() != inTDOs.size()) {
return false;
}
- for(int i = 0; i < inTDOs.size(); i++){
+ for (int i = 0; i < inTDOs.size(); i++) {
// the order in which DOs appears matter
TDO inTDO = inTDOs.get(i);
TDO thisTDO = thisTDOs.get(i);
- if(!thisTDO.getType().equals(inTDO.getType())
+ if (!thisTDO.getType().equals(inTDO.getType())
|| !thisTDO.getName().equals(inTDO.getName())
|| thisTDO.isTransient() != inTDO.isTransient()
- || !Objects.equals(thisTDO.getAccessControl(), inTDO.getAccessControl())){
+ || !Objects.equals(thisTDO.getAccessControl(), inTDO.getAccessControl())) {
return false;
}
}
@@ -120,6 +122,7 @@ public boolean hasSameContentAs(TLNodeType tlNodeType) {
/**
* Checks if current LNodeType contains DO with specific DOTYpe ID
+ *
* @param doTypeId ID of DOType in DO to check
* @return Boolean value of check result
*/
@@ -130,10 +133,11 @@ public boolean containsDOWithDOTypeId(String doTypeId) {
/**
* Gets LnClass value
+ *
* @return LnClass Value
*/
public String getLNClass() {
- if(!currentElem.getLnClass().isEmpty()){
+ if (!currentElem.getLnClass().isEmpty()) {
return currentElem.getLnClass().get(0);
}
return null;
@@ -141,10 +145,11 @@ public String getLNClass() {
/**
* Gets DOType ID from current LNodeType
+ *
* @param doName name of DO for which ID is search
* @return optional of Boolean value
*/
- public Optional getDOTypeId(String doName){
+ public Optional getDOTypeId(String doName) {
return currentElem.getDO()
.stream()
.filter(tdo -> doName.equals(Utils.removeTrailingDigits(tdo.getName())))
@@ -154,17 +159,18 @@ public Optional getDOTypeId(String doName){
/**
* return a list of summarized Data Attribute References beginning from given this LNodeType.
- * @apiNote This method doesn't check relationship between DO/SDO and DA. Check should be done by caller
+ *
* @param filter filter for LNodeType
* @return list of completed Data Attribute References beginning from this LNodeType.
+ * @apiNote This method doesn't check relationship between DO/SDO and DA. Check should be done by caller
*/
- public List getDataAttributeRefs(@NonNull DataAttributeRef filter) {
+ public List getDataAttributeRefs(@NonNull DataAttributeRef filter) {
List dataAttributeRefs = new ArrayList<>();
- if(filter.isDaNameDefined()) {
+ if (filter.isDaNameDefined()) {
try {
- check(filter.getDoName(),filter.getDaName());
- } catch (ScdException e){
+ check(filter.getDoName(), filter.getDaName());
+ } catch (ScdException e) {
log.error(e.getMessage());
return dataAttributeRefs;
}
@@ -175,26 +181,97 @@ public List getDataAttributeRefs(@NonNull DataAttributeRef fil
rootDataAttributeRef.setLnInst(filter.getLnInst());
rootDataAttributeRef.setPrefix(filter.getPrefix());
- for(TDO tdo : currentElem.getDO()){
- if(filter.isDoNameDefined() &&
- !filter.getDoName().getName().equals(tdo.getName())){
+ for (TDO tdo : currentElem.getDO()) {
+ if (filter.isDoNameDefined() &&
+ !filter.getDoName().getName().equals(tdo.getName())) {
continue;
}
parentAdapter.getDOTypeAdapterById(tdo.getType()).ifPresent(
- doTypeAdapter -> {
- DataAttributeRef currentDataAttributeRef = DataAttributeRef.copyFrom(rootDataAttributeRef);
- currentDataAttributeRef.getDoName().setName(tdo.getName());
- currentDataAttributeRef.getDoName().setCdc(doTypeAdapter.getCdc());
- dataAttributeRefs.addAll(doTypeAdapter.getDataAttributeRefs(currentDataAttributeRef, filter));
- }
+ doTypeAdapter -> {
+ DataAttributeRef currentDataAttributeRef = DataAttributeRef.copyFrom(rootDataAttributeRef);
+ currentDataAttributeRef.getDoName().setName(tdo.getName());
+ currentDataAttributeRef.getDoName().setCdc(doTypeAdapter.getCdc());
+ dataAttributeRefs.addAll(doTypeAdapter.getDataAttributeRefs(currentDataAttributeRef, filter));
+ }
); // else this should never happen or the scd won't be built in the first place and we'd never be here
}
return dataAttributeRefs;
}
+ /**
+ * Return a list of summarized Data Attribute References beginning from given this LNodeType.
+ * The key point in the algorithm is to find where the DO/SDO part ends and the DA/BDA part begins.
+ * Once it is found, we can use the usual method DOTypeAdapter#getDataAttributeRefs to retrieve the DataAttributeRef
+ * For example, with input "Do1.da1", we want to find the "da1" which is the DA/BDA part and also the DOTypeAdapter of "Do1" (to call DOTypeAdapter#getDataAttributeRefs)
+ * Other example, with input "Do1.sdo1.da1.bda1", we want to find the "da1.bda1" which is the DA/BDA part and also the DOTypeAdapter of "sdo1" (to call DOTypeAdapter#getDataAttributeRefs)
+ * To do that we put the input in a Queue ["Do1", "sdo1", "da1", "bda1"]
+ * 1. The first element "Do1" must be a DO in the curent LNodeTypeAdapter. We retrieve its DOTypeAdapter doTypeAdapterOfDo1.
+ * 2a. The next element "sdo1" can be a SDO or a DA. We call doTypeAdapterOfDo1.getDOTypeAdapterBySdoName, and we get the DOTypeAdapter for sdo1 doTypeAdapterOfSdo1. We found it so it really is a SDO.
+ * 2b. The next element "da1" can be a SDO or a DA. We call doTypeAdapterOfSdo1.getDOTypeAdapterBySdoName, and we get an empty Optional. So no it is not a SDO.
+ * We stop here because we have what we want : doTypeAdapterOfSdo1 and the DA/BDA part "da1.bda1"
+ * 3. we call doTypeAdapterOfSdo1#getDataAttributeRefs as usual with "da1.bda1" filter
+ *
+ * @param dataRef complete reference of Data Attribute including DO name, SDO names (optional), DA name, BDA names (optional).
+ * Ex: Do.sdo1.sdo2.da.bda1.bda2
+ * @return list of completed Data Attribute References beginning from this LNodeType.
+ * @apiNote This method doesn't check relationship between DO/SDO and DA. Check should be done by caller
+ */
+ public DataAttributeRef getDataAttributeRefs(@NonNull String dataRef) {
+ LinkedList dataRefList = new LinkedList<>(Arrays.asList(dataRef.split("\\.")));
+ if (dataRefList.size() < 2) {
+ throw new ScdException("Invalid data reference %s. At least DO name and DA name are required".formatted(dataRef));
+ }
+ // 1. Get the DO
+ String doName = dataRefList.remove();
+ return getDOAdapterByName(doName)
+ .flatMap(doAdapter -> getDataTypeTemplateAdapter().getDOTypeAdapterById(doAdapter.getType()))
+ .map(doTypeAdapter -> {
+ // 2. find the SDOs, if any
+ List sdoAccumulator = new ArrayList<>();
+ List daAccumulator = new ArrayList<>();
+ DOTypeAdapter deepestDo = dataRefList.stream()
+ .reduce(doTypeAdapter, // initial value is the DO
+ (lastDoTypeAdapter, name) -> {
+ if (daAccumulator.isEmpty()) { // We did not reach the DA/BDA part yet
+ Optional optSdo = lastDoTypeAdapter.getDOTypeAdapterBySdoName(name);
+ if (optSdo.isPresent()) {
+ // case name is a SDO name
+ sdoAccumulator.add(name);
+ return optSdo.get(); // return the found SDO
+ }
+ }
+ // case name is a DA or a BDA name
+ daAccumulator.add(name);
+ return lastDoTypeAdapter; // return the same as input
+ },
+ (doTypeAdapter1, doTypeAdapter2) -> {
+ throw new ScdException("This reduction cannot be parallel");
+ });
+ // 3. Find the DA/BDA by calling usual DOTypeAdapter.getDataAttributeRefs
+ DoTypeName doTypeName = new DoTypeName(doName);
+ doTypeName.getStructNames().addAll(sdoAccumulator);
+ doTypeName.setCdc(doTypeAdapter.getCdc());
+ DataAttributeRef rootDataAttributeRef = new DataAttributeRef();
+ rootDataAttributeRef.setDoName(doTypeName);
+ DataAttributeRef filter = new DataAttributeRef();
+ filter.setDaName(new DaTypeName(String.join(".", daAccumulator)));
+ List dataAttributeRefs = deepestDo.getDataAttributeRefs(rootDataAttributeRef, filter);
+ // We want exactly one result
+ if (dataAttributeRefs.size() > 1) {
+ throw new ScdException("Multiple Data Attribute found for this data reference %s in LNodeType.lnClass=%s, LNodeType.id=%s. Found DA : %s ".formatted(dataRef, getLNClass(), getId(), dataAttributeRefs.stream().map(DataAttributeRef::getDataAttributes).collect(Collectors.joining(", "))));
+ }
+ if (dataAttributeRefs.isEmpty() || !dataRef.equals(dataAttributeRefs.get(0).getDataAttributes())) {
+ return null;
+ }
+ return dataAttributeRefs.get(0);
+ }).orElseThrow(() ->
+ new ScdException("No Data Attribute found with this reference %s for LNodeType.lnClass=%s, LNodeType.id=%s ".formatted(dataRef, getLNClass(), getId())));
+ }
+
/**
* Gets linked DataTypeTemplateAdapter as parent
+ *
* @return DataTypeTemplateAdapter object
*/
@Override
@@ -204,13 +281,14 @@ public DataTypeTemplateAdapter getDataTypeTemplateAdapter() {
/**
* Gets DO from current LNodeType
+ *
* @param name name of DO to find
* @return optional of DOAdapter adapter
*/
public Optional getDOAdapterByName(String name) {
- for(TDO tdo : currentElem.getDO()){
- if(tdo.getName().equals(name)){
- return Optional.of(new DOAdapter(this,tdo));
+ for (TDO tdo : currentElem.getDO()) {
+ if (tdo.getName().equals(name)) {
+ return Optional.of(new DOAdapter(this, tdo));
}
}
return Optional.empty();
@@ -218,17 +296,18 @@ public Optional getDOAdapterByName(String name) {
/**
* Find path from a DO to DA (defined by names)
+ *
* @param doName DO from which find a path
* @param daName DA for which find a path to
* @return pair of DO name and DOType.
* @throws ScdException when inconsistency are found in th SCL's
- * DataTypeTemplate (unknown reference for example). Which should normally not happens.
+ * DataTypeTemplate (unknown reference for example). Which should normally not happens.
*/
- Pair findPathFromDo2DA(String doName, String daName) throws ScdException {
+ Pair findPathFromDo2DA(String doName, String daName) throws ScdException {
DOAdapter doAdapter = getDOAdapterByName(doName).orElseThrow();
DOTypeAdapter doTypeAdapter = doAdapter.getDoTypeAdapter().orElseThrow();
- if(doTypeAdapter.containsDAWithDAName(doName)){
- return Pair.of(doName,doTypeAdapter);
+ if (doTypeAdapter.containsDAWithDAName(doName)) {
+ return Pair.of(doName, doTypeAdapter);
}
return doTypeAdapter.findPathDoTypeToDA(daName);
}
@@ -236,24 +315,25 @@ Pair findPathFromDo2DA(String doName, String daName) throw
/**
* Check if DoTypeName and DaTypeName are correct and coherent with this LNodeTypeAdapter
+ *
* @param doTypeName DO/SDO to check
* @param daTypeName DA/BDA to check
* @throws ScdException when inconsistency are found in th SCL's
- * DataTypeTemplate (unknown reference for example). Which should normally not happens.
+ * DataTypeTemplate (unknown reference for example). Which should normally not happens.
*/
public void check(@NonNull DoTypeName doTypeName, @NonNull DaTypeName daTypeName) throws ScdException {
- if(!doTypeName.isDefined() || !daTypeName.isDefined() ){
+ if (!doTypeName.isDefined() || !daTypeName.isDefined()) {
throw new ScdException("Invalid Data: data attributes information are missing");
}
// check Data Object information
DOAdapter doAdapter = this.getDOAdapterByName(doTypeName.getName()).orElseThrow(
- () -> new ScdException(
- String.format("Unknown DO(%s) in LNodeType(%s)",doTypeName.getName(), currentElem.getId())
- )
+ () -> new ScdException(
+ String.format("Unknown DO(%s) in LNodeType(%s)", doTypeName.getName(), currentElem.getId())
+ )
);
DOTypeAdapter doTypeAdapter = doAdapter.getDoTypeAdapter().orElseThrow(
- () -> new ScdException("Corrupted SCL DataTypeTemplate, Unknown DOType id: " + doAdapter.getType())
+ () -> new ScdException("Corrupted SCL DataTypeTemplate, Unknown DOType id: " + doAdapter.getType())
);
Pair adapterPair = doTypeAdapter.checkAndCompleteStructData(doTypeName)
@@ -261,11 +341,11 @@ public void check(@NonNull DoTypeName doTypeName, @NonNull DaTypeName daTypeName
// check coherence between Data Object and Data Attributes information
DOTypeAdapter lastDoTypeAdapter;
- if(adapterPair == null){
- adapterPair = findPathFromDo2DA(doTypeName.getName(),daTypeName.getName());
+ if (adapterPair == null) {
+ adapterPair = findPathFromDo2DA(doTypeName.getName(), daTypeName.getName());
lastDoTypeAdapter = adapterPair.getValue();
} else {
- if(adapterPair.getRight().containsDAWithDAName(daTypeName.getName())){
+ if (adapterPair.getRight().containsDAWithDAName(daTypeName.getName())) {
lastDoTypeAdapter = adapterPair.getValue();
} else {
adapterPair = adapterPair.getRight().findPathDoTypeToDA(daTypeName.getName());
@@ -274,25 +354,25 @@ public void check(@NonNull DoTypeName doTypeName, @NonNull DaTypeName daTypeName
}
DAAdapter daAdapter = lastDoTypeAdapter.getDAAdapterByName(daTypeName.getName())
- .orElseThrow(
- ()-> new ScdException(
- String.format("Unknown DA (%s) in DOType (%s) ", daTypeName.getName(), "leafSdoId")
- )
- );
+ .orElseThrow(
+ () -> new ScdException(
+ String.format("Unknown DA (%s) in DOType (%s) ", daTypeName.getName(), "leafSdoId")
+ )
+ );
// check Data Attributes
- if(!daTypeName.getStructNames().isEmpty() && daAdapter.getBType() != TPredefinedBasicTypeEnum.STRUCT){
- throw new ScdException("Invalid DA chain" + daTypeName);
+ if (!daTypeName.getStructNames().isEmpty() && daAdapter.getBType() != TPredefinedBasicTypeEnum.STRUCT) {
+ throw new ScdException("Invalid DA chain" + daTypeName);
}
- if(daTypeName.getStructNames().isEmpty()){
+ if (daTypeName.getStructNames().isEmpty()) {
daAdapter.check(daTypeName);
} else {
daTypeName.setFc(daAdapter.getCurrentElem().getFc());
DATypeAdapter daTypeAdapter = parentAdapter.getDATypeAdapterById(daAdapter.getType()).orElseThrow(
- () -> new ScdException(
- String.format("Unknown DAType (%s) referenced by DA(%s)", daAdapter.getType(), daAdapter.getName())
- )
+ () -> new ScdException(
+ String.format("Unknown DAType (%s) referenced by DA(%s)", daAdapter.getType(), daAdapter.getName())
+ )
);
daTypeAdapter.check(daTypeName);
}
@@ -300,14 +380,15 @@ public void check(@NonNull DoTypeName doTypeName, @NonNull DaTypeName daTypeName
/**
* Gets list of summarized data type template from DaTypeName
+ *
* @param daTypeName DaTypeName from which summarized data type templates are created
* @return list of DataAttributeRef object
*/
public List getDataAttributeRefByDaName(DaTypeName daTypeName) throws ScdException {
Optional opDataAttributeRef;
List dataAttributeRefs = new ArrayList<>();
- for(TDO tdo : currentElem.getDO()){
- DOAdapter doAdapter = new DOAdapter(this,tdo);
+ for (TDO tdo : currentElem.getDO()) {
+ DOAdapter doAdapter = new DOAdapter(this, tdo);
DOTypeAdapter doTypeAdapter = doAdapter.getDoTypeAdapter().orElseThrow();
DataAttributeRef dataAttributeRef = new DataAttributeRef();
dataAttributeRef.setLnType(currentElem.getId());
@@ -321,6 +402,7 @@ public List getDataAttributeRefByDaName(DaTypeName daTypeName)
/**
* Gets list of summarized data type template from DoTypeName
+ *
* @param doTypeName DoTypeName from which summarized data type templates are created
* @return list of DataAttributeRef object
*/
@@ -331,12 +413,13 @@ public List getDataAttributeRefByDoName(DoTypeName doTypeName)
DataAttributeRef dataAttributeRef = new DataAttributeRef();
dataAttributeRef.getDoName().setName(doTypeName.getName());
DOTypeAdapter doTypeAdapter = doAdapter.getDoTypeAdapter().orElseThrow();
- return doTypeAdapter.getDataAttributeRefByDoName(doTypeName,0,dataAttributeRef);
+ return doTypeAdapter.getDataAttributeRefByDoName(doTypeName, 0, dataAttributeRef);
}
/**
* Gets current LNodeType ID
+ *
* @return LNodeType ID
*/
public String getId() {
@@ -345,11 +428,12 @@ public String getId() {
/**
* Find bound DOType info
+ *
* @param signalInfo extRef signal info for binding
* @return DOType info as object containing name, id and adapter
* @throws ScdException throws when DO unknown
*/
- public DataTypeTemplateAdapter.DOTypeInfo findMatchingDOType(ExtRefSignalInfo signalInfo) throws ScdException{
+ public DataTypeTemplateAdapter.DOTypeInfo findMatchingDOType(ExtRefSignalInfo signalInfo) throws ScdException {
DoTypeName doName = new DoTypeName(signalInfo.getPDO());
String extDoName = Utils.removeTrailingDigits(doName.getName());
String doTypeId = getDOTypeId(extDoName).orElseThrow(() ->
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LNodeDTOTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LNodeDTOTest.java
index 3a92cbe91..3d827e4b0 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LNodeDTOTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/LNodeDTOTest.java
@@ -18,9 +18,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
class LNodeDTOTest {
@@ -88,7 +86,7 @@ void from_whenCalledWithLNAdapter_shouldFillValues(){
when(lnAdapter.getDataTypeTemplateAdapter()).thenReturn(dataTypeTemplateAdapter);
LNodeTypeAdapter lNodeTypeAdapter = mock(LNodeTypeAdapter.class);
when(dataTypeTemplateAdapter.getLNodeTypeAdapterById(any())).thenReturn(Optional.of(lNodeTypeAdapter));
- when(lNodeTypeAdapter.getDataAttributeRefs(any())).thenReturn(List.of(DataAttributeRef.builder().build()));
+ when(lNodeTypeAdapter.getDataAttributeRefs(any(DataAttributeRef.class))).thenReturn(List.of(DataAttributeRef.builder().build()));
TExtRef extRef = DTO.createExtRef();
when(lnAdapter.getExtRefs(null)).thenReturn(List.of(extRef));
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateTestUtils.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateTestUtils.java
index 7dc02d6f3..fc4a263f6 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateTestUtils.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/DataTypeTemplateTestUtils.java
@@ -13,6 +13,7 @@
public class DataTypeTemplateTestUtils {
public static final String SCD_DTT = "/dtt-test-schema-conf/scd_dtt_import_test.xml";
public static final String SCD_DTT_DIFF_CONTENT_SAME_ID = "/dtt-test-schema-conf/scd_dtt_import_sameid-diff-content-test.xml";
+ public static final String SCD_DTT_DO_SDO_DA_BDA = "/dtt-test-schema-conf/scd_dtt_do_sdo_da_bda.xml";
public static DataTypeTemplateAdapter initDttAdapterFromFile(String fileName) {
SCL scd = SclTestMarshaller.getSCLFromFile(fileName);
diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapterTest.java
index 4dcb052e0..c0da58c3f 100644
--- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapterTest.java
+++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/dtt/LNodeTypeAdapterTest.java
@@ -6,6 +6,8 @@
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.dto.*;
import org.lfenergy.compas.sct.commons.exception.ScdException;
@@ -147,6 +149,59 @@ void testGetDataAttributeRefs() {
assertThat(lNodeTypeAdapter.getDataAttributeRefs(filter)).isEmpty();
}
+ @Test
+ @Tag("issue-321")
+ void testGetDataAttributeRefsString() {
+ // Given
+ DataTypeTemplateAdapter dttAdapter = initDttAdapterFromFile(SCD_DTT);
+ LNodeTypeAdapter lNodeTypeAdapter = assertDoesNotThrow(() -> dttAdapter.getLNodeTypeAdapterById("LN1").get());
+ // When
+ var dataAttributeRefs = lNodeTypeAdapter.getDataAttributeRefs("StrVal.origin.origin.ctlVal");
+ // Then
+ assertThat(dataAttributeRefs).isNotNull();
+ }
+
+ @Test
+ void getDataAttributeRefs_should_find_DO_SDO_DA_and_BDA() {
+ // Given
+ DataTypeTemplateAdapter dttAdapter = initDttAdapterFromFile(SCD_DTT_DO_SDO_DA_BDA);
+ LNodeTypeAdapter lNodeTypeAdapter = assertDoesNotThrow(() -> dttAdapter.getLNodeTypeAdapterById("LN1").orElseThrow());
+ // When
+ DataAttributeRef dataAttributeRefs = lNodeTypeAdapter.getDataAttributeRefs("Do1.sdo1.sdo2.da2.bda1.bda2");
+ // Then
+ assertThat(dataAttributeRefs).extracting(DataAttributeRef::getDoRef, DataAttributeRef::getDaRef)
+ .containsExactly("Do1.sdo1.sdo2", "da2.bda1.bda2");
+ assertThat(dataAttributeRefs.getDoName().getCdc()).isEqualTo(TPredefinedCDCEnum.WYE);
+ assertThat(dataAttributeRefs.getDaName()).extracting(DaTypeName::getBType, DaTypeName::getFc)
+ .containsExactly(TPredefinedBasicTypeEnum.ENUM, TFCEnum.ST);
+ }
+
+ @Test
+ void getDataAttributeRefs_should_find_DO_and_DA() {
+ // Given
+ DataTypeTemplateAdapter dttAdapter = initDttAdapterFromFile(SCD_DTT_DO_SDO_DA_BDA);
+ LNodeTypeAdapter lNodeTypeAdapter = assertDoesNotThrow(() -> dttAdapter.getLNodeTypeAdapterById("LN1").orElseThrow());
+ // When
+ DataAttributeRef dataAttributeRefs = lNodeTypeAdapter.getDataAttributeRefs("Do1.da1");
+ // Then
+ assertThat(dataAttributeRefs).extracting(DataAttributeRef::getDoRef, DataAttributeRef::getDaRef)
+ .containsExactly("Do1", "da1");
+ assertThat(dataAttributeRefs.getDoName().getCdc()).isEqualTo(TPredefinedCDCEnum.WYE);
+ assertThat(dataAttributeRefs.getDaName()).extracting(DaTypeName::getBType, DaTypeName::getFc)
+ .containsExactly(TPredefinedBasicTypeEnum.BOOLEAN, TFCEnum.ST);
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"", "malformed", "Do1", "InexistantDo.da1", "Do1.inexistantDa", "Do1.da1.inexistantBda", "Do1.sdo1.inexistantSdo.da2", "Do1.sdo1.sdo2.da2.bda1.inexistantBda"})
+ void getDataAttributeRefs_when_dataRef_not_found_should_throw_exception(String dataRef) {
+ // Given
+ DataTypeTemplateAdapter dttAdapter = initDttAdapterFromFile(SCD_DTT_DO_SDO_DA_BDA);
+ LNodeTypeAdapter lNodeTypeAdapter = assertDoesNotThrow(() -> dttAdapter.getLNodeTypeAdapterById("LN1").orElseThrow());
+ // When & Then
+ assertThatThrownBy(() -> lNodeTypeAdapter.getDataAttributeRefs(dataRef))
+ .isInstanceOf(ScdException.class);
+ }
+
@Test
@Tag("issue-321")
void testCheck() {
@@ -340,4 +395,4 @@ private TLNodeType createLNOdeType(){
}
-}
\ No newline at end of file
+}
diff --git a/sct-commons/src/test/resources/dtt-test-schema-conf/scd_dtt_do_sdo_da_bda.xml b/sct-commons/src/test/resources/dtt-test-schema-conf/scd_dtt_do_sdo_da_bda.xml
new file mode 100644
index 000000000..cb8e22941
--- /dev/null
+++ b/sct-commons/src/test/resources/dtt-test-schema-conf/scd_dtt_do_sdo_da_bda.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ val1
+ val2
+
+
+