Skip to content

Commit 0027b4a

Browse files
Merge pull request #108 from bci-oss/feature/#87-maven-plugin
Feature/#87 maven plugin
2 parents da6f77d + b557f9c commit 0027b4a

File tree

50 files changed

+2834
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2834
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
.Tooling Guide
22
* xref:bamm-cli.adoc[BAMM CLI]
33
* xref:java-aspect-tooling.adoc[Java Tooling for Aspect Models]
4+
* Java Build Tooling
5+
** xref:maven-plugin.adoc[Maven Plugin]

documentation/developer-guide/modules/tooling-guide/pages/java-aspect-tooling.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ To use the generated static meta classes, you need the following additional depe
314314

315315
include::sds-developer-guide:ROOT:partial$sds-aspect-static-meta-model-java-artifact.adoc[]
316316

317+
[[providing-custom-macros-for-code-generation]]
317318
==== Providing Custom Macros for Code Generation
318319

319320
It is possible to change predefined sections of the generated classes by providing custom https://velocity.apache.org/[Velocity] templates; see the https://velocity.apache.org/engine/2.3/user-guide.html[Velocity User Guide] for more information.

documentation/developer-guide/modules/tooling-guide/pages/maven-plugin.adoc

Lines changed: 465 additions & 0 deletions
Large diffs are not rendered by default.

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<module>core/sds-test-aspect-models</module>
6464
<module>core/sds-test-resources</module>
6565
<module>tools/bamm-cli</module>
66+
<module>tools/sds-aspect-model-maven-plugin</module>
6667
<module>sds-sdk-test-report</module>
6768
</modules>
6869

@@ -82,6 +83,10 @@
8283
<jena-version>4.2.0</jena-version>
8384
<jqwik-version>1.2.0</jqwik-version>
8485
<lombok-version>1.18.20</lombok-version>
86+
<maven-plugin-annotations-version>3.5</maven-plugin-annotations-version>
87+
<maven-plugin-depdendencies-version>3.3.9</maven-plugin-depdendencies-version>
88+
<maven-plugin-plugin-version>3.6.4</maven-plugin-plugin-version>
89+
<maven-plugin-testing-harness-version>3.3.0</maven-plugin-testing-harness-version>
8590
<rgxgen-version>1.3</rgxgen-version>
8691
<rhino-version>1.7.10</rhino-version>
8792
<roaster-version>2.23.2.Final</roaster-version>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright (c) 2022 Robert Bosch Manufacturing Solutions GmbH
4+
~
5+
~ See the AUTHORS file(s) distributed with this work for additional
6+
~ information regarding authorship.
7+
~
8+
~ This Source Code Form is subject to the terms of the Mozilla Public
9+
~ License, v. 2.0. If a copy of the MPL was not distributed with this
10+
~ file, You can obtain one at https://mozilla.org/MPL/2.0/.
11+
~
12+
~ SPDX-License-Identifier: MPL-2.0
13+
-->
14+
15+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
16+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
17+
<parent>
18+
<artifactId>sds-sdk-parent</artifactId>
19+
<groupId>io.openmanufacturing</groupId>
20+
<version>DEV-SNAPSHOT</version>
21+
<relativePath>../../pom.xml</relativePath>
22+
</parent>
23+
<modelVersion>4.0.0</modelVersion>
24+
25+
<artifactId>sds-aspect-model-maven-plugin</artifactId>
26+
<packaging>maven-plugin</packaging>
27+
<name>SDS Aspect Model Maven Plugin</name>
28+
29+
<dependencies>
30+
<dependency>
31+
<groupId>org.apache.maven</groupId>
32+
<artifactId>maven-core</artifactId>
33+
<version>${maven-plugin-depdendencies-version}</version>
34+
<scope>provided</scope>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.apache.maven</groupId>
38+
<artifactId>maven-plugin-api</artifactId>
39+
<version>${maven-plugin-depdendencies-version}</version>
40+
<scope>provided</scope>
41+
</dependency>
42+
<dependency>
43+
<groupId>org.apache.maven.plugin-tools</groupId>
44+
<artifactId>maven-plugin-annotations</artifactId>
45+
<version>${maven-plugin-annotations-version}</version>
46+
<scope>provided</scope>
47+
</dependency>
48+
<dependency>
49+
<groupId>org.apache.maven</groupId>
50+
<artifactId>maven-compat</artifactId>
51+
<version>${maven-plugin-depdendencies-version}</version>
52+
<scope>provided</scope>
53+
</dependency>
54+
55+
<dependency>
56+
<groupId>io.openmanufacturing</groupId>
57+
<artifactId>sds-aspect-model-starter</artifactId>
58+
</dependency>
59+
60+
<dependency>
61+
<groupId>org.apache.maven.plugin-testing</groupId>
62+
<artifactId>maven-plugin-testing-harness</artifactId>
63+
<scope>test</scope>
64+
<version>${maven-plugin-testing-harness-version}</version>
65+
</dependency>
66+
<dependency>
67+
<groupId>org.assertj</groupId>
68+
<artifactId>assertj-core</artifactId>
69+
<scope>test</scope>
70+
</dependency>
71+
</dependencies>
72+
73+
<build>
74+
<plugins>
75+
<plugin>
76+
<groupId>org.apache.maven.plugins</groupId>
77+
<artifactId>maven-plugin-plugin</artifactId>
78+
<version>${maven-plugin-plugin-version}</version>
79+
<executions>
80+
<execution>
81+
<id>mojo-descriptor</id>
82+
<goals>
83+
<goal>descriptor</goal>
84+
</goals>
85+
</execution>
86+
</executions>
87+
<configuration>
88+
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
89+
</configuration>
90+
</plugin>
91+
</plugins>
92+
</build>
93+
</project>
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright (c) 2022 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 io.openmanufacturing.sds.aspectmodel;
15+
16+
import java.io.File;
17+
import java.io.FileInputStream;
18+
import java.io.FileNotFoundException;
19+
import java.io.FileOutputStream;
20+
import java.io.IOException;
21+
import java.io.InputStream;
22+
import java.io.PrintWriter;
23+
import java.nio.file.Path;
24+
import java.util.HashMap;
25+
import java.util.HashSet;
26+
import java.util.Map;
27+
import java.util.Set;
28+
import java.util.stream.Collectors;
29+
30+
import org.apache.maven.plugin.AbstractMojo;
31+
import org.apache.maven.plugin.MojoExecutionException;
32+
import org.apache.maven.plugins.annotations.Parameter;
33+
34+
import io.openmanufacturing.sds.aspectmodel.resolver.AspectModelResolver;
35+
import io.openmanufacturing.sds.aspectmodel.resolver.FileSystemStrategy;
36+
import io.openmanufacturing.sds.aspectmodel.resolver.ModelResolutionException;
37+
import io.openmanufacturing.sds.aspectmodel.resolver.services.SdsAspectMetaModelResourceResolver;
38+
import io.openmanufacturing.sds.aspectmodel.resolver.services.TurtleLoader;
39+
import io.openmanufacturing.sds.aspectmodel.resolver.services.VersionedModel;
40+
import io.openmanufacturing.sds.aspectmodel.urn.AspectModelUrn;
41+
import io.openmanufacturing.sds.aspectmodel.validation.report.ValidationReport;
42+
import io.openmanufacturing.sds.aspectmodel.validation.services.AspectModelValidator;
43+
import io.vavr.control.Try;
44+
45+
public abstract class AspectModelMojo extends AbstractMojo {
46+
47+
@Parameter( defaultValue = "${basedir}/src/main/resources/aspects" )
48+
private String modelsRootDirectory = System.getProperty("user.dir") + "/src/main/resources/aspects";
49+
50+
@Parameter( required = true, property = "include" )
51+
private Set<String> includes;
52+
53+
@Parameter
54+
protected String outputDirectory = "";
55+
56+
protected void validateParameters() throws MojoExecutionException {
57+
if ( includes == null || includes.isEmpty() ) {
58+
throw new MojoExecutionException( "Missing configuration. Please provide Aspect Models to be included." );
59+
}
60+
}
61+
62+
protected Set<Try<VersionedModel>> loadAndResolveModels() throws MojoExecutionException {
63+
final Path modelsRoot = Path.of( modelsRootDirectory );
64+
return includes.stream().map( AspectModelUrn::fromUrn )
65+
.map( urn -> new AspectModelResolver().resolveAspectModel( new FileSystemStrategy( modelsRoot ), urn ) )
66+
.collect( Collectors.toSet() );
67+
}
68+
69+
protected Set<VersionedModel> loadModelsOrFail() throws MojoExecutionException {
70+
final Set<VersionedModel> versionedModels = new HashSet<>();
71+
final Set<Try<VersionedModel>> resolvedModels = loadAndResolveModels();
72+
for ( final Try<VersionedModel> versionedModel : resolvedModels ) {
73+
if ( versionedModel.isSuccess() ) {
74+
versionedModels.add( versionedModel.get() );
75+
continue;
76+
}
77+
handleFailedModelResolution( versionedModel );
78+
}
79+
return versionedModels;
80+
}
81+
82+
private void handleFailedModelResolution( final Try<VersionedModel> failedModel ) throws MojoExecutionException {
83+
final Throwable loadModelFailureCause = failedModel.getCause();
84+
85+
// Model can not be loaded, root cause e.g. File not found
86+
if ( loadModelFailureCause instanceof IllegalArgumentException ) {
87+
throw new MojoExecutionException( "Can not open file in models root directory.", loadModelFailureCause );
88+
}
89+
90+
if ( loadModelFailureCause instanceof ModelResolutionException ) {
91+
throw new MojoExecutionException( "Could not resolve all model elements", loadModelFailureCause );
92+
}
93+
94+
// Another exception, e.g. syntax error. Let the validator handle this
95+
final AspectModelValidator validator = new AspectModelValidator();
96+
final ValidationReport report = validator.validate( failedModel );
97+
throw new MojoExecutionException( report.toString(), loadModelFailureCause );
98+
}
99+
100+
protected Map<AspectModelUrn,VersionedModel> loadButNotResolveModels() throws MojoExecutionException {
101+
final Map<AspectModelUrn,VersionedModel> versionedModels = new HashMap<>();
102+
for ( final String urn : includes ) {
103+
final AspectModelUrn aspectModelUrn = AspectModelUrn.fromUrn( urn );
104+
final String aspectModelFilePath = String.format( "%s/%s/%s/%s.ttl", modelsRootDirectory, aspectModelUrn.getNamespace(), aspectModelUrn.getVersion(),
105+
aspectModelUrn.getName() );
106+
107+
final File inputFile = new File( aspectModelFilePath ).getAbsoluteFile();
108+
try ( final InputStream inputStream = new FileInputStream( inputFile ) ) {
109+
final SdsAspectMetaModelResourceResolver metaModelResourceResolver = new SdsAspectMetaModelResourceResolver();
110+
final Try<VersionedModel> versionedModel = TurtleLoader.loadTurtle( inputStream )
111+
.flatMap( model -> metaModelResourceResolver.getBammVersion( model )
112+
.flatMap( metaModelVersion -> metaModelResourceResolver.mergeMetaModelIntoRawModel( model, metaModelVersion ) ) );
113+
if ( versionedModel.isFailure() ) {
114+
final String errorMessage = String.format( "Failed to load Aspect Model %s.", aspectModelUrn.getName() );
115+
throw new MojoExecutionException( errorMessage, versionedModel.getCause() );
116+
}
117+
versionedModels.put( aspectModelUrn, versionedModel.get() );
118+
} catch ( final IOException exception ) {
119+
final String errorMessage = String.format( "Failed to load Aspect Model %s.", aspectModelUrn.getName() );
120+
throw new MojoExecutionException( errorMessage, exception );
121+
}
122+
}
123+
return versionedModels;
124+
}
125+
126+
protected FileOutputStream getStreamForFile( final String artifactName, final String outputDirectory ) {
127+
try {
128+
final File directory = new File( outputDirectory );
129+
directory.mkdirs();
130+
final File file = new File( directory.getPath() + File.separator + artifactName );
131+
return new FileOutputStream( file );
132+
} catch ( final FileNotFoundException exception ) {
133+
throw new RuntimeException( "Output file for Aspect Model documentation generation not found.", exception );
134+
}
135+
}
136+
137+
protected PrintWriter initializePrintWriter( final AspectModelUrn aspectModelUrn ) {
138+
final String aspectModelFileName = String.format( "%s.ttl", aspectModelUrn.getName() );
139+
final FileOutputStream streamForFile = getStreamForFile( aspectModelFileName, outputDirectory );
140+
return new PrintWriter( streamForFile );
141+
}
142+
143+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2022 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 io.openmanufacturing.sds.aspectmodel;
15+
16+
import java.io.File;
17+
import java.io.OutputStream;
18+
import java.util.function.Function;
19+
20+
import org.apache.maven.plugin.MojoExecutionException;
21+
import org.apache.maven.plugins.annotations.Parameter;
22+
23+
import io.openmanufacturing.sds.aspectmodel.java.QualifiedName;
24+
25+
public abstract class CodeGenerationMojo extends AspectModelMojo {
26+
27+
@Parameter
28+
protected String packageName = "";
29+
30+
@Parameter
31+
protected String templateFile = "";
32+
33+
@Parameter( defaultValue = "false" )
34+
protected boolean executeLibraryMacros;
35+
36+
protected void validateParameters( final File templateLibFile ) throws MojoExecutionException {
37+
if ( executeLibraryMacros && !templateLibFile.exists() ) {
38+
throw new MojoExecutionException( "Missing configuration. Valid path to velocity template library file must be provided." );
39+
}
40+
super.validateParameters();
41+
}
42+
43+
protected final Function<QualifiedName, OutputStream> nameMapper = artifact -> {
44+
final String path = artifact.getPackageName();
45+
final String fileName = artifact.getClassName();
46+
final String outputDirectoryForArtefact = outputDirectory + File.separator + path.replace( '.', File.separatorChar );
47+
final String artefactName = fileName + ".java";
48+
return getStreamForFile( artefactName, outputDirectoryForArtefact );
49+
};
50+
51+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2022 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 io.openmanufacturing.sds.aspectmodel;
15+
16+
import java.io.IOException;
17+
import java.util.Set;
18+
import java.util.stream.Collectors;
19+
20+
import org.apache.maven.plugin.MojoExecutionException;
21+
import org.apache.maven.plugins.annotations.LifecyclePhase;
22+
import org.apache.maven.plugins.annotations.Mojo;
23+
import org.apache.maven.plugins.annotations.Parameter;
24+
import org.slf4j.Logger;
25+
import org.slf4j.LoggerFactory;
26+
27+
import io.openmanufacturing.sds.aspectmodel.generator.diagram.AspectModelDiagramGenerator;
28+
import io.openmanufacturing.sds.aspectmodel.resolver.services.VersionedModel;
29+
30+
@Mojo( name = "generateDiagram", defaultPhase = LifecyclePhase.GENERATE_RESOURCES )
31+
public class GenerateDiagram extends AspectModelMojo {
32+
33+
private final Logger logger = LoggerFactory.getLogger( GenerateDiagram.class );
34+
35+
@Parameter( required = true, property = "targetFormat" )
36+
private Set<String> targetFormats;
37+
38+
@Override
39+
public void execute() throws MojoExecutionException {
40+
validateParameters();
41+
42+
final Set<VersionedModel> aspectModels = loadModelsOrFail();
43+
try {
44+
final Set<AspectModelDiagramGenerator.Format> formats = targetFormats.stream()
45+
.map( targetFormat -> AspectModelDiagramGenerator.Format.valueOf( targetFormat.toUpperCase() ) )
46+
.collect( Collectors.toSet() );
47+
48+
for ( final VersionedModel aspectModel : aspectModels ) {
49+
final AspectModelDiagramGenerator generator = new AspectModelDiagramGenerator( aspectModel );
50+
generator.generateDiagrams( formats, name -> getStreamForFile( name, outputDirectory ) );
51+
}
52+
} catch ( final IOException exception ) {
53+
throw new MojoExecutionException( "Could not generate diagram.", exception );
54+
} catch ( final IllegalArgumentException exception ) {
55+
throw new MojoExecutionException( "Invalid target format provided. Possible formats are dot, svg & png.", exception );
56+
}
57+
logger.info( "Successfully generated Aspect Model diagram(s)." );
58+
}
59+
60+
@Override
61+
protected void validateParameters() throws MojoExecutionException {
62+
if ( targetFormats == null || targetFormats.isEmpty() ) {
63+
throw new MojoExecutionException( "Please provide target formats." );
64+
}
65+
super.validateParameters();
66+
}
67+
}

0 commit comments

Comments
 (0)