Skip to content

Commit 88291aa

Browse files
authored
Merge pull request #195 from com-pas/develop
Merge develop into main
2 parents 845e7bf + 742016e commit 88291aa

File tree

31 files changed

+1170
-298
lines changed

31 files changed

+1170
-298
lines changed

pom.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,20 @@
157157
</execution>
158158
</executions>
159159
</plugin>
160+
<plugin>
161+
<groupId>org.apache.maven.plugins</groupId>
162+
<artifactId>maven-javadoc-plugin</artifactId>
163+
<version>${maven.plugin.javadoc}</version>
164+
<executions>
165+
<execution>
166+
<id>attach-javadocs</id>
167+
<phase>package</phase>
168+
<goals>
169+
<goal>aggregate</goal>
170+
</goals>
171+
</execution>
172+
</executions>
173+
</plugin>
160174
<plugin>
161175
<groupId>org.apache.maven.plugins</groupId>
162176
<artifactId>maven-source-plugin</artifactId>

sct-app/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@
6060
<version>3.6.28</version>
6161
<scope>test</scope>
6262
</dependency>
63+
<dependency>
64+
<groupId>org.assertj</groupId>
65+
<artifactId>assertj-core</artifactId>
66+
<version>3.23.1</version>
67+
</dependency>
6368
</dependencies>
6469
<build>
6570
<plugins>

sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ public class SclAutomationService {
3333
*/
3434
private static final Map<Pair<String, String>, List<String>> comMap = Map.of(
3535
Pair.of("RSPACE_PROCESS_NETWORK", SubNetworkDTO.SubnetworkType.MMS.toString()), Arrays.asList("PROCESS_AP", "TOTO_AP_GE"),
36-
Pair.of("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString()), Arrays.asList("ADMIN_AP","TATA_AP_EFFACEC"));
36+
Pair.of("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString()), Arrays.asList("ADMIN_AP", "TATA_AP_EFFACEC"));
3737

38-
private SclAutomationService(){throw new IllegalStateException("SclAutomationService class"); }
38+
private SclAutomationService() {
39+
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
40+
}
3941

4042
/**
4143
* Create a SCD file from specified parameters, it calls all functions defined in the process one by one, every step
@@ -48,13 +50,14 @@ public class SclAutomationService {
4850
*/
4951
public static SclRootAdapter createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO, Set<SCL> stds) throws ScdException {
5052
SclRootAdapter scdAdapter = SclService.initScl(Optional.ofNullable(headerDTO.getId()),
51-
headerDTO.getVersion(),headerDTO.getRevision());
52-
if(!headerDTO.getHistoryItems().isEmpty()) {
53+
headerDTO.getVersion(), headerDTO.getRevision());
54+
if (!headerDTO.getHistoryItems().isEmpty()) {
5355
HeaderDTO.HistoryItem hItem = headerDTO.getHistoryItems().get(0);
5456
SclService.addHistoryItem(scdAdapter.getCurrentElem(), hItem.getWho(), hItem.getWhat(), hItem.getWhy());
5557
}
5658
SubstationService.addSubstation(scdAdapter.getCurrentElem(), ssd);
5759
SclService.importSTDElementsInSCD(scdAdapter, stds, comMap);
60+
SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scdAdapter.getCurrentElem());
5861
return scdAdapter;
5962
}
6063
}

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

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,23 @@
66

77
import org.junit.jupiter.api.BeforeEach;
88
import org.junit.jupiter.api.Test;
9+
import org.lfenergy.compas.scl2007b4.model.LN0;
910
import org.lfenergy.compas.scl2007b4.model.SCL;
1011
import org.lfenergy.compas.sct.commons.dto.HeaderDTO;
1112
import org.lfenergy.compas.sct.commons.exception.ScdException;
13+
import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
1214
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
15+
import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter;
1316
import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
1417

18+
import java.lang.reflect.Constructor;
19+
import java.lang.reflect.InvocationTargetException;
1520
import java.util.Arrays;
1621
import java.util.HashSet;
1722
import java.util.Set;
1823

24+
import static org.assertj.core.api.Assertions.assertThat;
25+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1926
import static org.junit.jupiter.api.Assertions.*;
2027
import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable;
2128

@@ -24,7 +31,7 @@ class SclAutomationServiceTest {
2431
private HeaderDTO headerDTO;
2532

2633
@BeforeEach
27-
void init(){
34+
void init() {
2835
headerDTO = new HeaderDTO();
2936
headerDTO.setRevision("hRevision");
3037
headerDTO.setVersion("hVersion");
@@ -63,7 +70,7 @@ void createSCD_With_HItem() throws Exception {
6370
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std1, std2, std3));
6471
// Then
6572
assertNotNull(expectedSCD.getCurrentElem().getHeader().getId());
66-
assertEquals(1 ,expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size());
73+
assertEquals(1, expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size());
6774
assertEquals(1, expectedSCD.getCurrentElem().getSubstation().size());
6875
assertIsMarshallable(expectedSCD.getCurrentElem());
6976
}
@@ -85,7 +92,7 @@ void createSCD_With_HItems() throws Exception {
8592
SCL std2 = SclTestMarshaller.getSCLFromFile("/std_2.xml");
8693
SCL std3 = SclTestMarshaller.getSCLFromFile("/std_3.xml");
8794
// When
88-
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO,Set.of(std1, std2, std3));
95+
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std1, std2, std3));
8996
// Then
9097
assertNotNull(expectedSCD.getCurrentElem().getHeader().getId());
9198
assertEquals(1, expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size());
@@ -98,8 +105,68 @@ void createSCD_SSD_Without_Substation() throws Exception {
98105
// Given
99106
SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd_without_substations.xml");
100107
// When & Then
108+
Set<SCL> stdListEmpty = new HashSet<>();
101109
assertThrows(ScdException.class,
102-
() -> SclAutomationService.createSCD(ssd, headerDTO, new HashSet<>()) );
110+
() -> SclAutomationService.createSCD(ssd, headerDTO, stdListEmpty));
111+
}
112+
113+
@Test
114+
void createSCD_should_throw_exception_when_null_ssd() throws Exception {
115+
// Given
116+
HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem();
117+
historyItem.setWhat("what");
118+
historyItem.setWho("me");
119+
historyItem.setWhy("because");
120+
headerDTO.getHistoryItems().add(historyItem);
121+
SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml");
122+
Set<SCL> stdList = Set.of(std1);
123+
124+
// When & Then
125+
assertThrows(NullPointerException.class, () -> SclAutomationService.createSCD(null, headerDTO, stdList));
103126
}
104127

128+
@Test
129+
void createSCD_should_throw_exception_when_null_headerDTO() throws Exception {
130+
// Given
131+
SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml");
132+
SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml");
133+
Set<SCL> stdList = Set.of(std1);
134+
135+
// When & Then
136+
assertThrows(NullPointerException.class, () -> SclAutomationService.createSCD(ssd, null, stdList));
137+
}
138+
139+
@Test
140+
void createSCD_should_delete_ControlBlocks_DataSet_and_ExtRef_src_attributes() throws Exception {
141+
// Given
142+
SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml");
143+
SCL std = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml");
144+
// When
145+
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std));
146+
// Then
147+
LN0 ln0 = expectedSCD.streamIEDAdapters()
148+
.findFirst()
149+
.map(iedAdapter -> iedAdapter.getLDeviceAdapterByLdInst("lDeviceInst1").orElseThrow())
150+
.map(LDeviceAdapter::getLN0Adapter)
151+
.map(SclElementAdapter::getCurrentElem)
152+
.orElseThrow(() -> new RuntimeException("Test shouldn't fail here, please check your XML input file"));
153+
154+
assertThat(ln0.getDataSet()).isEmpty();
155+
assertThat(ln0.getInputs().getExtRef()).hasSize(2);
156+
assertFalse(ln0.getInputs().getExtRef().get(0).isSetSrcLDInst());
157+
assertIsMarshallable(expectedSCD.getCurrentElem());
158+
}
159+
160+
@Test
161+
void class_should_not_be_instantiable() {
162+
// Given
163+
Constructor<?>[] constructors = SclAutomationService.class.getDeclaredConstructors();
164+
assertThat(constructors).hasSize(1);
165+
Constructor<?> constructor = constructors[0];
166+
constructor.setAccessible(true);
167+
// When & Then
168+
assertThatThrownBy(constructor::newInstance)
169+
.isInstanceOf(InvocationTargetException.class)
170+
.getCause().isInstanceOf(UnsupportedOperationException.class);
171+
}
105172
}

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

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
import lombok.NoArgsConstructor;
99
import lombok.Setter;
1010
import org.apache.commons.lang3.StringUtils;
11-
import org.lfenergy.compas.scl2007b4.model.TExtRef;
12-
import org.lfenergy.compas.scl2007b4.model.TLLN0Enum;
13-
import org.lfenergy.compas.scl2007b4.model.TServiceType;
11+
import org.lfenergy.compas.scl2007b4.model.*;
12+
import org.lfenergy.compas.sct.commons.exception.ScdException;
13+
import org.lfenergy.compas.sct.commons.scl.dtt.DATypeAdapter;
14+
import org.lfenergy.compas.sct.commons.scl.dtt.DOTypeAdapter;
15+
import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter;
1416

1517
import java.util.Comparator;
1618
import java.util.Objects;
@@ -181,4 +183,29 @@ public String toString() {
181183
'}';
182184

183185
}
186+
187+
/**
188+
* updates bindingInfo from given data
189+
* @param signalInfo contains DAType info to set
190+
* @param doTypeInfo contains DOType info leading to DA
191+
* @throws ScdException thrown when inconsistency between DOType and DAType
192+
*/
193+
public void updateDAInfos(ExtRefSignalInfo signalInfo, DataTypeTemplateAdapter.DOTypeInfo doTypeInfo) throws ScdException {
194+
DaTypeName daTypeName = new DaTypeName(signalInfo.getPDA());
195+
String extDaName = daTypeName.getName();
196+
DOTypeAdapter lastDoTypeAdapter = doTypeInfo.getDoTypeAdapter();
197+
TDA da = lastDoTypeAdapter.getDAByName(extDaName).orElseThrow(() ->
198+
new ScdException(String.format("%s: Unknown DA (%s) in DOType (%s) ", doTypeInfo.getDoTypeName(), extDaName, doTypeInfo.getDoTypeId())));
199+
if (da.getBType() != TPredefinedBasicTypeEnum.STRUCT && !daTypeName.getStructNames().isEmpty()
200+
|| da.getBType() == TPredefinedBasicTypeEnum.STRUCT && daTypeName.getStructNames().isEmpty()) {
201+
throw new ScdException(String.format("Invalid ExtRef signal: no coherence between pDO(%s) and pDA(%s)",
202+
signalInfo.getPDO(), signalInfo.getPDA()));
203+
}
204+
String daTypeId = da.getType();
205+
DATypeAdapter daTypeAdapter = lastDoTypeAdapter.getParentAdapter().getDATypeAdapterById(daTypeId).orElseThrow(() ->
206+
new IllegalArgumentException(String.format("%s: Unknown DA (%s), or no reference to its type", daTypeName, extDaName)));
207+
daTypeAdapter.check(daTypeName);
208+
daTypeName.setFc(da.getFc());
209+
this.daName = daTypeName;
210+
}
184211
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,7 @@ public static List<ExtRefBindingInfo> getExtRefBinders(SCL scd, String iedName,
264264
.build();
265265

266266
// check for signal existence
267-
// The below throws exception if the signal doesn't exist
268-
//TODO: create method which purpose is only ckecking instead of this one
269-
abstractLNAdapter.getExtRefsBySignalInfo(signalInfo);
267+
abstractLNAdapter.isExtRefExist(signalInfo);
270268

271269
// find potential binders for the signalInfo
272270
return sclRootAdapter.streamIEDAdapters()

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

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import java.util.*;
1616
import java.util.stream.Collectors;
17+
import java.util.stream.Stream;
1718

1819
/**
1920
* A representation of the model object
@@ -195,13 +196,7 @@ protected String elementXPath() {
195196
* @return <em>Boolean</em> value of check result
196197
*/
197198
public boolean containsDAWithDAName(String da){
198-
return currentElem.getSDOOrDA()
199-
.stream()
200-
.filter(unNaming -> unNaming.getClass().equals(TDA.class))
201-
.map(TDA.class::cast)
202-
.anyMatch(
203-
tda -> tda.getName().equals(da)
204-
);
199+
return getTdaStream().anyMatch(tda -> tda.getName().equals(da));
205200
}
206201

207202
/**
@@ -210,10 +205,7 @@ public boolean containsDAWithDAName(String da){
210205
* @return <em>Boolean</em> value of check result
211206
*/
212207
public boolean containsDAWithEnumTypeId(String enumTypeId) {
213-
return currentElem.getSDOOrDA()
214-
.stream()
215-
.filter(unNaming -> unNaming.getClass().equals(TDA.class))
216-
.map(TDA.class::cast)
208+
return getTdaStream()
217209
.anyMatch(
218210
tda -> tda.getBType().equals(TPredefinedBasicTypeEnum.ENUM) &&
219211
tda.getType().equals(enumTypeId)
@@ -227,7 +219,7 @@ public boolean containsDAWithEnumTypeId(String enumTypeId) {
227219
* @throws ScdException when inconsistency are found in th SCL's
228220
* DataTypeTemplate (unknown reference for example). Which should normally not happens.
229221
*/
230-
Pair<String,DOTypeAdapter> findPathDoType2DA(String daName) throws ScdException {
222+
public Pair<String,DOTypeAdapter> findPathDoTypeToDA(String daName) throws ScdException {
231223
if(containsDAWithDAName(daName)){
232224
// Attention : Do this check before calling this function
233225
// It is not interesting to no have the DO/SDO that references this DoType
@@ -266,7 +258,7 @@ Pair<String,DOTypeAdapter> findPathDoType2DA(String daName) throws ScdException
266258
* @throws ScdException when inconsistency are found in th SCL's
267259
* DataTypeTemplate (unknown reference for example). Which should normally not happens.
268260
*/
269-
Pair<String,DOTypeAdapter> findPathSDO2DA(String sdoName, String daName) throws ScdException {
261+
Pair<String,DOTypeAdapter> findPathSDOToDA(String sdoName, String daName) throws ScdException {
270262
String errMsg = String.format("No coherence or path between DO/SDO(%s) and DA(%s)", sdoName,daName);
271263
Optional<TSDO> opSdo = getSDOByName(sdoName);
272264
if(opSdo.isEmpty()) {
@@ -280,7 +272,7 @@ Pair<String,DOTypeAdapter> findPathSDO2DA(String sdoName, String daName) throws
280272
if(doTypeAdapter.containsDAWithDAName(daName)){
281273
return Pair.of(opSdo.get().getName(),doTypeAdapter);
282274
}
283-
return doTypeAdapter.findPathDoType2DA(daName);
275+
return doTypeAdapter.findPathDoTypeToDA(daName);
284276
}
285277

286278
/**
@@ -289,10 +281,7 @@ Pair<String,DOTypeAdapter> findPathSDO2DA(String sdoName, String daName) throws
289281
* @return <em>Boolean</em> value of check result
290282
*/
291283
public boolean containsDAStructWithDATypeId(String daTypeId) {
292-
return currentElem.getSDOOrDA()
293-
.stream()
294-
.filter(unNaming -> unNaming.getClass().equals(TDA.class))
295-
.map(TDA.class::cast)
284+
return getTdaStream()
296285
.anyMatch(
297286
tda -> TPredefinedBasicTypeEnum.STRUCT.equals(tda.getBType()) &&
298287
tda.getType().equals(daTypeId)
@@ -422,12 +411,30 @@ public Optional<TSDO> getSDOByName(String sdoName) {
422411
* @return optional of <em>TDA</em> object or empty if unknown DA name
423412
*/
424413
public Optional<TDA> getDAByName(String name) {
425-
for(TUnNaming tUnNaming : currentElem.getSDOOrDA()){
426-
if(tUnNaming.getClass() == TDA.class && ((TDA)tUnNaming).getName().equals(name)){
427-
return Optional.of((TDA)tUnNaming);
428-
}
414+
TDOType tdoType = currentElem;
415+
if (!containsDAWithDAName(name)) {
416+
tdoType = findPathDoTypeToDA(name)
417+
.getValue()
418+
.getCurrentElem();
429419
}
430-
return Optional.empty();
420+
return tdoType.getSDOOrDA()
421+
.stream()
422+
.filter(unNaming -> unNaming.getClass().equals(TDA.class)
423+
&& ((TDA)unNaming).getName().equals(name))
424+
.map(TDA.class::cast)
425+
.findFirst();
426+
}
427+
428+
/**
429+
* Retrieves all TDA in DOType
430+
* @return stream of TDA
431+
*/
432+
private Stream<TDA> getTdaStream() {
433+
return getCurrentElem()
434+
.getSDOOrDA()
435+
.stream()
436+
.filter(unNaming -> unNaming.getClass().equals(TDA.class))
437+
.map(TDA.class::cast);
431438
}
432439

433440
/**

0 commit comments

Comments
 (0)