27
27
import org .apache .jena .rdf .model .ResourceFactory ;
28
28
import org .apache .jena .vocabulary .RDF ;
29
29
import org .apache .jena .vocabulary .XSD ;
30
+ import org .eclipse .digitaltwin .aas4j .v3 .model .AdministrativeInformation ;
30
31
import org .eclipse .digitaltwin .aas4j .v3 .model .AssetAdministrationShell ;
32
+ import org .eclipse .digitaltwin .aas4j .v3 .model .AssetKind ;
31
33
import org .eclipse .digitaltwin .aas4j .v3 .model .ConceptDescription ;
32
34
import org .eclipse .digitaltwin .aas4j .v3 .model .DataSpecificationIEC61360 ;
33
35
import org .eclipse .digitaltwin .aas4j .v3 .model .DataTypeDefXsd ;
41
43
import org .eclipse .digitaltwin .aas4j .v3 .model .Operation ;
42
44
import org .eclipse .digitaltwin .aas4j .v3 .model .OperationVariable ;
43
45
import org .eclipse .digitaltwin .aas4j .v3 .model .Reference ;
46
+ import org .eclipse .digitaltwin .aas4j .v3 .model .ReferenceTypes ;
44
47
import org .eclipse .digitaltwin .aas4j .v3 .model .Submodel ;
45
48
import org .eclipse .digitaltwin .aas4j .v3 .model .SubmodelElement ;
46
49
import org .eclipse .digitaltwin .aas4j .v3 .model .SubmodelElementCollection ;
47
50
import org .eclipse .digitaltwin .aas4j .v3 .model .SubmodelElementList ;
48
51
import org .eclipse .digitaltwin .aas4j .v3 .model .ValueList ;
49
52
import org .eclipse .digitaltwin .aas4j .v3 .model .ValueReferencePair ;
53
+ import org .eclipse .digitaltwin .aas4j .v3 .model .impl .DefaultAdministrativeInformation ;
50
54
import org .eclipse .digitaltwin .aas4j .v3 .model .impl .DefaultAssetAdministrationShell ;
55
+ import org .eclipse .digitaltwin .aas4j .v3 .model .impl .DefaultAssetInformation ;
51
56
import org .eclipse .digitaltwin .aas4j .v3 .model .impl .DefaultConceptDescription ;
52
57
import org .eclipse .digitaltwin .aas4j .v3 .model .impl .DefaultDataSpecificationIEC61360 ;
53
58
import org .eclipse .digitaltwin .aas4j .v3 .model .impl .DefaultEmbeddedDataSpecification ;
@@ -186,14 +191,25 @@ public Environment visitAspect( final Aspect aspect, Context context ) {
186
191
187
192
final Submodel submodel = context .getSubmodel ();
188
193
submodel .setIdShort ( aspect .getName () );
194
+ submodel .setId ( aspect .getAspectModelUrn ().toString () + "/submodel" );
189
195
submodel .setSemanticId ( buildReferenceToConceptDescription ( aspect ) );
190
196
submodel .setDescription ( map ( aspect .getDescriptions () ) );
191
197
submodel .setKind ( ModelingKind .TEMPLATE );
198
+ submodel .setAdministration ( new DefaultAdministrativeInformation .Builder ().build () );
199
+ submodel .setChecksum ( String .valueOf ( aspect .hashCode () ) );
192
200
193
201
createConceptDescription ( aspect , context );
194
202
195
203
final AssetAdministrationShell administrationShell =
196
- new DefaultAssetAdministrationShell .Builder ().idShort ( ADMIN_SHELL_NAME ).build ();
204
+ new DefaultAssetAdministrationShell .Builder ()
205
+ .idShort ( ADMIN_SHELL_NAME )
206
+ .description ( createLangString ( ADMIN_SHELL_NAME , "en" ) )
207
+ .checksum ( "a checksum" )
208
+ .id ( ADMIN_SHELL_NAME )
209
+ .administration ( new DefaultAdministrativeInformation .Builder ().build () )
210
+ .assetInformation ( new DefaultAssetInformation .Builder ().assetKind ( AssetKind .INSTANCE ).build () )
211
+ .embeddedDataSpecifications ( extractEmbeddedDataSpecification ( aspect ) )
212
+ .build ();
197
213
context
198
214
.getEnvironment ()
199
215
.setAssetAdministrationShells ( Collections .singletonList ( administrationShell ) );
@@ -211,14 +227,17 @@ private List<SubmodelElement> visitOperations(
211
227
212
228
private List <SubmodelElement > visitProperties (
213
229
final List <Property > elements , final Context context ) {
214
- return elements .stream ().map ( i -> map ( i , context ) ).collect ( Collectors .toList () );
230
+ return elements .stream ().map ( i -> map ( i , context ) )
231
+ .filter (Optional ::isPresent )
232
+ .map (Optional ::get )
233
+ .collect ( Collectors .toList () );
215
234
}
216
235
217
- private SubmodelElement map ( final Property property , final Context context ) {
218
- final Supplier <SubmodelElement > defaultResultForProperty = () -> context .getSubmodel ().getSubmodelElements ().stream ()
236
+ private Optional <SubmodelElement > map ( final Property property , final Context context ) {
237
+ final Optional <SubmodelElement > defaultResultForProperty = context .getSubmodel ()
238
+ .getSubmodelElements ().stream ()
219
239
.filter ( i -> i .getIdShort ().equals ( property .getName () ) )
220
- .findFirst ()
221
- .orElse ( new DefaultProperty .Builder ().build () );
240
+ .findFirst ();
222
241
if ( recursiveProperty .contains ( property ) ) {
223
242
// The guard checks for recursion in properties. If a recursion happens, the respective
224
243
// property will be excluded from generation.
@@ -228,13 +247,13 @@ private SubmodelElement map( final Property property, final Context context ) {
228
247
} else {
229
248
LOG .error ( String .format ( "Having a recursive Property: %s which is not optional is not valid. Check the model. Property will be excluded from AAS mapping." , property ) );
230
249
}
231
- return defaultResultForProperty . get () ;
250
+ return defaultResultForProperty ;
232
251
}
233
252
recursiveProperty .add ( property );
234
253
235
- if ( property .getCharacteristic ().isEmpty () ) {
254
+ if ( property .getCharacteristic ().isEmpty () || property . isAbstract () ) {
236
255
LOG .warn ( String .format ( "Having an Abstract Property. Will be excluded from AAS mapping." ) );
237
- return defaultResultForProperty . get ();
256
+ return Optional . empty ();
238
257
}
239
258
240
259
// Characteristic defines how the property is mapped to SubmodelElement
@@ -245,7 +264,8 @@ private SubmodelElement map( final Property property, final Context context ) {
245
264
final SubmodelElement element = context .getPropertyResult ();
246
265
247
266
recursiveProperty .remove ( property );
248
- return element ;
267
+
268
+ return Optional .of ( element );
249
269
}
250
270
251
271
private SubmodelElement decideOnMapping ( final Property property , final Context context ) {
@@ -283,12 +303,12 @@ private org.eclipse.digitaltwin.aas4j.v3.model.Property mapToAasProperty( final
283
303
return new DefaultProperty .Builder ()
284
304
.idShort ( property .getName () )
285
305
.kind ( ModelingKind .TEMPLATE )
286
- .valueType ( mapAASXSDataType ( property .getCharacteristic ().flatMap ( Characteristic ::getDataType ).map ( this ::mapType ).orElse ( UNKNOWN_TYPE ) ) ) // TODO this might not work and a proper mapping implementation is required
306
+ .valueType ( mapAASXSDataType ( property .getCharacteristic ().flatMap ( Characteristic ::getDataType ).map ( this ::mapType ).orElse ( UNKNOWN_TYPE ) ) )
287
307
.displayName ( map ( property .getPreferredNames () ) )
288
308
.value ( property .getExampleValue ().map ( i -> i .getValue ().toString () ).orElse ( UNKNOWN_EXAMPLE ) )
289
309
.description ( map ( property .getDescriptions () ) )
290
- .semanticId ( buildReferenceToConceptDescription ( property ) ) // this is the link to the conceptDescription containing the details for
291
- // the Characteristic
310
+ .semanticId ( buildReferenceToConceptDescription ( property ) ) // link to the conceptDescription containing the details for the Characteristic
311
+ . supplementalSemanticIds ( buildReferencesForSeeElements ( property . getSee ()) )
292
312
.build ();
293
313
}
294
314
@@ -318,7 +338,7 @@ private Operation map(
318
338
}
319
339
320
340
private OperationVariable mapOperationVariable ( final Property property , final Context context ) {
321
- return new DefaultOperationVariable .Builder ().value ( map ( property , context ) ).build ();
341
+ return new DefaultOperationVariable .Builder ().value ( map ( property , context ). get () ).build ();
322
342
}
323
343
324
344
private List <LangString > map ( final Set <io .openmanufacturing .sds .metamodel .datatypes .LangString > localizedStrings ) {
@@ -345,7 +365,7 @@ private Reference buildReferenceToEnumValue( final Enumeration enumeration, fina
345
365
.type ( KeyTypes .DATA_ELEMENT )
346
366
.value ( determineIdentifierFor ( enumeration ) + ":" + value .toString () )
347
367
.build ();
348
- return new DefaultReference .Builder ().keys ( key ).build ();
368
+ return new DefaultReference .Builder ().type ( ReferenceTypes . MODEL_REFERENCE ). keys ( key ).build ();
349
369
}
350
370
351
371
private Reference buildReferenceToConceptDescription ( final Aspect aspect ) {
@@ -354,7 +374,7 @@ private Reference buildReferenceToConceptDescription( final Aspect aspect ) {
354
374
.type ( KeyTypes .CONCEPT_DESCRIPTION )
355
375
.value ( extractIdentifier ( aspect ) )
356
376
.build ();
357
- return new DefaultReference .Builder ().keys ( key ).build ();
377
+ return new DefaultReference .Builder ().keys ( key ).type ( ReferenceTypes . MODEL_REFERENCE ). build ();
358
378
}
359
379
360
380
private Reference buildReferenceToConceptDescription ( final Property property ) {
@@ -363,7 +383,23 @@ private Reference buildReferenceToConceptDescription( final Property property )
363
383
.type ( KeyTypes .CONCEPT_DESCRIPTION )
364
384
.value ( extractIdentifier ( property ) )
365
385
.build ();
366
- return new DefaultReference .Builder ().keys ( key ).build ();
386
+ return new DefaultReference .Builder ().type ( ReferenceTypes .MODEL_REFERENCE ).keys ( key ).build ();
387
+ }
388
+
389
+ private Reference buildReferenceForSeeElement ( final String seeReference ) {
390
+ final Key key =
391
+ new DefaultKey .Builder ()
392
+ .type ( KeyTypes .GLOBAL_REFERENCE )
393
+ .value ( seeReference )
394
+ .build ();
395
+ return new DefaultReference .Builder ()
396
+ .type ( ReferenceTypes .GLOBAL_REFERENCE )
397
+ .keys ( key )
398
+ .build ();
399
+ }
400
+
401
+ private List <Reference > buildReferencesForSeeElements ( final List <String > seeReferences ) {
402
+ return seeReferences .stream ().map ( this ::buildReferenceForSeeElement ).collect ( Collectors .toList () );
367
403
}
368
404
369
405
private String determineIdentifierFor ( final NamedElement isDescribed ) {
@@ -410,12 +446,14 @@ private void createConceptDescription( final Aspect aspect, final Context contex
410
446
411
447
private EmbeddedDataSpecification extractEmbeddedDataSpecification ( final Property property ) {
412
448
return new DefaultEmbeddedDataSpecification .Builder ()
449
+ .dataSpecification ( buildReferenceForSeeElement ( property .getAspectModelUrn ().toString () ) )
413
450
.dataSpecificationContent ( extractDataSpecificationContent ( property ) )
414
451
.build ();
415
452
}
416
453
417
454
private EmbeddedDataSpecification extractEmbeddedDataSpecification ( final Aspect aspect ) {
418
455
return new DefaultEmbeddedDataSpecification .Builder ()
456
+ .dataSpecification ( buildReferenceForSeeElement ( aspect .getAspectModelUrn ().toString () ) )
419
457
.dataSpecificationContent ( extractDataSpecificationContent ( aspect ) )
420
458
.build ();
421
459
}
@@ -428,7 +466,9 @@ private DataSpecificationIEC61360 extractDataSpecificationContent( final Propert
428
466
429
467
return new DefaultDataSpecificationIEC61360 .Builder ()
430
468
.definition ( definitions )
431
- .preferredName ( map ( property .getPreferredNames () ) )
469
+ .preferredName ( property .getPreferredNames ().isEmpty () ?
470
+ Collections .singletonList ( createLangString ( property .getName (), DEFAULT_LOCALE ) ) :
471
+ map ( property .getPreferredNames () ) )
432
472
.shortName ( createLangString ( property .getName (), DEFAULT_LOCALE ) )
433
473
.dataType ( mapIEC61360DataType ( property .getCharacteristic () ) )
434
474
.build ();
@@ -440,8 +480,10 @@ private DataSpecificationIEC61360 extractDataSpecificationContent( final Aspect
440
480
441
481
return new DefaultDataSpecificationIEC61360 .Builder ()
442
482
.definition ( definitions )
443
- .preferredName ( map ( aspect .getPreferredNames () ) )
444
- .shortName ( createLangString ( aspect .getName (), DEFAULT_LOCALE ) )
483
+ .preferredName ( aspect .getPreferredNames ().isEmpty () ?
484
+ Collections .singletonList ( createLangString ( aspect .getName (), DEFAULT_LOCALE ) ) :
485
+ map ( aspect .getPreferredNames () ) )
486
+ .value ( aspect .getName () )
445
487
.build ();
446
488
}
447
489
0 commit comments