Skip to content

Commit

Permalink
Merge branch 'main' into 595-correctly-translate-idta-submodel-templa…
Browse files Browse the repository at this point in the history
…tes-to-samm
  • Loading branch information
Yauhenikapl committed Sep 20, 2024
2 parents c197f16 + 255fe98 commit 3ba23a8
Show file tree
Hide file tree
Showing 10 changed files with 361 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
*
* See the AUTHORS file(s) distributed with this work for additional
* information regarding authorship.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package org.eclipse.esmf.aspectmodel.generator.jsonld;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.function.Function;

import org.eclipse.esmf.aspectmodel.generator.AbstractGenerator;
import org.eclipse.esmf.metamodel.Aspect;

public class AspectModelToJsonLdGenerator extends AbstractGenerator {

private static final String JSON_LD_FORMAT = "JSON-LD";
private final Aspect aspect;

public AspectModelToJsonLdGenerator( final Aspect aspect ) {
this.aspect = aspect;
}

/**
* Generates a JSON-LD representation of the aspect's source model and writes it to an output stream.
*
* <p>This method takes a function (nameMapper) that maps the name of the aspect to an output stream,
* then writes the aspect's source model in JSON-LD format to that stream. The function is expected
* to accept the aspect's name as a parameter and return an appropriate OutputStream where the JSON-LD
* will be written. The OutputStream is closed automatically when the operation is complete.</p>
*
* @param nameMapper a function that maps the aspect name to an OutputStream for writing the JSON-LD.
* @throws IOException if an I/O error occurs while writing to the output stream.
*/
public void generateJsonLd( final Function<String, OutputStream> nameMapper ) throws IOException {
try ( final OutputStream output = nameMapper.apply( aspect.getName() ) ) {
aspect.getSourceFile().sourceModel().write( output, JSON_LD_FORMAT );
}
}

public String generateJsonLd() {
StringWriter stringWriter = new StringWriter();
aspect.getSourceFile().sourceModel().write( stringWriter, JSON_LD_FORMAT );
return stringWriter.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.eclipse.esmf.aspectmodel.generator.jsonld;

import static org.assertj.core.api.Assertions.assertThat;

import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn;
import org.eclipse.esmf.metamodel.Aspect;
import org.eclipse.esmf.test.TestAspect;
import org.eclipse.esmf.test.TestResources;

import org.junit.jupiter.api.Test;

class AspectModelJsonLdGeneratorTest {

@Test
void generateTest() {
final Aspect aspect = TestResources.load( TestAspect.ASPECT_WITH_ENTITY_LIST ).aspect();
final AspectModelToJsonLdGenerator jsonGenerator = new AspectModelToJsonLdGenerator( aspect );
final String generatedJsonLd = jsonGenerator.generateJsonLd();

assertJsonLdMeta( generatedJsonLd, aspect.urn() );
}

private void assertJsonLdMeta( final String generatedJsonLd, final AspectModelUrn aspectModelUrn ) {
final String context = """
"@context": {
"xsd": "http://www.w3.org/2001/XMLSchema#",
"samm-c": "urn:samm:org.eclipse.esmf.samm:characteristic:2.1.0#",
"samm": "urn:samm:org.eclipse.esmf.samm:meta-model:2.1.0#",
"@vocab": "urn:samm:org.eclipse.esmf.test:1.0.0#"
}
""";

assertThat( generatedJsonLd ).contains( "\"@graph\": [" );
assertThat( generatedJsonLd ).contains( context );
assertThat( generatedJsonLd ).contains( "\"xsd\": \"http://www.w3.org/2001/XMLSchema#\"," );
assertThat( generatedJsonLd ).contains( String.format( "\"@id\": \"%s\"", aspectModelUrn.toString() ) );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,50 @@ Configuration Properties:
| `outputDirectory` | The path to the directory where the generated JSON payload will be written to. | `String` | none | {ok}
|===

=== Generating JSON-LD representation of an Aspect Model

The `generateJsonLd` goal generates a JSON-LD represention of a given Aspect Model. The default life cycle phase for the goal is `generate-resources`.

Usage:

[source,xml,subs=attributes+]
----
<build>
<plugins>
<plugin>
<artifactId>esmf-aspect-model-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-jsonld</id>
<goals>
<goal>generateJsonLd</goal>
</goals>
</execution>
</executions>
<configuration>
<modelsRootDirectory>$\{path-to-models-root}</modelsRootDirectory>
<includes>
<include>$\{urn-of-aspect-model-to-be-included}</include>
</includes>
<outputDirectory>$\{directory-for-generated-source-files}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
----

Configuration Properties:

[width="100%", options="header", cols="20,50,10,10,10"]
|===
| Property | Description | Type | Default Value | Required
| `detailedValidationMessages` | Detailed validation messages if the model can not be loaded | `Boolean` | `false` | {nok}
| `modelsRootDirectory` | The path to the root directory containing the Aspect Model file(s). | `String` | `$\{basedir}/src/main/resources/aspects` | {nok}
| `includes` | A list of Aspect Model URNs identifying the Aspect Models to be included in the plugin execution. | `String` | none | {ok}
| `outputDirectory` | The path to the directory where the generated JSON-LD will be written to. | `String` | none | {ok}
|===


== Pretty Print

The `prettyPrint` goal formats the given Aspect Model. The formatted file is written to the location
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ The available options and their meaning can also be seen in the help text of the
.3+| [[aspect-to-json]] aspect <model> to json | Generate example JSON payload data for an Aspect Model | `samm aspect AspectModel.ttl to json`
| _--output, -o_ : output file path (default: stdout) |
| _--custom-resolver_ : use an external resolver for the resolution of the model elements |
.3+| [[aspect-to-jsonld]] aspect <model> to jsonld | Generate JSON-LD representation of an Aspect Model | `samm aspect AspectModel.ttl to jsonld`
| _--output, -o_ : output file path (default: stdout) |
| _--custom-resolver_ : use an external resolver for the resolution of the model elements |
.4+| [[aspect-to-schema]] aspect <model> to schema | Generate JSON schema for an Aspect Model | `samm aspect AspectModel.ttl to schema`
| _--output, -o_ : output file path (default: stdout) |
| _--language, -l_ : The language from the model for which a JSON schema should be
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
*
* See the AUTHORS file(s) distributed with this work for additional
* information regarding authorship.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package org.eclipse.esmf.aspectmodel;

import java.io.IOException;
import java.util.Set;

import org.eclipse.esmf.aspectmodel.generator.jsonld.AspectModelToJsonLdGenerator;
import org.eclipse.esmf.metamodel.Aspect;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Mojo( name = "generateJsonLd", defaultPhase = LifecyclePhase.GENERATE_RESOURCES )
public class GenerateJsonLd extends AspectModelMojo {
private static final Logger LOG = LoggerFactory.getLogger( GenerateJsonLd.class );

@Override
public void executeGeneration() throws MojoExecutionException, MojoFailureException {
validateParameters();

final Set<Aspect> aspects = loadAspects();
try {
for ( final Aspect context : aspects ) {
final AspectModelToJsonLdGenerator generator = new AspectModelToJsonLdGenerator( context );
generator.generateJsonLd( name -> getOutputStreamForFile( name + ".jsonld", outputDirectory ) );
}
} catch ( final IOException exception ) {
throw new MojoExecutionException( "Could not generate JSON-LD.", exception );
}
LOG.info( "Successfully generated JSON-LD for Aspect Models." );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
*
* See the AUTHORS file(s) distributed with this work for additional
* information regarding authorship.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package org.eclipse.esmf.aspectmodel;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;

import java.io.File;

import org.apache.maven.plugin.Mojo;
import org.junit.Test;

public class GenerateJsonLdTest extends AspectModelMojoTest {

@Test
public void testGenerateJsonLdValidAspectModel() throws Exception {
final File testPom = getTestFile( "src/test/resources/generate-jsonld-spec-json-pom-to-file.xml" );
final Mojo generateJsonLd = lookupMojo( "generateJsonLd", testPom );
assertThatCode( generateJsonLd::execute ).doesNotThrowAnyException();
assertThat( generatedFilePath( "AspectWithEvent.jsonld" ) ).exists();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
~
~ See the AUTHORS file(s) distributed with this work for additional
~ information regarding authorship.
~
~ This Source Code Form is subject to the terms of the Mozilla Public
~ License, v. 2.0. If a copy of the MPL was not distributed with this
~ file, You can obtain one at https://mozilla.org/MPL/2.0/.
~
~ SPDX-License-Identifier: MPL-2.0
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.eclipse.esmf</groupId>
<artifactId>test-generate-jsonld-spec-mojo</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>Test Generate JSON-LD Spec Mojo</name>

<build>
<plugins>
<plugin>
<artifactId>esmf-aspect-model-maven-plugin</artifactId>
<configuration>
<modelsRootDirectory>${basedir}/../../core/esmf-test-aspect-models/src/main/resources/valid</modelsRootDirectory>
<includes>
<include>urn:samm:org.eclipse.esmf.test:1.0.0#AspectWithEvent</include>
</includes>
<outputDirectory>${basedir}/target/test-artifacts</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.eclipse.esmf.aspect.to.AspectToHtmlCommand;
import org.eclipse.esmf.aspect.to.AspectToJavaCommand;
import org.eclipse.esmf.aspect.to.AspectToJsonCommand;
import org.eclipse.esmf.aspect.to.AspectToJsonLdCommand;
import org.eclipse.esmf.aspect.to.AspectToJsonSchemaCommand;
import org.eclipse.esmf.aspect.to.AspectToOpenapiCommand;
import org.eclipse.esmf.aspect.to.AspectToPngCommand;
Expand All @@ -36,6 +37,7 @@
AspectToHtmlCommand.class,
AspectToJavaCommand.class,
AspectToJsonCommand.class,
AspectToJsonLdCommand.class,
AspectToOpenapiCommand.class,
AspectToAsyncapiCommand.class,
AspectToPngCommand.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
*
* See the AUTHORS file(s) distributed with this work for additional
* information regarding authorship.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package org.eclipse.esmf.aspect.to;

import java.io.IOException;

import org.eclipse.esmf.AbstractCommand;
import org.eclipse.esmf.LoggingMixin;
import org.eclipse.esmf.ResolverConfigurationMixin;
import org.eclipse.esmf.aspect.AspectToCommand;
import org.eclipse.esmf.aspectmodel.generator.jsonld.AspectModelToJsonLdGenerator;
import org.eclipse.esmf.exception.CommandException;

import picocli.CommandLine;

@CommandLine.Command( name = AspectToJsonLdCommand.COMMAND_NAME,
description = "Generate JSON-LD representation of an Aspect Model",
descriptionHeading = "%n@|bold Description|@:%n%n",
parameterListHeading = "%n@|bold Parameters|@:%n",
optionListHeading = "%n@|bold Options|@:%n"
)
public class AspectToJsonLdCommand extends AbstractCommand {
public static final String COMMAND_NAME = "jsonld";

@CommandLine.Option( names = { "--output", "-o" }, description = "Output file path" )
private String outputFilePath = "-";

@CommandLine.ParentCommand
private AspectToCommand parentCommand;

@CommandLine.Mixin
private LoggingMixin loggingMixin;

@CommandLine.Mixin
private ResolverConfigurationMixin resolverConfiguration;

@Override
public void run() {
final AspectModelToJsonLdGenerator generator = new AspectModelToJsonLdGenerator(
loadAspectOrFail( parentCommand.parentCommand.getInput(), resolverConfiguration ) );
try {
// we intentionally override the name of the generated artifact here to the name explicitly desired by the user (outputFilePath),
// as opposed to what the model thinks it should be called (name)
generator.generateJsonLd( name -> getStreamForFile( outputFilePath ) );
} catch ( final IOException e ) {
throw new CommandException( e );
}
}
}
Loading

0 comments on commit 3ba23a8

Please sign in to comment.