2020import com .fasterxml .jackson .dataformat .xml .XmlMapper ;
2121import io .adminshell .aas .v3 .dataformat .SerializationException ;
2222import io .adminshell .aas .v3 .dataformat .Serializer ;
23- import io .adminshell .aas .v3 .dataformat .aml .model .caex .AdditionalInformation ;
24- import io .adminshell .aas .v3 .dataformat .aml .model .caex .Attribute ;
25- import io .adminshell .aas .v3 .dataformat .aml .model .caex .CAEXConstants ;
26- import io .adminshell .aas .v3 .dataformat .aml .model .caex .CAEXFile ;
27- import io .adminshell .aas .v3 .dataformat .aml .model .caex .ExternalInterface ;
28- import io .adminshell .aas .v3 .dataformat .aml .model .caex .InstanceHierarchy ;
29- import io .adminshell .aas .v3 .dataformat .aml .model .caex .InternalElement ;
30- import io .adminshell .aas .v3 .dataformat .aml .model .caex .RefSemantic ;
31- import io .adminshell .aas .v3 .dataformat .aml .model .caex .RoleRequirements ;
32- import io .adminshell .aas .v3 .dataformat .aml .model .mixin .AdditionalInformationMixin ;
33- import io .adminshell .aas .v3 .dataformat .aml .model .mixin .AttributeMixin ;
34- import io .adminshell .aas .v3 .dataformat .aml .model .mixin .CAEXMixin ;
35- import io .adminshell .aas .v3 .dataformat .aml .model .mixin .ExternalInterfaceMixin ;
36- import io .adminshell .aas .v3 .dataformat .aml .model .mixin .InstanceHierarchyMixin ;
37- import io .adminshell .aas .v3 .dataformat .aml .model .mixin .InternalElementMixin ;
38- import io .adminshell .aas .v3 .dataformat .aml .model .mixin .RefSemanticMixin ;
39- import io .adminshell .aas .v3 .dataformat .aml .model .mixin .RoleRequirementsMixin ;
23+ import io .adminshell .aas .v3 .dataformat .aml .model .caex .*;
24+ import io .adminshell .aas .v3 .dataformat .aml .model .mixin .*;
4025import io .adminshell .aas .v3 .dataformat .aml .serialize .mapper .AASEnvironmentMapper ;
4126import io .adminshell .aas .v3 .model .AssetAdministrationShell ;
4227import io .adminshell .aas .v3 .model .AssetAdministrationShellEnvironment ;
43- import io .adminshell .aas .v3 .model .AssetInformation ;
4428import io .adminshell .aas .v3 .model .Submodel ;
45- import io .adminshell .aas .v3 .model .SubmodelElementCollection ;
29+ import ma .glasnost .orika .MapperFacade ;
30+ import org .slf4j .Logger ;
31+ import org .slf4j .LoggerFactory ;
32+
4633import java .io .File ;
4734import java .io .IOException ;
4835import java .nio .file .Files ;
4936import java .util .ArrayList ;
5037import java .util .List ;
51- import java .util .function .BiConsumer ;
52- import java .util .logging .Level ;
53- import ma .glasnost .orika .MapperFacade ;
54- import org .slf4j .Logger ;
55- import org .slf4j .LoggerFactory ;
5638
5739public class AmlSerializer implements Serializer {
5840
5941 private static final Logger log = LoggerFactory .getLogger (AmlSerializer .class );
60- private final MapperFacade mapper = new AASEnvironmentMapper ();
61-
62- private boolean enableClassLibs = false ;
63-
64- public AmlSerializer () {
65- }
6642
67- public AmlSerializer (boolean enableClassLibs ) {
68- this .enableClassLibs = enableClassLibs ;
69- }
43+ private final MapperFacade mapper = new AASEnvironmentMapper ();
7044
7145 @ Override
7246 public String write (AssetAdministrationShellEnvironment aasEnvironment ) throws SerializationException {
7347 try {
7448 CAEXFile caexFile = modelTransformation (aasEnvironment );
7549 String xml = convertXml (caexFile );
76- String cleanUp = cleanUpXml (xml );
77- String result = cleanUp ;
78- if (enableClassLibs ) {
79- result = addClassLibs (cleanUp );
80- }
50+ String result = cleanUpXml (xml );
8151 return result ;
8252 } catch (JsonProcessingException ex ) {
8353 throw new SerializationException ("error serializing AssetAdministrationShellEnvironment" , ex );
8454 }
8555 }
8656
87- private String addClassLibs (String xml ) {
88- StringBuilder output = new StringBuilder (xml );
89- // Read class lib file
90- String path = "automation-ml-class-libs.txt" ;
91- ClassLoader classLoader = getClass ().getClassLoader ();
92- File file = new File (classLoader .getResource (path ).getFile ());
93- String content = null ;
94- try {
95- content = new String (Files .readAllBytes (file .toPath ()));
96- } catch (IOException e ) {
97- e .printStackTrace ();
98- }
99- // Delete CAEX closing tag
100- if (output .length () > 0 ) {
101- int last , prev = output .length () - 1 ;
102- while ((last = output .lastIndexOf ("\n " , prev )) == prev ) {
103- prev = last - 1 ;
104- }
105- if (last >= 0 ) {
106- output .delete (last , output .length ());
107- }
108- }
109- // Add class libs to xml
110- if (content != null ) {
111- output .append (content );
112- }
113- // Add new CAEX closing tag
114- output .append ("</CAEXFile>" );
115- return output .toString ();
116- }
57+ private CAEXFile modelTransformation (AssetAdministrationShellEnvironment environment ) {
58+ // Map environment to CAEX file
59+ CAEXFile caexFile = mapper .map (environment , CAEXFile .class );
60+ caexFile .setSchemaVersion (CAEXConstants .SCHEMA_VERSION );
61+ caexFile .setXmlns (CAEXConstants .XMLNS );
62+ caexFile .setXsi (CAEXConstants .XSI );
11763
118- private String cleanUpXml (String xml ) {
119- String withoutEmptyAttributes = xml .replaceAll ("<Attribute/>" , "" );
120- String withoutEmptyLines = withoutEmptyAttributes .replaceAll ("(?m)^[ \t ]*\r ?\n " , "" );
121- return withoutEmptyLines ;
64+ // Add additional information to CAEX
65+ AdditionalInformation additionalInformation = new AdditionalInformation ();
66+ additionalInformation .setAutomationMLVersion (CAEXConstants .AUTOMATION_ML_VERSION );
67+ caexFile .setAdditionalInformation (additionalInformation );
68+
69+ // Add AssetAdministrationShell instance hierarchy to CAEX
70+ InstanceHierarchy instanceHierarchy = new InstanceHierarchy ();
71+ instanceHierarchy .setName (CAEXConstants .AAS_INSTANCE_HIERARCHY );
72+ instanceHierarchy .setVersion (CAEXConstants .AAS_INSTANCE_HIERARCHY_VERSION );
73+ caexFile .setInstanceHierarchy (instanceHierarchy );
74+
75+ // Map all asset administration shells to internal elements
76+ List <AssetAdministrationShell > administrationShells = new ArrayList <>(environment .getAssetAdministrationShells ());
77+ List <InternalElement > shellInternalElements = mapper .mapAsList (administrationShells , InternalElement .class );
78+ instanceHierarchy .setInternalElements (shellInternalElements );
79+
80+ // Map all submodels to internal elements
81+ List <Submodel > submodels = new ArrayList <>(environment .getSubmodels ());
82+ List <InternalElement > submodelInternalElements = mapper .mapAsList (submodels , InternalElement .class );
83+ instanceHierarchy .getInternalElements ().addAll (submodelInternalElements );
84+
85+ return caexFile ;
12286 }
12387
12488 private String convertXml (CAEXFile caexFile ) throws JsonProcessingException {
89+ caexFile .setInterfaceClassLibs (new ArrayList <>(){{
90+ add (readClassLib ("interface-class-lib_aas.automl" ));
91+ add (readClassLib ("interface-class-lib_automl_interface.automl" ));
92+ add (readClassLib ("interface-class-lib_automl_bpr.automl" ));
93+ }});
94+
95+ caexFile .setRoleClassLibs (new ArrayList <>(){{
96+ add (readClassLib ("role-class-lib_aas.automl" ));
97+ add (readClassLib ("role-class-lib_automl_base.automl" ));
98+ add (readClassLib ("role-class-lib_automl_bpr.automl" ));
99+ }});
100+
101+ caexFile .setSystemUnitClassLibs (new ArrayList <>(){{
102+ add (readClassLib ("system-unit-class-lib_aas.automl" ));
103+ add (readClassLib ("system-unit-class-lib_aas_data_specification_templates.automl" ));
104+ }});
105+
125106 XmlMapper xmlMapper = XmlMapper .builder ()
126107 .disable (SerializationFeature .FAIL_ON_EMPTY_BEANS )
127108 .enable (SerializationFeature .INDENT_OUTPUT )
@@ -138,82 +119,21 @@ private String convertXml(CAEXFile caexFile) throws JsonProcessingException {
138119 return xmlMapper .writeValueAsString (caexFile );
139120 }
140121
141- private CAEXFile modelTransformation (AssetAdministrationShellEnvironment environment ) {
142- CAEXFile caexFile = mapper .map (environment , CAEXFile .class );
143- caexFile .setSchemaVersion (CAEXConstants .SCHEMA_VERSION );
144- caexFile .setXmlns (CAEXConstants .XMLNS );
145- caexFile .setXsi (CAEXConstants .XSI );
146- // Add additional information to CAEX
147- AdditionalInformation additionalInformation = new AdditionalInformation ();
148- additionalInformation .setAutomationMLVersion (CAEXConstants .AUTOMATION_ML_VERSION );
149- caexFile .setAdditionalInformation (additionalInformation );
150- // Add instance hierarchy to CAEX
151- InstanceHierarchy instanceHierarchy = new InstanceHierarchy ();
152- instanceHierarchy .setName ("AssetAdministrationShellInstanceHierarchy" );
153- instanceHierarchy .setVersion ("0" );
154- caexFile .setInstanceHierarchy (instanceHierarchy );
155- // Map all asset administration shells to internal elements
156- List <AssetAdministrationShell > administrationShells = new ArrayList <>(environment .getAssetAdministrationShells ());
157- List <InternalElement > shellInternalElements = mapper .mapAsList (administrationShells , InternalElement .class );
158- // Inside shell loop
159- forEachWithCounter (administrationShells , (i , administrationShell ) -> {
160- // Map asset info to internal element
161- // AssetInformation asset = administrationShell.getAssetInformation();
162- // InternalElement assetInternalElement = mapper.map(asset, InternalElement.class);
163- // shellInternalElements.get(i).setInternalElements(new ArrayList<>() {
164- // {
165- // add(assetInternalElement);
166- // }
167- // });
168-
169- // // Map view
170- // List<InternalElement> viewInternalElements = mapper.mapAsList(administrationShell.getViews(), InternalElement.class);
171- // shellInternalElements.addAll(viewInternalElements);
172-
173- // // Map all submodels to internal elements
174- // forEachWithCounter(administrationShell.getSubmodels(), (j, submodel) -> {
175- // InternalElement submodelInternalElement = mapper.map(submodel, InternalElement.class);
176- // shellInternalElements.get(i).getInternalElements().add(submodelInternalElement);
177- // });
178- });
179- // Inside environment loop
180- shellInternalElements .forEach (shellInternalElement -> {
181- // Map all submodels to internal elements
182- List <Submodel > submodels = new ArrayList <>(environment .getSubmodels ());
183- submodels .forEach (submodel -> {
184- InternalElement submodelInternalElement = mapper .map (submodel , InternalElement .class );
185- submodelInternalElement .setInternalElements (new ArrayList <>());
186- // Map all submodel elements
187- submodel .getSubmodelElements ().forEach (submodelElement -> {
188- // Submodels that are not SubmodelElementCollections
189- if (!(submodelElement instanceof SubmodelElementCollection )) {
190- InternalElement internalElement = mapper .map (submodelElement , InternalElement .class );
191- submodelInternalElement .getInternalElements ().add (internalElement );
192- }
193- // SubmodelElementCollection
194- if (submodelElement instanceof SubmodelElementCollection ) {
195- InternalElement submodelElementInternalElement = mapper .map (submodelElement , InternalElement .class );
196- submodelElementInternalElement .setInternalElements (new ArrayList <>());
197- ((SubmodelElementCollection ) submodelElement ).getValues ().forEach (value -> {
198- InternalElement submodelElementCollectionInternalElement = mapper .map (value , InternalElement .class );
199- submodelElementInternalElement .getInternalElements ().add (submodelElementCollectionInternalElement );
200- });
201- submodelInternalElement .getInternalElements ().add (submodelElementInternalElement );
202- }
203- });
204- shellInternalElement .getInternalElements ().add (submodelInternalElement );
205- });
206- });
207- instanceHierarchy .setInternalElements (shellInternalElements );
208- return caexFile ;
209- }
210-
211- private static <T > void forEachWithCounter (Iterable <T > source , BiConsumer <Integer , T > consumer ) {
212- int i = 0 ;
213- for (T item : source ) {
214- consumer .accept (i , item );
215- i ++;
122+ private String readClassLib (String fileName ) {
123+ ClassLoader classLoader = getClass ().getClassLoader ();
124+ File file = new File (classLoader .getResource (fileName ).getFile ());
125+ String content = null ;
126+ try {
127+ content = new String (Files .readAllBytes (file .toPath ()));
128+ } catch (IOException e ) {
129+ e .printStackTrace ();
216130 }
131+ return content ;
217132 }
218133
134+ private String cleanUpXml (String xml ) {
135+ String withoutEmptyAttributes = xml .replaceAll ("<Attribute/>" , "" );
136+ String withoutEmptyLines = withoutEmptyAttributes .replaceAll ("(?m)^[ \t ]*\r ?\n " , "" );
137+ return withoutEmptyLines ;
138+ }
219139}
0 commit comments