Skip to content

Commit 80ea755

Browse files
committed
Use Generator API for AspectModelAasGenerator
1 parent 94c68e2 commit 80ea755

File tree

11 files changed

+228
-72
lines changed

11 files changed

+228
-72
lines changed

core/esmf-aspect-model-aas-generator/pom.xml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
<groupId>org.eclipse.esmf</groupId>
2323
<artifactId>esmf-aspect-meta-model-java</artifactId>
2424
</dependency>
25+
<dependency>
26+
<groupId>org.eclipse.esmf</groupId>
27+
<artifactId>esmf-aspect-model-generator</artifactId>
28+
</dependency>
2529
<dependency>
2630
<groupId>org.eclipse.digitaltwin.aas4j</groupId>
2731
<artifactId>aas4j-model</artifactId>
@@ -42,6 +46,11 @@
4246
<groupId>org.apache.poi</groupId>
4347
<artifactId>poi</artifactId>
4448
</dependency>
49+
<dependency>
50+
<groupId>io.soabase.record-builder</groupId>
51+
<artifactId>record-builder-processor</artifactId>
52+
<scope>provided</scope>
53+
</dependency>
4554

4655
<dependency>
4756
<groupId>org.eclipse.esmf</groupId>
@@ -59,4 +68,22 @@
5968
<scope>test</scope>
6069
</dependency>
6170
</dependencies>
71+
72+
<build>
73+
<plugins>
74+
<plugin>
75+
<groupId>org.apache.maven.plugins</groupId>
76+
<artifactId>maven-compiler-plugin</artifactId>
77+
<configuration>
78+
<annotationProcessorPaths>
79+
<path>
80+
<groupId>io.soabase.record-builder</groupId>
81+
<artifactId>record-builder-processor</artifactId>
82+
<version>${record-builder-version}</version>
83+
</path>
84+
</annotationProcessorPaths>
85+
</configuration>
86+
</plugin>
87+
</plugins>
88+
</build>
6289
</project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
3+
*
4+
* See the AUTHORS file(s) distributed with this work for additional
5+
* information regarding authorship.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
10+
*
11+
* SPDX-License-Identifier: MPL-2.0
12+
*/
13+
14+
package org.eclipse.esmf.aspectmodel.aas;
15+
16+
import org.eclipse.esmf.aspectmodel.generator.BinaryArtifact;
17+
18+
public class AasArtifact extends BinaryArtifact {
19+
public AasArtifact( final String id, final byte[] content ) {
20+
super( id, content );
21+
}
22+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
3+
*
4+
* See the AUTHORS file(s) distributed with this work for additional
5+
* information regarding authorship.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
10+
*
11+
* SPDX-License-Identifier: MPL-2.0
12+
*/
13+
14+
package org.eclipse.esmf.aspectmodel.aas;
15+
16+
import java.util.List;
17+
18+
import org.eclipse.esmf.aspectmodel.generator.GenerationConfig;
19+
20+
import com.fasterxml.jackson.databind.JsonNode;
21+
import io.soabase.recordbuilder.core.RecordBuilder;
22+
23+
@RecordBuilder
24+
public record AasGenerationConfig(
25+
AasFileFormat format,
26+
JsonNode aspectData,
27+
List<PropertyMapper<?>> propertyMappers
28+
) implements GenerationConfig {
29+
public AasGenerationConfig {
30+
if ( format == null ) {
31+
format = AasFileFormat.XML;
32+
}
33+
if ( propertyMappers == null ) {
34+
propertyMappers = List.of();
35+
}
36+
}
37+
}

core/esmf-aspect-model-aas-generator/src/main/java/org/eclipse/esmf/aspectmodel/aas/AasGenerationException.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515

1616
import java.io.Serial;
1717

18-
public class AasGenerationException extends RuntimeException {
19-
public AasGenerationException( final Throwable cause ) {
20-
super( cause );
21-
}
18+
import org.eclipse.esmf.aspectmodel.generator.GenerationException;
2219

20+
public class AasGenerationException extends GenerationException {
2321
@Serial
2422
private static final long serialVersionUID = 6578531471799897531L;
23+
24+
public AasGenerationException( final Throwable cause ) {
25+
super( cause );
26+
}
2527
}

core/esmf-aspect-model-aas-generator/src/main/java/org/eclipse/esmf/aspectmodel/aas/AspectModelAasGenerator.java

Lines changed: 80 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@
1313
package org.eclipse.esmf.aspectmodel.aas;
1414

1515
import java.io.ByteArrayOutputStream;
16+
import java.io.IOException;
1617
import java.io.OutputStream;
1718
import java.util.List;
1819
import java.util.function.Function;
20+
import java.util.stream.Stream;
21+
1922
import javax.annotation.Nullable;
2023

21-
import org.eclipse.esmf.functions.ThrowingBiConsumer;
24+
import org.eclipse.esmf.aspectmodel.generator.AspectGenerator;
2225
import org.eclipse.esmf.metamodel.Aspect;
2326

2427
import com.fasterxml.jackson.databind.JsonNode;
2528
import org.eclipse.digitaltwin.aas4j.v3.dataformat.aasx.AASXSerializer;
29+
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.SerializationException;
2630
import org.eclipse.digitaltwin.aas4j.v3.dataformat.json.JsonSerializer;
2731
import org.eclipse.digitaltwin.aas4j.v3.dataformat.xml.XmlSerializer;
2832
import org.eclipse.digitaltwin.aas4j.v3.model.Environment;
@@ -33,26 +37,75 @@
3337
/**
3438
* Generator that generates an AAS file containing an AAS submodel for a given Aspect model.
3539
*/
36-
public class AspectModelAasGenerator {
37-
40+
public class AspectModelAasGenerator extends AspectGenerator<String, byte[], AasGenerationConfig, AasArtifact> {
41+
/*
42+
* This should be removed together with the deprecated constructors
43+
*/
44+
@Deprecated
3845
private List<PropertyMapper<?>> propertyMappers = List.of();
3946

47+
public AspectModelAasGenerator( final Aspect aspect, final AasGenerationConfig config ) {
48+
super( aspect, config );
49+
}
50+
51+
@Deprecated( forRemoval = true )
4052
public AspectModelAasGenerator() {
53+
super( null, null );
4154
}
4255

56+
@Deprecated( forRemoval = true )
4357
public AspectModelAasGenerator( final List<PropertyMapper<?>> propertyMappers ) {
58+
super( null, null );
4459
this.propertyMappers = propertyMappers;
4560
}
4661

62+
@Override
63+
public Stream<AasArtifact> generate() {
64+
final AspectModelAasVisitor visitor = new AspectModelAasVisitor().withPropertyMapper( new LangStringPropertyMapper() );
65+
config.propertyMappers().forEach( visitor::withPropertyMapper );
66+
final Context context;
67+
if ( config.aspectData() != null ) {
68+
final Submodel submodel = new DefaultSubmodel.Builder().build();
69+
final Environment inputEnvironment = new DefaultEnvironment.Builder().submodels( List.of( submodel ) ).build();
70+
context = new Context( inputEnvironment, submodel );
71+
context.setEnvironment( inputEnvironment );
72+
context.setAspectData( config.aspectData() );
73+
} else {
74+
context = null;
75+
}
76+
77+
try {
78+
final Environment environment = visitor.visitAspect( aspect(), context );
79+
final byte[] result = switch ( config.format() ) {
80+
case XML -> new XmlSerializer().write( environment ).getBytes();
81+
case JSON -> new JsonSerializer().write( environment ).getBytes();
82+
case AASX -> {
83+
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
84+
new AASXSerializer().write( environment, null, outputStream );
85+
yield outputStream.toByteArray();
86+
}
87+
};
88+
return Stream.of( new AasArtifact( aspect().getName() + "." + config.format(), result ) );
89+
} catch ( final SerializationException | IOException exception ) {
90+
throw new AasGenerationException( exception );
91+
}
92+
}
93+
4794
/**
4895
* Generates an AAS file for a given Aspect.
4996
*
5097
* @param format the output format
5198
* @param aspect the Aspect for which an AASX archive shall be generated
5299
* @return the generated AAS file as byte array
100+
* @deprecated Use {@link #AspectModelAasGenerator(Aspect, AasGenerationConfig)} and {@link #getContent()} instead
53101
*/
102+
@Deprecated( forRemoval = true )
54103
public byte[] generateAsByteArray( final AasFileFormat format, final Aspect aspect ) {
55-
return generateAsByteArray( format, aspect, null );
104+
final AasGenerationConfig generationConfig = AasGenerationConfigBuilder.builder()
105+
.format( format )
106+
.propertyMappers( propertyMappers )
107+
.build();
108+
return new AspectModelAasGenerator( aspect, generationConfig ).getContent();
56109
}
57110

58111
/**
@@ -62,11 +115,16 @@ public byte[] generateAsByteArray( final AasFileFormat format, final Aspect aspe
62115
* @param aspect the Aspect for which an AASX archive shall be generated
63116
* @return the generated AAS file as byte array
64117
* @throws AasGenerationException in case the generation can not properly be executed
118+
* @deprecated Use {@link #AspectModelAasGenerator(Aspect, AasGenerationConfig)} and {@link #getContent()} instead
65119
*/
120+
@Deprecated( forRemoval = true )
66121
public byte[] generateAsByteArray( final AasFileFormat format, final Aspect aspect, final JsonNode aspectData ) {
67-
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
68-
generate( format, aspect, aspectData, name -> baos );
69-
return baos.toByteArray();
122+
final AasGenerationConfig generationConfig = AasGenerationConfigBuilder.builder()
123+
.format( format )
124+
.aspectData( aspectData )
125+
.propertyMappers( propertyMappers )
126+
.build();
127+
return new AspectModelAasGenerator( aspect, generationConfig ).getContent();
70128
}
71129

72130
/**
@@ -76,17 +134,15 @@ public byte[] generateAsByteArray( final AasFileFormat format, final Aspect aspe
76134
* @param aspect the Aspect for which an AASX archive shall be generated
77135
* @param nameMapper a Name Mapper implementation, which provides an OutputStream for a given filename
78136
* @throws AasGenerationException in case the generation can not properly be executed
137+
* @deprecated Use {@link #AspectModelAasGenerator(Aspect, AasGenerationConfig)} and {@link #generate(Function)} instead
79138
*/
139+
@Deprecated( forRemoval = true )
80140
public void generate( final AasFileFormat format, final Aspect aspect, final Function<String, OutputStream> nameMapper ) {
81-
generate( format, aspect, null, nameMapper );
82-
}
83-
84-
private ThrowingBiConsumer<Environment, OutputStream, Throwable> serializer( final AasFileFormat format ) {
85-
return switch ( format ) {
86-
case AASX -> ( environment, output ) -> new AASXSerializer().write( environment, null, output );
87-
case XML -> ( environment, output ) -> output.write( new XmlSerializer().write( environment ).getBytes() );
88-
case JSON -> ( environment, output ) -> output.write( new JsonSerializer().write( environment ).getBytes() );
89-
};
141+
final AasGenerationConfig generationConfig = AasGenerationConfigBuilder.builder()
142+
.format( format )
143+
.propertyMappers( propertyMappers )
144+
.build();
145+
new AspectModelAasGenerator( aspect, generationConfig ).generate( nameMapper );
90146
}
91147

92148
/**
@@ -98,27 +154,16 @@ private ThrowingBiConsumer<Environment, OutputStream, Throwable> serializer( fin
98154
* @param aspectData the JSON data corresponding to the Aspect, may be null
99155
* @param nameMapper a Name Mapper implementation, which provides an OutputStream for a given filename
100156
* @throws AasGenerationException in case the generation can not properly be executed
157+
* @deprecated Use {@link #AspectModelAasGenerator(Aspect, AasGenerationConfig)} and {@link #generate(Function)} instead
101158
*/
159+
@Deprecated( forRemoval = true )
102160
public void generate( final AasFileFormat format, final Aspect aspect, @Nullable final JsonNode aspectData,
103161
final Function<String, OutputStream> nameMapper ) {
104-
try ( final OutputStream output = nameMapper.apply( aspect.getName() ) ) {
105-
final AspectModelAasVisitor visitor = new AspectModelAasVisitor().withPropertyMapper( new LangStringPropertyMapper() );
106-
propertyMappers.forEach( visitor::withPropertyMapper );
107-
final Context context;
108-
if ( aspectData != null ) {
109-
final Submodel submodel = new DefaultSubmodel.Builder().build();
110-
final Environment inputEnvironment = new DefaultEnvironment.Builder().submodels( List.of( submodel ) ).build();
111-
context = new Context( inputEnvironment, submodel );
112-
context.setEnvironment( inputEnvironment );
113-
context.setAspectData( aspectData );
114-
} else {
115-
context = null;
116-
}
117-
118-
final Environment environment = visitor.visitAspect( aspect, context );
119-
serializer( format ).accept( environment, output );
120-
} catch ( final Throwable exception ) {
121-
throw new AasGenerationException( exception );
122-
}
162+
final AasGenerationConfig generationConfig = AasGenerationConfigBuilder.builder()
163+
.format( format )
164+
.aspectData( aspectData )
165+
.propertyMappers( propertyMappers )
166+
.build();
167+
new AspectModelAasGenerator( aspect, generationConfig ).generate( nameMapper );
123168
}
124169
}

core/esmf-aspect-model-aas-generator/src/test/java/org/eclipse/esmf/aspectmodel/aas/AasToAspectModelGeneratorTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import org.junit.jupiter.params.provider.EnumSource;
3838

3939
class AasToAspectModelGeneratorTest {
40-
4140
@Test
4241
void testTranslateDigitalNameplate() {
4342
final InputStream aasx = AasToAspectModelGeneratorTest.class.getClassLoader()
@@ -75,11 +74,13 @@ void testRoundtripConversion( final TestAspect testAspect ) throws Deserializati
7574
} ).doesNotThrowAnyException();
7675

7776
final Environment aasEnvironmentFromXml = new XmlDeserializer().read(
78-
new ByteArrayInputStream( new AspectModelAasGenerator().generateAsByteArray( AasFileFormat.XML, aspect ) ) );
77+
new ByteArrayInputStream( new AspectModelAasGenerator( aspect,
78+
AasGenerationConfigBuilder.builder().format( AasFileFormat.XML ).build() ).getContent() ) );
7979
assertForValidator.accept( AasToAspectModelGenerator.fromEnvironment( aasEnvironmentFromXml ) );
8080

8181
final Environment aasEnvironmentFromJson = new JsonDeserializer().read(
82-
new ByteArrayInputStream( new AspectModelAasGenerator().generateAsByteArray( AasFileFormat.JSON, aspect ) ),
82+
new ByteArrayInputStream( new AspectModelAasGenerator( aspect,
83+
AasGenerationConfigBuilder.builder().format( AasFileFormat.JSON ).build() ).getContent() ),
8384
Environment.class );
8485
assertForValidator.accept( AasToAspectModelGenerator.fromEnvironment( aasEnvironmentFromJson ) );
8586
}
@@ -156,7 +157,7 @@ private InputStream getIdtaModel( final String path ) {
156157
final URL url = new URL(
157158
"https://github.com/admin-shell-io/submodel-templates/raw/refs/heads/main/published/" + path.replaceAll( " ", "%20" ) );
158159
return url.openStream();
159-
} catch ( Exception e ) {
160+
} catch ( final Exception e ) {
160161
e.printStackTrace();
161162
return null;
162163
}

0 commit comments

Comments
 (0)