Profiles & platforms (.profile)
This page explains how platform profiles are modeled in .profile files and how they interact with the canonical model (.cmn).
Application developers normally consume the profiles delivered by a facility. Defining a custom profile is an advanced, release-bound extension task; use the examples in this page as orientation for JoinedWorkz 1.3.80.
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 .profile 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
Minimal, syntactically complete example:
package com.example.profile
stereotype entity applicable for complextype not propagated by specialization
abstract outlet StandardOutput
createNotExistingDirectory=true
overwriteExistingFiles=true
outlet generatedOpenApi specialization of StandardOutput
directory='./src/generated/resources/openapi'
cartridge OpenApiCartridge
implementation='org.joinedworkz.common.OpenApiCartridge'
outlets=generatedOpenApi
setting CommonSetting
implementation='org.joinedworkz.common.CommonSetting'
platform Base setting=CommonSetting {
apply cartridge OpenApiCartridge
}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):
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 serviceKey aspects:
applicable forrestricts where the stereotype can be used (e.g.simpletype,complextype,field,service,operation,component, …).specialization ofexpresses inheritance between stereotypes, for exampleintegerandlongspecialisingnumber.propagated by ...controls how stereotypes propagate:specialization– along type inheritancereferencing– when something references another elementincluding– when elements are included/embedded
not propagated by ...can be used to explicitly stop propagation, e.g. forentityso that subtypes are not automatically entities.
2.2 Using stereotypes in CMN
In CMN models, stereotypes are applied in angle brackets on the annotated element:
type<entity> Customer {
id**: Id
name*: String
}Here:
Customeris a complex type with theentitystereotype.id**marks the field as a key using CMN shorthand.- 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:
abstract outlet StandardOutput
createNotExistingDirectory = true
overwriteExistingFiles = true
markAsDerived = true
deleteFilesOnCleanBuild = true
cleanWholdDirectoryOnCleanBuild = false
keepLocalHistory = true
outlet generatedDiagram specialization of StandardOutput
directory = "./diagram"
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:
The following declarations are an excerpt that uses the outlets from the previous section:
cartridge DiagramCartridge implementation="org.joinedworkz.common.DiagramCartridge"
outlets=generatedDiagram
cartridge OpenApiCartridge implementation="org.joinedworkz.common.OpenApiCartridge"
outlets=generatedOpenApi, generatedOpenApiHtmlCartridges 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.:
platform SpringBoot exclude DtoCartridgeThis 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:
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 following excerpt from the Base platform shows the platform body. The referenced stereotypes, cartridges, outlets, and setting are declared earlier in the same profile:
platform Base setting=CommonSetting {
/* apply cartridges */
apply cartridge DiagramCartridge
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=CommonSettinglinks 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:
platform Java specialization of Base {
apply cartridge DtoCartridge
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:
platform Baseor, with cartridge exclusions:
platform SpringBoot exclude DtoCartridgeThe 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):
strategy JavaNamingStrategy implementation="org.joinedworkz.common.java.Strategy"
strategy JavaTypeStrategy implementation="org.joinedworkz.common.java.JavaTypeStrategy"Strategies are then referenced in property contributions:
The contributions occur inside a platform declaration:
platform ExampleJava {
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
.profilefiles (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.).
- base type definitions (e.g.
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. A custom platform should live in its own Maven module and be treated as an advanced extension that is tested against the JoinedWorkz release it targets.
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 Profile reference for the release-specific syntax of stereotypes, strategies, outlets, cartridges, settings and platforms.
