Skip to main content

Working with RDF, SHACL, and SPARQL Inside the Codebase

Apache Jena

The backend uses Apache Jena 5.x end-to-end. The relevant entry points are:

  • org.apache.jena.rdf.model.Model — the high-level RDF API. Used in services for read-side work.
  • org.apache.jena.graph.Graph — the low-level triple-set API. Used in database/, rdf/, and the in-memory adapter where performance matters.
  • org.apache.jena.query.QueryFactory / UpdateAction — for SPARQL.
  • org.apache.jena.shacl.* — for SHACL evaluation when needed.

The rdf/ package contains the project's own helpers (graph wrappers with version history, RDF formatting that matches ENTSO-E conventions, model merging utilities). Use these instead of Jena's defaults where they exist — they encode CIM-specific output decisions (resource ordering, prefix handling, etc.) that downstream tooling expects.

SHACL generation

SHACL shapes are generated procedurally from CIM model objects. The entry point is services/shacl/SHACLGenerateService (use case: SHACLGenerateUseCase), which delegates to the builders under shacl/property/shapegenerator/ and shacl/property/shapebuilder/. Each property type (attribute, association, enum-typed) has its own builder.

When fixing a SHACL bug, the most useful starting point is SHACLFromCIMGeneratorTest. It loads a known-good CIM graph and asserts the shape of the generated SHACL — adding a failing case there is the quickest way to reproduce.

Diagram layout

Layout positions are persisted as RDF using a small custom vocabulary under dl/rdf/ (Diagram Layout). Layout DTOs live in api/dto/rendering/ with renderer-specific subdirectories (svelteflow/, mermaid/). When changing the layout schema, update both the dl/ model and any code that reads or writes layout data.

Migration scripts

The migration generator stitches together templates from src/main/resources/sparql-templates/migration/. Each template is a parameterised SPARQL UPDATE block — class-renamed.sparql, attribute-renamed.sparql, etc. The composer is in services/schemamigration/. Adding a new migration capability means: (1) adding the template, (2) wiring it into the composer, and (3) extending the wizard's confirmation step DTOs and UI.