4
4
5
5
package org .lfenergy .compas .sct .commons ;
6
6
7
+ import jakarta .xml .bind .JAXBContext ;
7
8
import lombok .Getter ;
8
9
import lombok .NonNull ;
9
10
import lombok .RequiredArgsConstructor ;
10
11
import lombok .extern .slf4j .Slf4j ;
11
12
import org .lfenergy .compas .scl2007b4 .model .*;
13
+ import org .lfenergy .compas .sct .commons .api .DataTypeTemplateReader ;
12
14
import org .lfenergy .compas .sct .commons .api .SclEditor ;
15
+ import org .lfenergy .compas .sct .commons .domain .DaVal ;
16
+ import org .lfenergy .compas .sct .commons .domain .DoLinkedToDaFilter ;
13
17
import org .lfenergy .compas .sct .commons .dto .*;
14
18
import org .lfenergy .compas .sct .commons .exception .ScdException ;
15
- import org .lfenergy .compas .sct .commons .scl .ExtRefService ;
16
19
import org .lfenergy .compas .sct .commons .scl .SclRootAdapter ;
17
20
import org .lfenergy .compas .sct .commons .scl .com .CommunicationAdapter ;
18
21
import org .lfenergy .compas .sct .commons .scl .com .ConnectedAPAdapter ;
26
29
import org .lfenergy .compas .sct .commons .scl .ldevice .LDeviceAdapter ;
27
30
import org .lfenergy .compas .sct .commons .scl .ln .AbstractLNAdapter ;
28
31
import org .lfenergy .compas .sct .commons .scl .ln .LN0Adapter ;
29
- import org .lfenergy .compas .sct .commons .scl .ln .LNAdapter ;
30
32
import org .lfenergy .compas .sct .commons .util .MonitoringLnClassEnum ;
31
33
import org .lfenergy .compas .sct .commons .util .PrivateUtils ;
32
34
import org .lfenergy .compas .sct .commons .util .Utils ;
33
35
34
36
import java .util .*;
37
+ import java .util .stream .Collectors ;
35
38
36
- import static org .lfenergy .compas .sct .commons .util .CommonConstants .IED_TEST_NAME ;
39
+ import static org .lfenergy .compas .sct .commons .util .CommonConstants .* ;
37
40
import static org .lfenergy .compas .sct .commons .util .PrivateEnum .COMPAS_ICDHEADER ;
38
- import static org .lfenergy .compas .sct .commons .util .Utils .copySclElement ;
39
41
40
42
@ Slf4j
41
43
@ RequiredArgsConstructor
@@ -48,6 +50,9 @@ public class SclService implements SclEditor {
48
50
private final IedService iedService ;
49
51
private final LdeviceService ldeviceService ;
50
52
private final LnService lnService ;
53
+ private final ExtRefReaderService extRefReaderService ;
54
+ private final DataTypeTemplateReader dataTypeTemplateService ;
55
+
51
56
@ Getter
52
57
private final List <SclReportItem > errorHanlder = new ArrayList <>();
53
58
@@ -213,61 +218,77 @@ public List<SclReportItem> updateDoInRef(SCL scd) {
213
218
.toList ();
214
219
}
215
220
221
+
216
222
@ Override
217
223
public List <SclReportItem > manageMonitoringLns (SCL scd ) {
218
224
errorHanlder .clear ();
219
225
iedService .getFilteredIeds (scd , ied -> !ied .getName ().contains (IED_TEST_NAME ))
220
- .forEach (tied -> ldeviceService .findLdevice (tied , tlDevice -> "LDSUIED" .equals (tlDevice .getInst ()))
221
- .filter (tlDevice -> tlDevice .getLN0 ().isSetInputs ())
222
- .ifPresent (tlDevice -> {
223
- List <TExtRef > tExtRefs = new ExtRefService ().filterDuplicatedExtRefs (tlDevice .getLN0 ().getInputs ().getExtRef ())
224
- .stream ()
225
- .filter (TExtRef ::isSetServiceType )
226
- .filter (TExtRef ::isSetSrcCBName )
227
- .toList ();
228
- manageMonitoringLns (tExtRefs .stream ().filter (tExtRef -> TServiceType .GOOSE .equals (tExtRef .getServiceType ())).toList (), scd , tied , tlDevice , DO_GOCBREF , MonitoringLnClassEnum .LGOS );
229
- manageMonitoringLns (tExtRefs .stream ().filter (tExtRef -> TServiceType .SMV .equals (tExtRef .getServiceType ())).toList (), scd , tied , tlDevice , DO_SVCBREF , MonitoringLnClassEnum .LSVS );
230
- }));
226
+ .forEach (tied -> {
227
+ Map <TServiceType , List <TExtRef >> serviceTypeToExtRefs = ldeviceService .getLdevices (tied )
228
+ .flatMap (tlDevice -> extRefReaderService .getExtRefs (tlDevice .getLN0 ()))
229
+ .filter (tExtRef -> tExtRef .isSetServiceType () && tExtRef .isSetSrcCBName () && (tExtRef .getServiceType ().equals (TServiceType .GOOSE ) || tExtRef .getServiceType ().equals (TServiceType .SMV )))
230
+ .collect (Collectors .groupingBy (TExtRef ::getServiceType ));
231
+ ldeviceService .findLdevice (tied , LDEVICE_LDSUIED ).ifPresent (ldSUIEDLDevice -> {
232
+ Optional .ofNullable (serviceTypeToExtRefs .get (TServiceType .GOOSE ))
233
+ .ifPresent (extRefs -> manageMonitoringLns (extRefs , scd , tied , ldSUIEDLDevice , DO_GOCBREF , MonitoringLnClassEnum .LGOS ));
234
+ Optional .ofNullable (serviceTypeToExtRefs .get (TServiceType .SMV ))
235
+ .ifPresent (extRefs -> manageMonitoringLns (extRefs , scd , tied , ldSUIEDLDevice , DO_SVCBREF , MonitoringLnClassEnum .LSVS ));
236
+ });
237
+ });
231
238
return errorHanlder ;
232
239
}
233
240
234
- private void manageMonitoringLns (List <TExtRef > tExtRefs , SCL scd , TIED tied , TLDevice tlDevice , String doName , MonitoringLnClassEnum monitoringLnClassEnum ) {
235
- List <TLN > tlns = lnService .getFilteredLns (tlDevice , tln -> monitoringLnClassEnum .value ().equals (tln .getLnClass ().getFirst ())).toList ();
236
- if (tlns .isEmpty ())
237
- errorHanlder .add (SclReportItem .warning (tied .getName ()+"/" +tlDevice .getInst ()+"/" +monitoringLnClassEnum .value (), "There is no LN %s present in LDevice" .formatted (monitoringLnClassEnum .value ())));
238
-
239
- tlns .forEach (tln -> {
240
- LNAdapter lnAdapter = new LNAdapter (new LDeviceAdapter (new IEDAdapter (new SclRootAdapter (scd ), tied ), tlDevice ), tln );
241
- lnAdapter
242
- .getDAI (new DataAttributeRef (tln , new DoTypeName (doName ), new DaTypeName (DA_SETSRCREF )), true )
243
- .stream ()
244
- .findFirst ()
245
- .ifPresentOrElse (daToUpdateFilter -> {
246
- removeLnsByLnClass (monitoringLnClassEnum , tlDevice );
247
- for (int i = 0 ; i < tExtRefs .size (); i ++) {
248
- TLN copiedLn = copySclElement (tln , TLN .class );
249
- TExtRef tExtRef = tExtRefs .get (i );
250
- TIED sourceIed = iedService .findByName (scd , tExtRef .getIedName ())
251
- .orElseThrow (() -> new ScdException ("IED.name '" + tExtRef .getIedName () + "' not found in SCD" ));
252
- String sourceLdName = ldeviceService .findLdevice (sourceIed , tExtRef .getSrcLDInst ())
253
- .orElseThrow (() -> new ScdException (String .format ("LDevice.inst '%s' not found in IED '%s'" , tExtRef .getSrcLDInst (), tExtRef .getIedName ())))
254
- .getLdName ();
255
- String lnClass = !tExtRef .isSetSrcLNClass () ? TLLN0Enum .LLN_0 .value () : tExtRef .getSrcLNClass ().getFirst ();
256
- lnAdapter .getCurrentElem ().setInst (String .valueOf (i + 1 ));
257
- daToUpdateFilter .setVal (sourceLdName + "/" + lnClass + "." + tExtRef .getSrcCBName ());
258
- lnAdapter .updateDAI (daToUpdateFilter );
259
- tlDevice .getLN ().add (copiedLn );//value copy
260
- }
261
- }, () -> errorHanlder .add (SclReportItem .warning (lnAdapter .getXPath () + "/DOI@name=\" " + doName + "\" /DAI@name=\" setSrcRef\" /Val" ,
262
- "The DAI cannot be updated" )));
263
- });
241
+ private void manageMonitoringLns (List <TExtRef > tExtRefs , SCL scd , TIED tied , TLDevice ldsuiedLdevice , String doName , MonitoringLnClassEnum monitoringLnClassEnum ) {
242
+ List <TLN > lgosOrLsvsLns = lnService .getFilteredLns (ldsuiedLdevice , tln -> monitoringLnClassEnum .value ().equals (tln .getLnClass ().getFirst ())).toList ();
243
+ if (lgosOrLsvsLns .isEmpty ())
244
+ errorHanlder .add (SclReportItem .warning (tied .getName () + "/" + LDEVICE_LDSUIED + "/" + monitoringLnClassEnum .value (), "There is no LN %s present in LDevice" .formatted (monitoringLnClassEnum .value ())));
245
+ DoLinkedToDaFilter doLinkedToDaFilter = new DoLinkedToDaFilter (doName , List .of (), DA_SETSRCREF , List .of ());
246
+ lgosOrLsvsLns .forEach (lgosOrLsvs -> dataTypeTemplateService .getFilteredDoLinkedToDa (scd .getDataTypeTemplates (), lgosOrLsvs .getLnType (), doLinkedToDaFilter )
247
+ .map (doLinkedToDa -> lnService .getDoLinkedToDaCompletedFromDAI (tied , LDEVICE_LDSUIED , lgosOrLsvs , doLinkedToDa ))
248
+ .findFirst ()
249
+ .filter (doLinkedToDa -> {
250
+ if (!doLinkedToDa .isUpdatable ())
251
+ errorHanlder .add (SclReportItem .warning (tied .getName () + "/" + LDEVICE_LDSUIED + "/" + monitoringLnClassEnum .value () + "/DOI@name=\" " + doName + "\" /DAI@name=\" setSrcRef\" /Val" , "The DAI cannot be updated" ));
252
+ return doLinkedToDa .isUpdatable ();
253
+ })
254
+ .ifPresent (doLinkedToDa -> {
255
+ log .info ("Processing %d ExtRefs in LDName=%s of service type %s for LN (lnClass=%s, inst=%s, prefix=%s)" .formatted (tExtRefs .size (), ldsuiedLdevice .getLdName (), monitoringLnClassEnum .value (), lgosOrLsvs .getLnClass ().getFirst (), lgosOrLsvs .getInst (), lgosOrLsvs .getPrefix ()));
256
+ for (int i = 0 ; i < tExtRefs .size (); i ++) {
257
+ TLN lnToAdd = copyLn (lgosOrLsvs ); //duplicate actual LGOS or LSVS in order to add LDSUIED with extRefs properties
258
+ TExtRef tExtRef = tExtRefs .get (i );
259
+ TIED sourceIed = iedService .findByName (scd , tExtRef .getIedName ()).orElseThrow (() -> new ScdException ("IED.name '" + tExtRef .getIedName () + "' not found in SCD" ));
260
+ String sourceLdName = ldeviceService .findLdevice (sourceIed , tExtRef .getSrcLDInst ()).orElseThrow (() -> new ScdException (String .format ("LDevice.inst '%s' not found in IED '%s'" , tExtRef .getSrcLDInst (), tExtRef .getIedName ()))).getLdName ();
261
+ String lnClass = !tExtRef .isSetSrcLNClass () ? TLLN0Enum .LLN_0 .value () : tExtRef .getSrcLNClass ().getFirst ();
262
+ lnToAdd .setInst (String .valueOf (i + 1 ));
263
+ DaVal newVal = new DaVal (null , sourceLdName + "/" + lnClass + "." + tExtRef .getSrcCBName ());
264
+ doLinkedToDa .dataAttribute ().getDaiValues ().clear ();
265
+ doLinkedToDa .dataAttribute ().getDaiValues ().add (newVal );
266
+ lnService .updateOrCreateDOAndDAInstances (lnToAdd , doLinkedToDa );
267
+ log .info ("Processing %d ExtRefs in LDName=%s - added LN (lnClass=%s, inst=%s, prefix=%s) - update DOI(name=%s)/DAI(name=%s) with value=%s" .formatted (tExtRefs .size (), ldsuiedLdevice .getLdName (), lgosOrLsvs .getLnClass ().getFirst (), String .valueOf (i + 1 ), lgosOrLsvs .getPrefix (), doName , DA_SETSRCREF , newVal .val ()));
268
+ ldsuiedLdevice .getLN ().add (lnToAdd );
269
+ }
270
+ ldsuiedLdevice .getLN ().remove (lgosOrLsvs ); //We can remove this LGOS or LSVS as we already added new ones
271
+ }));
264
272
}
265
273
266
- private void removeLnsByLnClass (MonitoringLnClassEnum monitoringLnClassEnum , TLDevice tlDevice ) {
267
- List <TLN > lnToKeep = tlDevice .getLN ().stream ()
268
- .filter (tln -> !Utils .lnClassEquals (tln .getLnClass (), monitoringLnClassEnum .value ()))
269
- .toList ();
270
- tlDevice .unsetLN ();
271
- tlDevice .getLN ().addAll (lnToKeep );
274
+ private TLN copyLn (TLN tln ) {
275
+ TLN newLn = new TLN ();
276
+ newLn .getLnClass ().addAll (tln .getLnClass ());
277
+ newLn .setInst (tln .getInst ());
278
+ newLn .setLnType (tln .getLnType ());
279
+ newLn .setPrefix (tln .getPrefix ());
280
+ newLn .setDesc (tln .getDesc ());
281
+ newLn .setInputs (tln .getInputs ());
282
+ newLn .setText (tln .getText ());
283
+ newLn .getPrivate ().addAll (tln .getPrivate ());
284
+ newLn .getDataSet ().addAll (tln .getDataSet ());
285
+ newLn .getAny ().addAll (tln .getAny ());
286
+ newLn .getDOI ().addAll (tln .getDOI ());
287
+ newLn .getLog ().addAll (tln .getLog ());
288
+ newLn .getLogControl ().addAll (tln .getLogControl ());
289
+ newLn .getOtherAttributes ().putAll (tln .getOtherAttributes ());
290
+ newLn .getReportControl ().addAll (tln .getReportControl ());
291
+ return newLn ;
272
292
}
293
+
273
294
}
0 commit comments