Generating Documentation for Aspect Models
Different types of artifacts can be generated from an Aspect model. All corresponding generators are included in the following dependency:
- Maven
-
<dependency> <groupId>org.eclipse.esmf</groupId> <artifactId>esmf-aspect-model-document-generators</artifactId> <version>2.12.0</version> </dependency> - Gradle Groovy DSL
-
implementation 'org.eclipse.esmf:esmf-aspect-model-document-generators:2.12.0' - Gradle Kotlin DSL
-
implementation("org.eclipse.esmf:esmf-aspect-model-document-generators:2.12.0")
The documentation generation APIs provide methods that take as an argument a Function<String, java.io.OutputStream>.
This is a mapping function that takes a file name as an input (which is determined by the respective generator) and
returns a corresponding OutputStream, for example (but not necessarily) a FileOutputStream. By providing this
function when calling the generator method, you can control where the output is written to, even when the generator
creates multiple files. For the code examples in the following subsections, we assume that the following method is
defined for calling the generators:
OutputStream outputStreamForName( final String aspectFileName ) {
// Create an OutputStream for the file name, e.g. a FileOutputStream
}
Generating SVG or PNG Diagrams
Using the AspectModelDiagramGenerator, automatically layouted diagrams can be created for Aspect models in
the formats PNG and SVG.
Show used imports
import org.eclipse.esmf.aspectmodel.generator.diagram.AspectModelDiagramGenerator;
import org.eclipse.esmf.aspectmodel.generator.diagram.DiagramGenerationConfig;
import org.eclipse.esmf.aspectmodel.generator.diagram.DiagramGenerationConfigBuilder;
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
import org.eclipse.esmf.metamodel.AspectModel;
// AspectModel as returned by the AspectModelLoader
final AspectModel aspectModel = // ...
final DiagramGenerationConfig config = DiagramGenerationConfigBuilder.builder()
.format( DiagramGenerationConfig.Format.SVG )
.language( Locale.ENGLISH )
.build();
new AspectModelDiagramGenerator( aspectModel.aspect(), config ) (1)
.generate( this::outputStreamForName ); (2)
| 1 | The diagram generator is initialized with the loaded model and the generation configuration. |
| 2 | The generation takes the output stream for the output file name as input and writes the generated diagram to the output stream. |
Generating HTML Documentation
A HTML reference documentation for an Aspect model can be generated as shown in the following code sample. The documentation contains an overview diagram and describes the model elements as specified in the Aspect model. Preferred names and descriptions in the respective language from the Aspect model are shown in the resulting document as part of each model element.
Show used imports
import org.eclipse.esmf.aspectmodel.generator.docu.AspectModelDocumentationGenerator;
import org.eclipse.esmf.aspectmodel.generator.docu.DocumentationGenerationConfig;
import org.eclipse.esmf.aspectmodel.generator.docu.DocumentationGenerationConfigBuilder;
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
import org.eclipse.esmf.metamodel.AspectModel;
// AspectModel as returned by the AspectModelLoader
final AspectModel aspectModel = // ...
final DocumentationGenerationConfig config = DocumentationGenerationConfigBuilder.builder() (1)
/* .stylesheet( customCss ) if required */
.build();
final AspectModelDocumentationGenerator generator = (2)
new AspectModelDocumentationGenerator( aspectModel.aspect(), config );
generator.generate( this::outputStreamForName );
| 1 | HTML generation can be controlled via options. |
| 2 | The HTML generator is initialized with the context consisting of the loaded RDF model and the selected Aspect. |
Generating Sample JSON Payload
The sample JSON payload generator is used to create a valid JSON payload for an Aspect model as it could be returned by an Aspect that implements that Aspect model. This follows the mapping rules as defined in the Meta Model specification. The generator uses `samm:exampleValue`s of Properties if present, otherwise random values corresponding to the respective data types are generated.
Show used imports
import org.eclipse.esmf.aspectmodel.generator.json.AspectModelJsonPayloadGenerator;
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
import org.eclipse.esmf.metamodel.AspectModel;
// AspectModel as returned by the AspectModelLoader
final AspectModel aspectModel = // ...
final AspectModelJsonPayloadGenerator generator = new AspectModelJsonPayloadGenerator( aspectModel.aspect() );
// Variant 1: Direct generation into a String
final String jsonString = generator.generateJson();
// Variant 2: Generate using mapping function
generator.generate( this::outputStreamForName );
Generating JSON Schema
The JSON schema generator creates a JSON Schema that describes the payload for an Aspect model as it could be returned by an Aspect that implements that Aspect model.
Show used imports
import org.eclipse.esmf.aspectmodel.generator.jsonschema.AspectModelJsonSchemaGenerator;
import org.eclipse.esmf.aspectmodel.generator.jsonschema.JsonSchemaGenerationConfig;
import org.eclipse.esmf.aspectmodel.generator.jsonschema.JsonSchemaGenerationConfigBuilder;
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
import org.eclipse.esmf.metamodel.AspectModel;
import java.util.Locale;
import com.fasterxml.jackson.databind.JsonNode;
// AspectModel as returned by the AspectModelLoader
final AspectModel aspectModel = // ...
final JsonSchemaGenerationConfig config = JsonSchemaGenerationConfigBuilder.builder()
.locale( Locale.ENGLISH )
.build();
final AspectModelJsonSchemaGenerator generator = new AspectModelJsonSchemaGenerator( aspectModel.aspect(), config );
// Get result as type-safe JSON object
final JsonNode jsonNode = generator.getContent();
// Or as pretty-printed JSON String:
final String json = generator.generateJson();
Generating OpenAPI Specification
The OpenAPI specification generator creates either a JSON Schema or a Yaml Spec that specifies an Aspect regarding to the OpenApi specification. The currently used versions corresponds Draft 4 of the JSON Schema specification, and 3.0.1.
Show used imports
import org.eclipse.esmf.aspectmodel.generator.openapi.AspectModelOpenApiGenerator;
import org.eclipse.esmf.aspectmodel.generator.openapi.OpenApiSchemaGenerationConfig;
import org.eclipse.esmf.aspectmodel.generator.openapi.OpenApiSchemaGenerationConfigBuilder;
import org.eclipse.esmf.aspectmodel.generator.openapi.PagingOption;
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
import org.eclipse.esmf.metamodel.AspectModel;
import com.fasterxml.jackson.databind.JsonNode;
// AspectModel as returned by the AspectModelLoader
final AspectModel aspectModel = // ...
final OpenApiSchemaGenerationConfig config = OpenApiSchemaGenerationConfigBuilder.builder()
// Server URL
.baseUrl( "http://www.example.com" )
// The resource path which shall be added
.resourcePath( "/testPath/{parameter}" )
// Determines whether semantic versioning should be used for the API
// i.e., true = v1.2.3, false = v1
.useSemanticVersion( false )
// A String containing all the information for dynamic properties mentioned in the resource path.
// The string must be syntactically valid YAML.
.properties( readYaml( """
parameter:
name: parameter
in: path
description: "A parameter."
required: true
schema:
type: string
""" ) )
// Should the query API be added to the generated specification?
.includeQueryApi( true )
// The paging Option to be chosen. In case paging is possible:
// The default for a time related collection is time-based paging.
// Otherwise the default is offset-based paging.
.pagingOption( PagingOption.OFFSET_BASED_PAGING )
.build();
// Generate pretty-printed YAML
final AspectModelOpenApiGenerator generator = new AspectModelOpenApiGenerator( aspectModel.aspect(), config );
final String yaml = generator.generateYaml();
// AspectModel as returned by the AspectModelLoader
final AspectModel aspectModel = // ...
final OpenApiSchemaGenerationConfig config = OpenApiSchemaGenerationConfigBuilder.builder()
// Server URL
.baseUrl( "http://www.example.com" )
// The resource path which shall be added
.resourcePath( "/testPath/{parameter}" )
// Determines whether semantic versioning should be used for the API
// i.e., true = v1.2.3, false = v1
.useSemanticVersion( false )
// A JsonNode containing all the information for variable properties mentioned
// in the resource path .
.properties( readYaml( """
{
"test-Id": {
"name": "test-Id",
"in": "path",
"description": "The ID of the unit.",
"required": true,
"schema": {
"type": "string"
}
}
}
""" ) )
// Should the query API be added to the generated specification?
.includeQueryApi( true )
// The paging Option to be chosen. In case paging is possible:
// The default for a time related collection is time-based paging.
// Otherwise the default is offset-based paging.
.pagingOption( PagingOption.OFFSET_BASED_PAGING )
.build();
// Generate the JSON
final AspectModelOpenApiGenerator generator = new AspectModelOpenApiGenerator( aspectModel.aspect(), config );
// Get result as type-safe JSON object
final JsonNode jsonNode = generator.getContent();
// Or as pretty-printed JSON String:
final String json = generator.generateJson();
| For Enumerations with complex data types, the values are modelled as instances of the Entity defined as the Enumeration’s data type (see Declaring Enumerations for more information). In case the Entity instances contain Properties with a sorted collection as their data type, the order of the values of said collection in the Entity instances is not preserved in the generated OpenAPI specification. Preserving this order in OpenAPI is not possible at this point. |
Generating AsyncAPI Specification
The AsyncAPI specification generator creates either a JSON Schema or a Yaml Spec that specifies an Aspect regarding to the AsyncApi specification. The currently used versions correspond to Draft 4 of the JSON Schema specification, and 3.0.0 of the AsyncAPI specification.
Show used imports
import org.eclipse.esmf.aspectmodel.generator.asyncapi.AspectModelAsyncApiGenerator;
import org.eclipse.esmf.aspectmodel.generator.asyncapi.AsyncApiSchemaGenerationConfig;
import org.eclipse.esmf.aspectmodel.generator.asyncapi.AsyncApiSchemaGenerationConfigBuilder;
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
import org.eclipse.esmf.metamodel.AspectModel;
import com.fasterxml.jackson.databind.JsonNode;
// AspectModel as returned by the AspectModelLoader
final AspectModel aspectModel = // ...
final AsyncApiSchemaGenerationConfig config = AsyncApiSchemaGenerationConfigBuilder.builder()
// i.e., true = v1.2.3, false = v1
.useSemanticVersion( false )
// Set Application id
.applicationId( "test:serve" )
.channelAddress( "/123-456/789-012/movement/0.0.1/Movement" )
.build();
// Generate pretty-printed YAML
final AspectModelAsyncApiGenerator generator = new AspectModelAsyncApiGenerator( aspectModel.aspect(), config );
final String yaml = generator.generateYaml();
// AspectModel as returned by the AspectModelLoader
final AspectModel aspectModel = // ...
final AsyncApiSchemaGenerationConfig config = AsyncApiSchemaGenerationConfigBuilder.builder()
// i.e., true = v1.2.3, false = v1
.useSemanticVersion( false )
// Set Application id
.applicationId( "test:serve" )
.channelAddress( "/123-456/789-012/movement/0.0.1/Movement" )
.build();
// Generate the JSON
final AspectModelAsyncApiGenerator generator = new AspectModelAsyncApiGenerator( aspectModel.aspect(), config );
// Get result as type-safe JSON object
final JsonNode jsonNode = generator.getContent();
// Or as pretty-printed JSON String:
final String json = generator.generateJson();