Skip to content

Commit 6d8a5d5

Browse files
committed
feat(92): RSR-473 - add check ExtRef is Bay internal and is ExtRef source a Fcda Candidate
Signed-off-by: massifben <[email protected]>
1 parent 1f13d17 commit 6d8a5d5

38 files changed

+41599
-248
lines changed

sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ void createSCD_should_delete_ControlBlocks_DataSet_and_ExtRef_src_attributes() t
146146
// Then
147147
LN0 ln0 = expectedSCD.streamIEDAdapters()
148148
.findFirst()
149-
.map(iedAdapter -> iedAdapter.getLDeviceAdapterByLdInst("lDeviceInst1").orElseThrow())
149+
.map(iedAdapter -> iedAdapter.findLDeviceAdapterByLdInst("lDeviceInst1").orElseThrow())
150150
.map(LDeviceAdapter::getLN0Adapter)
151151
.map(SclElementAdapter::getCurrentElem)
152152
.orElseThrow(() -> new RuntimeException("Test shouldn't fail here, please check your XML input file"));

sct-commons/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<sonar.coverage.jacoco.xmlReportPaths>${basedir}/${aggregate.report.dir}</sonar.coverage.jacoco.xmlReportPaths>
2222
<sonar.jacoco.excludes>**/scl2007b4/**/*</sonar.jacoco.excludes>
2323
<assertJ.version>3.22.0</assertJ.version>
24+
<opencsv.version>5.6</opencsv.version>
2425
<mockito.version>4.9.0</mockito.version>
2526
</properties>
2627

@@ -112,6 +113,11 @@
112113
<version>${assertJ.version}</version>
113114
<scope>test</scope>
114115
</dependency>
116+
<dependency>
117+
<groupId>com.opencsv</groupId>
118+
<artifactId>opencsv</artifactId>
119+
<version>${opencsv.version}</version>
120+
</dependency>
115121
</dependencies>
116122

117123
<build>

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ControlBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public void validateCB() throws ScdException {
105105
public void validateDestination(SclRootAdapter sclRootAdapter) throws ScdException {
106106
for(TControlWithIEDName.IEDName iedName : iedNames){
107107
IEDAdapter iedAdapter =sclRootAdapter.getIEDAdapterByName(iedName.getValue());
108-
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(iedName.getLdInst())
108+
LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(iedName.getLdInst())
109109
.orElseThrow(
110110
() -> new ScdException(
111111
String.format(

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataTypeName.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
@NoArgsConstructor
4646
@EqualsAndHashCode
4747
public class DataTypeName {
48+
protected static final String DELIMITER = ".";
49+
4850
protected String name = ""; // dataName or DataAttributeName
4951

5052
private List<String> structNames = new ArrayList<>(); // [.DataName[…]] or [.DAComponentName[ ….]]
@@ -98,13 +100,8 @@ public boolean isDefined(){
98100
*/
99101
@Override
100102
public String toString(){
101-
StringBuilder stringBuilder = new StringBuilder();
102-
stringBuilder.append(name);
103-
for(String sName : structNames){
104-
stringBuilder.append('.');
105-
stringBuilder.append(sName);
106-
}
107-
return stringBuilder.toString();
103+
return name
104+
+ (getStructNames().isEmpty() ? StringUtils.EMPTY : DELIMITER + String.join(DELIMITER, getStructNames()));
108105
}
109106

110107
/**

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DoTypeName.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
import lombok.Getter;
99
import lombok.NoArgsConstructor;
1010
import lombok.Setter;
11+
import org.apache.commons.lang3.StringUtils;
1112
import org.lfenergy.compas.scl2007b4.model.TPredefinedCDCEnum;
13+
import org.lfenergy.compas.sct.commons.util.Utils;
1214

1315
/**
1416
* A representation of the model object <em><b>DoTypeName</b></em>.
@@ -34,6 +36,7 @@ public class DoTypeName extends DataTypeName {
3436

3537
/**
3638
* Constructor
39+
*
3740
* @param doName input
3841
*/
3942
public DoTypeName(String doName) {
@@ -42,6 +45,7 @@ public DoTypeName(String doName) {
4245

4346
/**
4447
* Constructor
48+
*
4549
* @param ppDoName input
4650
* @param sdoNames input
4751
*/
@@ -51,24 +55,39 @@ public DoTypeName(String ppDoName, String sdoNames) {
5155

5256
/**
5357
* Initializes DoTypeName
58+
*
5459
* @param dataName input
5560
* @return DoTypeName object
5661
*/
57-
public static DoTypeName from(DoTypeName dataName){
62+
public static DoTypeName from(DoTypeName dataName) {
5863
DoTypeName doTypeName = new DoTypeName(dataName.toString());
59-
if(doTypeName.isDefined()) {
64+
if (doTypeName.isDefined()) {
6065
doTypeName.setCdc(dataName.getCdc());
6166
}
6267
return doTypeName;
6368
}
6469

6570
/**
6671
* Copy DO's content
72+
*
6773
* @param doName DO object
6874
*/
6975
public void merge(DoTypeName doName) {
70-
if(!isDefined()) return;
71-
if(cdc == null)
76+
if (!isDefined()) return;
77+
if (cdc == null)
7278
cdc = doName.getCdc();
7379
}
80+
81+
/**
82+
* Same as toString() without the instance of the DO.
83+
* Only the DO can have an instance number (not the SDO).
84+
* Prerequisites: A non instanced DO never ends with digits.
85+
*
86+
* @return Same as DataTypeName#toString(), without the digits at the end of the DO if any.
87+
* @see DataTypeName#toString()
88+
*/
89+
public String toStringWithoutInst() {
90+
return Utils.removeTrailingDigits(name)
91+
+ (getStructNames().isEmpty() ? StringUtils.EMPTY : DELIMITER + String.join(DELIMITER, getStructNames()));
92+
}
7493
}

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SclReportItem.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
import lombok.AllArgsConstructor;
88
import lombok.EqualsAndHashCode;
99
import lombok.Getter;
10+
import lombok.ToString;
1011

1112
@Getter
1213
@EqualsAndHashCode
1314
@AllArgsConstructor
15+
@ToString
1416
public final class SclReportItem {
1517
private final String xpath;
1618
private final String message;

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,12 @@
2020
import java.util.*;
2121
import java.util.function.Function;
2222
import java.util.stream.Collectors;
23+
import java.util.stream.Stream;
2324

2425
@UtilityClass
2526
public class ExtRefService {
2627

27-
public static final String MESSAGE_IED_NAME_NOT_FOUND = "IED.name '%s' not found in SCD";
28-
public static final String MESSAGE_LDEVICE_INST_NOT_FOUND = "LDevice.inst '%s' not found in IED '%s'";
29-
public static final String MESSAGE_MISSING_IED_NAME_PARAMETER = "IED.name parameter is missing";
28+
private static final String MESSAGE_MISSING_IED_NAME_PARAMETER = "IED.name parameter is missing";
3029

3130
/**
3231
* Updates iedName attribute of all ExtRefs in the Scd.
@@ -103,37 +102,32 @@ private static List<SclReportItem> checkIedUnityOfIcdSystemVersionUuid(SclRootAd
103102

104103
public static SclReport createDataSetAndControlBlocks(SCL scd) {
105104
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
106-
List<SclReportItem> sclReportItems = sclRootAdapter.streamIEDAdapters()
107-
.flatMap(IEDAdapter::streamLDeviceAdapters)
108-
.map(LDeviceAdapter::createDataSetAndControlBlocks)
109-
.flatMap(List::stream)
110-
.collect(Collectors.toList());
111-
return new SclReport(sclRootAdapter, sclReportItems);
105+
Stream<LDeviceAdapter> lDeviceAdapters = sclRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters);
106+
return createDataSetAndControlBlocks(sclRootAdapter, lDeviceAdapters);
112107
}
113108

114109
public static SclReport createDataSetAndControlBlocks(SCL scd, String targetIedName) {
115110
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
116-
IEDAdapter iedAdapter = sclRootAdapter.findIedAdapterByName(targetIedName)
117-
.orElseThrow(() -> new ScdException(String.format(MESSAGE_IED_NAME_NOT_FOUND, targetIedName)));
111+
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName);
112+
return createDataSetAndControlBlocks(sclRootAdapter, iedAdapter.streamLDeviceAdapters());
118113

119-
List<SclReportItem> sclReportItems = iedAdapter.streamLDeviceAdapters()
120-
.map(LDeviceAdapter::createDataSetAndControlBlocks)
121-
.flatMap(List::stream)
122-
.collect(Collectors.toList());
123-
return new SclReport(sclRootAdapter, sclReportItems);
124114
}
125115

126116
public static SclReport createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst) {
127117
if (StringUtils.isBlank(targetIedName)) {
128118
throw new ScdException(MESSAGE_MISSING_IED_NAME_PARAMETER);
129119
}
130120
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
131-
IEDAdapter iedAdapter = sclRootAdapter.findIedAdapterByName(targetIedName)
132-
.orElseThrow(() -> new ScdException(String.format(MESSAGE_IED_NAME_NOT_FOUND, targetIedName)));
133-
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(targetLDeviceInst)
134-
.orElseThrow(() -> new ScdException(String.format(MESSAGE_LDEVICE_INST_NOT_FOUND, targetLDeviceInst, targetIedName)));
121+
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName);
122+
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(targetLDeviceInst);
123+
return createDataSetAndControlBlocks(sclRootAdapter, Stream.of(lDeviceAdapter));
124+
}
135125

136-
List<SclReportItem> sclReportItems = lDeviceAdapter.createDataSetAndControlBlocks();
126+
private static SclReport createDataSetAndControlBlocks(SclRootAdapter sclRootAdapter, Stream<LDeviceAdapter> lDeviceAdapters) {
127+
List<SclReportItem> sclReportItems = lDeviceAdapters
128+
.map(LDeviceAdapter::createDataSetAndControlBlocks)
129+
.flatMap(List::stream)
130+
.collect(Collectors.toList());
137131
return new SclReport(sclRootAdapter, sclReportItems);
138132
}
139133
}

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclRootAdapter.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public class SclRootAdapter extends SclElementAdapter<SclRootAdapter, SCL> {
6161
public static final short RELEASE = 4;
6262
public static final String REVISION = "B";
6363
public static final String VERSION = "2007";
64+
private static final String MESSAGE_IED_NAME_NOT_FOUND = "IED.name '%s' not found in SCD";
6465

6566
/**
6667
* Constructor
@@ -187,7 +188,7 @@ public IEDAdapter addIED(SCL icd, String iedName) throws ScdException {
187188
throw new ScdException("No IED to import from ICD file");
188189
}
189190

190-
if(hasIED(iedName)){
191+
if(findIedAdapterByName(iedName).isPresent()){
191192
String msg = "SCL file already contains IED: " + iedName;
192193
log.error(msg);
193194
throw new ScdException(msg);
@@ -207,17 +208,6 @@ public IEDAdapter addIED(SCL icd, String iedName) throws ScdException {
207208
return getIEDAdapterByName(iedName);
208209
}
209210

210-
/**
211-
* Checks if IED is present in SCL
212-
* @param iedName name of IED to find in SCL
213-
* @return <em>Boolean</em> value of check result
214-
*/
215-
private boolean hasIED(String iedName) {
216-
return currentElem.getIED()
217-
.stream()
218-
.anyMatch(tied -> tied.getName().equals(iedName));
219-
}
220-
221211
/**
222212
* Gets Header from current SCL
223213
* @return <em>HeaderAdapter</em> object as Header of SCL
@@ -245,7 +235,7 @@ public DataTypeTemplateAdapter getDataTypeTemplateAdapter(){
245235
*/
246236
public IEDAdapter getIEDAdapterByName(String iedName) throws ScdException {
247237
return findIedAdapterByName(iedName)
248-
.orElseThrow(() -> new ScdException("IED.name '%s' not found in SCD"));
238+
.orElseThrow(() -> new ScdException(String.format(MESSAGE_IED_NAME_NOT_FOUND, iedName)));
249239
}
250240

251241
/**

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@
7979
@Slf4j
8080
public class SclService {
8181

82-
public static final String UNKNOWN_LDEVICE_S_IN_IED_S = "Unknown LDevice (%s) in IED (%s)";
83-
public static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info";
84-
public static final ObjectFactory objectFactory = new ObjectFactory();
82+
private static final String UNKNOWN_LDEVICE_S_IN_IED_S = "Unknown LDevice (%s) in IED (%s)";
83+
private static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info";
84+
private static final ObjectFactory objectFactory = new ObjectFactory();
8585

8686
private SclService() {
8787
throw new IllegalStateException("SclService class");
@@ -233,7 +233,7 @@ public static List<ExtRefInfo> getExtRefInfo(SCL scd, String iedName, String ldI
233233

234234
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
235235
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
236-
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
236+
LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst)
237237
.orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
238238
return lDeviceAdapter.getExtRefInfo();
239239
}
@@ -254,7 +254,7 @@ public static List<ExtRefInfo> getExtRefInfo(SCL scd, String iedName, String ldI
254254
public static List<ExtRefBindingInfo> getExtRefBinders(SCL scd, String iedName, String ldInst, String lnClass, String lnInst, String prefix, ExtRefSignalInfo signalInfo) throws ScdException {
255255
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
256256
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
257-
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
257+
LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst)
258258
.orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
259259
AbstractLNAdapter<?> abstractLNAdapter = AbstractLNAdapter.builder()
260260
.withLDeviceAdapter(lDeviceAdapter)
@@ -289,7 +289,7 @@ public static void updateExtRefBinders(SCL scd, ExtRefInfo extRefInfo) throws Sc
289289
String ldInst = extRefInfo.getHolderLDInst();
290290
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
291291
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
292-
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
292+
LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst)
293293
.orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
294294

295295
AbstractLNAdapter<?> abstractLNAdapter = AbstractLNAdapter.builder()
@@ -330,7 +330,7 @@ public static List<ControlBlock<?>> getExtRefSourceInfo(SCL scd, ExtRefInfo extR
330330

331331
// Get CBs
332332
IEDAdapter srcIEDAdapter = sclRootAdapter.getIEDAdapterByName(bindingInfo.getIedName());
333-
LDeviceAdapter srcLDeviceAdapter = srcIEDAdapter.getLDeviceAdapterByLdInst(extRefInfo.getBindingInfo().getLdInst())
333+
LDeviceAdapter srcLDeviceAdapter = srcIEDAdapter.findLDeviceAdapterByLdInst(extRefInfo.getBindingInfo().getLdInst())
334334
.orElseThrow();
335335

336336
List<AbstractLNAdapter<?>> aLNAdapters = srcLDeviceAdapter.getLNAdaptersInclundigLN0();
@@ -375,7 +375,7 @@ public static TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws
375375

376376
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
377377
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
378-
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
378+
LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst)
379379
.orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
380380
var anLNAdapter = AbstractLNAdapter.builder()
381381
.withLDeviceAdapter(lDeviceAdapter)
@@ -401,7 +401,7 @@ public static TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws
401401
public static Set<ResumedDataTemplate> getDAI(SCL scd, String iedName, String ldInst, ResumedDataTemplate rDtt, boolean updatable) throws ScdException {
402402
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
403403
IEDAdapter iedAdapter = new IEDAdapter(sclRootAdapter, iedName);
404-
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
404+
LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst)
405405
.orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
406406

407407
return lDeviceAdapter.getDAI(rDtt, updatable);
@@ -433,7 +433,7 @@ public static void updateDAI(SCL scd, String iedName, String ldInst, ResumedData
433433
}
434434

435435
IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName);
436-
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst)
436+
LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst)
437437
.orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName)));
438438

439439
AbstractLNAdapter<?> lnAdapter = AbstractLNAdapter.builder()

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ public TExtRef checkExtRefInfoCoherence(@NonNull ExtRefInfo extRefInfo) throws S
579579
} else {
580580
binderIEDAdapter = getCurrentIed();
581581
}
582-
LDeviceAdapter binderLDAdapter = binderIEDAdapter.getLDeviceAdapterByLdInst(binderLdInst)
582+
LDeviceAdapter binderLDAdapter = binderIEDAdapter.findLDeviceAdapterByLdInst(binderLdInst)
583583
.orElseThrow(
584584
() -> new ScdException(
585585
String.format("Unknown LDevice (%s) in IED (%s)", binderLdInst, binderIedName)

0 commit comments

Comments
 (0)