Skip to content

Profiles & platforms (.profil)

This page explains how platform profiles are modeled in .profil files and how they interact with the canonical model (.cmn).

A platform profile typically defines:

  • stereotypes – reusable annotations for model elements
  • strategies – logic to compute derived property values
  • outlets – where generated artifacts are written
  • cartridges – groups of generators for a specific concern
  • settings – wiring for dependency injection / implementation classes
  • platforms – how cartridges, properties and conventions are combined

Platforms are packaged as normal Maven artifacts that also contain the Java/Xtend implementations of cartridges, strategies and settings, and often additional CMN base models (for example base types and resource method types).


1. Profile file structure

A .profil file is organised similarly to a CMN file:

  • a package declaration at the top
  • then groups of definitions: stereotypes, strategies, outlets, cartridges, settings and platforms

Example (simplified):

text
package org.joinedworkz.facilities.common.profiles.base

/* stereotypes */
stereotype entity applicable for complextype not propagated by specialization

/* outlets */
abstract outlet StandardOutput { ... }
outlet generatedOpenApi   specialization of StandardOutput { ... }

/* cartridges */
cartridge OpenApiCartridge implementation="org.joinedworkz.common.OpenApiCartridge"
                            outlets=generatedOpenApi

/* settings */
setting CommonSetting implementation="org.joinedworkz.common.CommonSetting"

/* platforms */
platform Base setting=CommonSetting {
    apply cartridge OpenApiCartridge
    // property contributions ...
}

Concrete CMN models select a platform via the platform header, for example platform Base (see Model file structure).


2. Stereotypes

Stereotypes are reusable annotations you can attach to model elements in .cmn files. They:

  • have a name
  • declare for which model element types they are applicable
  • can have specialisation relationships
  • can define how they are propagated

2.1 Declaring stereotypes

In a profile, stereotypes are declared like this (Base platform examples):

text
stereotype entity applicable for complextype not propagated by specialization
stereotype aggregate applicable for complextype not propagated by specialization
stereotype key     applicable for field       propagated by specialization, including
stereotype controller applicable for service

Key aspects:

  • applicable for restricts where the stereotype can be used (e.g. simpletype, complextype, field, service, operation, component, …).
  • specialization of expresses inheritance between stereotypes, for example integer and long specialising number.
  • propagated by ... controls how stereotypes propagate:
    • specialization – along type inheritance
    • referencing – when something references another element
    • including – when elements are included/embedded
  • not propagated by ... can be used to explicitly stop propagation, e.g. for entity so that subtypes are not automatically entities.

2.2 Using stereotypes in CMN

In CMN models, stereotypes are applied by putting their names in angle brackets in front of an element. For example (simplified):

text
stereotype entity applicable for complextype

type<entity> Customer {
    id: Id
    name: String
}

Here:

  • Customer is a complex type with the entity stereotype.
  • id is a field with the key stereotype.
  • Platforms can use this information to decide how to treat the type (e.g. as a persisted entity, as a logical entity, etc.).

3. Outlets

Outlets define where generated files are written and how generation treats those directories.

The Base profile defines an abstract outlet and several concrete ones, for example:

text
abstract outlet StandardOutput
    createNotExistingDirectory = true
    overwriteExistingFiles     = true
    markAsDerived              = true
    deleteFilesOnCleanBuild    = true
    cleanWholdDirectoryOnCleanBuild = false
    keepLocalHistory           = true

outlet generatedDiagram  specialization of StandardOutput
    directory = "./diagram"

outlet generatedSchema   specialization of StandardOutput
    directory = "./target/joinedworkz/schema"

outlet generatedOpenApi  specialization of StandardOutput
    directory = "./src/generated/resources/openapi"

outlet generatedOpenApiHtml specialization of StandardOutput
    directory = "./diagram/api"

Cartridges refer to outlets to decide where to write their outputs. The directories can later be overridden at project level via joinedworkz.properties (see Create a project with Maven).


4. Cartridges

A cartridge is a bundle of generators for a specific aspect of a platform. It declares:

  • a name
  • an implementation class
  • the outlets it writes to

Examples from the Base profile:

text
cartridge DiagramCartridge implementation="org.joinedworkz.common.DiagramCartridge"
           outlets=generatedDiagram

cartridge SchemaCartridge implementation="org.joinedworkz.common.SchemaCartridge"
           outlets=generatedSchema

cartridge OpenApiCartridge implementation="org.joinedworkz.common.OpenApiCartridge"
           outlets=generatedOpenApi, generatedOpenApiHtml

Cartridges are not invoked directly from the CMN model. Instead, they are applied by platforms (see next section). A platform can also support disabling a cartridge at model level via the exclude clause in the CMN platform header, e.g.:

text
platform SpringBoot exclude DtoCartridge

This keeps the platform profile generic while allowing per-model control.


5. Settings

A setting connects a platform to its implementation classes, typically via dependency injection.

Example:

text
setting CommonSetting implementation="org.joinedworkz.common.CommonSetting"

The implementation class usually registers cartridges, generators, strategies and other services with a DI container. Derived platforms can override settings or replace specific strategies or generators by wiring different implementations.

Settings are mostly relevant when implementing platforms, not when consuming them in CMN models.


6. Platforms

A platform combines cartridges, property contributions and conventions to define how a canonical model is interpreted for a specific technology stack.

6.1 Base platform example

The Base platform (simplified) looks like this:

text
platform Base setting=CommonSetting {

    /* apply cartridges */
    apply cartridge DiagramCartridge
    apply cartridge SchemaCartridge
    apply cartridge OpenApiCartridge

    contribute to simpletype<string> {
        property minLength: INTEGER
        property maxLength: INTEGER
        property pattern:   STRING
        property javaType:  STRING
        property format:    STRING
    }

    contribute to complextype<entity> {
        property tableName: STRING not propagated by specialization
    }

    contribute to complextype<entity>.field {
        property columnName: STRING
    }
}

Key ideas:

  • setting=CommonSetting links the platform to the DI configuration.
  • apply cartridge ... lists the cartridges that belong to this platform.
  • contribute to ... adds or overrides properties on model elements that have certain stereotypes (e.g. simpletype<string>, complextype<entity>).
  • Properties can also define propagation rules (not propagated by specialization) and, in derived platforms, default values or overrides.

6.2 Platform inheritance

Platforms can inherit from other platforms:

text
platform Java specialization of Base {
    // additional cartridges and contributions
    contribute to simpletype<decimal> {
        override javaType value="java.math.BigDecimal"
    }
}

Inheritance allows you to:

  • reuse common behaviour (e.g. diagram and OpenAPI cartridges from Base),
  • add platform-specific cartridges (e.g. Java or Spring Boot generators),
  • refine property contributions (override or extend properties).

6.3 Binding CMN models to platforms

In CMN files, the header selects the platform, for example:

text
platform Base

or, with cartridge exclusions:

text
platform SpringBoot exclude DtoCartridge

The generator then:

  • loads the selected platform from the available profile modules,
  • applies its cartridges to the model,
  • uses property contributions, stereotypes and strategies defined by the platform to drive generation.

7. Strategies

Strategies are used to compute values for derived or calculated properties during generation.

They are declared in the profile, for example (Java platform):

text
strategy JavaNamingStrategy implementation="org.joinedworkz.common.java.Strategy"
strategy JavaTypeStrategy   implementation="org.joinedworkz.common.java.JavaTypeStrategy"

Strategies are then referenced in property contributions:

text
contribute to field {
    property javaName: STRING strategy=JavaNamingStrategy
}

contribute to type {
    property javaType: STRING strategy=JavaTypeStrategy
}

At generation time, the strategy implementations:

  • receive the relevant model element (field, type, …),
  • compute the property value (e.g. a Java-friendly name or type),
  • write it into the model’s derived properties for further use by generators.

Because strategies are wired via DI, derived platforms can easily swap in alternative implementations if needed.


8. Packaging and reuse

Each platform is typically delivered as a Maven module that contains:

  • one or more .profil files (platform profiles),
  • Java/Xtend implementations of cartridges, generators, strategies, settings and other helpers,
  • optional CMN base models, such as:
    • base type definitions (e.g. String, numeric types),
    • resource method types (create, read, etc.).

You make a platform available to your model module by adding it as a normal Maven dependency. The JoinedWorkz Maven plugin then:

  • loads the platform profiles and implementations from the classpath,
  • uses them when executing the generator for your models.

Platforms provided by JoinedSystems (such as the Base platform) are published to Maven Central and can be used freely. You can also define your own custom platforms and publish them within your organisation.


9. Next steps

From here you can:

  • revisit the Modeling overview with a clearer understanding of how platforms influence generation;
  • read Create a project with Maven to see how platforms are brought into a build via Maven dependencies;
  • explore Modeling with JoinedWorkz Studio to see how platforms, stereotypes and validations are surfaced in the editor;
  • consult the CMN reference for the exact syntax of .profil constructs: stereotypes, strategies, outlets, cartridges, settings and platforms.