Ontology Validation¶
How to validate Linked.Archi ontology files for syntax correctness and SHACL conformance.
Overview¶
The validation script (.scripts/validate.sh) provides two levels of validation:
-
Turtle syntax — parses every
.ttlfile using the RDF4J Rio Turtle parser. Catches malformed IRIs, missing prefixes, unclosed strings, and other syntax errors. -
SHACL conformance — loads ontology data into an RDF4J ShaclSail and validates it against the SHACL shapes. Catches missing required properties, wrong types, cardinality violations, and domain/range constraint violations.
Both levels use Eclipse RDF4J 4.3.14. The SDK is downloaded automatically on first run
(~50MB, cached in .scripts/.lib/).
Prerequisites¶
- Java 17+ (tested with OpenJDK 21)
curlandunzip(for SDK download)
Usage¶
# Syntax-check all .ttl files in the repo
./validate.sh
# Syntax-check a single file
./validate.sh --syntax path/to/file.ttl
# SHACL validate a preset profile
./validate.sh --shacl archimate
./validate.sh --shacl archimate-derived
./validate.sh --shacl archimate-principles
./validate.sh --shacl c4
./validate.sh --shacl backstage
./validate.sh --shacl bpmn
# SHACL validate all presets
./validate.sh --shacl all
# SHACL validate custom data against custom shapes
./validate.sh --shacl mydata.ttl core-shapes.ttl my-shapes.ttl
# Full CI run (syntax + all SHACL profiles)
./validate.sh --ci
Exit Codes¶
| Code | Meaning |
|---|---|
| 0 | All validations passed |
| 1 | One or more validations failed |
| 2 | Usage error (wrong arguments) |
SHACL Validation Architecture¶
Validation uses a two-layer shapes architecture:
flowchart TD
core["core-shapes.ttl<br/>(base contract — applies to all metamodels)"]
MCS["ModelConceptShape:<br/>every ModelConcept must have skos:prefLabel"]
QRS["QualifiedRelationshipShape:<br/>exactly one arch:source + arch:target"]
COS["ConceptOwnerShape:<br/>arch:conceptOwner must be a Stakeholder"]
core --> MCS & QRS & COS
amrel["archimate3.2-relationship-shapes.ttl<br/>11 qualified + 62 unqualified shapes"]
amelem["archimate3.2-element-shapes.ttl<br/>24 shapes: structural integrity, metamodel patterns"]
amprin["archimate3.2-principle-shapes.ttl<br/>20 shapes: governance principles"]
amderiv["archimate3.2-derivation-rules.ttl<br/>SHACL Rules: DR1-DR8 + PDR1-PDR12"]
c4s["c4-shapes.ttl<br/>4 per-relationship-type shapes"]
bss["backstage-shapes.ttl<br/>7 per-relationship-type shapes"]
core -->|"imports"| amrel & amelem & amprin & amderiv & c4s & bss
When you run --shacl archimate, the script loads:
1. core-shapes.ttl into the SHACL shapes graph
2. archimate3.2-relationship-shapes.ttl into the SHACL shapes graph
3. archimate3.2-element-shapes.ttl into the SHACL shapes graph
4. archimate3.2-onto.ttl as data
When you run --shacl archimate-derived, it loads all of the above plus:
5. archimate3.2-derivation-rules.ttl (DR1-DR8, PDR1-PDR12 SHACL Rules)
The ShaclSail validates the data against all loaded shapes on commit. Violations are reported as a SHACL validation report in Turtle format.
SHACL Profiles¶
| Profile | Data File | Shapes |
|---|---|---|
archimate |
archimate3.2-onto.ttl |
core-shapes.ttl + archimate3.2-relationship-shapes.ttl (generated) + archimate3.2-element-shapes.ttl |
archimate-derived |
archimate3.2-onto.ttl |
All archimate shapes + archimate3.2-derivation-rules.ttl (DR1-DR8, PDR1-PDR12) |
archimate-principles |
archimate3.2-onto.ttl |
core-shapes.ttl + archimate3.2-principle-shapes.ttl (20 governance principle shapes) |
c4 |
c4-onto.ttl |
core-shapes.ttl + c4-shapes.ttl |
backstage |
backstage-onto.ttl |
core-shapes.ttl + backstage-shapes.ttl |
bpmn |
linkedarchi-bpmn-onto.ttl |
core-shapes.ttl |
GitLab CI Integration¶
The .gitlab-ci.yml runs validate.sh --ci on every push that changes .ttl files. It uses
a custom Docker image (validator) with Java 21, RDF4J 4.3.14 SDK, and pre-compiled validators
baked in — no download or compilation at runtime.
Building the Validator Image¶
Push to your GitLab container registry:
docker tag linked-archi/validator registry.gitlab.com/<namespace>/linked-archi-meta/validator:latest
docker push registry.gitlab.com/<namespace>/linked-archi-meta/validator:latest
Why --platform linux/amd64: Apple Silicon Macs build ARM images by default. GitLab shared runners are x86_64 and will reject ARM images.
Why --no-cache: Prevents Docker from reusing cached ARM layers when switching platforms.
The image contains:
- Eclipse Temurin JDK 21
- RDF4J 4.3.14 SDK (/opt/rdf4j/lib/)
- Pre-compiled TurtleSyntaxCheck.class and ShaclValidator.class (/opt/rdf4j/build/)
The validate.sh script detects the pre-built paths via RDF4J_LIB and RDF4J_BUILD environment
variables and skips download/compilation entirely. For local development without Docker, the script
falls back to downloading the SDK on first run (cached in .scripts/.lib/).
The CI job:
1. Downloads the RDF4J SDK (cached after first run)
2. Compiles the Java validation tools (cached)
3. Runs syntax validation on all 69+ .ttl files
4. Runs SHACL validation on all 5 profiles
5. Reports pass/fail with proper exit codes
Adding a New SHACL Profile¶
To add validation for a new metamodel:
-
Create a shapes file (e.g.,
my-metamodel-shapes.ttl) that importscore-shapes: -
Add per-relationship-type shapes with domain/range constraints
-
Add a new case to the
run_profile()function invalidate.sh: -
Add the profile name to the
PROFILESvariable
Files¶
| File | Purpose |
|---|---|
.scripts/validate.sh |
Main validation script |
.scripts/TurtleSyntaxCheck.java |
RDF4J-based Turtle parser wrapper |
.scripts/ShaclValidator.java |
RDF4J ShaclSail-based SHACL validator |
.scripts/.lib/ |
Auto-downloaded RDF4J SDK (gitignored) |
.scripts/.build/ |
Compiled Java classes (gitignored) |
.gitlab-ci.yml |
CI pipeline configuration |
core/core-shapes.ttl |
Base SHACL shapes for all metamodels |
modelingLanguages/archimate/archimate3.2-relationship-shapes.ttl |
Generated SHACL shapes for relationship source-target pairs |
modelingLanguages/archimate/archimate3.2-element-shapes.ttl |
SHACL shapes for element/metamodel pattern constraints |
modelingLanguages/archimate/archimate3.2-principle-shapes.ttl |
SHACL shapes for architecture governance principles |
modelingLanguages/archimate/archimate3.2-derivation-rules.ttl |
ArchiMate derivation rules (DR1-DR8, PDR1-PDR12) |
.scripts/generate-archimate-shapes.py |
Generator for relationship shapes from XML matrix |