diff --git a/dev-docs/Includes/CIMToolFeature/CIMToolFeature-README.adoc b/dev-docs/Includes/CIMToolFeature/CIMToolFeature-README.adoc index 0d2ecf3b..dc98159d 100644 --- a/dev-docs/Includes/CIMToolFeature/CIMToolFeature-README.adoc +++ b/dev-docs/Includes/CIMToolFeature/CIMToolFeature-README.adoc @@ -25,7 +25,7 @@ provisioning system. [[status]] -=== Current Status — Legacy / Dormant +=== Current Status: Legacy / Dormant CIMToolFeature is **not actively used** in the current build and packaging workflow. The definitive indicator is the `useFeatures="false"` attribute in @@ -58,9 +58,9 @@ produced by the PDE product export in `CIMToolProduct`. When active, an Eclipse PDE feature serves two purposes: -. *Packaging* — groups a set of plugins into a single installable unit for +. *Packaging*: groups a set of plugins into a single installable unit for deployment via an Eclipse p2 update site -. *Dependency declaration* — declares the minimum plugin versions required for +. *Dependency declaration*: declares the minimum plugin versions required for the feature to function correctly CIMToolFeature (`au.com.langdale.cimtoole.feature`) groups the full set of @@ -136,12 +136,12 @@ following steps would be required: === Relationship to Other Projects -* *CIMToolProduct* — the active replacement for this project's packaging role. +* *CIMToolProduct*: the active replacement for this project's packaging role. `CIMTool.product` with `useFeatures="false"` performs plugin-based packaging directly, making this feature project redundant in the current workflow. * All plugins listed in `feature.xml` (`au.com.langdale.cimtoole`, `au.com.langdale.cimtoole.help`, `au.com.langdale.kena`, `au.com.langdale.rcputil`, `au.com.langdale.cimutil`, - `com.cimphony.cimtoole`) are active projects — only this feature wrapper is + `com.cimphony.cimtoole`) are active projects; only this feature wrapper is dormant. diff --git a/dev-docs/Includes/CIMToolFeature/CIMToolFeature-README.md b/dev-docs/Includes/CIMToolFeature/CIMToolFeature-README.md index 3d0b242b..e403c2c5 100644 --- a/dev-docs/Includes/CIMToolFeature/CIMToolFeature-README.md +++ b/dev-docs/Includes/CIMToolFeature/CIMToolFeature-README.md @@ -12,7 +12,7 @@ provisioning system. -## Current Status — Legacy / Dormant +## Current Status: Legacy / Dormant CIMToolFeature is **not actively used** in the current build and packaging workflow. The definitive indicator is the `useFeatures="false"` attribute in @@ -44,8 +44,8 @@ produced by the PDE product export in `CIMToolProduct`. When active, an Eclipse PDE feature serves two purposes: -1. **Packaging** — groups a set of plugins into a single installable unit for deployment via an Eclipse p2 update site -2. **Dependency declaration** — declares the minimum plugin versions required for the feature to function correctly +1. **Packaging**: groups a set of plugins into a single installable unit for deployment via an Eclipse p2 update site +2. **Dependency declaration**: declares the minimum plugin versions required for the feature to function correctly CIMToolFeature (`au.com.langdale.cimtoole.feature`) groups the full set of in-repository CIMTool plugins plus the license and release note text files that @@ -104,5 +104,5 @@ following steps would be required: ## Relationship to Other Projects -- **CIMToolProduct** — the active replacement for this project's packaging role. `CIMTool.product` with `useFeatures="false"` performs plugin-based packaging directly, making this feature project redundant in the current workflow. -- All plugins listed in `feature.xml` (`au.com.langdale.cimtoole`, `au.com.langdale.cimtoole.help`, `au.com.langdale.kena`, `au.com.langdale.rcputil`, `au.com.langdale.cimutil`, `com.cimphony.cimtoole`) are active projects — only this feature wrapper is dormant. +- **CIMToolProduct**: the active replacement for this project's packaging role. `CIMTool.product` with `useFeatures="false"` performs plugin-based packaging directly, making this feature project redundant in the current workflow. +- All plugins listed in `feature.xml` (`au.com.langdale.cimtoole`, `au.com.langdale.cimtoole.help`, `au.com.langdale.kena`, `au.com.langdale.rcputil`, `au.com.langdale.cimutil`, `com.cimphony.cimtoole`) are active projects, and only this feature wrapper is dormant. diff --git a/dev-docs/Includes/CIMToolHelp/CIMToolHelp-README.adoc b/dev-docs/Includes/CIMToolHelp/CIMToolHelp-README.adoc index 73df3c04..f2f498c1 100644 --- a/dev-docs/Includes/CIMToolHelp/CIMToolHelp-README.adoc +++ b/dev-docs/Includes/CIMToolHelp/CIMToolHelp-README.adoc @@ -25,9 +25,9 @@ that contributes to the `org.eclipse.help.toc` extension point, registering `toc.xml` as the table of contents for the CIMTool help system. All content is static HTML stored in the `html/` directory. -The documentation covers the full range of CIMTool user topics — from getting +The documentation covers the full range of CIMTool user topics, from getting started and importing EA models through to profiling, validation, namespace -management, and OWL/RDF concepts — and is displayed directly within the Eclipse +management, and OWL/RDF concepts, and is displayed directly within the Eclipse Help viewer. @@ -178,7 +178,7 @@ All documentation is hand-authored HTML. To add or update a topic: . Add or edit the HTML file in `html/` . If adding a new topic, add a `` entry to `toc.xml` referencing it via the `PLUGINS_ROOT/au.com.langdale.cimtoole.help/html/.html` path -. Rebuild and re-export the product — no Java compilation is required +. Rebuild and re-export the product, with no Java compilation required NOTE: The `PLUGINS_ROOT/` prefix in `toc.xml` href values is an Eclipse help framework convention that resolves to the installed plugins directory at runtime. diff --git a/dev-docs/Includes/CIMToolHelp/CIMToolHelp-README.md b/dev-docs/Includes/CIMToolHelp/CIMToolHelp-README.md index a6e04701..469aa133 100644 --- a/dev-docs/Includes/CIMToolHelp/CIMToolHelp-README.md +++ b/dev-docs/Includes/CIMToolHelp/CIMToolHelp-README.md @@ -16,9 +16,9 @@ that contributes to the `org.eclipse.help.toc` extension point, registering `toc.xml` as the table of contents for the CIMTool help system. All content is static HTML stored in the `html/` directory. -The documentation covers the full range of CIMTool user topics — from getting +The documentation covers the full range of CIMTool user topics, from getting started and importing EA models through to profiling, validation, namespace -management, and OWL/RDF concepts — and is displayed directly within the Eclipse +management, and OWL/RDF concepts, and is displayed directly within the Eclipse Help viewer. @@ -125,7 +125,7 @@ All documentation is hand-authored HTML. To add or update a topic: 1. Add or edit the HTML file in `html/` 2. If adding a new topic, add a `` entry to `toc.xml` referencing it via the `PLUGINS_ROOT/au.com.langdale.cimtoole.help/html/.html` path -3. Rebuild and re-export the product — no Java compilation is required +3. Rebuild and re-export the product, with no Java compilation required > **Note:** The `PLUGINS_ROOT/` prefix in `toc.xml` href values is an Eclipse > help framework convention that resolves to the installed plugins directory at diff --git a/dev-docs/Includes/CIMToolPlugin/CIMToolPlugin-README.adoc b/dev-docs/Includes/CIMToolPlugin/CIMToolPlugin-README.adoc index 9e1cd79f..f553e4eb 100644 --- a/dev-docs/Includes/CIMToolPlugin/CIMToolPlugin-README.adoc +++ b/dev-docs/Includes/CIMToolPlugin/CIMToolPlugin-README.adoc @@ -10,8 +10,8 @@ :xrefstyle: short The core Eclipse RCP plugin for the CIMTool application. It provides all of the -user-facing Eclipse UI — perspectives, editors, views, wizards, actions, and the -incremental build system — that together constitute the CIMTool workbench +user-facing Eclipse UI, perspectives, editors, views, wizards, actions, and the +incremental build system, that together constitute the CIMTool workbench experience. This is the largest and most central of the in-repository plugins. All user @@ -35,7 +35,7 @@ to provide: * Preference pages for general settings and PlantUML builder configuration * Extension point registries for pluggable model parsers and profile buildlets * Pandoc integration for AsciiDoc report generation -* Unified logging pipeline — installs the JUL-to-SLF4J bridge at startup and +* A unified logging pipeline that installs the JUL-to-SLF4J bridge at startup and extracts `logging.properties` and `logback.xml` so all three logging subsystems (JUL, SLF4J, Log4j 1.x) converge into a single Logback-controlled output in `logs/cimtool.log` @@ -130,7 +130,7 @@ in-repository plugins: | RCPUtil | `au.com.langdale.rcputil` -| Eclipse UI infrastructure — data binding (`UIBinding`), form builder, +| Eclipse UI infrastructure: data binding (`UIBinding`), form builder, JFace plumbing, wizard and editor base classes |=== @@ -141,55 +141,55 @@ It also depends on the following standard Eclipse platform bundles: | Bundle | What it provides | `org.eclipse.ui` -| Core Eclipse workbench UI framework — `IWorkbench`, `IWorkbenchPage`, +| Core Eclipse workbench UI framework: `IWorkbench`, `IWorkbenchPage`, `IWorkbenchPart`, action and command infrastructure | `org.eclipse.core.runtime` -| OSGi runtime utilities — `IProgressMonitor`, `Platform`, `FileLocator`, +| OSGi runtime utilities: `IProgressMonitor`, `Platform`, `FileLocator`, extension registry, `IPath`, `Status` | `org.eclipse.core.resources` -| Eclipse workspace resource model — `IProject`, `IFile`, `IFolder`, +| Eclipse workspace resource model: `IProject`, `IFile`, `IFolder`, `IResource`, resource change listeners, workspace build API | `org.eclipse.ui.ide` -| IDE-specific workbench extensions — `ResourceUtil`, file editor input, +| IDE-specific workbench extensions: `ResourceUtil`, file editor input, IDE markers, open resource dialog | `org.eclipse.jface.text` -| JFace text framework — `IDocument`, `ITextViewer`, source viewer +| JFace text framework: `IDocument`, `ITextViewer`, source viewer infrastructure used by text-based editors | `org.eclipse.ui.editors` -| Standard editor contributions — base classes for text editors, +| Standard editor contributions: base classes for text editors, editor registry, `FileDocumentProvider` | `org.eclipse.ui.views` -| Standard Eclipse view contributions — `IViewPart`, content outline view, +| Standard Eclipse view contributions: `IViewPart`, content outline view, properties view infrastructure | `org.eclipse.ui.forms` -| Eclipse Forms UI toolkit — `FormToolkit`, `ScrolledForm`, `Section`, +| Eclipse Forms UI toolkit: `FormToolkit`, `ScrolledForm`, `Section`, used to build the multi-page profile and model editors | `org.eclipse.compare` -| Eclipse Compare framework — `CompareEditorInput`, structure and content +| Eclipse Compare framework: `CompareEditorInput`, structure and content merge viewer APIs used by the model diff/compare feature | `org.eclipse.ui.themes` -| Eclipse theming and colour/font registry — `IThemeManager`, +| Eclipse theming and colour/font registry: `IThemeManager`, `ColorRegistry`, `FontRegistry` for consistent UI styling | `org.eclipse.core.filesystem` -| Abstraction over file system access — `IFileStore`, `EFS`, +| Abstraction over file system access: `IFileStore`, `EFS`, used for file operations that span local and remote file systems | `net.sourceforge.plantuml.library` -| PlantUML rendering library — generates SVG diagrams from `.puml` source in the +| PlantUML rendering library: generates SVG diagrams from `.puml` source in the Real-Time Preview pipeline. Declared as a hard `Require-Bundle` dependency. | `net.sourceforge.plantuml.eclipse` -| PlantUML Eclipse integration bundle — provides the Eclipse-side PlantUML API. +| PlantUML Eclipse integration bundle: provides the Eclipse-side PlantUML API. Declared as `resolution:=optional` since the feature degrades gracefully when absent. |=== @@ -226,9 +226,9 @@ in `MANIFEST.MF` (not resolved from the target platform): | jul-to-slf4j | 2.0.17 -| JUL-to-SLF4J bridge — `SLF4JBridgeHandler` is installed at startup to redirect +| JUL-to-SLF4J bridge: `SLF4JBridgeHandler` is installed at startup to redirect all `java.util.logging` events into the SLF4J -> Logback pipeline. Wired to the -platform SLF4J 2.x bundle via `Import-Package` — `MANIFEST.MF` declares `org.slf4j`, +platform SLF4J 2.x bundle via `Import-Package`, with `MANIFEST.MF` declaring `org.slf4j`, `org.slf4j.event`, `org.slf4j.helpers`, and `org.slf4j.spi`. |=== @@ -247,12 +247,12 @@ These extension points allow third-party plugins to contribute to CIMTool: | Extension Point | Purpose | `au.com.langdale.cimtoole.model_parser` -| Pluggable model parsers — allows contributors to register parsers for +| Pluggable model parsers: allows contributors to register parsers for additional model file formats beyond the built-in EA/XMI support. Schema: `schema/model_parser.exsd` | `au.com.langdale.cimtoole.profile_buildlet` -| Pluggable profile buildlets — allows contributors to register additional +| Pluggable profile buildlets: allows contributors to register additional transform builders that produce new output artefact types from a CIM profile. Schema: `schema/profile_buildlet.exsd` |=== @@ -284,7 +284,7 @@ CIMToolPlugin contributes to the following Eclipse platform extension points via | `org.eclipse.ui.perspectives` | Registers the CIMTool Perspective, CIMTool Browsing Perspective, and Validation - Perspective — defines the initial layout of views, editors, and toolbars for each + Perspective, defining the initial layout of views, editors, and toolbars for each | `org.eclipse.ui.editors` | Registers multi-page editors for CIM profiles, model artefacts, mappings, @@ -351,12 +351,12 @@ CIMToolPlugin contributes to the following Eclipse platform extension points via -=== Plugin Activator — CIMToolPlugin.java +=== Plugin Activator: CIMToolPlugin.java The bundle activator (`CIMToolPlugin.java`) runs when the plugin is first activated and is responsible for: -. *`configureLogging()`* — First calls `SLF4JBridgeHandler.removeHandlersForRootLogger()` +. *`configureLogging()`*: First calls `SLF4JBridgeHandler.removeHandlersForRootLogger()` to remove any existing JUL handlers from the root logger, preventing duplicate log output. Then installs `SLF4JBridgeHandler` to redirect all JUL events into the SLF4J -> Logback pipeline, giving CIMTool a single unified log output in @@ -370,7 +370,7 @@ activated and is responsible for: `logs/cimtool.log` via the bridge. In development mode the streams are left untouched so output remains visible in the Eclipse Console view. -. *`extractLoggingProperties()`* — On first run, extracts both +. *`extractLoggingProperties()`*: On first run, extracts both `logging.properties` and `logback.xml` from the `au.com.langdale.cimtool.product` plugin bundle to the installation root directory, and creates the `logs/` subdirectory. On subsequent runs both files @@ -378,7 +378,7 @@ activated and is responsible for: `-Djava.util.logging.config.file` and `-Dlogback.configurationFile` JVM arguments set in `CIMTool.ini`. -. *`loadEmbeddedPandocLibraries()`* — On first run, extracts the platform-specific +. *`loadEmbeddedPandocLibraries()`*: On first run, extracts the platform-specific Pandoc binary ZIP from the `native/` directory of this bundle to the Eclipse state location (`~/.cimtool-workspace/.metadata/.plugins/au.com.langdale.cimtoole/native//pandoc/`). On subsequent runs the already-extracted binary is used directly. @@ -406,29 +406,29 @@ redirected through JUL loggers `CIMTool.console.out` (INFO) and `CIMTool.console The `builder/` package implements CIMTool's incremental build system, which integrates with the Eclipse *workspace build* mechanism: -* `CIMBuilder` — the Eclipse `IncrementalProjectBuilder` implementation. +* `CIMBuilder`: the Eclipse `IncrementalProjectBuilder` implementation. Registered via `org.eclipse.core.resources.builders` in `plugin.xml`. Determines which resources have changed and dispatches to the appropriate buildlets. -* `Buildlet` — abstract base class for all build steps. Each buildlet is +* `Buildlet`: abstract base class for all build steps. Each buildlet is responsible for one output artefact type. -* `ProfileBuildlets` — orchestrates the full set of buildlets for a profile +* `ProfileBuildlets`: orchestrates the full set of buildlets for a profile build, including consistency checks, all registered transform builders, and report generation. -* `ConsistencyChecks` — validates the profile against the background model +* `ConsistencyChecks`: validates the profile against the background model before building. -* `ValidationBuildlet` / `IncrementalValidationBuildlet` / `SplitValidationBuildlet` - — buildlets for the various validation output modes. +* `ValidationBuildlet` / `IncrementalValidationBuildlet` / `SplitValidationBuildlet`: + buildlets for the various validation output modes. -* `ValidationBaseBuildlet` — shared base class for the validation buildlets. +* `ValidationBaseBuildlet`: shared base class for the validation buildlets. -* `SchemaBuildlet` — handles schema-related build steps. +* `SchemaBuildlet`: handles schema-related build steps. -* `PlantUMLRealTimePreviewBuildlet` — generates a hidden dot-prefixed `.puml` file +* `PlantUMLRealTimePreviewBuildlet`: generates a hidden dot-prefixed `.puml` file in the `Profiles/` folder on every `.owl` profile save, triggering the Real-Time Preview pipeline. See the <> section below. @@ -443,11 +443,11 @@ manually via *Project > Build Project*. The `pandoc/` package manages the embedded Pandoc installation: -* `PandocPathResolver` — resolves the path to the Pandoc executable within the +* `PandocPathResolver`: resolves the path to the Pandoc executable within the state location extraction directory. Supports Windows, macOS Intel, and macOS Apple Silicon. -* `PandocConverter` — invokes the Pandoc executable as a subprocess to convert +* `PandocConverter`: invokes the Pandoc executable as a subprocess to convert AsciiDoc content to HTML for display in the `DocView`. Pandoc is embedded as platform-specific ZIP archives in the `native/` directory @@ -463,13 +463,13 @@ The Real-Time Preview feature renders a live PlantUML class diagram of the activ CIM profile in the `CurrentProfilePlantUmlSvgView` view. The pipeline has three components: -* *`PlantUMLRealTimePreviewBuildlet`* — a `TextBuildlet` registered in `CIMBuilder` +* *`PlantUMLRealTimePreviewBuildlet`*: a `TextBuildlet` registered in `CIMBuilder` that fires on every `.owl` profile save. It generates a hidden dot-prefixed `.puml` file (e.g. `.EndDeviceConfig.puml`) in the project's `Profiles/` folder. The dot-prefix keeps the file out of CIMTool's resource model and prevents it from appearing in the user's workspace as a build artefact. -* *`CurrentProfilePlantUmlSvgView`* — a `ViewPart` that tracks the active profile +* *`CurrentProfilePlantUmlSvgView`*: a `ViewPart` that tracks the active profile editor via `IPartListener2` and the generated `.puml` file via `IResourceChangeListener`. When either changes, it invokes the PlantUML library (`net.sourceforge.plantuml.library`) with `PLANTUML_SECURITY_PROFILE=SANDBOX` @@ -477,7 +477,7 @@ components: widget using in-place DOM replacement via `BrowserFunction` + `DOMParser` to avoid visual flash-of-content artifacts. -* *`svg-pan-zoom.js`* (`js/svg-pan-zoom.js`) — the pan/zoom library bundled locally +* *`svg-pan-zoom.js`* (`js/svg-pan-zoom.js`), the pan/zoom library bundled locally and injected into the Browser widget. Bundled locally rather than loaded from a CDN to ensure air-gap compliance in utility company environments with no internet access. @@ -486,7 +486,7 @@ Diagram style (the XSLT builder used to generate the `.puml`) is configurable vi a three-tier preference hierarchy: profile-level -> project-level -> global. Global defaults are set in `PlantUMLBuildersPreferencesPage`. -`net.sourceforge.plantuml.library` is a hard `Require-Bundle` dependency — +`net.sourceforge.plantuml.library` is a hard `Require-Bundle` dependency; the buildlet calls the PlantUML API directly. `net.sourceforge.plantuml.eclipse` is `resolution:=optional` and is not used by the preview pipeline. @@ -494,24 +494,24 @@ is `resolution:=optional` and is not used by the preview pipeline. === Relationship to Other Projects -* *CIMUtil* — CIMToolPlugin is the Eclipse UI shell around CIMUtil's core logic. +* *CIMUtil*: CIMToolPlugin is the Eclipse UI shell around CIMUtil's core logic. The build system in `builder/` delegates all model parsing, profile processing, and artefact generation to classes in CIMUtil. CIMToolPlugin never duplicates this logic. -* *Kena* — the RDF graph used by the `Cache` and the editors is the Kena +* *Kena*: the RDF graph used by the `Cache` and the editors is the Kena `OntModel` API. CIMToolPlugin never calls Apache Jena directly. -* *RCPUtil* — all custom Eclipse UI infrastructure (form binding, wizard base +* *RCPUtil*: all custom Eclipse UI infrastructure (form binding, wizard base classes, JFace plumbing) comes from RCPUtil. CIMToolPlugin's editors and wizards extend RCPUtil base classes rather than raw Eclipse classes. -* *CIMToolProduct* — the product project that packages CIMToolPlugin into a +* *CIMToolProduct*: the product project that packages CIMToolPlugin into a runnable application. `CIMToolPlugin.java` references the product bundle (`au.com.langdale.cimtool.product`) by its symbolic name when extracting `logging.properties` and `logback.xml` at startup. -* *cimtool-cli* — the CLI project sources `cimutil.jar` from the PDE export of +* *cimtool-cli*: the CLI project sources `cimutil.jar` from the PDE export of this plugin's sibling projects. CIMToolPlugin itself is not used at runtime by - the CLI — but the CIMBuilder's output artifacts and the same underlying CIMUtil + the CLI, but the CIMBuilder's output artifacts and the same underlying CIMUtil logic are what the CLI invokes headlessly. diff --git a/dev-docs/Includes/CIMToolPlugin/CIMToolPlugin-README.md b/dev-docs/Includes/CIMToolPlugin/CIMToolPlugin-README.md index 250f3bd1..bd6aec2b 100644 --- a/dev-docs/Includes/CIMToolPlugin/CIMToolPlugin-README.md +++ b/dev-docs/Includes/CIMToolPlugin/CIMToolPlugin-README.md @@ -1,8 +1,8 @@ # CIMToolPlugin The core Eclipse RCP plugin for the CIMTool application. It provides all of the -user-facing Eclipse UI — perspectives, editors, views, wizards, actions, and the -incremental build system — that together constitute the CIMTool workbench +user-facing Eclipse UI, perspectives, editors, views, wizards, actions, and the +incremental build system, that together constitute the CIMTool workbench experience. This is the largest and most central of the in-repository plugins. All user @@ -24,7 +24,7 @@ to provide: - Preference pages for general settings and PlantUML builder configuration - Extension point registries for pluggable model parsers and profile buildlets - Pandoc integration for AsciiDoc report generation -- Unified logging pipeline — installs the JUL-to-SLF4J bridge at startup and extracts `logging.properties` and `logback.xml` so all three logging subsystems (JUL, SLF4J, Log4j 1.x) converge into a single Logback-controlled output in `logs/cimtool.log` +- A unified logging pipeline that installs the JUL-to-SLF4J bridge at startup and extracts `logging.properties` and `logback.xml` so all three logging subsystems (JUL, SLF4J, Log4j 1.x) converge into a single Logback-controlled output in `logs/cimtool.log` @@ -104,29 +104,29 @@ in-repository plugins: | --- | --- | --- | | CIMUtil | `au.com.langdale.cimutil` | Profile model, XMI import, XSLT transform engine, validation framework, all builder output generation logic, EA project parser | | Kena | `au.com.langdale.kena` | RDF/OWL graph API (`OntModel`, `ModelFactory`, graph traversal) used throughout the project model, cache, editors, and views | -| RCPUtil | `au.com.langdale.rcputil` | Eclipse UI infrastructure — data binding (`UIBinding`), form builder, JFace plumbing, wizard and editor base classes | +| RCPUtil | `au.com.langdale.rcputil` | Eclipse UI infrastructure: data binding (`UIBinding`), form builder, JFace plumbing, wizard and editor base classes | It also depends on the following standard Eclipse platform bundles: | Bundle | What it provides | | --- | --- | -| `org.eclipse.ui` | Core Eclipse workbench UI framework — `IWorkbench`, `IWorkbenchPage`, `IWorkbenchPart`, action and command infrastructure | -| `org.eclipse.core.runtime` | OSGi runtime utilities — `IProgressMonitor`, `Platform`, `FileLocator`, extension registry, `IPath`, `Status` | -| `org.eclipse.core.resources` | Eclipse workspace resource model — `IProject`, `IFile`, `IFolder`, `IResource`, resource change listeners, workspace build API | -| `org.eclipse.ui.ide` | IDE-specific workbench extensions — `ResourceUtil`, file editor input, IDE markers, open resource dialog | -| `org.eclipse.jface.text` | JFace text framework — `IDocument`, `ITextViewer`, source viewer infrastructure used by text-based editors | -| `org.eclipse.ui.editors` | Standard editor contributions — base classes for text editors, editor registry, `FileDocumentProvider` | -| `org.eclipse.ui.views` | Standard Eclipse view contributions — `IViewPart`, content outline view, properties view infrastructure | -| `org.eclipse.ui.forms` | Eclipse Forms UI toolkit — `FormToolkit`, `ScrolledForm`, `Section`, used to build the multi-page profile and model editors | -| `org.eclipse.compare` | Eclipse Compare framework — `CompareEditorInput`, structure and content merge viewer APIs used by the model diff/compare feature | -| `org.eclipse.ui.themes` | Eclipse theming and colour/font registry — `IThemeManager`, `ColorRegistry`, `FontRegistry` for consistent UI styling | -| `org.eclipse.core.filesystem` | Abstraction over file system access — `IFileStore`, `EFS`, used for file operations that span local and remote file systems | -| `net.sourceforge.plantuml.library` | PlantUML rendering library — generates SVG diagrams from `.puml` source in the Real-Time Preview pipeline. Declared as a hard `Require-Bundle` dependency. | -| `net.sourceforge.plantuml.eclipse` | PlantUML Eclipse integration bundle — provides the Eclipse-side PlantUML API. Declared as `resolution:=optional` since the feature degrades gracefully when absent. | +| `org.eclipse.ui` | Core Eclipse workbench UI framework: `IWorkbench`, `IWorkbenchPage`, `IWorkbenchPart`, action and command infrastructure | +| `org.eclipse.core.runtime` | OSGi runtime utilities: `IProgressMonitor`, `Platform`, `FileLocator`, extension registry, `IPath`, `Status` | +| `org.eclipse.core.resources` | Eclipse workspace resource model: `IProject`, `IFile`, `IFolder`, `IResource`, resource change listeners, workspace build API | +| `org.eclipse.ui.ide` | IDE-specific workbench extensions: `ResourceUtil`, file editor input, IDE markers, open resource dialog | +| `org.eclipse.jface.text` | JFace text framework: `IDocument`, `ITextViewer`, source viewer infrastructure used by text-based editors | +| `org.eclipse.ui.editors` | Standard editor contributions: base classes for text editors, editor registry, `FileDocumentProvider` | +| `org.eclipse.ui.views` | Standard Eclipse view contributions: `IViewPart`, content outline view, properties view infrastructure | +| `org.eclipse.ui.forms` | Eclipse Forms UI toolkit: `FormToolkit`, `ScrolledForm`, `Section`, used to build the multi-page profile and model editors | +| `org.eclipse.compare` | Eclipse Compare framework: `CompareEditorInput`, structure and content merge viewer APIs used by the model diff/compare feature | +| `org.eclipse.ui.themes` | Eclipse theming and colour/font registry: `IThemeManager`, `ColorRegistry`, `FontRegistry` for consistent UI styling | +| `org.eclipse.core.filesystem` | Abstraction over file system access: `IFileStore`, `EFS`, used for file operations that span local and remote file systems | +| `net.sourceforge.plantuml.library` | PlantUML rendering library: generates SVG diagrams from `.puml` source in the Real-Time Preview pipeline. Declared as a hard `Require-Bundle` dependency. | +| `net.sourceforge.plantuml.eclipse` | PlantUML Eclipse integration bundle: provides the Eclipse-side PlantUML API. Declared as `resolution:=optional` since the feature degrades gracefully when absent. | ### Vendored Third-Party Libraries -> **Note — Keeping vendored libraries in sync:** Adding, removing, or upgrading any library listed in this section must be mirrored in the same change across this project's `META-INF/MANIFEST.MF` (`Bundle-ClassPath`), `build.properties`, and `.classpath`, as well as the repository-wide reference chain. See the [Vendored Library Change Checklist](../CIMToolProduct/CIMToolProduct-README.md#maintaining-vendored-third-party-libraries) in the CIMToolProduct documentation. +> **Note: Keeping vendored libraries in sync:** Adding, removing, or upgrading any library listed in this section must be mirrored in the same change across this project's `META-INF/MANIFEST.MF` (`Bundle-ClassPath`), `build.properties`, and `.classpath`, as well as the repository-wide reference chain. See the [Vendored Library Change Checklist](../CIMToolProduct/CIMToolProduct-README.md#maintaining-vendored-third-party-libraries) in the CIMToolProduct documentation. The following JARs are included directly in the plugin bundle via `Bundle-ClassPath` in `MANIFEST.MF` (not resolved from the target platform): @@ -136,7 +136,7 @@ in `MANIFEST.MF` (not resolved from the target platform): | commons-io | 2.5 | File and stream utilities used in import/export operations | | commons-logging | 1.1.1 | Logging facade required by other vendored dependencies | | joda-time | 2.10.6 | Date/time handling used in builder preferences and buildlet configuration | -| jul-to-slf4j | 2.0.17 | JUL-to-SLF4J bridge — `SLF4JBridgeHandler` is installed at startup to redirect all `java.util.logging` events into the SLF4J → Logback pipeline. Wired to the platform SLF4J 2.x bundle via `Import-Package` — `MANIFEST.MF` declares `org.slf4j`, `org.slf4j.event`, `org.slf4j.helpers`, and `org.slf4j.spi`. | +| jul-to-slf4j | 2.0.17 | JUL-to-SLF4J bridge: `SLF4JBridgeHandler` is installed at startup to redirect all `java.util.logging` events into the SLF4J → Logback pipeline. Wired to the platform SLF4J 2.x bundle via `Import-Package`, with `MANIFEST.MF` declaring `org.slf4j`, `org.slf4j.event`, `org.slf4j.helpers`, and `org.slf4j.spi`. | @@ -150,8 +150,8 @@ These extension points allow third-party plugins to contribute to CIMTool: | Extension Point | Purpose | | --- | --- | -| `au.com.langdale.cimtoole.model_parser` | Pluggable model parsers — allows contributors to register parsers for additional model file formats beyond the built-in EA/XMI support. Schema: `schema/model_parser.exsd` | -| `au.com.langdale.cimtoole.profile_buildlet` | Pluggable profile buildlets — allows contributors to register additional transform builders that produce new output artefact types from a CIM profile. Schema: `schema/profile_buildlet.exsd` | +| `au.com.langdale.cimtoole.model_parser` | Pluggable model parsers: allows contributors to register parsers for additional model file formats beyond the built-in EA/XMI support. Schema: `schema/model_parser.exsd` | +| `au.com.langdale.cimtoole.profile_buildlet` | Pluggable profile buildlets: allows contributors to register additional transform builders that produce new output artefact types from a CIM profile. Schema: `schema/profile_buildlet.exsd` | ### Contributed Extension Points @@ -164,7 +164,7 @@ CIMToolPlugin contributes to the following Eclipse platform extension points via | `org.eclipse.core.resources.natures` | Registers `CIMNature` as the Eclipse project nature that marks a project as a CIMTool project and associates it with `CIMBuilder` | | `org.eclipse.core.resources.markers` | Defines CIMTool-specific problem markers used to display build errors and validation warnings in the Eclipse Problems view and editor gutter | | `org.eclipse.core.contenttype.contentTypes` | Registers CIMTool file content types (e.g. `.xmi`, `.owl`, `.profile`) so Eclipse can associate them with the correct editors and handlers | -| `org.eclipse.ui.perspectives` | Registers the CIMTool Perspective, CIMTool Browsing Perspective, and Validation Perspective — defines the initial layout of views, editors, and toolbars for each | +| `org.eclipse.ui.perspectives` | Registers the CIMTool Perspective, CIMTool Browsing Perspective, and Validation Perspective, defining the initial layout of views, editors, and toolbars for each | | `org.eclipse.ui.editors` | Registers multi-page editors for CIM profiles, model artefacts, mappings, diagnosis output, and repair files, bound to their respective content types | | `org.eclipse.ui.views` | Registers the Project Model view, Documentation view, and Validation view as Eclipse workbench views | | `org.eclipse.ui.importWizards` | Registers import wizards for EA projects, XMI models, schemas, profiles, rulesets, spreadsheets, and transform builders under the CIMTool category | @@ -184,14 +184,14 @@ CIMToolPlugin contributes to the following Eclipse platform extension points via -## Plugin Activator — CIMToolPlugin.java +## Plugin Activator: CIMToolPlugin.java The bundle activator (`CIMToolPlugin.java`) runs when the plugin is first activated and is responsible for: -1. **`configureLogging()`** — First calls `SLF4JBridgeHandler.removeHandlersForRootLogger()` to remove any existing JUL handlers from the root logger, preventing duplicate log output. Then installs `SLF4JBridgeHandler` to redirect all JUL events into the SLF4J → Logback pipeline, giving CIMTool a single unified log output in `logs/cimtool.log`. Filters `System.err` via an `AtomicBoolean`-guarded `PrintStream` to suppress the multi-line UCanAccess reserved-word warning, which originates from a direct `System.err.println` call inside the JDBC driver and cannot be suppressed via logging configuration. In production mode (`!Platform.inDevelopmentMode()`) additionally redirects `System.out` and `System.err` through JUL loggers `CIMTool.console.out` (INFO) and `CIMTool.console.err` (WARNING) so all console output is also captured in `logs/cimtool.log` via the bridge. In development mode the streams are left untouched so output remains visible in the Eclipse Console view. +1. **`configureLogging()`**: First calls `SLF4JBridgeHandler.removeHandlersForRootLogger()` to remove any existing JUL handlers from the root logger, preventing duplicate log output. Then installs `SLF4JBridgeHandler` to redirect all JUL events into the SLF4J → Logback pipeline, giving CIMTool a single unified log output in `logs/cimtool.log`. Filters `System.err` via an `AtomicBoolean`-guarded `PrintStream` to suppress the multi-line UCanAccess reserved-word warning, which originates from a direct `System.err.println` call inside the JDBC driver and cannot be suppressed via logging configuration. In production mode (`!Platform.inDevelopmentMode()`) additionally redirects `System.out` and `System.err` through JUL loggers `CIMTool.console.out` (INFO) and `CIMTool.console.err` (WARNING) so all console output is also captured in `logs/cimtool.log` via the bridge. In development mode the streams are left untouched so output remains visible in the Eclipse Console view. -2. **`extractLoggingProperties()`** — On first run, extracts both +2. **`extractLoggingProperties()`**: On first run, extracts both `logging.properties` and `logback.xml` from the `au.com.langdale.cimtool.product` plugin bundle to the installation root directory, and creates the `logs/` subdirectory. On subsequent runs both @@ -199,7 +199,7 @@ activated and is responsible for: via the `-Djava.util.logging.config.file` and `-Dlogback.configurationFile` JVM arguments set in `CIMTool.ini`. -3. **`loadEmbeddedPandocLibraries()`** — On first run, extracts the +3. **`loadEmbeddedPandocLibraries()`**: On first run, extracts the platform-specific Pandoc binary ZIP from the `native/` directory of this bundle to the Eclipse state location. On subsequent runs the already-extracted binary is used directly. @@ -227,14 +227,14 @@ redirected through JUL loggers `CIMTool.console.out` (INFO) and `CIMTool.console The `builder/` package implements CIMTool's incremental build system, which integrates with the Eclipse workspace build mechanism: -- **`CIMBuilder`** — the Eclipse `IncrementalProjectBuilder` implementation. Registered via `org.eclipse.core.resources.builders` in `plugin.xml`. Determines which resources have changed and dispatches to the appropriate buildlets. -- **`Buildlet`** — abstract base class for all build steps. Each buildlet is responsible for one output artefact type. -- **`ProfileBuildlets`** — orchestrates the full set of buildlets for a profile build, including consistency checks, all registered transform builders, and report generation. -- **`ConsistencyChecks`** — validates the profile against the background model before building. -- **`ValidationBuildlet`** / **`IncrementalValidationBuildlet`** / **`SplitValidationBuildlet`** — buildlets for the various validation output modes. -- **`ValidationBaseBuildlet`** — shared base class for the validation buildlets. -- **`SchemaBuildlet`** — handles schema-related build steps. -- **`PlantUMLRealTimePreviewBuildlet`** — generates a hidden dot-prefixed `.puml` file in the `Profiles/` folder on every `.owl` profile save, triggering the Real-Time Preview pipeline. See the PlantUML Real-Time Preview section below. +- **`CIMBuilder`**: the Eclipse `IncrementalProjectBuilder` implementation. Registered via `org.eclipse.core.resources.builders` in `plugin.xml`. Determines which resources have changed and dispatches to the appropriate buildlets. +- **`Buildlet`**: abstract base class for all build steps. Each buildlet is responsible for one output artefact type. +- **`ProfileBuildlets`**: orchestrates the full set of buildlets for a profile build, including consistency checks, all registered transform builders, and report generation. +- **`ConsistencyChecks`**: validates the profile against the background model before building. +- **`ValidationBuildlet`** / **`IncrementalValidationBuildlet`** / **`SplitValidationBuildlet`**: buildlets for the various validation output modes. +- **`ValidationBaseBuildlet`**: shared base class for the validation buildlets. +- **`SchemaBuildlet`**: handles schema-related build steps. +- **`PlantUMLRealTimePreviewBuildlet`**: generates a hidden dot-prefixed `.puml` file in the `Profiles/` folder on every `.owl` profile save, triggering the Real-Time Preview pipeline. See the PlantUML Real-Time Preview section below. The build is triggered automatically by Eclipse whenever a relevant workspace resource changes. It can also be triggered manually via **Project > Build Project**. @@ -245,8 +245,8 @@ resource changes. It can also be triggered manually via **Project > Build Projec The `pandoc/` package manages the embedded Pandoc installation: -- **`PandocPathResolver`** — resolves the path to the Pandoc executable within the state location extraction directory. Supports Windows, macOS Intel, and macOS Apple Silicon. -- **`PandocConverter`** — invokes the Pandoc executable as a subprocess to convert AsciiDoc content to HTML for display in the `DocView`. +- **`PandocPathResolver`**: resolves the path to the Pandoc executable within the state location extraction directory. Supports Windows, macOS Intel, and macOS Apple Silicon. +- **`PandocConverter`**: invokes the Pandoc executable as a subprocess to convert AsciiDoc content to HTML for display in the `DocView`. Pandoc is embedded as platform-specific ZIP archives in the `native/` directory and extracted on first run by `CIMToolPlugin.loadEmbeddedPandocLibraries()`. @@ -260,15 +260,15 @@ The Real-Time Preview feature renders a live PlantUML class diagram of the activ CIM profile in the `CurrentProfilePlantUmlSvgView` view. The pipeline has three components: -- **`PlantUMLRealTimePreviewBuildlet`** — a `TextBuildlet` registered in `CIMBuilder` that fires on every `.owl` profile save. It generates a hidden dot-prefixed `.puml` file (e.g. `.EndDeviceConfig.puml`) in the project's `Profiles/` folder. The dot-prefix keeps the file out of CIMTool's resource model and prevents it from appearing in the user's workspace as a build artefact. -- **`CurrentProfilePlantUmlSvgView`** — a `ViewPart` that tracks the active profile editor via `IPartListener2` and the generated `.puml` file via `IResourceChangeListener`. When either changes, it invokes the PlantUML library (`net.sourceforge.plantuml.library`) with `PLANTUML_SECURITY_PROFILE=SANDBOX` to render the `.puml` to SVG, then injects the SVG into the embedded `Browser` widget using in-place DOM replacement via `BrowserFunction` + `DOMParser` to avoid visual flash-of-content artifacts. -- **`svg-pan-zoom.js`** (`js/svg-pan-zoom.js`) — the pan/zoom library bundled locally and injected into the Browser widget. Bundled locally rather than loaded from a CDN to ensure air-gap compliance in utility company environments with no internet access. +- **`PlantUMLRealTimePreviewBuildlet`**: a `TextBuildlet` registered in `CIMBuilder` that fires on every `.owl` profile save. It generates a hidden dot-prefixed `.puml` file (e.g. `.EndDeviceConfig.puml`) in the project's `Profiles/` folder. The dot-prefix keeps the file out of CIMTool's resource model and prevents it from appearing in the user's workspace as a build artefact. +- **`CurrentProfilePlantUmlSvgView`**: a `ViewPart` that tracks the active profile editor via `IPartListener2` and the generated `.puml` file via `IResourceChangeListener`. When either changes, it invokes the PlantUML library (`net.sourceforge.plantuml.library`) with `PLANTUML_SECURITY_PROFILE=SANDBOX` to render the `.puml` to SVG, then injects the SVG into the embedded `Browser` widget using in-place DOM replacement via `BrowserFunction` + `DOMParser` to avoid visual flash-of-content artifacts. +- **`svg-pan-zoom.js`** (`js/svg-pan-zoom.js`), the pan/zoom library bundled locally and injected into the Browser widget. Bundled locally rather than loaded from a CDN to ensure air-gap compliance in utility company environments with no internet access. Diagram style (the XSLT builder used to generate the `.puml`) is configurable via a three-tier preference hierarchy: profile-level → project-level → global. Global defaults are set in `PlantUMLBuildersPreferencesPage`. -`net.sourceforge.plantuml.library` is a hard `Require-Bundle` dependency — +`net.sourceforge.plantuml.library` is a hard `Require-Bundle` dependency; the buildlet calls the PlantUML API directly. `net.sourceforge.plantuml.eclipse` is `resolution:=optional` and is not used by the preview pipeline. @@ -276,8 +276,8 @@ is `resolution:=optional` and is not used by the preview pipeline. ## Relationship to Other Projects -- **CIMUtil** — CIMToolPlugin is the Eclipse UI shell around CIMUtil's core logic. The build system in `builder/` delegates all model parsing, profile processing, and artefact generation to classes in CIMUtil. CIMToolPlugin never duplicates this logic. -- **Kena** — the RDF graph used by the `Cache` and the editors is the Kena `OntModel` API. CIMToolPlugin never calls Apache Jena directly. -- **RCPUtil** — all custom Eclipse UI infrastructure (form binding, wizard base classes, JFace plumbing) comes from RCPUtil. CIMToolPlugin's editors and wizards extend RCPUtil base classes rather than raw Eclipse classes. -- **CIMToolProduct** — the product project that packages CIMToolPlugin into a runnable application. `CIMToolPlugin.java` references the product bundle (`au.com.langdale.cimtool.product`) by its symbolic name when extracting `logging.properties` and `logback.xml` at startup. -- **cimtool-cli** — the CLI project sources `cimutil.jar` from the PDE export of this plugin's sibling projects. CIMToolPlugin itself is not used at runtime by the CLI — but the same underlying CIMUtil logic is what the CLI invokes headlessly. +- **CIMUtil**: CIMToolPlugin is the Eclipse UI shell around CIMUtil's core logic. The build system in `builder/` delegates all model parsing, profile processing, and artefact generation to classes in CIMUtil. CIMToolPlugin never duplicates this logic. +- **Kena**: the RDF graph used by the `Cache` and the editors is the Kena `OntModel` API. CIMToolPlugin never calls Apache Jena directly. +- **RCPUtil**: all custom Eclipse UI infrastructure (form binding, wizard base classes, JFace plumbing) comes from RCPUtil. CIMToolPlugin's editors and wizards extend RCPUtil base classes rather than raw Eclipse classes. +- **CIMToolProduct**: the product project that packages CIMToolPlugin into a runnable application. `CIMToolPlugin.java` references the product bundle (`au.com.langdale.cimtool.product`) by its symbolic name when extracting `logging.properties` and `logback.xml` at startup. +- **cimtool-cli**: the CLI project sources `cimutil.jar` from the PDE export of this plugin's sibling projects. CIMToolPlugin itself is not used at runtime by the CLI, but the same underlying CIMUtil logic is what the CLI invokes headlessly. diff --git a/dev-docs/Includes/CIMToolProduct/CIMToolProduct-README.adoc b/dev-docs/Includes/CIMToolProduct/CIMToolProduct-README.adoc index 042bec2d..b803a17c 100644 --- a/dev-docs/Includes/CIMToolProduct/CIMToolProduct-README.adoc +++ b/dev-docs/Includes/CIMToolProduct/CIMToolProduct-README.adoc @@ -19,7 +19,7 @@ the Eclipse PDE build system uses to assemble a distributable CIMTool ZIP archiv === Overview -In Eclipse PDE terminology a *product* is the outermost packaging unit — it +In Eclipse PDE terminology a *product* is the outermost packaging unit. It defines what an end user actually runs. The `CIMTool.product` file at the root of this project is the authoritative descriptor for everything about the CIMTool application from the user's perspective: its name, version, icons, splash screen, @@ -86,8 +86,8 @@ CIMToolProduct/ This project has *no compile-time dependencies*. It contains no Java source and does not declare `Require-Bundle` dependencies in its MANIFEST. Instead it -references other plugins by symbolic name in `CIMTool.product` via the `` -list — these are resolved by the PDE export at packaging time. +references other plugins by symbolic name in `CIMTool.product` via the +`` list, which are resolved by the PDE export at packaging time. The plugins that CIMTool.product explicitly includes which are developed within this repository are: @@ -98,7 +98,7 @@ this repository are: | CIMToolPlugin | `au.com.langdale.cimtoole` -| Core Eclipse UI plugin — perspectives, editors, views, wizards, builders +| Core Eclipse UI plugin: perspectives, editors, views, wizards, builders | CIMUtil | `au.com.langdale.cimutil` @@ -118,11 +118,11 @@ this repository are: | com.cimphony.cimtoole | `com.cimphony.cimtoole` -| CIMphony extensions — Ecore integration, additional buildlets +| Cimphony extensions: Ecore integration, additional buildlets | SLF4J Logback Binding | `io.ucaiug.slf4j.logback.binding` -| OSGi fragment bundle — wires SLF4J 2.x to Logback as its logging provider +| OSGi fragment bundle: wires SLF4J 2.x to Logback as its logging provider |=== All remaining plugins in the `` list are Eclipse platform and third-party @@ -180,8 +180,8 @@ workspace. Key settings: * Places the perspective switcher in the top-right * Shows a progress indicator on startup -These are default values only — users can override them through Eclipse preferences -and their choices are persisted per-workspace. +These are default values only, and users can override them through Eclipse +preferences and their choices are persisted per-workspace. ==== logging.properties @@ -213,17 +213,17 @@ Configures Logback for the CIMTool application. This file is: on first startup alongside `logging.properties` . Loaded by Logback via the `-Dlogback.configurationFile=./logback.xml` JVM argument -SLF4J is wired to Logback via the `io.ucaiug.slf4j.logback.binding` fragment bundle -— a minimal OSGi fragment that attaches to `slf4j.api` and provides the +SLF4J is wired to Logback via the `io.ucaiug.slf4j.logback.binding` fragment bundle, +a minimal OSGi fragment that attaches to `slf4j.api` and provides the `META-INF/services/org.slf4j.spi.SLF4JServiceProvider` registration that makes `LogbackServiceProvider` visible through `slf4j.api`'s classloader. This requires no bytecode weaving and has no impact on security scanning tools. The following logging sources route through `logback.xml`: -* *SLF4J API calls* — direct (Saxon-HE, m2e/Aether, UCanAccess, and other vendored libraries) -* *Log4j 1.x API calls* — routed via `log4j-over-slf4j` bridge in Kena -* *JUL API calls* — bridged via `SLF4JBridgeHandler` installed in +* *SLF4J API calls*: direct (Saxon-HE, m2e/Aether, UCanAccess, and other vendored libraries) +* *Log4j 1.x API calls*: routed via `log4j-over-slf4j` bridge in Kena +* *JUL API calls*: bridged via `SLF4JBridgeHandler` installed in `CIMToolPlugin.configureLogging()` at startup, including `System.out`/`System.err` console output in production mode which is routed through the `CIMTool.console` JUL logger @@ -248,27 +248,27 @@ Changes to `logback.xml` take effect on the next restart. === Release Process The CIMTool release process consists of four sequential phases. All phases must -be completed in order — no phase should begin until the previous one is fully +be completed in order, with no phase beginning until the previous one is fully complete and verified. [cols="1,3", options="header"] |=== | Phase | Description -| *1 — Pre-Build Preparation* +| *1: Pre-Build Preparation* | Versioning, release notes, PR to master -| *2 — PDE Product Export* +| *2: PDE Product Export* | Eclipse product export to a local directory -| *3 — Code Signing and Packaging* +| *3: Code Signing and Packaging* | Signing, cimtool-cli build, ZIP assembly, checksums -| *4 — Post-Build and Publishing* +| *4: Post-Build and Publishing* | `lib-repo/` PR, GitHub Release creation, tagging, artifact upload |=== -==== Phase 1 — Pre-Build Preparation +==== Phase 1: Pre-Build Preparation All preparation work must be completed, reviewed, and merged to master via Pull Request *before* any build or signing activity begins. Master is intended to @@ -286,9 +286,9 @@ review and update is the mandatory first step in every release cycle. All CIMTool sub-projects follow *Semantic Versioning* as defined at https://semver.org. A version number takes the form `MAJOR.MINOR.PATCH`, where each element is incremented according to the following rules: -* *MAJOR* — incremented when incompatible API or behavioral changes are introduced that would break existing consumers of the component. -* *MINOR* — incremented when new functionality is added in a backward-compatible manner (new features, new builders, new extension points, etc.). -* *PATCH* — incremented for backward-compatible bug fixes, documentation corrections, or minor internal changes that do not alter the component's public interface or behavior. +* *MAJOR*: incremented when incompatible API or behavioral changes are introduced that would break existing consumers of the component. +* *MINOR*: incremented when new functionality is added in a backward-compatible manner (new features, new builders, new extension points, etc.). +* *PATCH*: incremented for backward-compatible bug fixes, documentation corrections, or minor internal changes that do not alter the component's public interface or behavior. ===== Product-Aligned Projects @@ -304,7 +304,7 @@ The following projects must always be versioned in lockstep with the primary CIM | CIMToolPlugin | `META-INF/MANIFEST.MF` -| Core UI plugin — ships in every release +| Core UI plugin, ships in every release | CIMToolHelp | `META-INF/MANIFEST.MF` @@ -312,11 +312,11 @@ The following projects must always be versioned in lockstep with the primary CIM | CIMUtil | `META-INF/MANIFEST.MF` -| Core processing library — ships in every release +| Core processing library, ships in every release | RCPUtil | `META-INF/MANIFEST.MF` -| Eclipse RCP utility layer — ships in every release +| Eclipse RCP utility layer, ships in every release | CIMToolFeature | `feature.xml` @@ -345,7 +345,7 @@ version in `cimtool-cli/pom.xml` must also be updated to match before running | com.cimphony.cimtoole | `1.1.0` -| CIMphony extensions; versioned independently of the core product +| Cimphony extensions; versioned independently of the core product | CIMToolTest | `1.2.0` @@ -382,23 +382,23 @@ entry for the release being prepared must be added at the top of the file following the established format used by prior releases. The content of this entry is also used verbatim as the release notes body when -creating the GitHub Release in Phase 4. Authoring the release notes here first — -as part of the pre-build PR — ensures the notes are reviewed before publication +creating the GitHub Release in Phase 4. Authoring the release notes here first, +as part of the pre-build PR, ensures the notes are reviewed before publication and that the GitHub Release and the public website remain in sync. Once versioning updates and release notes are complete, open a Pull Request to merge all changes to master and obtain the required review approval before proceeding. -==== Phase 2 — PDE Product Export +==== Phase 2: PDE Product Export -The CIMTool distribution is produced via the Eclipse PDE product export. The export must always target a *Directory* destination — the distribution ZIP is produced by the code signing pipeline in the subsequent step, not by the PDE exporter directly. +The CIMTool distribution is produced via the Eclipse PDE product export. The export must always target a *Directory* destination. The distribution ZIP is produced by the code signing pipeline in the subsequent step, not by the PDE exporter directly. . From the Eclipse menu select *File > Export* . In the Export dialog select *Plug-in Development > Eclipse product* and click *Next* . Set the fields as shown in the screenshot below: ** *Configuration:* `/CIMToolProduct/CIMTool.product` -** *Root directory:* `CIMTool-` (e.g. `CIMTool-2.3.0-RC8`) — +** *Root directory:* `CIMTool-` (e.g. `CIMTool-2.3.0-RC8`); replace with the actual release version being built ** *Destination:* Select *Directory* and set the path to your release staging area (e.g. `D:\CIMTool-Releases`) @@ -431,12 +431,12 @@ placed there by the PDE export directly. Both are extracted from the `au.com.langdale.cimtool.product` plugin bundle at first startup by `CIMToolPlugin.extractLoggingProperties()`. -Once the export completes, proceed immediately to Phase 3 — Code Signing and -Packaging before creating the distribution ZIP. +Once the export completes, proceed immediately to Phase 3, Code Signing and +Packaging, before creating the distribution ZIP. -==== Phase 3 — Code Signing and Packaging +==== Phase 3: Code Signing and Packaging [WARNING] ==== @@ -464,7 +464,7 @@ untrusted application. CIMTool uses an EV (Extended Validation) code signing certificate issued to *UCA USERS GROUP* by TrustID (IdenTrust). The certificate is stored on a SafeNet -USB hardware token and the private key never leaves the token — all signing +USB hardware token and the private key never leaves the token. All signing operations are performed on the hardware itself. [NOTE] @@ -481,23 +481,23 @@ of certificate expiry. Ensure the following are in place on the build machine before running the signing script: -. *Eclipse Temurin JDK 20* — must be installed from https://adoptium.net. +. *Eclipse Temurin JDK 20*: must be installed from https://adoptium.net. Temurin is specifically required because it includes the `SunPKCS11` security provider that `jarsigner` uses to communicate with the IdenTrust EV hardware token. Other OpenJDK distributions such as Zulu omit this provider and cannot be used for JAR signing. The script expects `jarsigner` at `C:\Program Files\Eclipse Adoptium\jdk-20.0.2.9-hotspot\bin\jarsigner.exe` (the default install location for the - `OpenJDK20U-jdk_x64_windows_hotspot_20.0.2_9` installer) — update the + `OpenJDK20U-jdk_x64_windows_hotspot_20.0.2_9` installer); update the `JARSIGNER` variable in the script if your installation path differs. -. *Windows SDK `signtool.exe`* — used to apply Authenticode signatures to +. *Windows SDK `signtool.exe`*: used to apply Authenticode signatures to `CIMTool.exe`. Installed with Visual Studio or as a standalone Windows SDK download. The script expects it at - `C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe` — update the + `C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe`; update the `SIGNTOOL` variable in the script if your installation path differs. -. *SafeNet Authentication Client (SAC)* — must be installed *and running*, and the +. *SafeNet Authentication Client (SAC)*: must be installed *and running*, and the IdenTrust EV USB token must be inserted, before launching the script. Installing SAC is not sufficient on its own: the SafeNet service that backs the PKCS#11 library must be active for `jarsigner` and `keytool` to reach the token, so launch @@ -506,18 +506,18 @@ script: `C:\Windows\System32\eTPKCS11.dll`; if this file is not found the script automatically attempts the alternate location `C:\Windows\System32\pkcs11.dll`. -. *Token PIN* — the script prompts for the hardware token PIN once at startup using +. *Token PIN*: the script prompts for the hardware token PIN once at startup using a masked input field. *No characters, asterisks, or cursor movement appear as the - PIN is typed* — this is expected; type the PIN and press Enter once. Wait for the + PIN is typed*. This is expected; type the PIN and press Enter once. Wait for the prompt to appear before typing, and avoid pressing Enter on an empty line, which submits no PIN and fails without authenticating. The PIN is held in memory for the duration of the signing session, cleared immediately on completion, and never written to disk. -. *Certificate alias* — The `CERT_ALIAS` variable in the script is set to the +. *Certificate alias*: The `CERT_ALIAS` variable in the script is set to the UUID that the IdenTrust token uses internally to identify the certificate entry. Note that this UUID does not match the friendly display name (`UCA USERS GROUP`) - shown in the SafeNet Authentication Client GUI — `jarsigner` resolves aliases + shown in the SafeNet Authentication Client GUI, because `jarsigner` resolves aliases through the PKCS#11 provider which exposes the underlying token UUID. If the certificate is ever renewed onto a new token the alias UUID will change and the `CERT_ALIAS` variable must be updated. To rediscover the alias run the following @@ -537,11 +537,11 @@ The alias is the value appearing before the first comma in the output entry, e.g ===== Hardware Token PIN Management and Lockout Prevention -The UCA Users Group EV code signing key — used to sign all UCA open source project -releases, not CIMTool alone — is protected by a PIN held entirely on the hardware +The UCA Users Group EV code signing key (used to sign all UCA open source project +releases, not CIMTool alone) is protected by a PIN held entirely on the hardware token, and the token enforces its own retry counter. A sequence of failed -authentication attempts can lock the token, and — depending on how the token was -provisioned — a fully locked token may require replacement and certificate +authentication attempts can lock the token, and, depending on how the token was +provisioned, a fully locked token may require replacement and certificate re-issuance. Understanding the token's PIN model before running a signing session is therefore essential. @@ -549,11 +549,11 @@ is therefore essential. project releases is a SafeNet/Thales IDPrime device that exposes more than one PIN object, and they are not interchangeable: -* *Token Passcode* — the user PIN that protects the code signing key, with a +* *Token Passcode*: the user PIN that protects the code signing key, with a maximum of *15* retries on this token. The retry counter resets to its maximum on _any_ single successful authentication, so one correct login fully restores the budget. -* *Digital Signature PIN / PUK* — a separate PIN object (maximum 3 retries each) +* *Digital Signature PIN / PUK*: a separate PIN object (maximum 3 retries each) that exists on the token but does *not* protect the code signing key. Its much tighter limit is a hazard only if a signing operation is mistakenly bound to it. @@ -570,7 +570,7 @@ image::{cimtoolproduct-imagesdir}/SAC_Private_Key_PIN_Binding.png[SafeNet Authen [WARNING] ==== *Inspecting token status is safe; guessing the PIN is not.* Viewing the token's -properties and retry counters in SAC consumes no attempts — only an actual +properties and retry counters in SAC consumes no attempts, since only an actual authentication with an incorrect PIN decrements the counter. Before any signing session, inspect *Token Passcode retries remaining* in SAC. If it is below maximum, a previous session left the counter eroded; do not run anything that submits a PIN @@ -580,7 +580,7 @@ until the correct PIN is confirmed. Never "test" the token by trying candidate P image::{cimtoolproduct-imagesdir}/SAC_Token_Passcode_Retries.png[SafeNet Authentication Client token detail showing Token Passcode retries remaining against the maximum of 15] *Why the signing script fails fast.* `release-cimtool.bat` signs the entire -`plugins/` set — on the order of 150 JARs — in a single loop. If that loop continued +`plugins/` set, on the order of 150 JARs, in a single loop. If that loop continued past a failed signing attempt, an incorrect PIN or an unusable keystore would produce one failed token authentication _per JAR_, draining the retry counter and locking the token within a single run. To prevent this, the script treats the first JAR as a live @@ -599,7 +599,7 @@ does not necessarily decrement the retry counter. A common cause on JDK 9 and la the deprecated `-providerClass sun.security.pkcs11.SunPKCS11` invocation, which can fail to load the provider; the supported form is `-addprovider SunPKCS11` (retaining `-providerArg `). To verify token access independently of the full -pipeline — and to reset the retry counter with a known-good PIN — run a single +pipeline, and to reset the retry counter with a known-good PIN, run a single `keytool` listing with PKCS#11 debug enabled: [source,cmd] @@ -621,7 +621,7 @@ distinguishes a provider or library problem from a genuine PIN rejection. *Recovering a locked token:* If the Token Passcode counter reaches zero the token locks. On this token the *Token unlock object* is the *Administrator Passcode* (there is no user PUK), which can reset the user PIN via SAC. However, possession of the -Administrator Passcode depends on how IdenTrust provisioned the token — it is not +Administrator Passcode depends on how IdenTrust provisioned the token; it is not always released to the subscriber, and it has its own independent retry limit that can also lock permanently. Do not rely on the admin unlock as a safety net unless the Administrator Passcode value is known to be held and recorded. Treat a lockout as a @@ -676,27 +676,27 @@ The script exits immediately with a non-zero error code if any step fails. The following screenshots illustrate a complete successful run of the signing pipeline. -*Confirm Prerequisites — Confirm EV USB token inserted and SafeNet Authentication Client running / Step 1 — Start JAR signing:* +*Confirm Prerequisites: Confirm EV USB token inserted and SafeNet Authentication Client running / Step 1: Start JAR signing:* image::{cimtoolproduct-imagesdir}/Step1.png[Step 1 Insert EV USB Token and SafeNet PIN prompt] -*Step 1 — JAR signing complete / Step 2 — CIMTool.exe signing begins:* +*Step 1: JAR signing complete / Step 2: CIMTool.exe signing begins:* image::{cimtoolproduct-imagesdir}/Step2.png[Step 1 complete\, Step 2 SafeNet PIN prompt] -When Step 2 begins, the SafeNet Authentication Client presents a native GUI dialog -prompting for the *Token Passcode* again. This second prompt is expected and cannot -be automated — `signtool` communicates with the hardware token through Windows -CryptoAPI rather than the PKCS#11 path used by `jarsigner`, which triggers a -separate authentication dialog from the SafeNet middleware. Enter the token PIN -in this dialog and click *OK* to proceed. +When Step 2 begins, the SafeNet Authentication Client presents a native GUI +dialog prompting for the *Token Passcode* again. This second prompt is expected +and cannot be automated, because `signtool` communicates with the hardware token +through Windows CryptoAPI rather than the PKCS#11 path used by `jarsigner`, +which triggers a separate authentication dialog from the SafeNet middleware. +Enter the token PIN in this dialog and click *OK* to proceed. -*Step 2 complete / Step 3 — Distribution archive creation in progress:* +*Step 2 complete / Step 3: Distribution archive creation in progress:* image::{cimtoolproduct-imagesdir}/Step3.png[Step 2 complete\, Step 3 ZIP creation progress] -*Steps 3 and 4 complete — Successful completion summary:* +*Steps 3 and 4 complete: Successful completion summary:* image::{cimtoolproduct-imagesdir}/Step4.png[Steps 3 and 4 complete\, final summary] @@ -712,14 +712,14 @@ is the only confirmation needed that signing succeeded. * *`The timestamp will expire within one year on . However, the JAR will be valid until the signer certificate expires on .`* + This warning has two distinct subjects that are easy to conflate. The first date -refers to the *TSA server's own infrastructure certificate* — the IdenTrust +refers to the *TSA server's own infrastructure certificate*, the IdenTrust timestamp authority server's cert, not the UCA Users Group signing cert and not the timestamp embedded in the JAR. When that cert expires IdenTrust simply renews it as with any server cert, and it has no effect whatsoever on timestamps already -embedded in signed JARs. The second date is the EV signing certificate's expiry — +embedded in signed JARs. The second date is the EV signing certificate's expiry; `jarsigner` is confirming that the JAR remains valid through the signing cert's full lifetime. More importantly: once a JAR is signed with a TSA timestamp -embedded, it remains trusted and valid *indefinitely* — even after the EV signing +embedded, it remains trusted and valid *indefinitely*, even after the EV signing cert expires. The timestamp is permanent cryptographic proof that the signature was created while the cert was valid. This is how every major software vendor ships signed software and is precisely why timestamping is mandatory for all release @@ -732,7 +732,7 @@ simply ignored by `jarsigner` during the signing process. * *`The signer certificate will expire on .`* + -Informational only — confirms the expiry date of the EV signing certificate. +Informational only, confirming the expiry date of the EV signing certificate. No action required until renewal time. *Unpacked plugin resources:* @@ -741,7 +741,7 @@ Some plugins in the CIMTool distribution are deployed with resources unpacked directly onto the filesystem rather than bundled inside a JAR. For example, the `au.com.langdale.cimutil_\builders\` directory contains `.xsl` transform files that are written loose to disk so that the Saxon XSLT processor can access -them directly at runtime. These files are not covered by JAR signing — there is no +them directly at runtime. These files are not covered by JAR signing; there is no JAR container for `jarsigner` to sign. Their integrity is instead protected by the SHA-256 checksum published alongside the ZIP archive. Users who verify the checksum before extracting the distribution are assured of the integrity of all contents, @@ -756,28 +756,29 @@ their respective publishers. When `jarsigner` processes them as part of this pipeline it replaces those original publisher signatures with the UCA Users Group EV certificate signature. This is standard practice for Eclipse RCP distributions: by re-signing all bundled JARs under a single certificate the UCA Users Group is -asserting that this specific combination of libraries — as integrated, tested, and -shipped in CIMTool — has been reviewed and vouched for. The original publisher +asserting that this specific combination of libraries, as integrated, tested, and +shipped in CIMTool, has been reviewed and vouched for. The original publisher signatures served their purpose at the point of download; at the point of redistribution the responsibility for the bundled artifact passes to the distributor. Running `jarsigner -verify` on any `\lib\` JAR after signing will -show the UCA Users Group signature rather than the original publisher signature — -this is expected and correct. +show the UCA Users Group signature rather than the original publisher signature. +This is expected and correct. *Known unsignable JARs:* -One JAR in the distribution cannot be signed due to a structural defect in the JAR -itself that is outside of CIMTool's control: `asp-server-asciidoctorj-dist.jar`, -part of the `de.jcup.asciidoctoreditor` plugin. It contains a duplicate -`META-INF/BSDL` entry in its internal ZIP structure which causes `jarsigner` to -reject it with a `ZipException: duplicate entry` error. The signing script handles -this automatically via the `SKIP_JARS` configuration variable — the JAR is skipped -without aborting the pipeline and is reported in the final summary as a skipped -entry rather than an error. The JAR remains protected by the distribution ZIP -SHA-256 checksum. If a future release of the AsciiDoc editor plugin corrects this -defect, the entry can be removed from `SKIP_JARS`. +One JAR in the distribution cannot be signed due to a structural defect in the +JAR itself that is outside of CIMTool's control: +`asp-server-asciidoctorj-dist.jar`, part of the `de.jcup.asciidoctoreditor` +plugin. It contains a duplicate `META-INF/BSDL` entry in its internal ZIP +structure which causes `jarsigner` to reject it with a `ZipException: duplicate +entry` error. The signing script handles this automatically via the `SKIP_JARS` +configuration variable, so the JAR is skipped without aborting the pipeline and +is reported in the final summary as a skipped entry rather than an error. The +JAR remains protected by the distribution ZIP SHA-256 checksum. If a future +release of the AsciiDoc editor plugin corrects this defect, the entry can be +removed from `SKIP_JARS`. -==== Phase 4 — Post-Build and Publishing +==== Phase 4: Post-Build and Publishing ===== Commit lib-repo/ Changes @@ -791,12 +792,12 @@ that must be committed back to master before the release is tagged. This commit is only required when the Kena or CIMUtil versions have actually changed since the previous release. If both versions are unchanged, `install-jars.bat` reinstalls identical JARs producing identical checksums, -resulting in no git diff — and no PR is needed. +resulting in no git diff, and no PR is needed. ==== When changes are present, open a Pull Request containing only the `lib-repo/` changes, obtain review approval, and merge to master. *The tag must not be -created until this PR is merged* — the tag must capture the exact `lib-repo/` +created until this PR is merged*: the tag must capture the exact `lib-repo/` state that produced the release, so that any developer cloning at the tag can immediately run `mvn clean package` without needing to re-run `install-jars.bat`. @@ -804,13 +805,13 @@ immediately run `mvn clean package` without needing to re-run `install-jars.bat` Navigate to https://github.com/cimug-org/CIMTool/releases and create a new release against the `master` target. By project convention the release tag is a *new* tag -named for the release version — not an existing tag. Open the *Select tag* dropdown, -type the release version exactly as it should appear (for this example, `2.3.0` — the +named for the release version, not an existing tag. Open the *Select tag* dropdown, +type the release version exactly as it should appear (for this example, `2.3.0`, the bare version, with no `v` prefix, matching the existing tags such as `2.2.0`), and choose *Create new tag* so the tag is created on the `master` target when the release is published: -image::{cimtoolproduct-imagesdir}/Tag_Release.png[GitHub release tag selection — create a new tag named for the release version targeting master,700] +image::{cimtoolproduct-imagesdir}/Tag_Release.png[GitHub release tag selection: create a new tag named for the release version targeting master,700] Copy the release notes entry for this version from `docs/release-notes.md` into the release notes body. Attach all five release artifacts by dropping them into the @@ -825,7 +826,7 @@ Assets upload area highlighted below, then click *Publish release*: image::{cimtoolproduct-imagesdir}/Release_Artifacts.png[GitHub Release Assets upload area,700] Publishing the release simultaneously creates the tag on master at the current -HEAD commit — which at this point includes all pre-build version changes, release +HEAD commit, which at this point includes all pre-build version changes, release notes, and the post-build `lib-repo/` commit. This tagged commit is the definitive reproducible state for this release. @@ -855,7 +856,7 @@ In the event of future macOS support, `codesign` would be used in place of === Maintaining Vendored Third-Party Libraries CIMTool does not pull third-party libraries from Maven Central at build time; every -third-party JAR is vendored — committed to the repository and referenced explicitly. +third-party JAR is vendored, committed to the repository and referenced explicitly. A vendored JAR is therefore referenced in several places at once, and adding, removing, or upgrading one requires updating _all_ of its references in the same change. Missing one typically produces a build that passes in the IDE but fails at @@ -863,46 +864,46 @@ PDE export or runtime, or a CLI build that cannot resolve the dependency. There are two vendoring patterns, with different reference sets. -*Pattern A — JAR bundled inside a plugin.* The JAR lives in `/lib/` and is +*Pattern A: JAR bundled inside a plugin.* The JAR lives in `/lib/` and is woven into that plugin's classpath. When it changes, update all of the following in that plugin, in lockstep: -* `/lib/` — add, remove, or replace the physical JAR (the filename carries the version) -* `/META-INF/MANIFEST.MF` — the `Bundle-ClassPath` entry -* `/build.properties` — the `bin.includes` and/or `jars.extra.classpath` entry, so PDE export ships the JAR -* `/.classpath` — the `kind="lib"` classpath entry, so the IDE compiles against it -* The project's README — `Project Structure` tree and `Vendored Third-Party Libraries` table +* `/lib/`: add, remove, or replace the physical JAR (the filename carries the version) +* `/META-INF/MANIFEST.MF`: the `Bundle-ClassPath` entry +* `/build.properties`: the `bin.includes` and/or `jars.extra.classpath` entry, so PDE export ships the JAR +* `/.classpath`: the `kind="lib"` classpath entry, so the IDE compiles against it +* The project's README: `Project Structure` tree and `Vendored Third-Party Libraries` table Plugins using this pattern include CIMToolPlugin, CIMUtil, and Kena. -*Pattern B — library shipped as its own bundle in the product.* The library is a +*Pattern B: library shipped as its own bundle in the product.* The library is a standalone OSGi bundle listed in the product. When it changes, update: -* `CIMToolProduct/CIMTool.product` — the `` entry -* `CIMToolProduct/build.properties` — where the bundle is referenced +* `CIMToolProduct/CIMTool.product`: the `` entry +* `CIMToolProduct/build.properties`: where the bundle is referenced * This README's product composition documentation Two cross-cutting layers apply to any vendored JAR, regardless of pattern: *Signing (release).* `release-cimtool.bat` discovers and signs every JAR in the exported `plugins/` directory automatically, so no per-JAR list is maintained for -signing — _except_ `SKIP_JARS`. A newly added JAR that cannot be signed (for example, +signing, _except_ `SKIP_JARS`. A newly added JAR that cannot be signed (for example, one already signed by its vendor) must be added to `SKIP_JARS`; a removed JAR should be pruned from it. *CLI (Maven / cimtool-cli).* If the CLI uses the library, it is vendored into the CLI's local `lib-repo/` rather than fetched from Maven Central. Update, together: -* `cimtool-cli/pom.xml` — the `` (groupId / artifactId / version) -* `cimtool-cli/install-jars.bat` and `cimtool-cli/install-jars.sh` — the `mvn install:install-file` line that seeds `lib-repo/` (keep the two in sync; the `.sh` retains LF line endings) -* `cimtool-cli/lib-repo/` — the installed artifact, regenerated by running `install-jars` +* `cimtool-cli/pom.xml`: the `` (groupId / artifactId / version) +* `cimtool-cli/install-jars.bat` and `cimtool-cli/install-jars.sh`: the `mvn install:install-file` line that seeds `lib-repo/` (keep the two in sync; the `.sh` retains LF line endings) +* `cimtool-cli/lib-repo/`: the installed artifact, regenerated by running `install-jars` === Relationship to cimtool-cli The PDE product export produces versioned plugin folders under `plugins/`. Two of -these — `au.com.langdale.kena_/kena.jar` and -`au.com.langdale.cimutil_/cimutil.jar` — are consumed by the +these, `au.com.langdale.kena_/kena.jar` and +`au.com.langdale.cimutil_/cimutil.jar`, are consumed by the `cimtool-cli` project's `install-jars.bat` script to assemble the standalone CLI uber JAR. See `cimtool-cli/cimtool-cli-README.adoc` for details. diff --git a/dev-docs/Includes/CIMToolProduct/CIMToolProduct-README.md b/dev-docs/Includes/CIMToolProduct/CIMToolProduct-README.md index d8ce0800..a268edcf 100644 --- a/dev-docs/Includes/CIMToolProduct/CIMToolProduct-README.md +++ b/dev-docs/Includes/CIMToolProduct/CIMToolProduct-README.md @@ -11,7 +11,7 @@ the Eclipse PDE build system uses to assemble a distributable CIMTool ZIP archiv ## Overview -In Eclipse PDE terminology a **product** is the outermost packaging unit — it +In Eclipse PDE terminology a **product** is the outermost packaging unit. It defines what an end user actually runs. The `CIMTool.product` file at the root of this project is the authoritative descriptor for everything about the CIMTool application from the user's perspective: its name, version, icons, splash screen, @@ -78,21 +78,20 @@ CIMToolProduct/ This project has **no compile-time dependencies**. It contains no Java source and does not declare `Require-Bundle` dependencies in its MANIFEST. Instead it -references other plugins by symbolic name in `CIMTool.product` via the `` -list — these are resolved by the PDE export at packaging time. +references other plugins by symbolic name in `CIMTool.product` via the `` list, which are resolved by the PDE export at packaging time. The plugins that CIMTool.product explicitly includes which are developed within this repository are: | Plugin | Symbolic Name | Role | | --- | --- | --- | -| CIMToolPlugin | `au.com.langdale.cimtoole` | Core Eclipse UI plugin — perspectives, editors, views, wizards, builders | +| CIMToolPlugin | `au.com.langdale.cimtoole` | Core Eclipse UI plugin: perspectives, editors, views, wizards, builders | | CIMUtil | `au.com.langdale.cimutil` | Profile processing, XMI import, validation, XSLT transforms, CLI entry point | | Kena | `au.com.langdale.kena` | RDF/OWL abstraction layer over Apache Jena | | RCPUtil | `au.com.langdale.rcputil` | Reusable Eclipse RCP UI utilities (binding, builder, plumbing) | | CIMToolHelp | `au.com.langdale.cimtoole.help` | Integrated HTML help documentation | -| com.cimphony.cimtoole | `com.cimphony.cimtoole` | CIMphony extensions — Ecore integration, additional buildlets | -| SLF4J Logback Binding | `io.ucaiug.slf4j.logback.binding` | OSGi fragment bundle — wires SLF4J 2.x to Logback as its logging provider | +| com.cimphony.cimtoole | `com.cimphony.cimtoole` | Cimphony extensions: Ecore integration, additional buildlets | +| SLF4J Logback Binding | `io.ucaiug.slf4j.logback.binding` | OSGi fragment bundle: wires SLF4J 2.x to Logback as its logging provider | All remaining plugins in the `` list are Eclipse platform and third-party plugins resolved from the active Eclipse target platform at export time. @@ -132,7 +131,7 @@ workspace. Key settings: - Places the perspective switcher in the top-right - Shows a progress indicator on startup -These are default values only — users can override them through Eclipse preferences +These are default values only, and users can override them through Eclipse preferences and their choices are persisted per-workspace. ### logging.properties @@ -146,8 +145,7 @@ application. This file is: `CIMToolPlugin.configureLogging()` installs `SLF4JBridgeHandler` at startup which redirects all JUL events into the SLF4J → Logback pipeline. `logging.properties` -is therefore retained solely to ensure JUL does not pre-filter events before they -reach the bridge — it declares `handlers=` empty and `.level=ALL`. The `FileHandler` +is therefore retained solely to ensure JUL does not pre-filter events before they reach the bridge, declaring `handlers=` empty and `.level=ALL`. The `FileHandler` that previously wrote to `logs/cimtool-%u-%g.log` has been removed; Logback is now the sole log output target. UCanAccess and HSQLDB are still suppressed at the JUL level (`SEVERE`) to prevent their noise from reaching the bridge at all. @@ -162,17 +160,17 @@ Configures Logback for the CIMTool application. This file is: 2. Extracted by `CIMToolPlugin.extractLoggingProperties()` to the installation root on first startup alongside `logging.properties` 3. Loaded by Logback via the `-Dlogback.configurationFile=./logback.xml` JVM argument -SLF4J is wired to Logback via the `io.ucaiug.slf4j.logback.binding` fragment bundle -— a minimal OSGi fragment that attaches to `slf4j.api` and provides the +SLF4J is wired to Logback via the `io.ucaiug.slf4j.logback.binding` fragment bundle, +a minimal OSGi fragment that attaches to `slf4j.api` and provides the `META-INF/services/org.slf4j.spi.SLF4JServiceProvider` registration that makes `LogbackServiceProvider` visible through `slf4j.api`'s classloader. This requires no bytecode weaving and has no impact on security scanning tools. The following logging sources route through `logback.xml`: -- **SLF4J API calls** — direct (Saxon-HE, m2e/Aether, UCanAccess, and other vendored libraries) -- **Log4j 1.x API calls** — routed via `log4j-over-slf4j` bridge in Kena -- **JUL API calls** — bridged via `SLF4JBridgeHandler` installed in `CIMToolPlugin.configureLogging()` at startup, including `System.out`/`System.err` console output in production mode which is routed through the `CIMTool.console` JUL logger +- **SLF4J API calls**: direct (Saxon-HE, m2e/Aether, UCanAccess, and other vendored libraries) +- **Log4j 1.x API calls**: routed via `log4j-over-slf4j` bridge in Kena +- **JUL API calls**: bridged via `SLF4JBridgeHandler` installed in `CIMToolPlugin.configureLogging()` at startup, including `System.out`/`System.err` console output in production mode which is routed through the `CIMTool.console` JUL logger `logback.xml` configures a rolling `FileAppender` writing to `logs/cimtool.log` under the installation root (5 × 10 MB rotating files), suppresses spurious @@ -190,18 +188,17 @@ Changes to `logback.xml` take effect on the next restart. ## Release Process -The CIMTool release process consists of four sequential phases. All phases must -be completed in order — no phase should begin until the previous one is fully +The CIMTool release process consists of four sequential phases. All phases must be completed in order, with no phase beginning until the previous one is fully complete and verified. | Phase | Description | | --- | --- | -| **1 — Pre-Build Preparation** | Versioning, release notes, PR to master | -| **2 — PDE Product Export** | Eclipse product export to a local directory | -| **3 — Code Signing and Packaging** | Signing, cimtool-cli build, ZIP assembly, checksums | -| **4 — Post-Build and Publishing** | `lib-repo/` PR, GitHub Release creation, tagging, artifact upload | +| **1: Pre-Build Preparation** | Versioning, release notes, PR to master | +| **2: PDE Product Export** | Eclipse product export to a local directory | +| **3: Code Signing and Packaging** | Signing, cimtool-cli build, ZIP assembly, checksums | +| **4: Post-Build and Publishing** | `lib-repo/` PR, GitHub Release creation, tagging, artifact upload | -### Phase 1 — Pre-Build Preparation +### Phase 1: Pre-Build Preparation All preparation work must be completed, reviewed, and merged to master via Pull Request **before** any build or signing activity begins. Master is intended to @@ -219,9 +216,9 @@ review and update is the mandatory first step in every release cycle. All CIMTool sub-projects follow **Semantic Versioning** as defined at [https://semver.org](https://semver.org). A version number takes the form `MAJOR.MINOR.PATCH`, where each element is incremented according to the following rules: -- **MAJOR** — incremented when incompatible API or behavioral changes are introduced that would break existing consumers of the component. -- **MINOR** — incremented when new functionality is added in a backward-compatible manner (new features, new builders, new extension points, etc.). -- **PATCH** — incremented for backward-compatible bug fixes, documentation corrections, or minor internal changes that do not alter the component's public interface or behavior. +- **MAJOR**: incremented when incompatible API or behavioral changes are introduced that would break existing consumers of the component. +- **MINOR**: incremented when new functionality is added in a backward-compatible manner (new features, new builders, new extension points, etc.). +- **PATCH**: incremented for backward-compatible bug fixes, documentation corrections, or minor internal changes that do not alter the component's public interface or behavior. #### Product-Aligned Projects @@ -230,10 +227,10 @@ The following projects must always be versioned in lockstep with the primary CIM | Project | Version Descriptor(s) | Notes | | --- | --- | --- | | CIMToolProduct | `CIMTool.product`, `META-INF/MANIFEST.MF`, `plugin.xml` | Primary release anchor | -| CIMToolPlugin | `META-INF/MANIFEST.MF` | Core UI plugin — ships in every release | +| CIMToolPlugin | `META-INF/MANIFEST.MF` | Core UI plugin, ships in every release | | CIMToolHelp | `META-INF/MANIFEST.MF` | Help content is release-specific | -| CIMUtil | `META-INF/MANIFEST.MF` | Core processing library — ships in every release | -| RCPUtil | `META-INF/MANIFEST.MF` | Eclipse RCP utility layer — ships in every release | +| CIMUtil | `META-INF/MANIFEST.MF` | Core processing library, ships in every release | +| RCPUtil | `META-INF/MANIFEST.MF` | Eclipse RCP utility layer, ships in every release | | CIMToolFeature | `feature.xml` | Top-level feature version matches the product version; internal plugin references use `0.0.0` and require no manual updates | > **Note:** Before running a product export at release time, verify that all version references above are updated and consistent. Exporting with stale or mismatched version values will produce an incorrectly versioned distribution that is difficult to retract once published. @@ -245,7 +242,7 @@ The following projects maintain their own version lifecycle and should only be u | Project | Current Version | Notes | | --- | --- | --- | | Kena | `3.4.0` | RDF/OWL abstraction library; versioned on its own API contract independent of the CIMTool release cycle. **When Kena's version changes, the `kena` dependency version in `cimtool-cli/pom.xml` must also be updated to match before running `install-jars.bat`.** | -| com.cimphony.cimtoole | `1.1.0` | CIMphony extensions; versioned independently of the core product | +| com.cimphony.cimtoole | `1.1.0` | Cimphony extensions; versioned independently of the core product | | CIMToolTest | `1.2.0` | Test suite; only increment when tests or test infrastructure are changed or added | #### Dormant Projects @@ -269,23 +266,23 @@ release being prepared must be added at the top of the file following the established format used by prior releases. The content of this entry is also used verbatim as the release notes body when -creating the GitHub Release in Phase 4. Authoring the release notes here first — -as part of the pre-build PR — ensures the notes are reviewed before publication +creating the GitHub Release in Phase 4. Authoring the release notes here first, +as part of the pre-build PR, ensures the notes are reviewed before publication and that the GitHub Release and the public website remain in sync. Once versioning updates and release notes are complete, open a Pull Request to merge all changes to master and obtain the required review approval before proceeding. -### Phase 2 — PDE Product Export +### Phase 2: PDE Product Export -The CIMTool distribution is produced via the Eclipse PDE product export. The export must always target a **Directory** destination — the distribution ZIP is produced by the code signing pipeline in the subsequent step, not by the PDE exporter directly. +The CIMTool distribution is produced via the Eclipse PDE product export. The export must always target a **Directory** destination. The distribution ZIP is produced by the code signing pipeline in the subsequent step, not by the PDE exporter directly. 1. From the Eclipse menu select **File > Export** 2. In the Export dialog select **Plug-in Development > Eclipse product** and click **Next** 3. Set the fields as shown in the screenshot below: - **Configuration:** `/CIMToolProduct/CIMTool.product` - - **Root directory:** `CIMTool-` (e.g. `CIMTool-2.3.0-RC8`) — replace with the actual release version being built + - **Root directory:** `CIMTool-` (e.g. `CIMTool-2.3.0-RC8`), replaced with the actual release version being built - **Destination:** Select **Directory** and set the path to your release staging area (e.g. `D:\CIMTool-Releases`) - Check **Synchronize before exporting** - Check **Allow for binary cycles in target platform** @@ -316,11 +313,11 @@ The export produces a versioned directory under the destination path: > `au.com.langdale.cimtool.product` plugin bundle at first startup by > `CIMToolPlugin.extractLoggingProperties()`. -Once the export completes, proceed immediately to Phase 3 — Code Signing and Packaging before creating the distribution ZIP. +Once the export completes, proceed immediately to Phase 3, Code Signing and Packaging, before creating the distribution ZIP. -### Phase 3 — Code Signing and Packaging +### Phase 3: Code Signing and Packaging > ⚠️ **Authorized Personnel Only** > @@ -339,7 +336,7 @@ Once the export completes, proceed immediately to Phase 3 — Code Signing and P All CIMTool release artifacts must be code signed before distribution. Signing serves two purposes: it assures end users that the software originates from the UCA International Users Group and has not been tampered with, and it prevents Windows SmartScreen from flagging the `CIMTool.exe` launcher as an unknown or untrusted application. -CIMTool uses an EV (Extended Validation) code signing certificate issued to **UCA USERS GROUP** by TrustID (IdenTrust). The certificate is stored on a SafeNet USB hardware token and the private key never leaves the token — all signing operations are performed on the hardware itself. +CIMTool uses an EV (Extended Validation) code signing certificate issued to **UCA USERS GROUP** by TrustID (IdenTrust). The certificate is stored on a SafeNet USB hardware token and the private key never leaves the token. All signing operations are performed on the hardware itself. > **Certificate renewal:** The UCA Users Group EV code signing certificate is renewed annually per industry requirements. All releases must therefore be signed with an RFC 3161 TSA timestamp so that signed artifacts remain valid after the certificate expires. Releases signed with a timestamp remain trusted indefinitely regardless of certificate expiry. @@ -347,24 +344,24 @@ CIMTool uses an EV (Extended Validation) code signing certificate issued to **UC Ensure the following are in place on the build machine before running the signing script: -1. **Eclipse Temurin JDK 20** — must be installed from [https://adoptium.net](https://adoptium.net). Temurin is specifically required because it includes the `SunPKCS11` security provider that `jarsigner` uses to communicate with the IdenTrust EV hardware token. Other OpenJDK distributions such as Zulu omit this provider and cannot be used for JAR signing. The script expects `jarsigner` at `C:\Program Files\Eclipse Adoptium\jdk-20.0.2.9-hotspot\bin\jarsigner.exe` (the default install location for the `OpenJDK20U-jdk_x64_windows_hotspot_20.0.2_9` installer) — update the `JARSIGNER` variable in the script if your installation path differs. +1. **Eclipse Temurin JDK 20**: must be installed from [https://adoptium.net](https://adoptium.net). Temurin is specifically required because it includes the `SunPKCS11` security provider that `jarsigner` uses to communicate with the IdenTrust EV hardware token. Other OpenJDK distributions such as Zulu omit this provider and cannot be used for JAR signing. The script expects `jarsigner` at `C:\Program Files\Eclipse Adoptium\jdk-20.0.2.9-hotspot\bin\jarsigner.exe` (the default install location for the `OpenJDK20U-jdk_x64_windows_hotspot_20.0.2_9` installer); update the `JARSIGNER` variable in the script if your installation path differs. -2. **Windows SDK `signtool.exe`** — used to apply Authenticode signatures to `CIMTool.exe`. Installed with Visual Studio or as a standalone Windows SDK download. The script expects it at `C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe` — update the `SIGNTOOL` variable in the script if your installation path differs. +2. **Windows SDK `signtool.exe`**: used to apply Authenticode signatures to `CIMTool.exe`. Installed with Visual Studio or as a standalone Windows SDK download. The script expects it at `C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe`; update the `SIGNTOOL` variable in the script if your installation path differs. -3. **SafeNet Authentication Client (SAC)** — must be installed **and running**, and the IdenTrust EV USB token must be inserted, before launching the script. Installing SAC is not sufficient on its own: the SafeNet service that backs the PKCS#11 library must be active for `jarsigner` and `keytool` to reach the token, so launch SafeNet Authentication Client and confirm it lists the inserted token before running `release-cimtool.bat`. SAC installs the PKCS#11 library at `C:\Windows\System32\eTPKCS11.dll`; if this file is not found the script automatically attempts the alternate location `C:\Windows\System32\pkcs11.dll`. +3. **SafeNet Authentication Client (SAC)**: must be installed **and running**, and the IdenTrust EV USB token must be inserted, before launching the script. Installing SAC is not sufficient on its own: the SafeNet service that backs the PKCS#11 library must be active for `jarsigner` and `keytool` to reach the token, so launch SafeNet Authentication Client and confirm it lists the inserted token before running `release-cimtool.bat`. SAC installs the PKCS#11 library at `C:\Windows\System32\eTPKCS11.dll`; if this file is not found the script automatically attempts the alternate location `C:\Windows\System32\pkcs11.dll`. -4. **Token PIN** — the script prompts for the hardware token PIN once at startup +4. **Token PIN**: the script prompts for the hardware token PIN once at startup using a masked input field. **No characters, asterisks, or cursor movement - appear as the PIN is typed** — this is expected; type the PIN and press Enter + appear as the PIN is typed**. This is expected; type the PIN and press Enter once. Wait for the prompt to appear before typing, and avoid pressing Enter on an empty line, which submits no PIN and fails without authenticating. The PIN is held in memory for the duration of the signing session, cleared immediately on completion, and never written to disk. -5. **Certificate alias** — The `CERT_ALIAS` variable in the script is set to the +5. **Certificate alias**: The `CERT_ALIAS` variable in the script is set to the UUID that the IdenTrust token uses internally to identify the certificate entry. Note that this UUID does not match the friendly display name (`UCA USERS GROUP`) - shown in the SafeNet Authentication Client GUI — `jarsigner` resolves aliases + shown in the SafeNet Authentication Client GUI, because `jarsigner` resolves aliases through the PKCS#11 provider which exposes the underlying token UUID. If the certificate is ever renewed onto a new token the alias UUID will change and the `CERT_ALIAS` variable must be updated. To rediscover the alias run the following @@ -381,24 +378,24 @@ Ensure the following are in place on the build machine before running the signin #### Hardware Token PIN Management and Lockout Prevention -The UCA Users Group EV code signing key — used to sign all UCA open source project releases, not CIMTool alone — is protected by a PIN held entirely on the hardware token, and the token enforces its own retry counter. A sequence of failed authentication attempts can lock the token, and — depending on how the token was provisioned — a fully locked token may require replacement and certificate re-issuance. Understanding the token's PIN model before running a signing session is therefore essential. +The UCA Users Group EV code signing key (used to sign all UCA open source project releases, not CIMTool alone) is protected by a PIN held entirely on the hardware token, and the token enforces its own retry counter. A sequence of failed authentication attempts can lock the token, and, depending on how the token was provisioned, a fully locked token may require replacement and certificate re-issuance. Understanding the token's PIN model before running a signing session is therefore essential. **PIN objects on the token.** The IdenTrust EV token used to sign UCA open source project releases is a SafeNet/Thales IDPrime device that exposes more than one PIN object, and they are not interchangeable: -- **Token Passcode** — the user PIN that protects the code signing key, with a maximum of **15** retries on this token. The retry counter resets to its maximum on *any* single successful authentication, so one correct login fully restores the budget. -- **Digital Signature PIN / PUK** — a separate PIN object (maximum 3 retries each) that exists on the token but does **not** protect the code signing key. Its much tighter limit is a hazard only if a signing operation is mistakenly bound to it. +- **Token Passcode**: the user PIN that protects the code signing key, with a maximum of **15** retries on this token. The retry counter resets to its maximum on *any* single successful authentication, so one correct login fully restores the budget. +- **Digital Signature PIN / PUK**: a separate PIN object (maximum 3 retries each) that exists on the token but does **not** protect the code signing key. Its much tighter limit is a hazard only if a signing operation is mistakenly bound to it. To confirm which PIN protects the signing key, open the certificate's **Private key** detail in SafeNet Authentication Client (SAC): Advanced View → Tokens → IdenTrust Token → User certificates → the certificate. The field **Token authentication on board** reading **No** confirms the key is gated by the standard Token Passcode rather than a separate on-board authentication object. On this token the signing key uses the **eToken Base Cryptographic Provider** with key specification **AT_KEYEXCHANGE**, gated by the Token Passcode. -![SafeNet Authentication Client private key detail showing the signing key gated by the Token Passcode — Token authentication on board reads No, with key specification AT_KEYEXCHANGE](readme-images/SAC_Private_Key_PIN_Binding.png) +![SafeNet Authentication Client private key detail showing the signing key gated by the Token Passcode. Token authentication on board reads No, with key specification AT_KEYEXCHANGE](readme-images/SAC_Private_Key_PIN_Binding.png) -> ⚠️ **Inspecting token status is safe; guessing the PIN is not.** Viewing the token's properties and retry counters in SAC consumes no attempts — only an actual authentication with an incorrect PIN decrements the counter. Before any signing session, inspect **Token Passcode retries remaining** in SAC. If it is below maximum, a previous session left the counter eroded; do not run anything that submits a PIN until the correct PIN is confirmed. Never "test" the token by trying candidate PINs. +> ⚠️ **Inspecting token status is safe; guessing the PIN is not.** Viewing the token's properties and retry counters in SAC consumes no attempts, since only an actual authentication with an incorrect PIN decrements the counter. Before any signing session, inspect **Token Passcode retries remaining** in SAC. If it is below maximum, a previous session left the counter eroded; do not run anything that submits a PIN until the correct PIN is confirmed. Never "test" the token by trying candidate PINs. ![SafeNet Authentication Client token detail showing Token Passcode retries remaining against the maximum of 15](readme-images/SAC_Token_Passcode_Retries.png) -**Why the signing script fails fast.** `release-cimtool.bat` signs the entire `plugins/` set — on the order of 150 JARs — in a single loop. If that loop continued past a failed signing attempt, an incorrect PIN or an unusable keystore would produce one failed token authentication *per JAR*, draining the retry counter and locking the token within a single run. To prevent this, the script treats the first JAR as a live token-access test: if the first signing attempt fails, the script aborts immediately, before any further `jarsigner` invocation. A misconfigured run therefore costs at most one attempt rather than the entire counter. This guard is intentional and must be preserved in any future revision of the signing pipeline. +**Why the signing script fails fast.** `release-cimtool.bat` signs the entire `plugins/` set, on the order of 150 JARs, in a single loop. If that loop continued past a failed signing attempt, an incorrect PIN or an unusable keystore would produce one failed token authentication *per JAR*, draining the retry counter and locking the token within a single run. To prevent this, the script treats the first JAR as a live token-access test: if the first signing attempt fails, the script aborts immediately, before any further `jarsigner` invocation. A misconfigured run therefore costs at most one attempt rather than the entire counter. This guard is intentional and must be preserved in any future revision of the signing pipeline. -> **Note — Distinguishing a keystore-load failure from a PIN failure:** Not every `jarsigner` failure is a wrong-PIN failure, and the distinction matters for the retry counter. A failure reported as `keystore load: load failed` or a provider error generally occurs in the JVM/PKCS#11 provider layer *before* a PIN is ever submitted to the token, and does not necessarily decrement the retry counter. A common cause on JDK 9 and later is the deprecated `-providerClass sun.security.pkcs11.SunPKCS11` invocation, which can fail to load the provider; the supported form is `-addprovider SunPKCS11` (retaining `-providerArg `). To verify token access independently of the full pipeline — and to reset the retry counter with a known-good PIN — run a single `keytool` listing with PKCS#11 debug enabled: +> **Note: Distinguishing a keystore-load failure from a PIN failure:** Not every `jarsigner` failure is a wrong-PIN failure, and the distinction matters for the retry counter. A failure reported as `keystore load: load failed` or a provider error generally occurs in the JVM/PKCS#11 provider layer *before* a PIN is ever submitted to the token, and does not necessarily decrement the retry counter. A common cause on JDK 9 and later is the deprecated `-providerClass sun.security.pkcs11.SunPKCS11` invocation, which can fail to load the provider; the supported form is `-addprovider SunPKCS11` (retaining `-providerArg `). To verify token access independently of the full pipeline, and to reset the retry counter with a known-good PIN, run a single `keytool` listing with PKCS#11 debug enabled: > ```cmd > "C:\Program Files\Eclipse Adoptium\jdk-20.0.2.9-hotspot\bin\keytool.exe" ^ > -list -keystore NONE -storetype PKCS11 ^ @@ -407,7 +404,7 @@ To confirm which PIN protects the signing key, open the certificate's **Private > ``` > A clean listing of the UCA USERS GROUP certificate confirms both that the provider invocation is correct and that the token is accessible. The `sunpkcs11` debug output names the underlying PKCS#11 `CKR_*` result code when something is wrong, which distinguishes a provider or library problem from a genuine PIN rejection. -> **Note — Recovering a locked token:** If the Token Passcode counter reaches zero the token locks. On this token the **Token unlock object** is the **Administrator Passcode** (there is no user PUK), which can reset the user PIN via SAC. However, possession of the Administrator Passcode depends on how IdenTrust provisioned the token — it is not always released to the subscriber, and it has its own independent retry limit that can also lock permanently. Do not rely on the admin unlock as a safety net unless the Administrator Passcode value is known to be held and recorded. Treat a lockout as a worst case that may require a replacement token and certificate re-issuance from IdenTrust. +> **Note: Recovering a locked token:** If the Token Passcode counter reaches zero the token locks. On this token the **Token unlock object** is the **Administrator Passcode** (there is no user PUK), which can reset the user PIN via SAC. However, possession of the Administrator Passcode depends on how IdenTrust provisioned the token; it is not always released to the subscriber, and it has its own independent retry limit that can also lock permanently. Do not rely on the admin unlock as a safety net unless the Administrator Passcode value is known to be held and recorded. Treat a lockout as a worst case that may require a replacement token and certificate re-issuance from IdenTrust. ![SafeNet Authentication Client token detail showing the Token unlock object is the Administrator Passcode, with the separate three-retry Digital Signature PIN and PUK](readme-images/SAC_Token_Unlock_Object.png) @@ -443,30 +440,29 @@ The script exits immediately with a non-zero error code if any step fails. The following screenshots illustrate a complete successful run of the signing pipeline. -**Confirm Prerequisites — Confirm EV USB token inserted and SafeNet Authentication Client running / Step 1 — Start JAR signing:** +**Confirm Prerequisites: Confirm EV USB token inserted and SafeNet Authentication Client running / Step 1: Start JAR signing:** ![Step 1 Insert EV USB Token and SafeNet PIN prompt](readme-images/Step1.png) -**Step 1 — JAR signing complete / Step 2 — CIMTool.exe signing begins:** +**Step 1: JAR signing complete / Step 2: CIMTool.exe signing begins:** ![Step 1 complete, Step 2 SafeNet PIN prompt](readme-images/Step2.png) When Step 2 begins, the SafeNet Authentication Client presents a native GUI dialog -prompting for the **Token Passcode** again. This second prompt is expected and -cannot be automated — `signtool` communicates with the hardware token through +prompting for the **Token Passcode** again. This second prompt is expected and cannot be automated, because `signtool` communicates with the hardware token through Windows CryptoAPI rather than the PKCS#11 path used by `jarsigner`, which triggers a separate authentication dialog from the SafeNet middleware. Enter the token PIN in this dialog and click **OK** to proceed. -**Step 2 complete / Step 3 — Distribution archive creation in progress:** +**Step 2 complete / Step 3: Distribution archive creation in progress:** ![Step 2 complete, Step 3 ZIP creation progress](readme-images/Step3.png) -**Steps 3 and 4 complete — Successful completion summary:** +**Steps 3 and 4 complete: Successful completion summary:** ![Steps 3 and 4 complete, final summary](readme-images/Step4.png) -> **Note — Expected `jarsigner` console warnings:** During JAR signing the +> **Note: Expected `jarsigner` console warnings:** During JAR signing the > following three warnings will appear in the console output for every JAR > processed. They are all purely informational and do not indicate any problem > with the signing process. The presence of **`jar signed.`** after each JAR @@ -474,15 +470,15 @@ in this dialog and click **OK** to proceed. > > - `The timestamp will expire within one year on . However, the JAR will be valid until the signer certificate expires on .` > This warning has two distinct subjects that are easy to conflate. The first -> date refers to the **TSA server's own infrastructure certificate** — the +> date refers to the **TSA server's own infrastructure certificate**, the > IdenTrust timestamp authority server's cert, not the UCA Users Group signing > cert and not the timestamp embedded in the JAR. When that cert expires > IdenTrust simply renews it as with any server cert, and it has no effect > whatsoever on timestamps already embedded in signed JARs. The second date is -> the EV signing certificate's expiry — `jarsigner` is confirming that the JAR +> the EV signing certificate's expiry, with `jarsigner` confirming that the JAR > remains valid through the signing cert's full lifetime. > More importantly: once a JAR is signed with a TSA timestamp embedded, it -> remains trusted and valid **indefinitely** — even after the EV signing cert +> remains trusted and valid **indefinitely**, even after the EV signing cert > expires. The timestamp is permanent cryptographic proof that the signature was > created while the cert was valid. This is how every major software vendor ships > signed software and is precisely why timestamping is mandatory for all release @@ -493,20 +489,20 @@ in this dialog and click **OK** to proceed. > are simply ignored by `jarsigner` during the signing process. > > - `The signer certificate will expire on .` -> Informational only — confirms the expiry date of the EV signing certificate. +> Informational only, confirming the expiry date of the EV signing certificate. > No action required until renewal time. -> **Note — Unpacked plugin resources:** Some plugins in the CIMTool distribution +> **Note: Unpacked plugin resources:** Some plugins in the CIMTool distribution > are deployed with resources unpacked directly onto the filesystem rather than > bundled inside a JAR. For example, the `au.com.langdale.cimutil_\builders\` > directory contains `.xsl` transform files that are written loose to disk so that > the Saxon XSLT processor can access them directly at runtime. These files are not -> covered by JAR signing — there is no JAR container for `jarsigner` to sign. Their +> covered by JAR signing, since there is no JAR container for `jarsigner` to sign. Their > integrity is instead protected by the SHA-256 checksum published alongside the ZIP > archive. Users who verify the checksum before extracting the distribution are > assured of the integrity of all contents, including unpacked resources. -> **Note — Third-party library JAR re-signing:** The `plugins/` directory contains +> **Note: Third-party library JAR re-signing:** The `plugins/` directory contains > third-party library JARs bundled under `\lib\` subdirectories (for example, > Saxon, Apache Commons, HSQLDB, and others under > `au.com.langdale.cimutil_\lib\`). These JARs were originally signed by @@ -514,27 +510,27 @@ in this dialog and click **OK** to proceed. > pipeline it replaces those original publisher signatures with the UCA Users Group > EV certificate signature. This is standard practice for Eclipse RCP distributions: > by re-signing all bundled JARs under a single certificate the UCA Users Group is -> asserting that this specific combination of libraries — as integrated, tested, and -> shipped in CIMTool — has been reviewed and vouched for. The original publisher +> asserting that this specific combination of libraries, as integrated, tested, and +> shipped in CIMTool, has been reviewed and vouched for. The original publisher > signatures served their purpose at the point of download; at the point of > redistribution the responsibility for the bundled artifact passes to the > distributor. Running `jarsigner -verify` on any `\lib\` JAR after signing will -> show the UCA Users Group signature rather than the original publisher signature — -> this is expected and correct. +> show the UCA Users Group signature rather than the original publisher signature. +> This is expected and correct. -> **Note — Known unsignable JARs:** One JAR in the distribution cannot be signed +> **Note: Known unsignable JARs:** One JAR in the distribution cannot be signed > due to a structural defect in the JAR itself that is outside of CIMTool's > control: `asp-server-asciidoctorj-dist.jar`, part of the `de.jcup.asciidoctoreditor` > plugin. It contains a duplicate `META-INF/BSDL` entry in its internal ZIP > structure which causes `jarsigner` to reject it with a `ZipException: duplicate entry` > error. The signing script handles this automatically via the `SKIP_JARS` -> configuration variable — the JAR is skipped without aborting the pipeline and +> configuration variable; the JAR is skipped without aborting the pipeline and > is reported in the final summary as a skipped entry rather than an error. The > JAR remains protected by the distribution ZIP SHA-256 checksum. If future > releases of the AsciiDoc editor plugin correct this defect, the entry can be > removed from `SKIP_JARS`. -### Phase 4 — Post-Build and Publishing +### Phase 4: Post-Build and Publishing #### Commit lib-repo/ Changes @@ -546,11 +542,11 @@ that must be committed back to master before the release is tagged. > **Note:** This commit is only required when the Kena or CIMUtil versions have > actually changed since the previous release. If both versions are unchanged, > `install-jars.bat` reinstalls identical JARs producing identical checksums, -> resulting in no git diff — and no PR is needed. +> resulting in no git diff, and no PR is needed. When changes are present, open a Pull Request containing only the `lib-repo/` changes, obtain review approval, and merge to master. **The tag must not be -created until this PR is merged** — the tag must capture the exact `lib-repo/` +created until this PR is merged**: the tag must capture the exact `lib-repo/` state that produced the release, so that any developer cloning at the tag can immediately run `mvn clean package` without needing to re-run `install-jars.bat`. @@ -558,13 +554,13 @@ immediately run `mvn clean package` without needing to re-run `install-jars.bat` Navigate to [https://github.com/cimug-org/CIMTool/releases](https://github.com/cimug-org/CIMTool/releases) and create a new release against the `master` target. By project convention the -release tag is a **new** tag named for the release version — not an existing tag. +release tag is a **new** tag named for the release version, not an existing tag. Open the **Select tag** dropdown, type the release version exactly as it should -appear (for this example, `2.3.0` — the bare version, with no `v` prefix, matching +appear (for this example, `2.3.0`, the bare version, with no `v` prefix, matching the existing tags such as `2.2.0`), and choose **Create new tag** so the tag is created on the `master` target when the release is published: -![GitHub release tag selection — create a new tag named for the release version, e.g. 2.3.0, targeting master](readme-images/Tag_Release.png) +![GitHub release tag selection: create a new tag named for the release version, e.g. 2.3.0, targeting master](readme-images/Tag_Release.png) Copy the release notes entry for this version from `docs/release-notes.md` into the release notes body. Attach all four release artifacts by dropping them @@ -578,7 +574,7 @@ into the Assets upload area highlighted below, then click **Publish release**: ![GitHub Release Assets upload area](readme-images/Release_Artifacts.png) Publishing the release simultaneously creates the tag on master at the current -HEAD commit — which at this point includes all pre-build version changes, release +HEAD commit, which at this point includes all pre-build version changes, release notes, and the post-build `lib-repo/` commit. This tagged commit is the definitive reproducible state for this release. @@ -602,43 +598,43 @@ In the event of future macOS support, `codesign` would be used in place of `sign ## Maintaining Vendored Third-Party Libraries -CIMTool does not pull third-party libraries from Maven Central at build time; every third-party JAR is vendored — committed to the repository and referenced explicitly. A vendored JAR is therefore referenced in several places at once, and adding, removing, or upgrading one requires updating *all* of its references in the same change. Missing one typically produces a build that passes in the IDE but fails at PDE export or runtime, or a CLI build that cannot resolve the dependency. +CIMTool does not pull third-party libraries from Maven Central at build time; every third-party JAR is vendored, committed to the repository and referenced explicitly. A vendored JAR is therefore referenced in several places at once, and adding, removing, or upgrading one requires updating *all* of its references in the same change. Missing one typically produces a build that passes in the IDE but fails at PDE export or runtime, or a CLI build that cannot resolve the dependency. There are two vendoring patterns, with different reference sets. -**Pattern A — JAR bundled inside a plugin.** The JAR lives in `/lib/` and is woven into that plugin's classpath. When it changes, update all of the following in that plugin, in lockstep: +**Pattern A: JAR bundled inside a plugin.** The JAR lives in `/lib/` and is woven into that plugin's classpath. When it changes, update all of the following in that plugin, in lockstep: -- `/lib/` — add, remove, or replace the physical JAR (the filename carries the version) -- `/META-INF/MANIFEST.MF` — the `Bundle-ClassPath` entry -- `/build.properties` — the `bin.includes` and/or `jars.extra.classpath` entry, so PDE export ships the JAR -- `/.classpath` — the `kind="lib"` classpath entry, so the IDE compiles against it -- The project's README — `Project Structure` tree and `Vendored Third-Party Libraries` table +- `/lib/`: add, remove, or replace the physical JAR (the filename carries the version) +- `/META-INF/MANIFEST.MF`: the `Bundle-ClassPath` entry +- `/build.properties`: the `bin.includes` and/or `jars.extra.classpath` entry, so PDE export ships the JAR +- `/.classpath`: the `kind="lib"` classpath entry, so the IDE compiles against it +- The project's README: `Project Structure` tree and `Vendored Third-Party Libraries` table Plugins using this pattern include CIMToolPlugin, CIMUtil, and Kena. -**Pattern B — library shipped as its own bundle in the product.** The library is a standalone OSGi bundle listed in the product. When it changes, update: +**Pattern B: library shipped as its own bundle in the product.** The library is a standalone OSGi bundle listed in the product. When it changes, update: -- `CIMToolProduct/CIMTool.product` — the `` entry -- `CIMToolProduct/build.properties` — where the bundle is referenced +- `CIMToolProduct/CIMTool.product`: the `` entry +- `CIMToolProduct/build.properties`: where the bundle is referenced - This README's product composition documentation Two cross-cutting layers apply to any vendored JAR, regardless of pattern: -**Signing (release).** `release-cimtool.bat` discovers and signs every JAR in the exported `plugins/` directory automatically, so no per-JAR list is maintained for signing — *except* `SKIP_JARS`. A newly added JAR that cannot be signed (for example, one already signed by its vendor) must be added to `SKIP_JARS`; a removed JAR should be pruned from it. +**Signing (release).** `release-cimtool.bat` discovers and signs every JAR in the exported `plugins/` directory automatically, so no per-JAR list is maintained for signing, *except* `SKIP_JARS`. A newly added JAR that cannot be signed (for example, one already signed by its vendor) must be added to `SKIP_JARS`; a removed JAR should be pruned from it. **CLI (Maven / cimtool-cli).** If the CLI uses the library, it is vendored into the CLI's local `lib-repo/` rather than fetched from Maven Central. Update, together: -- `cimtool-cli/pom.xml` — the `` (groupId / artifactId / version) -- `cimtool-cli/install-jars.bat` and `cimtool-cli/install-jars.sh` — the `mvn install:install-file` line that seeds `lib-repo/` (keep the two in sync; the `.sh` retains LF line endings) -- `cimtool-cli/lib-repo/` — the installed artifact, regenerated by running `install-jars` +- `cimtool-cli/pom.xml`: the `` (groupId / artifactId / version) +- `cimtool-cli/install-jars.bat` and `cimtool-cli/install-jars.sh`: the `mvn install:install-file` line that seeds `lib-repo/` (keep the two in sync; the `.sh` retains LF line endings) +- `cimtool-cli/lib-repo/`: the installed artifact, regenerated by running `install-jars` ## Relationship to cimtool-cli The PDE product export produces versioned plugin folders under `plugins/`. Two of -these — `au.com.langdale.kena_/kena.jar` and -`au.com.langdale.cimutil_/cimutil.jar` — are consumed by the +these, `au.com.langdale.kena_/kena.jar` and +`au.com.langdale.cimutil_/cimutil.jar`, are consumed by the `cimtool-cli` project's `install-jars.bat` script to assemble the standalone CLI uber JAR. See `cimtool-cli/cimtool-cli-README.adoc` for details. diff --git a/dev-docs/Includes/CIMToolTest/CIMToolTest-README.adoc b/dev-docs/Includes/CIMToolTest/CIMToolTest-README.adoc index 778a18fb..672f7872 100644 --- a/dev-docs/Includes/CIMToolTest/CIMToolTest-README.adoc +++ b/dev-docs/Includes/CIMToolTest/CIMToolTest-README.adoc @@ -22,18 +22,18 @@ suite are welcome. === Overview -CIMToolTest is structured as an Eclipse *plugin fragment* — its `MANIFEST.MF` +CIMToolTest is structured as an Eclipse *plugin fragment* whose `MANIFEST.MF` declares `Fragment-Host: au.com.langdale.cimtoole`, which means it attaches directly to the `CIMToolPlugin` bundle at runtime and has access to all of its -packages without requiring explicit exports. This is the standard Eclipse pattern -for test fragments: the tests run inside the same OSGi bundle as the code under -test, giving them access to package-private and internal APIs. +packages without requiring explicit exports. This is the standard Eclipse +pattern for test fragments: the tests run inside the same OSGi bundle as the +code under test, giving them access to package-private and internal APIs. The test suite is divided into two main categories: -* *Headless tests* — run without a UI, exercising the core model, validation, +* *Headless tests*: run without a UI, exercising the core model, validation, schema processing, Kena RDF layer, and incremental build logic -* *UI tests* — exercise the Eclipse wizard and workbench UI components using +* *UI tests*: exercise the Eclipse wizard and workbench UI components using the Eclipse SWTBot-style workbench testing infrastructure A set of CIM/XML and Turtle validation fixture files in `src/ValidationCases/` @@ -137,7 +137,7 @@ dependencies on: | Bundle | Role in tests | `org.junit` (4.x) -| JUnit 4 test framework — `@Test`, `assertEquals`, `TestCase` base class +| JUnit 4 test framework: `@Test`, `assertEquals`, `TestCase` base class | `au.com.langdale.kena` | Used directly in `KenaTests` to test the RDF/OWL graph API independently @@ -150,7 +150,7 @@ dependencies on: assert the presence or absence of problem markers | `org.eclipse.core.runtime` -| OSGi runtime utilities — `IProgressMonitor`, `CoreException`, `IPath` +| OSGi runtime utilities: `IProgressMonitor`, `CoreException`, `IPath` | `org.eclipse.ui` | Workbench APIs used by the UI test base classes @@ -172,19 +172,19 @@ These tests run without a display and exercise the core CIMTool logic: | Kena RDF/OWL model creation, traversal, resource lookup, and serialization | `SchemaTests` -| CIM/XML validation against the CPSM profile without topology constraints — +| CIM/XML validation against the CPSM profile without topology constraints: exercises cardinality, type, range, and domain checks across all validation fixture cases | `TopologyTests` -| CIM/XML validation against the CPSM profile with topology constraints — +| CIM/XML validation against the CPSM profile with topology constraints: exercises terminal connectivity, isolated node, and loop detection cases | `IncrementalTests` -| Incremental model change processing — add and remove cases, delta handling +| Incremental model change processing: add and remove cases, delta handling | `SplitReaderTest` -| Split CIM/XML file reader — multi-file model assembly +| Split CIM/XML file reader: multi-file model assembly | `ExtractorTest` | XMI/EA model extraction and parsing @@ -202,10 +202,10 @@ These tests require a running Eclipse workbench and exercise the wizard UI: | Test Class | What it tests | `ModelWizards` -| Model import wizard flows — XMI, EA project, and schema import +| Model import wizard flows: XMI, EA project, and schema import | `ProfileWizards` -| Profile creation wizard — new profile, namespace setup +| Profile creation wizard: new profile, namespace setup | `SchemaWizards` | Schema import wizard flows @@ -230,8 +230,8 @@ pair represents a specific validation scenario: Two OWL profile files drive the validation: -* `cpsm2007.owl` — the CPSM profile including topology constraints, used by `TopologyTests` -* `cpsm2007_no_topol.owl` — the CPSM profile without topology, used by `SchemaTests` +* `cpsm2007.owl`: the CPSM profile including topology constraints, used by `TopologyTests` +* `cpsm2007_no_topol.owl`: the CPSM profile without topology, used by `SchemaTests` The `build.sh` and `run.sh` scripts in `ValidationCases/` support standalone execution of the validation fixtures outside of the Eclipse test runner. @@ -243,7 +243,7 @@ execution of the validation fixtures outside of the Eclipse test runner. The `CIMToolTestFiles/` folder at the project root contains two ZIP archives that provide test fixture data at runtime: -==== CIMToolTestFiles.zip — Fully Implemented +==== CIMToolTestFiles.zip: Fully Implemented This is the primary test data archive. `ProjectTest.setUpTestData()` loads it automatically via the OSGi classloader on every `setUp()` call: @@ -257,12 +257,12 @@ unzip(is, getSamplesFolder()); The extracted folder is placed adjacent to the test workspace root and torn down after each test in `tearDown()`. It contains the schema files, OWL profiles, rules files, and other inputs referenced by the constants in -`ProjectTest` — `SAMPLE_SCHEMA_XMI`, `SAMPLE_SCHEMA_EAP`, `SAMPLE_SCHEMA_QEA`, +`ProjectTest`: `SAMPLE_SCHEMA_XMI`, `SAMPLE_SCHEMA_EAP`, `SAMPLE_SCHEMA_QEA`, `SAMPLE_PROFILE`, `SAMPLE_RULES`, etc. All tests that extend `ProjectTest` (the majority of the test suite) depend on this ZIP being present and correctly bundled. -==== IOP10Kit.zip — Pending Implementation +==== IOP10Kit.zip: Pending Implementation This archive contains the `ABB40BusIOP10_rev7` split model folder used by `SplitReaderTest` and `ExtractorTest`. Currently these tests locate the folder diff --git a/dev-docs/Includes/CIMToolTest/CIMToolTest-README.md b/dev-docs/Includes/CIMToolTest/CIMToolTest-README.md index f48db17d..9eb5d31a 100644 --- a/dev-docs/Includes/CIMToolTest/CIMToolTest-README.md +++ b/dev-docs/Includes/CIMToolTest/CIMToolTest-README.md @@ -13,8 +13,7 @@ profile transforms, topology processing, and UI wizards. ## Overview -CIMToolTest is structured as an Eclipse **plugin fragment** — its `MANIFEST.MF` -declares `Fragment-Host: au.com.langdale.cimtoole`, which means it attaches +CIMToolTest is structured as an Eclipse **plugin fragment** whose `MANIFEST.MF` declares `Fragment-Host: au.com.langdale.cimtoole`, which means it attaches directly to the `CIMToolPlugin` bundle at runtime and has access to all of its packages without requiring explicit exports. This is the standard Eclipse pattern for test fragments: the tests run inside the same OSGi bundle as the code under @@ -22,8 +21,8 @@ test, giving them access to package-private and internal APIs. The test suite is divided into two main categories: -- **Headless tests** — run without a UI, exercising the core model, validation, schema processing, Kena RDF layer, and incremental build logic -- **UI tests** — exercise the Eclipse wizard and workbench UI components using the Eclipse workbench testing infrastructure +- **Headless tests**: run without a UI, exercising the core model, validation, schema processing, Kena RDF layer, and incremental build logic +- **UI tests**: exercise the Eclipse wizard and workbench UI components using the Eclipse workbench testing infrastructure A set of CIM/XML and Turtle validation fixture files in `src/ValidationCases/` provides the test data used by the validation and schema test classes. @@ -121,11 +120,11 @@ dependencies on: | Bundle | Role in tests | | --- | --- | -| `org.junit` (4.x) | JUnit 4 test framework — `@Test`, `assertEquals`, `TestCase` base class | +| `org.junit` (4.x) | JUnit 4 test framework: `@Test`, `assertEquals`, `TestCase` base class | | `au.com.langdale.kena` | Used directly in `KenaTests` to test the RDF/OWL graph API independently | | `au.com.langdale.rcputil` | Eclipse UI utilities needed by workbench-level test base classes | | `org.eclipse.core.resources` | Workspace and project resource APIs used to set up test projects and assert the presence or absence of problem markers | -| `org.eclipse.core.runtime` | OSGi runtime utilities — `IProgressMonitor`, `CoreException`, `IPath` | +| `org.eclipse.core.runtime` | OSGi runtime utilities: `IProgressMonitor`, `CoreException`, `IPath` | | `org.eclipse.ui` | Workbench APIs used by the UI test base classes | @@ -139,10 +138,10 @@ These tests run without a display and exercise the core CIMTool logic: | Test Class | What it tests | | --- | --- | | `KenaTests` | Kena RDF/OWL model creation, traversal, resource lookup, and serialization | -| `SchemaTests` | CIM/XML validation against the CPSM profile without topology constraints — exercises cardinality, type, range, and domain checks across all validation fixture cases | -| `TopologyTests` | CIM/XML validation against the CPSM profile with topology constraints — exercises terminal connectivity, isolated node, and loop detection cases | -| `IncrementalTests` | Incremental model change processing — add and remove cases, delta handling | -| `SplitReaderTest` | Split CIM/XML file reader — multi-file model assembly | +| `SchemaTests` | CIM/XML validation against the CPSM profile without topology constraints: exercises cardinality, type, range, and domain checks across all validation fixture cases | +| `TopologyTests` | CIM/XML validation against the CPSM profile with topology constraints: exercises terminal connectivity, isolated node, and loop detection cases | +| `IncrementalTests` | Incremental model change processing: add and remove cases, delta handling | +| `SplitReaderTest` | Split CIM/XML file reader: multi-file model assembly | | `ExtractorTest` | XMI/EA model extraction and parsing | | `ProfileBuildletConfigUtilsTest` | JSON serialization and deserialization of buildlet configuration objects | @@ -152,8 +151,8 @@ These tests require a running Eclipse workbench and exercise the wizard UI: | Test Class | What it tests | | --- | --- | -| `ModelWizards` | Model import wizard flows — XMI, EA project, and schema import | -| `ProfileWizards` | Profile creation wizard — new profile, namespace setup | +| `ModelWizards` | Model import wizard flows: XMI, EA project, and schema import | +| `ProfileWizards` | Profile creation wizard: new profile, namespace setup | | `SchemaWizards` | Schema import wizard flows | | `RuleWizards` | Ruleset creation and import wizard flows | | `CustomBuildersWizards` | Custom transform builder configuration wizard | @@ -171,8 +170,8 @@ pair represents a specific validation scenario: Two OWL profile files drive the validation: -- `cpsm2007.owl` — the CPSM profile including topology constraints, used by `TopologyTests` -- `cpsm2007_no_topol.owl` — the CPSM profile without topology, used by `SchemaTests` +- `cpsm2007.owl`: the CPSM profile including topology constraints, used by `TopologyTests` +- `cpsm2007_no_topol.owl`: the CPSM profile without topology, used by `SchemaTests` The `build.sh` and `run.sh` scripts in `ValidationCases/` support standalone execution of the validation fixtures outside of the Eclipse test runner. @@ -184,7 +183,7 @@ execution of the validation fixtures outside of the Eclipse test runner. The `CIMToolTestFiles/` folder at the project root contains two ZIP archives that provide test fixture data at runtime. -### CIMToolTestFiles.zip — Fully Implemented +### CIMToolTestFiles.zip: Fully Implemented This is the primary test data archive. `ProjectTest.setUpTestData()` loads it automatically via the OSGi classloader on every `setUp()` call: @@ -198,12 +197,12 @@ unzip(is, getSamplesFolder()); The extracted folder is placed adjacent to the test workspace root and torn down after each test in `tearDown()`. It contains the schema files, OWL profiles, rules files, and other inputs referenced by the constants in -`ProjectTest` — `SAMPLE_SCHEMA_XMI`, `SAMPLE_SCHEMA_EAP`, `SAMPLE_SCHEMA_QEA`, +`ProjectTest`: `SAMPLE_SCHEMA_XMI`, `SAMPLE_SCHEMA_EAP`, `SAMPLE_SCHEMA_QEA`, `SAMPLE_PROFILE`, `SAMPLE_RULES`, etc. All tests that extend `ProjectTest` (the majority of the test suite) depend on this ZIP being present and correctly bundled. -### IOP10Kit.zip — Pending Implementation +### IOP10Kit.zip: Pending Implementation This archive contains the `ABB40BusIOP10_rev7` split model folder used by `SplitReaderTest` and `ExtractorTest`. Currently these tests locate the folder diff --git a/dev-docs/Includes/CIMToolUpdate/CIMToolUpdate-README.adoc b/dev-docs/Includes/CIMToolUpdate/CIMToolUpdate-README.adoc index 20da293f..d482bf20 100644 --- a/dev-docs/Includes/CIMToolUpdate/CIMToolUpdate-README.adoc +++ b/dev-docs/Includes/CIMToolUpdate/CIMToolUpdate-README.adoc @@ -24,12 +24,12 @@ and uploading platform-specific ZIP archives to Amazon S3. [[status]] -=== Current Status — Legacy / Dormant +=== Current Status: Legacy / Dormant CIMToolUpdate is *not actively used*. The update site it referenced (`http://files.cimtool.org`) is defunct, and the current CIMTool distribution model uses a standalone ZIP archive produced directly by the PDE product export -in `CIMToolProduct` — no update site or S3 upload step is involved. +in `CIMToolProduct`, with no update site or S3 upload step involved. This project has no `MANIFEST.MF`, no `build.properties`, and no Eclipse plugin or feature structure. It is a plain Eclipse project (`.project` only) containing @@ -38,7 +38,7 @@ a handful of files left over from the original deployment pipeline. Additional indicators of dormancy: * `site.xml` references `au.com.langdale.cimtoole.feature` at version - `1.8.3.201008171439` — a build timestamp from 2010, far behind the current + `1.8.3.201008171439`: a build timestamp from 2010, far behind the current `2.3.0` release * `makepackages.sh` uploads to `files.cimtool.org` via an `s3` command-line tool that is no longer configured @@ -84,11 +84,11 @@ effect on the current build. === Relationship to Other Projects -* *CIMToolFeature* — `site.xml` references the feature produced by `CIMToolFeature` +* *CIMToolFeature*: `site.xml` references the feature produced by `CIMToolFeature` (`au.com.langdale.cimtoole.feature`). Both projects are dormant and were part of the same legacy update site deployment pipeline. -* *CIMToolProduct* — the active replacement for this project's distribution role. +* *CIMToolProduct*: the active replacement for this project's distribution role. The PDE product export in `CIMToolProduct` produces the ZIP archive directly without any separate packaging or upload step. @@ -100,7 +100,7 @@ If Eclipse update site / p2 deployment is ever reinstated, the following would be required: . Reinstate `CIMToolFeature` (set `useFeatures="true"` in `CIMTool.product`, - update versions — see `CIMToolFeature-README.adoc` for details) + update versions, see `CIMToolFeature-README.adoc` for details) . Update `site.xml` to reference the current feature version . Provision a new update site host and update the URL in `site.xml` and `CIMToolFeature/feature.xml` diff --git a/dev-docs/Includes/CIMToolUpdate/CIMToolUpdate-README.md b/dev-docs/Includes/CIMToolUpdate/CIMToolUpdate-README.md index 61c03292..80f29096 100644 --- a/dev-docs/Includes/CIMToolUpdate/CIMToolUpdate-README.md +++ b/dev-docs/Includes/CIMToolUpdate/CIMToolUpdate-README.md @@ -12,12 +12,12 @@ and uploading platform-specific ZIP archives to Amazon S3. -## Current Status — Legacy / Dormant +## Current Status: Legacy / Dormant CIMToolUpdate is **not actively used**. The update site it referenced (`http://files.cimtool.org`) is defunct, and the current CIMTool distribution model uses a standalone ZIP archive produced directly by the PDE product export -in `CIMToolProduct` — no update site or S3 upload step is involved. +in `CIMToolProduct`, with no update site or S3 upload step involved. This project has no `MANIFEST.MF`, no `build.properties`, and no Eclipse plugin or feature structure. It is a plain Eclipse project (`.project` only) containing @@ -25,7 +25,7 @@ a handful of files left over from the original deployment pipeline. Additional indicators of dormancy: -- `site.xml` references `au.com.langdale.cimtoole.feature` at version `1.8.3.201008171439` — a build timestamp from 2010, far behind the current `2.3.0` release +- `site.xml` references `au.com.langdale.cimtoole.feature` at version `1.8.3.201008171439`, a build timestamp from 2010, far behind the current `2.3.0` release - `makepackages.sh` uploads to `files.cimtool.org` via an `s3` command-line tool that is no longer configured - The `Assembly/` directory referenced in `makepackages.sh` is excluded via `.gitignore` and does not exist in the repository @@ -65,8 +65,8 @@ CIMToolUpdate/ ## Relationship to Other Projects -- **CIMToolFeature** — `site.xml` references the feature produced by `CIMToolFeature` (`au.com.langdale.cimtoole.feature`). Both projects are dormant and were part of the same legacy update site deployment pipeline. -- **CIMToolProduct** — the active replacement for this project's distribution role. The PDE product export in `CIMToolProduct` produces the ZIP archive directly without any separate packaging or upload step. +- **CIMToolFeature**: `site.xml` references the feature produced by `CIMToolFeature` (`au.com.langdale.cimtoole.feature`). Both projects are dormant and were part of the same legacy update site deployment pipeline. +- **CIMToolProduct**: the active replacement for this project's distribution role. The PDE product export in `CIMToolProduct` produces the ZIP archive directly without any separate packaging or upload step. @@ -75,7 +75,7 @@ CIMToolUpdate/ If Eclipse update site / p2 deployment is ever reinstated, the following would be required: -1. Reinstate `CIMToolFeature` (set `useFeatures="true"` in `CIMTool.product`, update versions — see `CIMToolFeature-README.adoc` for details) +1. Reinstate `CIMToolFeature` (set `useFeatures="true"` in `CIMTool.product`, update versions, see `CIMToolFeature-README.adoc` for details) 2. Update `site.xml` to reference the current feature version 3. Provision a new update site host and update the URL in `site.xml` and `CIMToolFeature/feature.xml` 4. Update `makepackages.sh` with the correct S3 bucket or hosting target diff --git a/dev-docs/Includes/CIMUtil/CIMUtil-README.adoc b/dev-docs/Includes/CIMUtil/CIMUtil-README.adoc index 8360edd9..71a0e61d 100644 --- a/dev-docs/Includes/CIMUtil/CIMUtil-README.adoc +++ b/dev-docs/Includes/CIMUtil/CIMUtil-README.adoc @@ -23,31 +23,31 @@ perspective. The Eclipse UI in `CIMToolPlugin` and the standalone CLI in CIMUtil (`au.com.langdale.cimutil`) serves two distinct roles: -. *Eclipse plugin* - required by `CIMToolPlugin` and `com.cimphony.cimtoole` +. *Eclipse plugin*: required by `CIMToolPlugin` and `com.cimphony.cimtoole` at runtime. Exports its packages via OSGi so they are available to other bundles in the Eclipse workbench. -. *Standalone library* - its compiled `cimutil.jar` is extracted from the PDE +. *Standalone library*: its compiled `cimutil.jar` is extracted from the PDE product export and installed into the `cimtool-cli` local Maven repository by `install-jars.bat`, where Maven Shade packages it into the CLI uber JAR. The key functional areas are: -* *XMI / EA project import* - parses Sparx Enterprise Architect `.eap`, `.eapx`, +* *XMI / EA project import*: parses Sparx Enterprise Architect `.eap`, `.eapx`, `.qea`, and `.qeax` project files (via UCanAccess / SQLite JDBC) and XMI exports into an RDF ontology graph via Kena -* *Profile model* - the CIM profile object model (`ProfileClass`, `ProfileModel`, +* *Profile model*: the CIM profile object model (`ProfileClass`, `ProfileModel`, `HierarchyModel`) and profile manipulation operations (reorganize, refactor, rename, remap, repair) -* *XSLT transform engine* - 34 XSLT builders in `builders/` that generate +* *XSLT transform engine*: 34 XSLT builders in `builders/` that generate diverse output artefacts (XSD, RDFS, OWL, JSON Schema, HTML, RTF, SQL, Java, Scala, C#, Avro, LinkML, PlantUML, AsciiDoc, and more) from a CIM profile -* *Validation* - CIM/XML and Turtle instance document validation against a +* *Validation*: CIM/XML and Turtle instance document validation against a profile using a Jena rules engine -* *CIM Modelling Guide compliance* - an Easy Rules engine with 100+ rules +* *CIM Modelling Guide compliance*: an Easy Rules engine with 100+ rules implementing the IEC CIM Modelling Guidelines, used to generate the audit/compliance report -* *CLI entry point* - `CIMToolCLI` and supporting classes in `profiles.cl` +* *CLI entry point*: `CIMToolCLI` and supporting classes in `profiles.cl` provide a headless command-line interface for profile transformation @@ -191,7 +191,7 @@ platform: | Saxon HE | 10.8 -| XSLT 2.0 / 3.0 processor - executes all builder stylesheets +| XSLT 2.0 / 3.0 processor: executes all builder stylesheets | Apache POI | 3.9 @@ -232,7 +232,7 @@ platform: | SLF4J API | 2.x (platform) | Logging facade used by Saxon-HE and other vendored dependencies. Resolved via -`Import-Package` rather than vendored — `MANIFEST.MF` declares `org.slf4j`, +`Import-Package` rather than vendored, `MANIFEST.MF` declares `org.slf4j`, `org.slf4j.event`, `org.slf4j.helpers`, and `org.slf4j.spi`, wiring these calls to the platform SLF4J 2.x bundle. Saxon's SLF4J log events route through the platform bundle into the Logback pipeline. @@ -384,56 +384,56 @@ using in-memory knowledge graphs. | `cimantic-graphs-init.xsl` | `.__init__.py` -| Companion builder to `cimantic-graphs.xsl` — generates the Python `__init__.py` +| Companion builder to `cimantic-graphs.xsl`: generates the Python `__init__.py` file required for library imports to work correctly. Both builders must be enabled together for the CIMantic Graphs output to be usable as a Python package. | `puml-rdfs-t2b.xsl` / `puml-rdfs-l2r.xsl` | `.rdfs-t2b.puml` / `.rdfs-l2r.puml` | Generates a PlantUML class diagram representing the profile classes and -relationships derived from an RDFS schema. Two layout variants — top-to-bottom +relationships derived from an RDFS schema. Two layout variants, top-to-bottom (`t2b`) and left-to-right (`l2r`). | `puml-xsd-t2b.xsl` / `puml-xsd-l2r.xsl` | `.xsd-t2b.puml` / `.xsd-l2r.puml` | Generates a PlantUML class diagram representing the profile classes and -relationships derived from an XSD schema. Two layout variants — top-to-bottom +relationships derived from an XSD schema. Two layout variants, top-to-bottom (`t2b`) and left-to-right (`l2r`). | `puml-json-t2b.xsl` / `puml-json-l2r.xsl` | `.json-t2b.puml` / `.json-l2r.puml` | Generates a PlantUML class diagram representing the profile classes and -relationships derived from a JSON Schema. Two layout variants — top-to-bottom +relationships derived from a JSON Schema. Two layout variants, top-to-bottom (`t2b`) and left-to-right (`l2r`). | `adoc-article-xsd.xsl` / `adoc-inline-xsd.xsl` | `.article-xsd.adoc` / `.inline-xsd.adoc` | Generates AsciiDoc documentation for a profile derived from an XSD schema. Two -structural variants — `article` (standalone AsciiDoc document) and `inline` +structural variants, `article` (standalone AsciiDoc document) and `inline` (content fragment for inclusion in a larger document). ^1^ | `adoc-article-rdfs.xsl` / `adoc-inline-rdfs.xsl` | `.article-rdfs.adoc` / `.inline-rdfs.adoc` | Generates AsciiDoc documentation for a profile derived from an RDFS schema. Two -structural variants — `article` (standalone AsciiDoc document) and `inline` +structural variants, `article` (standalone AsciiDoc document) and `inline` (content fragment for inclusion in a larger document). ^1^ | `adoc-article-json.xsl` / `adoc-inline-json.xsl` | `.article-json.adoc` / `.inline-json.adoc` | Generates AsciiDoc documentation for a profile derived from a JSON Schema. Two -structural variants — `article` (standalone AsciiDoc document) and `inline` +structural variants, `article` (standalone AsciiDoc document) and `inline` (content fragment for inclusion in a larger document). ^1^ | `adoc-article-rdfs-mappings.xsl` / `adoc-inline-rdfs-mappings.xsl` | `.article-rdfs-mappings.adoc` / `.inline-rdfs-mappings.adoc` -| Generates AsciiDoc documentation describing the RDFS mappings for a profile — +| Generates AsciiDoc documentation describing the RDFS mappings for a profile: classes, attributes, associations, and their corresponding RDFS/RDF URI mappings. -Two structural variants — `article` and `inline`. ^1^ +Two structural variants, `article` and `inline`. ^1^ |=== [.footnote] ^1^ The `article` and `inline` variants differ in their intended embedding context. -An *article* builder generates a complete, standalone AsciiDoc document — it includes +An *article* builder generates a complete, standalone AsciiDoc document; it includes a document title (`=`), preamble, and full section structure that can be processed independently by Asciidoctor to produce a self-contained HTML, PDF, or other output format. An *inline* builder generates only the body content of the documentation as @@ -450,15 +450,15 @@ The `easyrules/` package implements the CIM Modelling Guide compliance checker using the Easy Rules framework. Rules are organised into categories matching the IEC CIM Modelling Guidelines document structure: -* *Packages* - naming, uniqueness, visibility (Rules 025–182) -* *Classes* - naming, datatypes, abstract classes (Rules 038–187) -* *Attributes* - naming, types, multiplicity, scope (Rules 049–195) -* *Associations* - naming, roles, cardinality, directionality (Rules 065–198) -* *Enumerations* - structure, literal naming, stereotypes (Rules 084–205) -* *Descriptions* - documentation requirements (Rule 104) -* *Inheritance* - multiple inheritance, datatype inheritance (Rules 115–119) -* *Namespaces* - namespace URI and prefix requirements (Rules 143–146) -* *Extensions* - shadow class and user-defined extension rules +* *Packages*: naming, uniqueness, visibility (Rules 025–182) +* *Classes*: naming, datatypes, abstract classes (Rules 038–187) +* *Attributes*: naming, types, multiplicity, scope (Rules 049–195) +* *Associations*: naming, roles, cardinality, directionality (Rules 065–198) +* *Enumerations*: structure, literal naming, stereotypes (Rules 084–205) +* *Descriptions*: documentation requirements (Rule 104) +* *Inheritance*: multiple inheritance, datatype inheritance (Rules 115–119) +* *Namespaces*: namespace URI and prefix requirements (Rules 143–146) +* *Extensions*: shadow class and user-defined extension rules Each rule class implements the Easy Rules `Rule` interface and is annotated with `@RuleMetadata` declaring its rule number, severity, category, and type. @@ -481,18 +481,18 @@ by `cimtool-cli`. Key classes: | Class | Role | `CIMToolCLI` -| Main entry point - initialises JUL logging suppression, delegates to `run()` +| Main entry point: initialises JUL logging suppression, delegates to `run()` | `CLIOptions` | Parses and validates command-line arguments (`--project-dir`, `--builder`, `--output`, `--schema`, `--namespace`, `--help`, `--version`, `--list-builders`) | `CLIProfileTransformer` -| Orchestrates the headless transform pipeline - loads schema, loads profile, +| Orchestrates the headless transform pipeline: loads schema, loads profile, runs the selected builder stylesheet via Saxon | `CLISchemaParser` -| Headless XMI/EA project schema parser - wraps `EAPParser` / `QEAParser` for +| Headless XMI/EA project schema parser: wraps `EAPParser` / `QEAParser` for use outside the Eclipse workspace | `CLISettings` @@ -508,20 +508,20 @@ image::{cimutil-imagesdir}/CIMTool_CLI_Profile_Transformation_Sequence_Diagram.s === Relationship to Other Projects -* *Kena* - CIMUtil's single OSGi dependency. All RDF graph operations use the +* *Kena*: CIMUtil's single OSGi dependency. All RDF graph operations use the Kena `OntModel` API rather than calling Apache Jena directly. -* *CIMToolPlugin* - the Eclipse UI shell around CIMUtil's logic. The builder +* *CIMToolPlugin*: the Eclipse UI shell around CIMUtil's logic. The builder system, profile editors, import wizards, and validation views all delegate to CIMUtil classes. CIMToolPlugin does not duplicate any model processing. -* *com.cimphony.cimtoole* - extends CIMUtil's profile buildlet extension point +* *com.cimphony.cimtoole*: extends CIMUtil's profile buildlet extension point to add Ecore output support, and uses CIMUtil's profile model and Kena graph API directly. -* *cimtool-cli* - packages `cimutil.jar` (extracted from the PDE product export) +* *cimtool-cli*: packages `cimutil.jar` (extracted from the PDE product export) into a standalone uber JAR. At runtime the CLI uses `CIMToolCLI` as its entry point and `CLIProfileTransformer` for all transform operations. -* *CIMToolTest* - tests CIMUtil's validation engine, Kena integration, profile +* *CIMToolTest*: tests CIMUtil's validation engine, Kena integration, profile tasks, and transform pipeline via the `headless/` test package. diff --git a/dev-docs/Includes/CIMUtil/CIMUtil-README.md b/dev-docs/Includes/CIMUtil/CIMUtil-README.md index 4a9842de..6084c677 100644 --- a/dev-docs/Includes/CIMUtil/CIMUtil-README.md +++ b/dev-docs/Includes/CIMUtil/CIMUtil-README.md @@ -1,6 +1,6 @@ # CIMUtil -The core library plugin for CIMTool. It provides all model processing logic — +The core library plugin for CIMTool. It provides all model processing logic: XMI/EA project import, CIM profile manipulation, XSLT-based artefact generation, CIM/XML validation, CIM Modelling Guide compliance checking, and the standalone CLI entry point. It contains no Eclipse UI code of its own. @@ -15,18 +15,18 @@ perspective. The Eclipse UI in `CIMToolPlugin` and the standalone CLI in CIMUtil (`au.com.langdale.cimutil`) serves two distinct roles: -1. **Eclipse plugin** — required by `CIMToolPlugin` and `com.cimphony.cimtoole` at runtime. Exports its packages via OSGi so they are available to other bundles in the Eclipse workbench. +1. **Eclipse plugin**: required by `CIMToolPlugin` and `com.cimphony.cimtoole` at runtime. Exports its packages via OSGi so they are available to other bundles in the Eclipse workbench. -2. **Standalone library** — its compiled `cimutil.jar` is extracted from the PDE product export and installed into the `cimtool-cli` local Maven repository by `install-jars.bat`, where Maven Shade packages it into the CLI uber JAR. +2. **Standalone library**: its compiled `cimutil.jar` is extracted from the PDE product export and installed into the `cimtool-cli` local Maven repository by `install-jars.bat`, where Maven Shade packages it into the CLI uber JAR. The key functional areas are: -- **XMI / EA project import** — parses Sparx Enterprise Architect `.eap`, `.eapx`, `.qea`, and `.qeax` project files (via UCanAccess / SQLite JDBC) and XMI exports into an RDF ontology graph via Kena -- **Profile model** — the CIM profile object model (`ProfileClass`, `ProfileModel`, `HierarchyModel`) and profile manipulation operations (reorganize, refactor, rename, remap, repair) -- **XSLT transform engine** — 34 XSLT builders in `builders/` that generate diverse output artefacts (XSD, RDFS, OWL, JSON Schema, HTML, RTF, SQL, Java, Scala, C#, Avro, LinkML, PlantUML, AsciiDoc, and more) from a CIM profile -- **Validation** — CIM/XML and Turtle instance document validation against a profile using a Jena rules engine -- **CIM Modelling Guide compliance** — an Easy Rules engine with 100+ rules implementing the IEC CIM Modelling Guidelines, used to generate the audit/compliance report -- **CLI entry point** — `CIMToolCLI` and supporting classes in `profiles.cl` provide a headless command-line interface for profile transformation +- **XMI / EA project import**: parses Sparx Enterprise Architect `.eap`, `.eapx`, `.qea`, and `.qeax` project files (via UCanAccess / SQLite JDBC) and XMI exports into an RDF ontology graph via Kena +- **Profile model**: the CIM profile object model (`ProfileClass`, `ProfileModel`, `HierarchyModel`) and profile manipulation operations (reorganize, refactor, rename, remap, repair) +- **XSLT transform engine**: 34 XSLT builders in `builders/` that generate diverse output artefacts (XSD, RDFS, OWL, JSON Schema, HTML, RTF, SQL, Java, Scala, C#, Avro, LinkML, PlantUML, AsciiDoc, and more) from a CIM profile +- **Validation**: CIM/XML and Turtle instance document validation against a profile using a Jena rules engine +- **CIM Modelling Guide compliance**: an Easy Rules engine with 100+ rules implementing the IEC CIM Modelling Guidelines, used to generate the audit/compliance report +- **CLI entry point**: `CIMToolCLI` and supporting classes in `profiles.cl` provide a headless command-line interface for profile transformation @@ -143,13 +143,13 @@ CIMUtil has a single OSGi `Require-Bundle` dependency on another in-repository p ### Vendored Third-Party Libraries -> **Note — Keeping vendored libraries in sync:** Adding, removing, or upgrading any library listed in this section must be mirrored in the same change across this project's `META-INF/MANIFEST.MF` (`Bundle-ClassPath`), `build.properties`, and `.classpath`, as well as the repository-wide reference chain. See the [Vendored Library Change Checklist](../CIMToolProduct/CIMToolProduct-README.md#maintaining-vendored-third-party-libraries) in the CIMToolProduct documentation. +> **Note: Keeping vendored libraries in sync:** Adding, removing, or upgrading any library listed in this section must be mirrored in the same change across this project's `META-INF/MANIFEST.MF` (`Bundle-ClassPath`), `build.properties`, and `.classpath`, as well as the repository-wide reference chain. See the [Vendored Library Change Checklist](../CIMToolProduct/CIMToolProduct-README.md#maintaining-vendored-third-party-libraries) in the CIMToolProduct documentation. The following JARs are declared in `Bundle-ClassPath` in `MANIFEST.MF` and included in the plugin bundle: | Library | Version | Purpose | | --- | --- | --- | -| Saxon HE | 10.8 | XSLT 2.0 / 3.0 processor — executes all builder stylesheets | +| Saxon HE | 10.8 | XSLT 2.0 / 3.0 processor: executes all builder stylesheets | | Apache POI | 3.9 | Excel `.xls` spreadsheet reading for `SpreadsheetParser` | | UCanAccess | 4.0.4 | JDBC bridge for reading Sparx EA `.eap` and `.eapx` Access database files | | HSQLDB | 2.3.6 | In-memory SQL engine used internally by UCanAccess | @@ -159,7 +159,7 @@ The following JARs are declared in `Bundle-ClassPath` in `MANIFEST.MF` and inclu | Easy Rules Core + Support | 4.1.0 | Rule engine framework for CIM Modelling Guide compliance rules | | commons-lang | 2.6 | Apache Commons general utilities | | commons-logging | 1.1.3 | Logging facade used by vendored dependencies | -| SLF4J API | 2.x (platform) | Logging facade used by Saxon-HE and other vendored dependencies. Resolved via `Import-Package` rather than vendored — `MANIFEST.MF` declares `org.slf4j`, `org.slf4j.event`, `org.slf4j.helpers`, and `org.slf4j.spi`, wiring these calls to the platform SLF4J 2.x bundle. Saxon's SLF4J log events route through the platform bundle into the Logback pipeline. | +| SLF4J API | 2.x (platform) | Logging facade used by Saxon-HE and other vendored dependencies. Resolved via `Import-Package` rather than vendored: `MANIFEST.MF` declares `org.slf4j`, `org.slf4j.event`, `org.slf4j.helpers`, and `org.slf4j.spi`, wiring these calls to the platform SLF4J 2.x bundle. Saxon's SLF4J log events route through the platform bundle into the Logback pipeline. | | xml-resolver | 1.2 | XML catalog resolver for XSLT stylesheet includes | Three additional Easy Rules extension JARs are physically present in `lib/` but are intentionally excluded from `Bundle-ClassPath` and from the table above: `easy-rules-jexl-4.1.0.jar`, `easy-rules-mvel-4.1.0.jar`, and `easy-rules-spel-4.1.0.jar`. These provide JEXL, MVEL, and Spring EL expression language support for Easy Rules and are retained for planned future use. None of the current compliance rule implementations use these expression languages. @@ -191,16 +191,16 @@ The `builders/` directory contains 34 XSLT stylesheets registered in `builders.j | `sql.xsl` | `.sql` | Legacy generator for generating an ANSI SQL-92 compliant DDL script from a profile that is defined with the full class hierarchy and without anonymous or inline definitions. The legacy generator does not support CIM Compound classes and has been retained for backwards compatibility. | | `sql-rdfs-ansi92.xsl` | `.rdfs-ansi92.sql` | Generates an ANSI SQL-92 compliant DDL script from a profile that is defined with the full class hierarchy and without anonymous or inline definitions. | | `cimantic-graphs.xsl` | `.cimantic-graphs.py` | Generates a specialized Python dataclass schema for use with the [CIMantic Graphs](https://github.com/PNNL-CIMug/cimantic-graphs) open source library for creating, parsing, and editing CIM power system models using in-memory knowledge graphs. | -| `cimantic-graphs-init.xsl` | `.__init__.py` | Companion builder to `cimantic-graphs.xsl` — generates the Python `__init__.py` file required for library imports to work correctly. Both builders must be enabled together for the CIMantic Graphs output to be usable as a Python package. | -| `puml-rdfs-t2b.xsl` / `puml-rdfs-l2r.xsl` | `.rdfs-t2b.puml` / `.rdfs-l2r.puml` | Generates a PlantUML class diagram representing the profile classes and relationships derived from an RDFS schema. Two layout variants are provided — top-to-bottom (`t2b`) and left-to-right (`l2r`). | -| `puml-xsd-t2b.xsl` / `puml-xsd-l2r.xsl` | `.xsd-t2b.puml` / `.xsd-l2r.puml` | Generates a PlantUML class diagram representing the profile classes and relationships derived from an XSD schema. Two layout variants are provided — top-to-bottom (`t2b`) and left-to-right (`l2r`). | -| `puml-json-t2b.xsl` / `puml-json-l2r.xsl` | `.json-t2b.puml` / `.json-l2r.puml` | Generates a PlantUML class diagram representing the profile classes and relationships derived from a JSON Schema. Two layout variants are provided — top-to-bottom (`t2b`) and left-to-right (`l2r`). | -| `adoc-article-xsd.xsl` / `adoc-inline-xsd.xsl` | `.article-xsd.adoc` / `.inline-xsd.adoc` | Generates AsciiDoc documentation for a profile derived from an XSD schema. Two structural variants are provided — `article` (standalone AsciiDoc document) and `inline` (content fragment for inclusion in a larger document). ¹ | -| `adoc-article-rdfs.xsl` / `adoc-inline-rdfs.xsl` | `.article-rdfs.adoc` / `.inline-rdfs.adoc` | Generates AsciiDoc documentation for a profile derived from an RDFS schema. Two structural variants are provided — `article` (standalone AsciiDoc document) and `inline` (content fragment for inclusion in a larger document). ¹ | -| `adoc-article-json.xsl` / `adoc-inline-json.xsl` | `.article-json.adoc` / `.inline-json.adoc` | Generates AsciiDoc documentation for a profile derived from a JSON Schema. Two structural variants are provided — `article` (standalone AsciiDoc document) and `inline` (content fragment for inclusion in a larger document). ¹ | -| `adoc-article-rdfs-mappings.xsl` / `adoc-inline-rdfs-mappings.xsl` | `.article-rdfs-mappings.adoc` / `.inline-rdfs-mappings.adoc` | Generates AsciiDoc documentation describing the RDFS mappings for a profile — classes, attributes, associations, and their corresponding RDFS/RDF URI mappings. Two structural variants are provided — `article` and `inline`. ¹ | +| `cimantic-graphs-init.xsl` | `.__init__.py` | Companion builder to `cimantic-graphs.xsl`: generates the Python `__init__.py` file required for library imports to work correctly. Both builders must be enabled together for the CIMantic Graphs output to be usable as a Python package. | +| `puml-rdfs-t2b.xsl` / `puml-rdfs-l2r.xsl` | `.rdfs-t2b.puml` / `.rdfs-l2r.puml` | Generates a PlantUML class diagram representing the profile classes and relationships derived from an RDFS schema. Two layout variants are provided: top-to-bottom (`t2b`) and left-to-right (`l2r`). | +| `puml-xsd-t2b.xsl` / `puml-xsd-l2r.xsl` | `.xsd-t2b.puml` / `.xsd-l2r.puml` | Generates a PlantUML class diagram representing the profile classes and relationships derived from an XSD schema. Two layout variants are provided: top-to-bottom (`t2b`) and left-to-right (`l2r`). | +| `puml-json-t2b.xsl` / `puml-json-l2r.xsl` | `.json-t2b.puml` / `.json-l2r.puml` | Generates a PlantUML class diagram representing the profile classes and relationships derived from a JSON Schema. Two layout variants are provided: top-to-bottom (`t2b`) and left-to-right (`l2r`). | +| `adoc-article-xsd.xsl` / `adoc-inline-xsd.xsl` | `.article-xsd.adoc` / `.inline-xsd.adoc` | Generates AsciiDoc documentation for a profile derived from an XSD schema. Two structural variants are provided: `article` (standalone AsciiDoc document) and `inline` (content fragment for inclusion in a larger document). ¹ | +| `adoc-article-rdfs.xsl` / `adoc-inline-rdfs.xsl` | `.article-rdfs.adoc` / `.inline-rdfs.adoc` | Generates AsciiDoc documentation for a profile derived from an RDFS schema. Two structural variants are provided: `article` (standalone AsciiDoc document) and `inline` (content fragment for inclusion in a larger document). ¹ | +| `adoc-article-json.xsl` / `adoc-inline-json.xsl` | `.article-json.adoc` / `.inline-json.adoc` | Generates AsciiDoc documentation for a profile derived from a JSON Schema. Two structural variants are provided: `article` (standalone AsciiDoc document) and `inline` (content fragment for inclusion in a larger document). ¹ | +| `adoc-article-rdfs-mappings.xsl` / `adoc-inline-rdfs-mappings.xsl` | `.article-rdfs-mappings.adoc` / `.inline-rdfs-mappings.adoc` | Generates AsciiDoc documentation describing the RDFS mappings for a profile: classes, attributes, associations, and their corresponding RDFS/RDF URI mappings. Two structural variants are provided: `article` and `inline`. ¹ | -¹ The `article` and `inline` variants differ in their intended embedding context. An **article** builder generates a complete, standalone AsciiDoc document — it includes a document title (`=`), preamble, and full section structure that can be processed independently by Asciidoctor to produce a self-contained HTML, PDF, or other output format. An **inline** builder generates only the body content of the documentation as a fragment without a document header or title, designed to be pulled into a larger parent document using AsciiDoc's `include::` directive. Use the `article` variant when the profile documentation is the primary deliverable; use the `inline` variant when embedding profile documentation within a larger technical specification or report. +¹ The `article` and `inline` variants differ in their intended embedding context. An **article** builder generates a complete, standalone AsciiDoc document that includes a document title (`=`), preamble, and full section structure that can be processed independently by Asciidoctor to produce a self-contained HTML, PDF, or other output format. An **inline** builder generates only the body content of the documentation as a fragment without a document header or title, designed to be pulled into a larger parent document using AsciiDoc's `include::` directive. Use the `article` variant when the profile documentation is the primary deliverable; use the `inline` variant when embedding profile documentation within a larger technical specification or report. @@ -209,7 +209,7 @@ The `builders/` directory contains 34 XSLT stylesheets registered in `builders.j ## CIM Modelling Guide Rule Engine -The `easyrules/` package implements the CIM Modelling Guide compliance checker using the Easy Rules framework. Rules are organised into categories matching the IEC CIM Modelling Guidelines document structure — packages, classes, attributes, associations, enumerations, descriptions, inheritance, namespaces, and extensions — with over 100 rules in total. Each rule class implements the Easy Rules `Rule` interface and carries `@RuleMetadata` annotations declaring its rule number, severity, category, and type. Extension rule variants apply the same checks to user-defined CIM extension classes and packages. +The `easyrules/` package implements the CIM Modelling Guide compliance checker using the Easy Rules framework. Rules are organised into categories matching the IEC CIM Modelling Guidelines document structure (packages, classes, attributes, associations, enumerations, descriptions, inheritance, namespaces, and extensions) with over 100 rules in total. Each rule class implements the Easy Rules `Rule` interface and carries `@RuleMetadata` annotations declaring its rule number, severity, category, and type. Extension rule variants apply the same checks to user-defined CIM extension classes and packages. The compliance check runs during the CIMBuilder build cycle and results are written as an AsciiDoc report into the project's `/Schema` folder using the templates in `import-reports/`. @@ -221,10 +221,10 @@ The `profiles/cl/` package provides the standalone command-line interface used b | Class | Role | | --- | --- | -| `CIMToolCLI` | Main entry point — initialises logging, delegates to `run()` | +| `CIMToolCLI` | Main entry point: initialises logging, delegates to `run()` | | `CLIOptions` | Parses and validates command-line arguments (`--project-dir`, `--builder`, `--output`, `--schema`, `--namespace`, `--help`, `--version`, `--list-builders`) | -| `CLIProfileTransformer` | Orchestrates the headless transform pipeline — loads schema, loads profile, runs the selected builder stylesheet via Saxon | -| `CLISchemaParser` | Headless XMI/EA project schema parser — wraps `EAPParser` / `QEAParser` for use outside the Eclipse workspace | +| `CLIProfileTransformer` | Orchestrates the headless transform pipeline: loads schema, loads profile, runs the selected builder stylesheet via Saxon | +| `CLISchemaParser` | Headless XMI/EA project schema parser: wraps `EAPParser` / `QEAParser` for use outside the Eclipse workspace | | `CLISettings` | Adapts the CLI project directory structure to the `Settings` interface expected by the profile model | The following sequence diagram documents the full CLI transform pipeline architecture. @@ -235,8 +235,8 @@ The following sequence diagram documents the full CLI transform pipeline archite ## Relationship to Other Projects -- **Kena** — CIMUtil's single OSGi dependency. All RDF graph operations use the Kena `OntModel` API rather than calling Apache Jena directly. -- **CIMToolPlugin** — the Eclipse UI shell around CIMUtil's logic. The builder system, profile editors, import wizards, and validation views all delegate to CIMUtil classes. CIMToolPlugin does not duplicate any model processing. -- **com.cimphony.cimtoole** — extends CIMUtil's profile buildlet extension point to add Ecore output support, and uses CIMUtil's profile model and Kena graph API directly. -- **cimtool-cli** — packages `cimutil.jar` into a standalone uber JAR. At runtime the CLI uses `CIMToolCLI` as its entry point and `CLIProfileTransformer` for all transform operations. -- **CIMToolTest** — tests CIMUtil's validation engine, Kena integration, profile tasks, and transform pipeline via the `headless/` test package. +- **Kena**: CIMUtil's single OSGi dependency. All RDF graph operations use the Kena `OntModel` API rather than calling Apache Jena directly. +- **CIMToolPlugin**: the Eclipse UI shell around CIMUtil's logic. The builder system, profile editors, import wizards, and validation views all delegate to CIMUtil classes. CIMToolPlugin does not duplicate any model processing. +- **com.cimphony.cimtoole**: extends CIMUtil's profile buildlet extension point to add Ecore output support, and uses CIMUtil's profile model and Kena graph API directly. +- **cimtool-cli**: packages `cimutil.jar` into a standalone uber JAR. At runtime the CLI uses `CIMToolCLI` as its entry point and `CLIProfileTransformer` for all transform operations. +- **CIMToolTest**: tests CIMUtil's validation engine, Kena integration, profile tasks, and transform pipeline via the `headless/` test package. diff --git a/dev-docs/Includes/CIMUtil/CIMUtil-Sequence-Diagrams.md b/dev-docs/Includes/CIMUtil/CIMUtil-Sequence-Diagrams.md index dede3609..53bbb44a 100644 --- a/dev-docs/Includes/CIMUtil/CIMUtil-Sequence-Diagrams.md +++ b/dev-docs/Includes/CIMUtil/CIMUtil-Sequence-Diagrams.md @@ -43,43 +43,43 @@ with. ### Key Classes -**`EAProjectParserFactory`** — Selects the concrete parser implementation based on +**`EAProjectParserFactory`**: Selects the concrete parser implementation based on file extension. `.eap` / `.eapx` files use `EAPParser` (UCanAccess JDBC over MS Access); `.qea` / `.qeax` files use `QEAParser` (SQLite JDBC). -**`AbstractEAProjectParsor`** — The abstract base for all EA database parsers. Extends +**`AbstractEAProjectParsor`**: The abstract base for all EA database parsers. Extends `XMIModel` and implements `EAProjectParser`. Its `parse()` method drives the full EA database read sequence: `dbInit`, `loadStereotypesCache`, `initializeDBModelRulesValidator`, `loadTagValuesCaches`, `gatherPackageIDs`, `parsePackages`, `parseClasses`, `parseAssociations`, `parseAttributes`. -**`XMIModel`** — The low-level OWL graph builder. Receives calls from the +**`XMIModel`**: The low-level OWL graph builder. Receives calls from the `parseXxx()` methods and emits RDF triples into the Kena `OntModel` being assembled. -**`CIMInterpreterImpl`** — Post-processes the raw `OntModel` produced by the +**`CIMInterpreterImpl`**: Post-processes the raw `OntModel` produced by the EA parser through a four-stage pipeline: Stage 1 (prune and label), Stage 3 (URI translation via `Translator`), Stage 3 post-processing (stereotypes, attributes, comments), and Stage 4 (optional shadow extension merging via `ExtensionsTranslator`). -**`Translator`** — Renames all XMI-internal resource URIs (e.g. `EAID_xxxx` or +**`Translator`**: Renames all XMI-internal resource URIs (e.g. `EAID_xxxx` or `xuid#nnn`) to proper CIM namespace URIs. Runs in two passes to handle both forward and back-references. -**`CIMInterpreterResult`** — The value object returned by `CIMInterpreterImpl`. Holds +**`CIMInterpreterResult`**: The value object returned by `CIMInterpreterImpl`. Holds the final translated `OntModel` and the combined list of `RuleViolation` instances from both the EA database validation phase and the OWL model validation phase. ### Two Import Paths -**Path A - EA Project** (`.eap`, `.eapx`, `.qea`, `.qeax`) — The EA database is +**Path A - EA Project** (`.eap`, `.eapx`, `.qea`, `.qeax`): The EA database is read via JDBC. The `AbstractEAProjectParsor` queries the EA internal tables (`t_package`, `t_object`, `t_connector`, `t_attribute`) to build the raw `OntModel`. `CIMInterpreterImpl` then post-processes it. This is the primary path for real CIM model work. -**Path B - XMI file** (`.xmi`) — The EA database path is bypassed entirely. +**Path B - XMI file** (`.xmi`): The EA database path is bypassed entirely. `XMIParser` drives a SAX-based parse using the `XMLMode` / `XMLInterpreter` framework from Kena's `sax` package. `LegacyCIMInterpreterImpl` applies a simplified post-processing pipeline without the EA-specific namespace resolution. @@ -100,39 +100,39 @@ against a different data representation. ### Key Classes -**`CIMModellingGuideDBRulesValidator`** — Fires during EA database parsing +**`CIMModellingGuideDBRulesValidator`**: Fires during EA database parsing (`AbstractEAProjectParsor`). Validates JDBC `ResultSet` rows combined with `OntResource` facts. Contains four specialised rule engines targeting packages, classes/enumerations, attributes/enum literals, and associations. Rules at this phase can also perform optional self-healing corrections when the **self heal on import** project setting is enabled. -**`CIMModellingGuideRulesValidator`** — Fires after `CIMInterpreterImpl` has +**`CIMModellingGuideRulesValidator`**: Fires after `CIMInterpreterImpl` has completed Stage 3 post-processing, before shadow extension merging. Validates the fully translated OWL `OntModel`. Contains nine specialised rule engines targeting all model element categories. Each engine carries a `DefaultRuleListener` that collects invocation statistics. -**`DBBaseRule` / `OntResourceBaseRule`** — Abstract base classes for the two rule +**`DBBaseRule` / `OntResourceBaseRule`**: Abstract base classes for the two rule families. Both extend `BaseRule` which provides access to `@RuleMetadata` annotations, placeholder value resolution for error message templates, and AsciiDoc styling helpers for the generated compliance report. -**`RuleViolation`** — The immutable value object produced by every fired rule. +**`RuleViolation`**: The immutable value object produced by every fired rule. Carries the rule ID, composite rule ID, type, category, error message, resource URI, package hierarchy, severity, and a map of placeholder values used to render the message into the compliance report. ### Two-Phase Validation Sequence -**Phase 1 (DB Validation)** — `AbstractEAProjectParsor.parse()` fires +**Phase 1 (DB Validation)**: `AbstractEAProjectParsor.parse()` fires `CIMModellingGuideDBRulesValidator` as each EA element is read from the database. Violations are accumulated on the parser and returned via `getRuleViolations()`. -**Phase 2 (OWL Validation)** — `CIMInterpreterImpl.postProcess()` fires +**Phase 2 (OWL Validation)**: `CIMInterpreterImpl.postProcess()` fires `CIMModellingGuideRulesValidator` against the translated `OntModel`. -**Phase 3 (Merge)** — `Task.parseEAProject()` merges DB violations from Phase 1 into +**Phase 3 (Merge)**: `Task.parseEAProject()` merges DB violations from Phase 1 into the `CIMInterpreterResult` alongside OWL violations from Phase 2. The combined list is passed to `CIMModellingGuideViolationsReportGenerator.generateReport()` to produce the AsciiDoc compliance report written to the project's `/Schema` folder. @@ -153,32 +153,32 @@ path (for RDFS and OWL output). ### Key Classes -**`ProfileModel`** — The root model object that holds the profile `OntModel` and the +**`ProfileModel`**: The root model object that holds the profile `OntModel` and the background schema `OntModel`. Constructs a `Refactory` internally and exposes the profile tree as a hierarchy of typed node classes (`CatalogNode`, `EnvelopeNode`, `MessageNode`, `ElementNode`, etc.) for serialization. -**`Refactory`** — The central profile editing facade. Wraps both the profile and +**`Refactory`**: The central profile editing facade. Wraps both the profile and background `OntModel` instances and provides all operations for adding, removing, and reorganising classes and properties in the profile. Acts as the bridge between the raw OWL graph and the `ProfileClass` domain object layer. -**`ProfileClass`** — Wraps an `OntResource` and exposes the profile-level view of a +**`ProfileClass`**: Wraps an `OntResource` and exposes the profile-level view of a CIM class: `getBaseClass()`, `getProperties()`, `getPropertyInfo()` (cardinality, type), `getSuperClasses()` / `getSubClasses()`, `isRestrictedEnum()`, `isUnion()`. Central to both the XSLT and `SchemaGenerator` pipelines. -**`ProfileSerializer`** — Extends `AbstractReader` - it *is* the SAX `XMLReader` +**`ProfileSerializer`**: Extends `AbstractReader` - it *is* the SAX `XMLReader` that Saxon uses as its input source. When Saxon calls `parse()` during the XSLT transformation, `ProfileSerializer` walks the `ProfileModel` tree and emits SAX events that the XSLT stylesheet processes to produce the output format. -**`SchemaGenerator`** — Abstract base for the direct RDFS/OWL output path +**`SchemaGenerator`**: Abstract base for the direct RDFS/OWL output path (`OWLGenerator`, `RDFSGenerator`). Traverses `ProfileClass` objects directly via `scanProfiles()` / `scanProperties()` and emits OWL/RDFS triples into a result `OntModel`, bypassing the SAX + XSLT pipeline entirely. -**`Reorganizer` / `ProfileReorganizer` / `SchemaReorganizer`** — Apply a structural +**`Reorganizer` / `ProfileReorganizer` / `SchemaReorganizer`**: Apply a structural normalisation pass over the profile `OntModel` before either pipeline runs, ensuring cardinalities and class hierarchies conform to IEC 61970-501 rules. @@ -208,27 +208,27 @@ standalone uber JAR by the `cimtool-cli` Maven project. ### Key Classes -**`CIMToolCLI`** — Main entry point. Suppresses verbose UCanAccess / HSQLDB logging, +**`CIMToolCLI`**: Main entry point. Suppresses verbose UCanAccess / HSQLDB logging, delegates to `run()`, and calls `System.exit()` with the result code. -**`CLIOptions`** — Parses and validates all command-line arguments. Supports +**`CLIOptions`**: Parses and validates all command-line arguments. Supports `--project-dir`, `--profile` / `--profiles-dir`, `--builder` / `--xslt`, `--output`, `--copyright-*`, `--list-builders`, `--version`, `--help`. `isDirectoryMode()` returns `true` when `--profiles-dir` is used (or defaulted) to drive the directory-mode transform loop. -**`CLISettings`** — Adapts the CLI project directory structure to the `Settings` +**`CLISettings`**: Adapts the CLI project directory structure to the `Settings` interface expected by the profile model. Loads `.cimtool-settings` (Turtle format) and extracts schema file paths from their URI representations. -**`CLIBuilderPreferences`** — Loads `.builder-preferences` (Turtle format) and +**`CLIBuilderPreferences`**: Loads `.builder-preferences` (Turtle format) and exposes builder-specific XSLT parameter maps used by `ProfileSerializer`. -**`CLISchemaParser`** — Headless schema parser wrapping `EAPParser` / `QEAParser` for +**`CLISchemaParser`**: Headless schema parser wrapping `EAPParser` / `QEAParser` for use outside the Eclipse workspace. Returns a parsed `OntModel` that is merged into the background schema model passed to `CLIProfileTransformer`. -**`CLIProfileTransformer`** — Orchestrates the headless transform pipeline. Loads the +**`CLIProfileTransformer`**: Orchestrates the headless transform pipeline. Loads the profile `.owl` file, merges schema models, configures `ProfileModel` and `ProfileSerializer`, loads the XSLT stylesheet, and writes the output file. Supports three transform modes: explicit `--builder`, explicit `--xslt`, and @@ -251,38 +251,38 @@ rule-expansion infrastructure built on CIMTool's custom rule engine. ### Key Classes -**`ValidatorUtil`** — Abstract base shared by all validators. Provides +**`ValidatorUtil`**: Abstract base shared by all validators. Provides `openStandardRules(name)` to load bundled `.rules` files from the classpath, and the two-phase `expandRules(schema, ruleText, registry)` method that parses raw rule text and expands generic templates into schema-specific backward-chaining rules (`brules`) using the schema `OntModel`. -**`RuleParser`** — Parses CIMTool's triple-pattern rule language into `Rule` objects. +**`RuleParser`**: Parses CIMTool's triple-pattern rule language into `Rule` objects. Resolves the CIM topology namespace prefix from the schema before parsing. -**`SimpleReasoner` / `SimpleInfGraph`** — CIMTool's custom Jena `Reasoner` +**`SimpleReasoner` / `SimpleInfGraph`**: CIMTool's custom Jena `Reasoner` implementation. Distinct from Jena's built-in OWL/RDFS reasoners. `bind(graph)` produces a `SimpleInfGraph` whose `prepare()` fires Stage 1 forward-chaining: schema triples expand generic rule templates into concrete schema-specific rules. The resulting `brules` are then applied to instance data. -**`ModelValidator`** — Validates a single CIM/XML or Turtle instance document. Reads +**`ModelValidator`**: Validates a single CIM/XML or Turtle instance document. Reads the document into a Jena `InfModel` backed by `SimpleReasoner`, calls `prepare()` to fire the expanded rules against the instance triples, then iterates the deductions graph for `LOG.Problem` triples and logs each as an Eclipse `IMarker` (or stderr in CLI mode). -**`SplitValidator`** — Validates a partitioned CIM/XML dataset. Uses `SplitReader` to +**`SplitValidator`**: Validates a partitioned CIM/XML dataset. Uses `SplitReader` to stream triples part-by-part and `Extractor` to apply the `brules` without loading the full dataset into memory. Supports additional topology-specific options via `ProxyRegistry` and `ValidationBuiltins`. -**`ProfileValidator`** — Checks a CIM profile for consistency with its background +**`ProfileValidator`**: Checks a CIM profile for consistency with its background schema. Wraps the schema in a `TransitiveReasoner` for inheritance-aware checking, then applies profile-validation rules via `Extractor`. Produces a deductions graph of `LOG.Problem` triples. -**`DiagnosisModel` / `RepairMan`** — `DiagnosisModel` wraps the deductions graph as a +**`DiagnosisModel` / `RepairMan`**: `DiagnosisModel` wraps the deductions graph as a JFace tree model for the Eclipse `DiagnosisEditor` and `RepairEditor` views. It groups `LOG.Problem` nodes by the instance resource they apply to via `LOG.hasProblems`. `RepairMan` holds `RepairAction` entries that can apply @@ -292,16 +292,16 @@ automatic fixes to the profile OWL model when the user accepts a repair suggesti The three paths share Phase 1 (rule expansion) and then diverge: -**Path A - Single-File CIM/XML** — `ValidationBuildlet` -> `ModelValidator`. Uses +**Path A - Single-File CIM/XML**: `ValidationBuildlet` -> `ModelValidator`. Uses standard Jena `InfModel` + `prepare()` over a single input file. Bundled rule set: `cimtool-simple.rules`. -**Path B - Split Model** — `SplitValidationBuildlet` or +**Path B - Split Model**: `SplitValidationBuildlet` or `IncrementalValidationBuildlet` -> `SplitValidator`. Streams the partitioned dataset via `SplitReader` through `Extractor`. Bundled rule sets: `cimtool-split.rules` / `cimtool-inc.rules`. -**Path C - Profile Consistency** — `ConsistencyChecks.ProfileChecker` -> +**Path C - Profile Consistency**: `ConsistencyChecks.ProfileChecker` -> `ProfileValidator`. Applies profile-validation rules against the profile graph using a transitively-reasoned schema. Results are written to a `.repair` file and displayed in the `RepairEditor`. @@ -335,32 +335,32 @@ internal implementation - the rest of the codebase is fully insulated. ### Key Classes -**`ModelFactory`** — Factory methods for creating `OntModel` instances. +**`ModelFactory`**: Factory methods for creating `OntModel` instances. `createMem()` produces a plain in-memory graph. `createTransInf()` wraps the graph in a Jena `TransitiveReasoner` `InfGraph` for rdfs:subClassOf / rdfs:subPropertyOf transitive closure queries. -**`OntModel`** — The central graph model. Wraps a Jena `Graph` directly. All query +**`OntModel`**: The central graph model. Wraps a Jena `Graph` directly. All query methods (`listSubjectsWithProperty`, `listObjectsOfProperty`, etc.) delegate to `graph.find()` and compose the results through the `filters/` package to produce typed `OntResource` iterators. -**`OntResource` / `Resource` / `Property`** — Typed wrappers over Jena `Node`. +**`OntResource` / `Resource` / `Property`**: Typed wrappers over Jena `Node`. `OntResource` carries a reference to its owning `OntModel` so it can issue property access queries back against the graph. -**`Composition`** — Graph composition utilities. `merge(a, b)` creates a +**`Composition`**: Graph composition utilities. `merge(a, b)` creates a `MultiUnion` of both graphs' raw underlying `Graph` instances (recursively decomposing any existing `InfGraph` or `MultiUnion` layers to prevent hierarchy growth) and wraps the result in a `TransitiveReasoner`. `simpleMerge()` does the same without the inferencer. -**`IO`** — RDF serialization and deserialization. `read()` has two paths: the custom +**`IO`**: RDF serialization and deserialization. `read()` has two paths: the custom `RDFParser` / `GraphInjector` path for `RDF_XML_WITH_NODEIDS` syntax (which preserves blank node identifiers for split model I/O), and the standard Jena delegation path for all other syntaxes (Turtle, RDF/XML, N3). -**`filters/` package** — Iterator filter implementations that sit between raw Jena +**`filters/` package**: Iterator filter implementations that sit between raw Jena `Triple` iterators and typed `OntResource` iterators. `Subjects` / `Objects` extract the subject or object `Node` from each `Triple`. `UniqueSubjects` / `UniqueObjects` additionally de-duplicate via a `HashSet`. `Wrapper` is the diff --git a/dev-docs/Includes/CIMUtil/readme-images/.asciidoctorconfig.adoc b/dev-docs/Includes/CIMUtil/readme-images/.asciidoctorconfig.adoc new file mode 100644 index 00000000..d3cddb77 --- /dev/null +++ b/dev-docs/Includes/CIMUtil/readme-images/.asciidoctorconfig.adoc @@ -0,0 +1,12 @@ +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + Initial AsciiDoc editor configuration file - V1.0 + +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +// Did not find any configuration files, so creating this at project root level. +// If you do not like those files to be generated - you can turn it off inside Asciidoctor Editor preferences. +// +// You can define editor specific parts here. +// For example: with next line you could set imagesdir attribute to subfolder "images" relative to the folder where this config file is located. +// :imagesdir: {asciidoctorconfigdir}/images +// +// For more information please take a look at https://github.com/de-jcup/eclipse-asciidoctor-editor/wiki/Asciidoctor-configfiles diff --git a/dev-docs/Includes/CSharpEFTestProject/CSharpEFTestProject-README.adoc b/dev-docs/Includes/CSharpEFTestProject/CSharpEFTestProject-README.adoc index 4e21fe2e..1e273804 100644 --- a/dev-docs/Includes/CSharpEFTestProject/CSharpEFTestProject-README.adoc +++ b/dev-docs/Includes/CSharpEFTestProject/CSharpEFTestProject-README.adoc @@ -19,13 +19,13 @@ using a real relational EF Core provider backed by an in-memory SQLite database. CSharpEFTestProject exercises the generated `SampleProfile.csharp-ef-rdfs.cs` file against two overarching goals that guided the design of the `csharp-ef-rdfs.xsl` XSLT builder. The first goal is that application developers should write as little EF Core and Fluent API -code as possible — the generated `DbContextBase` class provides DbSet properties, complete +code as possible, the generated `DbContextBase` class provides DbSet properties, complete Fluent API model configuration, a `DbContextOptions` constructor for dependency injection integration, and automatic compound orphan cleanup through `SaveChanges` and `SaveChangesAsync` overrides, leaving the developer with nothing more than a one-class thin subclass. The second goal is that the companion SQL DDL script produced by the `sql-rdfs-ansi92.xsl` builder is the authoritative schema, and the generated EF Core code -is a tightly complementary layer above it — for example, the SQL DDL's reverse-reference +is a tightly complementary layer above it, for example, the SQL DDL's reverse-reference `ON DELETE CASCADE` pattern for compound value objects is paired with `DeleteBehavior.Restrict` in the EF Core model configuration, enforcing the compound ownership invariant at both layers. @@ -105,9 +105,9 @@ SQLite connection and database via `WithFreshDatabase`, `WithFreshDatabaseAsync` Certain behaviors are documented through a `diagnostics` list rather than hard `AssertCondition` calls. Diagnostics appear in the output under a `Diagnostics:` heading after the section summary. They are used for intentional architectural divergences between -the SQL DDL and EF Core layers — specifically the `PARITY GAP OBSERVED` message confirming +the SQL DDL and EF Core layers, specifically the `PARITY GAP OBSERVED` message confirming that the SQL `ON DELETE CASCADE` and EF Core `DeleteBehavior.Restrict` plus `SaveChanges` -cleanup are complementary rather than identical — and for the `BASELINE OBSERVED` message +cleanup are complementary rather than identical, and for the `BASELINE OBSERVED` message confirming that orphan accumulation without `DbContextBase` is the expected baseline behavior of `GeneratedOnlySampleProfileDbContext`. @@ -161,7 +161,7 @@ all three entity categories. Enumerated types compare by natural `Name` key. Com compare by surrogate `Id`. `IdentifiedObject` subclasses compare by `MRId` and reject cross-type equality even when `MRId` values match. Confirms that compound constructors assign a non-empty surrogate `Id` on construction without requiring application code to -set it, and that each constructor call produces a distinct `Id` — enforcing the +set it, and that each constructor call produces a distinct `Id`, enforcing the one-compound-per-slot ownership invariant that the generated cleanup logic depends on. ==== Name Association Behavior @@ -216,7 +216,7 @@ path completes correctly and that the full TPT deletion chain removes both the Exercises the same compound replacement and null-detach operations using `GeneratedOnlySampleProfileDbContext`, which has no `SaveChanges` overrides. Confirms that -all replaced and detached compound rows — including nested compounds — remain orphaned in +all replaced and detached compound rows, including nested compounds, remain orphaned in the database when cleanup is absent, establishing the baseline that motivates the generated `DbContextBase` implementation. @@ -230,8 +230,8 @@ runtime types when queried through the hierarchy root. ==== Inheritance Delete Cleanup Deletes `ParentOrganization` and `OverheadWireInfo` entities through their typed DbSet -properties and verifies that all TPT rows — including base `IdentifiedObject` rows and -intermediate table rows — are removed across the full inheritance chain. +properties and verifies that all TPT rows, including base `IdentifiedObject` rows and +intermediate table rows, are removed across the full inheritance chain. === Eclipse IDE Integration @@ -240,11 +240,11 @@ CIMTool developers who work primarily in Eclipse IDE have two options for access `EfCoreSmokeTest` project from within their existing Eclipse workspace. -==== Option A — General Project Import (view only) +==== Option A: General Project Import (view only) Importing the project as a General Project requires no additional plugins and takes less -than a minute. It gives full access to all project files — including this README, the -`.csproj`, and all `.cs` source files — through Eclipse's file browser and text editor, +than a minute. It gives full access to all project files, including this README, the +`.csproj`, and all `.cs` source files, through Eclipse's file browser and text editor, with no C#-specific language intelligence. . In Eclipse, select *File → Import → General → Existing Projects into Workspace*. @@ -252,19 +252,19 @@ with no C#-specific language intelligence. . Click *Finish*. The project appears in the Package Explorer. Files open in Eclipse's built-in text editor. -All developmental work — editing `Program.cs`, running `dotnet run`, debugging — is +All developmental work (editing `Program.cs`, running `dotnet run`, debugging) is performed externally in Visual Studio Code or a terminal. Eclipse serves purely as a project viewer under this option. -==== Option B — Eclipse aCute Plugin (full C# language support) +==== Option B: Eclipse aCute Plugin (full C# language support) Eclipse aCute provides a rich C# editor with error reporting, hover, content assist, and jump to references using OmniSharp, and syntax highlighting using TextMate grammar. Integration with OmniSharp-Roslyn and the Language Server Protocol is powered by Eclipse LSP4E. This is the same OmniSharp language server that the C# extension for Visual -Studio Code uses, so the editing experience — completions, diagnostics, hover -documentation, go-to-definition, find references — is equivalent to working in VS Code, +Studio Code uses, so the editing experience, completions, diagnostics, hover +documentation, go-to-definition, find references, is equivalent to working in VS Code, presented through the familiar Eclipse IDE shell. aCute supports Eclipse versions through 2025-03 (4.35) and later. The .NET 8 SDK @@ -273,7 +273,7 @@ must already be installed and available on `PATH` before configuring aCute. *Prerequisites* * Eclipse IDE (2023-06 or later recommended) -* .NET 8 SDK installed and on `PATH` — verify with `dotnet --version` +* .NET 8 SDK installed and on `PATH`, verify with `dotnet --version` *Installation steps* @@ -313,7 +313,7 @@ dotnet run A successful run prints a summary of completed sections followed by any informational diagnostics. Any assertion failure terminates the run immediately with a message -identifying the failed condition. No test runner or xUnit dependency is required — the +identifying the failed condition. No test runner or xUnit dependency is required, the harness is a self-contained console application. diff --git a/dev-docs/Includes/CSharpEFTestProject/CSharpEFTestProject-README.md b/dev-docs/Includes/CSharpEFTestProject/CSharpEFTestProject-README.md index 49962bab..e853dc5e 100644 --- a/dev-docs/Includes/CSharpEFTestProject/CSharpEFTestProject-README.md +++ b/dev-docs/Includes/CSharpEFTestProject/CSharpEFTestProject-README.md @@ -10,13 +10,13 @@ using a real relational EF Core provider backed by an in-memory SQLite database. CSharpEFTestProject exercises the generated `SampleProfile.csharp-ef-rdfs.cs` file against two overarching goals that guided the design of the `csharp-ef-rdfs.xsl` XSLT builder. The first goal is that application developers should write as little EF Core and Fluent API -code as possible — the generated `DbContextBase` class provides DbSet properties, complete +code as possible, the generated `DbContextBase` class provides DbSet properties, complete Fluent API model configuration, a `DbContextOptions` constructor for dependency injection integration, and automatic compound orphan cleanup through `SaveChanges` and `SaveChangesAsync` overrides, leaving the developer with nothing more than a one-class thin subclass. The second goal is that the companion SQL DDL script produced by the `sql-rdfs-ansi92.xsl` builder is the authoritative schema, and the generated EF Core code -is a tightly complementary layer above it — for example, the SQL DDL's reverse-reference +is a tightly complementary layer above it, for example, the SQL DDL's reverse-reference `ON DELETE CASCADE` pattern for compound value objects is paired with `DeleteBehavior.Restrict` in the EF Core model configuration, enforcing the compound ownership invariant at both layers. @@ -87,9 +87,9 @@ SQLite connection and database via `WithFreshDatabase`, `WithFreshDatabaseAsync` Certain behaviors are documented through a `diagnostics` list rather than hard `AssertCondition` calls. Diagnostics appear in the output under a `Diagnostics:` heading after the section summary. They are used for intentional architectural divergences between -the SQL DDL and EF Core layers — specifically the `PARITY GAP OBSERVED` message confirming +the SQL DDL and EF Core layers, specifically the `PARITY GAP OBSERVED` message confirming that the SQL `ON DELETE CASCADE` and EF Core `DeleteBehavior.Restrict` plus `SaveChanges` -cleanup are complementary rather than identical — and for the `BASELINE OBSERVED` message +cleanup are complementary rather than identical, and for the `BASELINE OBSERVED` message confirming that orphan accumulation without `DbContextBase` is the expected baseline behavior of `GeneratedOnlySampleProfileDbContext`. @@ -143,7 +143,7 @@ all three entity categories. Enumerated types compare by natural `Name` key. Com compare by surrogate `Id`. `IdentifiedObject` subclasses compare by `MRId` and reject cross-type equality even when `MRId` values match. Confirms that compound constructors assign a non-empty surrogate `Id` on construction without requiring application code to -set it, and that each constructor call produces a distinct `Id` — enforcing the +set it, and that each constructor call produces a distinct `Id`, enforcing the one-compound-per-slot ownership invariant that the generated cleanup logic depends on. ### Name Association Behavior @@ -198,7 +198,7 @@ path completes correctly and that the full TPT deletion chain removes both the Exercises the same compound replacement and null-detach operations using `GeneratedOnlySampleProfileDbContext`, which has no `SaveChanges` overrides. Confirms that -all replaced and detached compound rows — including nested compounds — remain orphaned in +all replaced and detached compound rows, including nested compounds, remain orphaned in the database when cleanup is absent, establishing the baseline that motivates the generated `DbContextBase` implementation. @@ -212,8 +212,8 @@ runtime types when queried through the hierarchy root. ### Inheritance Delete Cleanup Deletes `ParentOrganization` and `OverheadWireInfo` entities through their typed DbSet -properties and verifies that all TPT rows — including base `IdentifiedObject` rows and -intermediate table rows — are removed across the full inheritance chain. +properties and verifies that all TPT rows, including base `IdentifiedObject` rows and +intermediate table rows, are removed across the full inheritance chain. ## Eclipse IDE Integration @@ -222,11 +222,11 @@ CIMTool developers who work primarily in Eclipse IDE have two options for access `EfCoreSmokeTest` project from within their existing Eclipse workspace. -### Option A — General Project Import (view only) +### Option A: General Project Import (view only) Importing the project as a General Project requires no additional plugins and takes less -than a minute. It gives full access to all project files — including this README, the -`.csproj`, and all `.cs` source files — through Eclipse's file browser and text editor, +than a minute. It gives full access to all project files, including this README, the +`.csproj`, and all `.cs` source files, through Eclipse's file browser and text editor, with no C#-specific language intelligence. 1. In Eclipse, select **File → Import → General → Existing Projects into Workspace**. @@ -234,19 +234,19 @@ with no C#-specific language intelligence. 3. Click **Finish**. The project appears in the Package Explorer. Files open in Eclipse's built-in text editor. -All developmental work — editing `Program.cs`, running `dotnet run`, debugging — is +All developmental work (editing `Program.cs`, running `dotnet run`, debugging) is performed externally in Visual Studio Code or a terminal. Eclipse serves purely as a project viewer under this option. -### Option B — Eclipse aCute Plugin (full C# language support) +### Option B: Eclipse aCute Plugin (full C# language support) Eclipse aCute provides a rich C# editor with error reporting, hover, content assist, and jump to references using OmniSharp, and syntax highlighting using TextMate grammar. Integration with OmniSharp-Roslyn and the Language Server Protocol is powered by Eclipse LSP4E. This is the same OmniSharp language server that the C# extension for Visual -Studio Code uses, so the editing experience — completions, diagnostics, hover -documentation, go-to-definition, find references — is equivalent to working in VS Code, +Studio Code uses, so the editing experience, completions, diagnostics, hover +documentation, go-to-definition, find references, is equivalent to working in VS Code, presented through the familiar Eclipse IDE shell. aCute supports Eclipse versions through 2025-03 (4.35) and later. The .NET 8 SDK @@ -255,7 +255,7 @@ must already be installed and available on `PATH` before configuring aCute. **Prerequisites** - Eclipse IDE (2023-06 or later recommended) -- .NET 8 SDK installed and on `PATH` — verify with `dotnet --version` +- .NET 8 SDK installed and on `PATH`, verify with `dotnet --version` **Installation steps** @@ -294,7 +294,7 @@ dotnet run A successful run prints a summary of completed sections followed by any informational diagnostics. Any assertion failure terminates the run immediately with a message -identifying the failed condition. No test runner or xUnit dependency is required — the +identifying the failed condition. No test runner or xUnit dependency is required, the harness is a self-contained console application. diff --git a/dev-docs/Includes/DevEnvSetup/DevEnvSetup-README.adoc b/dev-docs/Includes/DevEnvSetup/DevEnvSetup-README.adoc index 0490cfe0..c3253adc 100644 --- a/dev-docs/Includes/DevEnvSetup/DevEnvSetup-README.adoc +++ b/dev-docs/Includes/DevEnvSetup/DevEnvSetup-README.adoc @@ -21,7 +21,7 @@ A specific Eclipse edition and release is recommended to eliminate unanticipated configuration and setup issues. Development and deployment of CIMTool against this release has been fully tested and its plugin dependencies verified out of the box. Questions may be posted to the -https://github.com/cimug-org/CIMTool/discussions/92[CIMTool 2.x Release Line — Development Community Discussion Board]. +https://github.com/cimug-org/CIMTool/discussions/92[CIMTool 2.x Release Line: Development Community Discussion Board]. ==== @@ -66,15 +66,15 @@ IDE, which may then be relocated to a preferred location on the file system. When a newer JDK has been installed in Step 2, it must be registered in the Eclipse IDE configuration before the CIMTool projects are imported. -image::{devenvsetup-imagesdir}/eclipse-configure-jre-step1.png[Configure the installed JRE — step 1] +image::{devenvsetup-imagesdir}/eclipse-configure-jre-step1.png[Configure the installed JRE, step 1] -image::{devenvsetup-imagesdir}/eclipse-configure-jre-step2.png[Configure the installed JRE — step 2] +image::{devenvsetup-imagesdir}/eclipse-configure-jre-step2.png[Configure the installed JRE, step 2] -image::{devenvsetup-imagesdir}/eclipse-configure-jre-step3.png[Configure the installed JRE — step 3] +image::{devenvsetup-imagesdir}/eclipse-configure-jre-step3.png[Configure the installed JRE, step 3] -image::{devenvsetup-imagesdir}/eclipse-configure-jre-step4.png[Configure the installed JRE — step 4] +image::{devenvsetup-imagesdir}/eclipse-configure-jre-step4.png[Configure the installed JRE, step 4] -image::{devenvsetup-imagesdir}/eclipse-configure-jre-step5.png[Configure the installed JRE — step 5] +image::{devenvsetup-imagesdir}/eclipse-configure-jre-step5.png[Configure the installed JRE, step 5] === Installing Required Eclipse Plugins @@ -239,20 +239,20 @@ https://github.com/cimug-org/CIMTool[CIMTool GitHub repository] and import its projects into the workspace. Two approaches are available, and they differ in how the projects are brought into Eclipse: -* *External Git client* — such as https://desktop.github.com/[GitHub Desktop], +* *External Git client*: such as https://desktop.github.com/[GitHub Desktop], https://tortoisegit.org/[TortoiseGit], or https://gitforwindows.org/[Git for Windows] -(see the https://git-scm.com/downloads/guis[full list]) — used to clone the +(see the https://git-scm.com/downloads/guis[full list]), used to clone the repository to a local directory _outside_ Eclipse. The cloned projects are then brought in with Eclipse's _Existing Projects into Workspace_ import (described below). -* *Eclipse's bundled Git tooling (EGit)* — used to clone _and_ import the CIMTool +* *Eclipse's bundled Git tooling (EGit)*: used to clone _and_ import the CIMTool projects directly from the repository in a single operation, via `File` > `Import...` > `Git` > `Projects from Git`. ==== Importing Existing Projects from an External Clone When the repository has been cloned with an external Git client, the projects are imported -as *existing projects from the file system* — not as Git-managed projects retrieved +as *existing projects from the file system*, not as Git-managed projects retrieved through Eclipse. Choose `File` > `Import...` > `General` > `Existing Projects into Workspace`, set _Select root directory_ to the clone location (for example, `D:\CIMug-GIT-REPOS\release-2.3.0`), and let Eclipse discover the projects it contains. @@ -265,5 +265,5 @@ image::{devenvsetup-imagesdir}/import-existing-projects.png[Importing the CIMToo ==== The checked projects in the screenshot are the *core* projects required to build and deploy CIMTool. The remaining, unchecked projects may optionally be imported, but they -are *dormant* — not required to build or deploy the product. +are *dormant*, not required to build or deploy the product. ==== diff --git a/dev-docs/Includes/DevEnvSetup/DevEnvSetup-README.md b/dev-docs/Includes/DevEnvSetup/DevEnvSetup-README.md index 418cf9e9..f06d6f80 100644 --- a/dev-docs/Includes/DevEnvSetup/DevEnvSetup-README.md +++ b/dev-docs/Includes/DevEnvSetup/DevEnvSetup-README.md @@ -10,7 +10,7 @@ to the 2.x line only. > unanticipated configuration and setup issues. Development and deployment of > CIMTool against this release has been fully tested and its plugin dependencies > verified out of the box. Questions may be posted to the -> [CIMTool 2.x Release Line — Development Community Discussion Board](https://github.com/cimug-org/CIMTool/discussions/92). +> [CIMTool 2.x Release Line: Development Community Discussion Board](https://github.com/cimug-org/CIMTool/discussions/92). ## Eclipse Installation @@ -52,15 +52,15 @@ IDE, which may then be relocated to a preferred location on the file system. When a newer JDK has been installed in Step 2, it must be registered in the Eclipse IDE configuration before the CIMTool projects are imported. -![Configure the installed JRE — step 1](readme-images/eclipse-configure-jre-step1.png) +![Configure the installed JRE, step 1](readme-images/eclipse-configure-jre-step1.png) -![Configure the installed JRE — step 2](readme-images/eclipse-configure-jre-step2.png) +![Configure the installed JRE, step 2](readme-images/eclipse-configure-jre-step2.png) -![Configure the installed JRE — step 3](readme-images/eclipse-configure-jre-step3.png) +![Configure the installed JRE, step 3](readme-images/eclipse-configure-jre-step3.png) -![Configure the installed JRE — step 4](readme-images/eclipse-configure-jre-step4.png) +![Configure the installed JRE, step 4](readme-images/eclipse-configure-jre-step4.png) -![Configure the installed JRE — step 5](readme-images/eclipse-configure-jre-step5.png) +![Configure the installed JRE, step 5](readme-images/eclipse-configure-jre-step5.png) ## Installing Required Eclipse Plugins @@ -193,9 +193,9 @@ Complete the installation by accepting the license and restarting, as described > **Note:** **Verified versions** (installed and confirmed against the pinned Eclipse > 2023-06 / 4.28 platform): > -> - *Asciidoctor Editor* — `3.1.2` -> - *PlantUML Eclipse support* — `1.2.0.202511102215` -> - *PlantUML Library* — `1.2025.10.202511041744` +> - *Asciidoctor Editor*: `3.1.2` +> - *PlantUML Eclipse support*: `1.2.0.202511102215` +> - *PlantUML Library*: `1.2025.10.202511041744` > > Both update sites publish the most recent release of each plugin, and a later install > may retrieve a newer version that has not been verified against this platform. The @@ -215,20 +215,20 @@ The final step is to clone a development branch of the CIMTool codebase from the projects into the workspace. Two approaches are available, and they differ in how the projects are brought into Eclipse: -- **External Git client** — such as [GitHub Desktop](https://desktop.github.com/), +- **External Git client**: such as [GitHub Desktop](https://desktop.github.com/), [TortoiseGit](https://tortoisegit.org/), or [Git for Windows](https://gitforwindows.org/) - (see the [full list](https://git-scm.com/downloads/guis)) — used to clone the + (see the [full list](https://git-scm.com/downloads/guis)), used to clone the repository to a local directory *outside* Eclipse. The cloned projects are then brought in with Eclipse's *Existing Projects into Workspace* import (described below). -- **Eclipse's bundled Git tooling (EGit)** — used to clone *and* import the CIMTool +- **Eclipse's bundled Git tooling (EGit)**: used to clone *and* import the CIMTool projects directly from the repository in a single operation, via `File` > `Import...` > `Git` > `Projects from Git`. ### Importing Existing Projects from an External Clone When the repository has been cloned with an external Git client, the projects are imported -as **existing projects from the file system** — not as Git-managed projects retrieved +as **existing projects from the file system**, not as Git-managed projects retrieved through Eclipse. Choose `File` > `Import...` > `General` > `Existing Projects into Workspace`, set *Select root directory* to the clone location (for example, `D:\CIMug-GIT-REPOS\release-2.3.0`), and let Eclipse discover the projects it contains. @@ -239,4 +239,4 @@ cloned Git working tree, where the external client continues to manage them. > **Note:** The checked projects in the screenshot are the **core** projects required to > build and deploy CIMTool. The remaining, unchecked projects may optionally be imported, -> but they are **dormant** — not required to build or deploy the product. +> but they are **dormant**, not required to build or deploy the product. diff --git a/dev-docs/Includes/Kena/Kena-README.adoc b/dev-docs/Includes/Kena/Kena-README.adoc index 23191456..549dbbde 100644 --- a/dev-docs/Includes/Kena/Kena-README.adoc +++ b/dev-docs/Includes/Kena/Kena-README.adoc @@ -11,7 +11,7 @@ An Eclipse plugin that provides a clean, purpose-built RDF/OWL graph API for CIMTool, wrapping Apache Jena 2.6.3 behind a stable abstraction layer. All -RDF graph operations across the CIMTool codebase use the Kena API exclusively — +RDF graph operations across the CIMTool codebase use the Kena API exclusively; no other plugin calls Apache Jena directly. @@ -20,8 +20,8 @@ no other plugin calls Apache Jena directly. Kena (`au.com.langdale.kena`) serves as the foundational RDF layer for the entire CIMTool plugin ecosystem. Its central contribution is the `OntModel` / -`Resource` / `Property` API — a simplified, CIMTool-specific facade over -Apache Jena's `Graph` and `Model` infrastructure — that insulates the rest of +`Resource` / `Property` API, a simplified, CIMTool-specific facade over +Apache Jena's `Graph` and `Model` infrastructure, that insulates the rest of the codebase from Jena's complexity and from potential Jena version changes. Beyond the API facade, Kena also provides: @@ -31,7 +31,7 @@ Beyond the API facade, Kena also provides: * A *split model* reader/writer (`splitmodel/`) for partitioned CIM/XML files * A *SAX parsing* framework (`sax/`) used by the XMI import pipeline * *Utility classes* (`util/`) shared across the project -* Several *targeted Jena patches* — source overrides of specific Jena internal +* Several *targeted Jena patches*, source overrides of specific Jena internal classes to fix bugs or add behaviour not available in the vendored version @@ -127,7 +127,7 @@ Kena/ === Dependencies on Other Projects Kena has *no dependencies on other in-repository plugins*. It is the -foundational layer of the dependency stack — all other plugins depend on it, +foundational layer of the dependency stack, all other plugins depend on it, but it depends on none of them. ==== Vendored Third-Party Libraries @@ -152,28 +152,28 @@ bundle via `build.properties`: | Apache Jena | 2.6.3 -| Core RDF graph engine — `Graph`, `Model`, `OntModel`, reasoner framework, +| Core RDF graph engine: `Graph`, `Model`, `OntModel`, reasoner framework, RDF/XML and N3/Turtle parsers and serializers | ARQ | 2.8.4 -| SPARQL query processor for Jena — used by the inference engine +| SPARQL query processor for Jena: used by the inference engine | ICU4J | 71.1 -| Unicode character set and locale support — required by Jena's IRI handling +| Unicode character set and locale support: required by Jena's IRI handling | IRI | 0.8 -| IRI syntax and validation library — used by Jena's ARP RDF/XML parser +| IRI syntax and validation library: used by Jena's ARP RDF/XML parser | Lucene Core | 2.3.1 -| Full-text indexing — used by Jena LARQ (`SearchIndex`) +| Full-text indexing: used by Jena LARQ (`SearchIndex`) | StAX API | 1.0.1 -| Streaming XML API interface — required by Jena +| Streaming XML API interface: required by Jena | Woodstox (wstx-asl) | 3.2.9 @@ -181,14 +181,26 @@ bundle via `build.properties`: | Xerces | 2.7.1 -| XML parser implementation — used by Jena's ARP RDF/XML parser +| XML parser implementation: used by Jena's ARP RDF/XML parser | log4j-over-slf4j | 2.0.17 -| Log4j 1.x → SLF4J bridge — intercepts all Apache Jena Log4j 1.x API calls and redirects them into the SLF4J pipeline. No Log4j 1.x bytecode executes at runtime. Vendored in `Bundle-ClassPath` rather than a real Log4j 1.x implementation intentionally — the vulnerable Log4j appender classes (`SocketServer`, `JMSSink`, `JMSAppender`, `JDBCAppender`) are never present on the classpath. Wired to the platform SLF4J 2.x bundle via `Import-Package: org.slf4j` in `MANIFEST.MF`. +| Log4j 1.x → SLF4J bridge: intercepts all Apache Jena Log4j 1.x API calls and redirects them into the SLF4J pipeline. No Log4j 1.x bytecode executes at runtime. Vendored in `Bundle-ClassPath` rather than a real Log4j 1.x implementation intentionally: the vulnerable Log4j appender classes (`SocketServer`, `JMSSink`, `JMSAppender`, `JDBCAppender`) are never present on the classpath. Wired to the platform SLF4J 2.x bundle via `Import-Package: org.slf4j` in `MANIFEST.MF`. |=== -NOTE: `log4j-over-slf4j` is declared in `Bundle-ClassPath` rather than resolved via `Import-Package` because it must intercept Log4j 1.x API calls at the classloader level — the bridge's `org.apache.log4j.*` stub classes must be found before Jena's code attempts to load the real Log4j classes. Routing through SLF4J is then achieved via `Import-Package: org.slf4j`, which wires the bridge output to the platform SLF4J 2.x bundle at runtime rather than to a private vendored copy. This is the same `Import-Package` pattern used by CIMUtil for Saxon-HE's SLF4J calls. Because no real Log4j 1.x implementation is ever on the classpath, the current pipeline also eliminates the security risks associated with https://nvd.nist.gov/vuln/detail/CVE-2019-17571[CVE-2019-17571], https://nvd.nist.gov/vuln/detail/CVE-2022-23302[CVE-2022-23302], https://nvd.nist.gov/vuln/detail/CVE-2022-23303[CVE-2022-23303], and https://nvd.nist.gov/vuln/detail/CVE-2022-23305[CVE-2022-23305]. +NOTE: `log4j-over-slf4j` is declared in `Bundle-ClassPath` rather than resolved +via `Import-Package` because it must intercept Log4j 1.x API calls at the +classloader level, so the bridge's `org.apache.log4j.*` stub classes must be +found before Jena's code attempts to load the real Log4j classes. Routing +through SLF4J is then achieved via `Import-Package: org.slf4j`, which wires the +bridge output to the platform SLF4J 2.x bundle at runtime rather than to a +private vendored copy. This is the same `Import-Package` pattern used by CIMUtil +for Saxon-HE's SLF4J calls. Because no real Log4j 1.x implementation is ever on +the classpath, the current pipeline also eliminates the security risks +associated with https://nvd.nist.gov/vuln/detail/CVE-2019-17571[CVE-2019-17571], +https://nvd.nist.gov/vuln/detail/CVE-2022-23302[CVE-2022-23302], +https://nvd.nist.gov/vuln/detail/CVE-2022-23303[CVE-2022-23303], and +https://nvd.nist.gov/vuln/detail/CVE-2022-23305[CVE-2022-23305]. @@ -198,20 +210,20 @@ The Kena API (`au.com.langdale.kena`) is a deliberate simplification of the Apache Jena API, designed specifically for CIMTool's use cases. Key design decisions: -* `OntModel` is *not* a subclass of `com.hp.hpl.jena.ontology.OntModel` — it +* `OntModel` is *not* a subclass of `com.hp.hpl.jena.ontology.OntModel`; it wraps a Jena `Graph` directly and exposes only the operations CIMTool needs * All iterators (`ResIterator`, `NodeIterator`) are typed Java iterators rather - than Jena's `ExtendedIterator` — simpler to use and chain with the `filters/` + than Jena's `ExtendedIterator`, simpler to use and chain with the `filters/` package * `Resource`, `Property`, and `OntResource` are thin, typed wrappers over - Jena's `Node` and `FrontsNode` — they provide a stable API that does not + Jena's `Node` and `FrontsNode`, providing a stable API that does not change if Jena is upgraded * `ModelFactory` provides named factory methods (`createMem()`, `createMem(Graph)`, `createTransitive()`) rather than Jena's reflection-based factory pattern This design means that if Apache Jena is ever upgraded to a newer version, -the rest of the CIMTool codebase is insulated from the API changes — only +the rest of the CIMTool codebase is insulated from the API changes; only Kena's internal implementation would need to change. ==== Jena Patches @@ -220,8 +232,8 @@ The `com/hp/hpl/jena/` source files in Kena's `src/` directory are targeted patches to specific Jena internal classes. These override the corresponding classes in `jena-2.6.3.jar` at compile time (PDE compiles source into `kena.jar`, which takes precedence over the vendored JAR on the classpath). -They exist to fix specific bugs or add behaviour — such as RDF reification -support and quoted statement handling — that was not available in the vendored +They exist to fix specific bugs or add behaviour, such as RDF reification +support and quoted statement handling, that was not available in the vendored Jena version. @@ -235,15 +247,15 @@ against a CIM profile. It is built directly on top of Jena's `Graph` and Key components: -* `RuleParser` / `RuleLexer` — parse CIMTool's validation rule language into +* `RuleParser` / `RuleLexer`: parse CIMTool's validation rule language into rule objects. The rule language is a triple-pattern language similar to Jena's rule syntax but tailored for CIM validation. -* `SimpleReasoner` / `SimpleInfGraph` — a custom Jena `Reasoner` implementation +* `SimpleReasoner` / `SimpleInfGraph`: a custom Jena `Reasoner` implementation that applies the parsed rules to a CIM/XML graph and produces an inferred graph of validation violations -* `Extractor` — applies rules to extract a result graph from an input graph, +* `Extractor`: applies rules to extract a result graph from an input graph, used by the CLI and test framework -* `AsyncModel` / `AsyncResult` — asynchronous callback interfaces for streaming +* `AsyncModel` / `AsyncResult`: asynchronous callback interfaces for streaming rule results from the `SplitReader` @@ -251,7 +263,7 @@ Key components: === Split Model The `au.com.langdale.splitmodel` package handles CIM/XML datasets that are -partitioned across multiple files — a common practice in large power system +partitioned across multiple files, a common practice in large power system models. `SplitReader` locates and reads the parts via a hash-based directory structure, and `SplitWriter` writes a model in the same partitioned format. The `SplitReaderTest` and `ExtractorTest` in `CIMToolTest` exercise this @@ -261,18 +273,18 @@ package directly. === Relationship to Other Projects -* *CIMUtil* — its single OSGi dependency. All profile model, XMI import, and +* *CIMUtil*: its single OSGi dependency. All profile model, XMI import, and validation logic in CIMUtil uses the Kena `OntModel` API. -* *CIMToolPlugin* — uses Kena for the project model cache, editors, views, +* *CIMToolPlugin*: uses Kena for the project model cache, editors, views, and the incremental build system. The `KenaTests` in `CIMToolTest` test Kena directly. -* *RCPUtil* — no dependency on Kena. +* *RCPUtil*: no dependency on Kena. -* *com.cimphony.cimtoole* — uses Kena `OntModel` and related types via +* *com.cimphony.cimtoole*: uses Kena `OntModel` and related types via `Import-Package` declarations for Ecore extraction and generation. -* *cimtool-cli* — packages `kena.jar` (extracted from the PDE product export) +* *cimtool-cli*: packages `kena.jar` (extracted from the PDE product export) alongside `cimutil.jar` in the CLI uber JAR. At CLI runtime, all RDF operations go through the Kena API. diff --git a/dev-docs/Includes/Kena/Kena-README.md b/dev-docs/Includes/Kena/Kena-README.md index f9a6e602..ae106989 100644 --- a/dev-docs/Includes/Kena/Kena-README.md +++ b/dev-docs/Includes/Kena/Kena-README.md @@ -2,7 +2,7 @@ An Eclipse plugin that provides a clean, purpose-built RDF/OWL graph API for CIMTool, wrapping Apache Jena 2.6.3 behind a stable abstraction layer. All -RDF graph operations across the CIMTool codebase use the Kena API exclusively — +RDF graph operations across the CIMTool codebase use the Kena API exclusively; no other plugin calls Apache Jena directly. @@ -11,8 +11,8 @@ no other plugin calls Apache Jena directly. Kena (`au.com.langdale.kena`) serves as the foundational RDF layer for the entire CIMTool plugin ecosystem. Its central contribution is the `OntModel` / -`Resource` / `Property` API — a simplified, CIMTool-specific facade over -Apache Jena's `Graph` and `Model` infrastructure — that insulates the rest of +`Resource` / `Property` API, a simplified, CIMTool-specific facade over +Apache Jena's `Graph` and `Model` infrastructure, that insulates the rest of the codebase from Jena's complexity and from potential Jena version changes. Beyond the API facade, Kena also provides: @@ -21,7 +21,7 @@ Beyond the API facade, Kena also provides: - A **split model** reader/writer (`splitmodel/`) for partitioned CIM/XML files - A **SAX parsing** framework (`sax/`) used by the XMI import pipeline - **Utility classes** (`util/`) shared across the project -- Several **targeted Jena patches** — source overrides of specific Jena internal classes to fix bugs or add behaviour not available in the vendored version +- Several **targeted Jena patches**, source overrides of specific Jena internal classes to fix bugs or add behaviour not available in the vendored version @@ -116,30 +116,30 @@ Kena/ ## Dependencies on Other Projects Kena has **no dependencies on other in-repository plugins**. It is the -foundational layer of the dependency stack — all other plugins depend on it, +foundational layer of the dependency stack, all other plugins depend on it, but it depends on none of them. ### Vendored Third-Party Libraries -> **Note — Keeping vendored libraries in sync:** Adding, removing, or upgrading any library listed in this section must be mirrored in the same change across this project's `META-INF/MANIFEST.MF` (`Bundle-ClassPath`), `build.properties`, and `.classpath`, as well as the repository-wide reference chain. See the [Vendored Library Change Checklist](../CIMToolProduct/CIMToolProduct-README.md#maintaining-vendored-third-party-libraries) in the CIMToolProduct documentation. +> **Note: Keeping vendored libraries in sync:** Adding, removing, or upgrading any library listed in this section must be mirrored in the same change across this project's `META-INF/MANIFEST.MF` (`Bundle-ClassPath`), `build.properties`, and `.classpath`, as well as the repository-wide reference chain. See the [Vendored Library Change Checklist](../CIMToolProduct/CIMToolProduct-README.md#maintaining-vendored-third-party-libraries) in the CIMToolProduct documentation. Kena bundles Apache Jena 2.6.3 and all of its required dependencies, declared in `Bundle-ClassPath` in `MANIFEST.MF` and included via `build.properties`: | Library | Version | Purpose | | --- | --- | --- | -| Apache Jena | 2.6.3 | Core RDF graph engine — `Graph`, `Model`, `OntModel`, reasoner framework, RDF/XML and N3/Turtle parsers and serializers | -| ARQ | 2.8.4 | SPARQL query processor for Jena — used by the inference engine | -| ICU4J | 71.1 | Unicode character set and locale support — required by Jena's IRI handling | -| IRI | 0.8 | IRI syntax and validation library — used by Jena's ARP RDF/XML parser | -| Lucene Core | 2.3.1 | Full-text indexing — used by Jena LARQ (`SearchIndex`) | -| StAX API | 1.0.1 | Streaming XML API interface — required by Jena | +| Apache Jena | 2.6.3 | Core RDF graph engine: `Graph`, `Model`, `OntModel`, reasoner framework, RDF/XML and N3/Turtle parsers and serializers | +| ARQ | 2.8.4 | SPARQL query processor for Jena: used by the inference engine | +| ICU4J | 71.1 | Unicode character set and locale support: required by Jena's IRI handling | +| IRI | 0.8 | IRI syntax and validation library: used by Jena's ARP RDF/XML parser | +| Lucene Core | 2.3.1 | Full-text indexing: used by Jena LARQ (`SearchIndex`) | +| StAX API | 1.0.1 | Streaming XML API interface: required by Jena | | Woodstox (wstx-asl) | 3.2.9 | StAX streaming XML implementation used by Jena's N-Triples parser | -| Xerces | 2.7.1 | XML parser implementation — used by Jena's ARP RDF/XML parser | -| log4j-over-slf4j | 2.0.17 | Log4j 1.x → SLF4J bridge — intercepts all Apache Jena Log4j 1.x API calls and redirects them into the SLF4J pipeline. No Log4j 1.x bytecode executes at runtime. Vendored in `Bundle-ClassPath` rather than a real Log4j 1.x implementation intentionally — the vulnerable Log4j appender classes (`SocketServer`, `JMSSink`, `JMSAppender`, `JDBCAppender`) are never present on the classpath. Wired to the platform SLF4J 2.x bundle via `Import-Package: org.slf4j` in `MANIFEST.MF`. | +| Xerces | 2.7.1 | XML parser implementation: used by Jena's ARP RDF/XML parser | +| log4j-over-slf4j | 2.0.17 | Log4j 1.x → SLF4J bridge: intercepts all Apache Jena Log4j 1.x API calls and redirects them into the SLF4J pipeline. No Log4j 1.x bytecode executes at runtime. Vendored in `Bundle-ClassPath` rather than a real Log4j 1.x implementation intentionally: the vulnerable Log4j appender classes (`SocketServer`, `JMSSink`, `JMSAppender`, `JDBCAppender`) are never present on the classpath. Wired to the platform SLF4J 2.x bundle via `Import-Package: org.slf4j` in `MANIFEST.MF`. | > [!NOTE] -> `log4j-over-slf4j` is declared in `Bundle-ClassPath` rather than resolved via `Import-Package` because it must intercept Log4j 1.x API calls at the classloader level — the bridge's `org.apache.log4j.*` stub classes must be found before Jena's code attempts to load the real Log4j classes. Routing through SLF4J is then achieved via `Import-Package: org.slf4j`, which wires the bridge output to the platform SLF4J 2.x bundle at runtime rather than to a private vendored copy. This is the same `Import-Package` pattern used by CIMUtil for Saxon-HE's SLF4J calls. Because no real Log4j 1.x implementation is ever on the classpath, the current pipeline also eliminates the security risks associated with [CVE-2019-17571](https://nvd.nist.gov/vuln/detail/CVE-2019-17571), [CVE-2022-23302](https://nvd.nist.gov/vuln/detail/CVE-2022-23302), [CVE-2022-23303](https://nvd.nist.gov/vuln/detail/CVE-2022-23303), and [CVE-2022-23305](https://nvd.nist.gov/vuln/detail/CVE-2022-23305). +> `log4j-over-slf4j` is declared in `Bundle-ClassPath` rather than resolved via `Import-Package` because it must intercept Log4j 1.x API calls at the classloader level, so the bridge's `org.apache.log4j.*` stub classes must be found before Jena's code attempts to load the real Log4j classes. Routing through SLF4J is then achieved via `Import-Package: org.slf4j`, which wires the bridge output to the platform SLF4J 2.x bundle at runtime rather than to a private vendored copy. This is the same `Import-Package` pattern used by CIMUtil for Saxon-HE's SLF4J calls. Because no real Log4j 1.x implementation is ever on the classpath, the current pipeline also eliminates the security risks associated with [CVE-2019-17571](https://nvd.nist.gov/vuln/detail/CVE-2019-17571), [CVE-2022-23302](https://nvd.nist.gov/vuln/detail/CVE-2022-23302), [CVE-2022-23303](https://nvd.nist.gov/vuln/detail/CVE-2022-23303), and [CVE-2022-23305](https://nvd.nist.gov/vuln/detail/CVE-2022-23305). @@ -149,12 +149,12 @@ The Kena API (`au.com.langdale.kena`) is a deliberate simplification of the Apache Jena API, designed specifically for CIMTool's use cases. Key design decisions: -- `OntModel` is **not** a subclass of `com.hp.hpl.jena.ontology.OntModel` — it wraps a Jena `Graph` directly and exposes only the operations CIMTool needs -- All iterators (`ResIterator`, `NodeIterator`) are typed Java iterators rather than Jena's `ExtendedIterator` — simpler to use and chain with the `filters/` package -- `Resource`, `Property`, and `OntResource` are thin, typed wrappers over Jena's `Node` and `FrontsNode` — they provide a stable API that does not change if Jena is upgraded +- `OntModel` is **not** a subclass of `com.hp.hpl.jena.ontology.OntModel` but wraps a Jena `Graph` directly, exposing only the operations CIMTool needs +- All iterators (`ResIterator`, `NodeIterator`) are typed Java iterators rather than Jena's `ExtendedIterator`, simpler to use and chain with the `filters/` package +- `Resource`, `Property`, and `OntResource` are thin, typed wrappers over Jena's `Node` and `FrontsNode`, providing a stable API that does not change if Jena is upgraded - `ModelFactory` provides named factory methods (`createMem()`, `createMem(Graph)`, `createTransitive()`) rather than Jena's reflection-based factory pattern -This design means that if Apache Jena is ever upgraded to a newer version, the rest of the CIMTool codebase is insulated from the API changes — only Kena's internal implementation would need to change. +This design means that if Apache Jena is ever upgraded to a newer version, the rest of the CIMTool codebase is insulated from the API changes, with only Kena's internal implementation needing to change. ### Jena Patches @@ -162,8 +162,8 @@ The `com/hp/hpl/jena/` source files in Kena's `src/` directory are targeted patches to specific Jena internal classes. These override the corresponding classes in `jena-2.6.3.jar` at compile time (PDE compiles source into `kena.jar`, which takes precedence over the vendored JAR on the classpath). -They exist to fix specific bugs or add behaviour — such as RDF reification -support and quoted statement handling — that was not available in the vendored +They exist to fix specific bugs or add behaviour, such as RDF reification +support and quoted statement handling, that was not available in the vendored Jena version. @@ -174,17 +174,17 @@ The `au.com.langdale.inference` package implements CIMTool's custom rule-based inference engine, used to validate CIM/XML and Turtle instance documents against a CIM profile. Key components: -- **`RuleParser` / `RuleLexer`** — parse CIMTool's validation rule language into rule objects -- **`SimpleReasoner` / `SimpleInfGraph`** — a custom Jena `Reasoner` that applies rules to a CIM/XML graph and produces an inferred graph of validation violations -- **`Extractor`** — applies rules to extract a result graph from an input graph, used by the CLI and test framework -- **`AsyncModel` / `AsyncResult`** — asynchronous callback interfaces for streaming rule results from the `SplitReader` +- **`RuleParser` / `RuleLexer`**: parse CIMTool's validation rule language into rule objects +- **`SimpleReasoner` / `SimpleInfGraph`**: a custom Jena `Reasoner` that applies rules to a CIM/XML graph and produces an inferred graph of validation violations +- **`Extractor`**: applies rules to extract a result graph from an input graph, used by the CLI and test framework +- **`AsyncModel` / `AsyncResult`**: asynchronous callback interfaces for streaming rule results from the `SplitReader` ## Split Model The `au.com.langdale.splitmodel` package handles CIM/XML datasets partitioned -across multiple files — a common practice in large power system models. +across multiple files, a common practice in large power system models. `SplitReader` locates and reads the parts via a hash-based directory structure, and `SplitWriter` writes a model in the same partitioned format. The `SplitReaderTest` and `ExtractorTest` in `CIMToolTest` exercise this package @@ -194,8 +194,8 @@ directly. ## Relationship to Other Projects -- **CIMUtil** — its single OSGi dependency. All profile model, XMI import, and validation logic in CIMUtil uses the Kena `OntModel` API. -- **CIMToolPlugin** — uses Kena for the project model cache, editors, views, and the incremental build system. -- **RCPUtil** — no dependency on Kena. -- **com.cimphony.cimtoole** — uses Kena `OntModel` and related types via `Import-Package` declarations for Ecore extraction and generation. -- **cimtool-cli** — packages `kena.jar` alongside `cimutil.jar` in the CLI uber JAR. At CLI runtime, all RDF operations go through the Kena API. +- **CIMUtil**: its single OSGi dependency. All profile model, XMI import, and validation logic in CIMUtil uses the Kena `OntModel` API. +- **CIMToolPlugin**: uses Kena for the project model cache, editors, views, and the incremental build system. +- **RCPUtil**: no dependency on Kena. +- **com.cimphony.cimtoole**: uses Kena `OntModel` and related types via `Import-Package` declarations for Ecore extraction and generation. +- **cimtool-cli**: packages `kena.jar` alongside `cimutil.jar` in the CLI uber JAR. At CLI runtime, all RDF operations go through the Kena API. diff --git a/dev-docs/Includes/MaintainerNotes/MaintainerNotes-README.adoc b/dev-docs/Includes/MaintainerNotes/MaintainerNotes-README.adoc index aa12c7d7..323a7da3 100644 --- a/dev-docs/Includes/MaintainerNotes/MaintainerNotes-README.adoc +++ b/dev-docs/Includes/MaintainerNotes/MaintainerNotes-README.adoc @@ -11,8 +11,8 @@ This document retains engineering context for changes that may be undertaken in the future. It is not a roadmap and not a task tracker. It records _what_ a -potential change involves and _why_ — the background, rationale, and constraints -understood at the time of writing — so that whoever eventually carries out the +potential change involves and _why_, the background, rationale, and constraints +understood at the time of writing, so that whoever eventually carries out the change inherits that context rather than rediscovering it. Each entry describes potential work; an entry does not commit the project to that work, imply a schedule, or report status. @@ -50,7 +50,7 @@ target-platform definition (next entry) would be a natural part of the same upgrade. -=== Build Reproducibility — Plugin and Target-Platform Version Pinning +=== Build Reproducibility: Plugin and Target-Platform Version Pinning The product resolves against whatever plugin versions are present in the developer's IDE / target platform; it pins nothing. The product file lists plugins @@ -67,9 +67,9 @@ are not duplicated here, to avoid drift. Two places a fix could live, with their trade-offs: -* `bundle-version` constraints in `MANIFEST.MF` — localized and precise, but must +* `bundle-version` constraints in `MANIFEST.MF`, localized and precise, but must be maintained per bundle. -* A committed target-platform (`.target`) definition in the repository — +* A committed target-platform (`.target`) definition in the repository, comprehensive and deterministic across machines, but a larger artifact to maintain. @@ -94,7 +94,7 @@ registered through an `org.eclipse.ui.startup` extension in `CIMToolPlugin/plugin.xml`. It attaches raw `SWT.MouseDown` and `SWT.KeyDown` listeners to the Project Explorer tree, reconstructs the double-click and handles Enter / keypad-Enter from the primitive input events, and routes the open through -`IDE.openEditor(...)` — beneath SWT's gesture synthesis, which is why it succeeds +`IDE.openEditor(...)`: beneath SWT's gesture synthesis, which is why it succeeds where the broken gesture does not. It resolves the tree by reflection (`getCommonViewer().getTree()`), which is acceptable only because it is bound to the pinned 4.28 platform. The sanctioned `CommonActionProvider` open hook was @@ -109,8 +109,8 @@ This workaround MUST be removed as part of the platform upgrade that resolves SW `requires-platform-upgrade`) documents the failure and remains the long-term fix. ==== -Packaging note for any similar change: `CIMToolPlugin` is a nested-JAR build — -its classes ship inside `cimtool.jar`. A self-hosted _Run As ▸ Eclipse +Packaging note for any similar change: `CIMToolPlugin` is a nested-JAR build, +with its classes shipping inside `cimtool.jar`. A self-hosted _Run As ▸ Eclipse Application_ launch serves classes from `bin/` and can therefore mask whether a -class is actually packaged into the jar. Changes of this kind should be validated -from a product export, not only from a self-hosted launch. +class is actually packaged into the jar. Changes of this kind should be +validated from a product export, not only from a self-hosted launch. diff --git a/dev-docs/Includes/MaintainerNotes/MaintainerNotes-README.md b/dev-docs/Includes/MaintainerNotes/MaintainerNotes-README.md index 277efd5b..b710d10f 100644 --- a/dev-docs/Includes/MaintainerNotes/MaintainerNotes-README.md +++ b/dev-docs/Includes/MaintainerNotes/MaintainerNotes-README.md @@ -2,8 +2,8 @@ This document retains engineering context for changes that may be undertaken in the future. It is not a roadmap and not a task tracker. It records *what* a -potential change involves and *why* — the background, rationale, and constraints -understood at the time of writing — so that whoever eventually carries out the +potential change involves and *why*, the background, rationale, and constraints +understood at the time of writing, so that whoever eventually carries out the change inherits that context rather than rediscovering it. Each entry describes potential work; an entry does not commit the project to that work, imply a schedule, or report status. @@ -38,7 +38,7 @@ target-platform definition (next entry) would be a natural part of the same upgrade. -## Build Reproducibility — Plugin and Target-Platform Version Pinning +## Build Reproducibility: Plugin and Target-Platform Version Pinning The product resolves against whatever plugin versions are present in the developer's IDE / target platform; it pins nothing. The product file lists plugins @@ -55,9 +55,9 @@ are not duplicated here, to avoid drift. Two places a fix could live, with their trade-offs: -- `bundle-version` constraints in `MANIFEST.MF` — localized and precise, but must +- `bundle-version` constraints in `MANIFEST.MF`, localized and precise, but must be maintained per bundle. -- A committed target-platform (`.target`) definition in the repository — +- A committed target-platform (`.target`) definition in the repository, comprehensive and deterministic across machines, but a larger artifact to maintain. @@ -82,7 +82,7 @@ registered through an `org.eclipse.ui.startup` extension in `CIMToolPlugin/plugin.xml`. It attaches raw `SWT.MouseDown` and `SWT.KeyDown` listeners to the Project Explorer tree, reconstructs the double-click and handles Enter / keypad-Enter from the primitive input events, and routes the open through -`IDE.openEditor(...)` — beneath SWT's gesture synthesis, which is why it succeeds +`IDE.openEditor(...)`: beneath SWT's gesture synthesis, which is why it succeeds where the broken gesture does not. It resolves the tree by reflection (`getCommonViewer().getTree()`), which is acceptable only because it is bound to the pinned 4.28 platform. The sanctioned `CommonActionProvider` open hook was @@ -95,8 +95,7 @@ focus state. > (labeled `requires-platform-upgrade`) documents the failure and remains the > long-term fix. -Packaging note for any similar change: `CIMToolPlugin` is a nested-JAR build — its -classes ship inside `cimtool.jar`. A self-hosted *Run As ▸ Eclipse Application* +Packaging note for any similar change: `CIMToolPlugin` is a nested-JAR build, with its classes shipping inside `cimtool.jar`. A self-hosted *Run As ▸ Eclipse Application* launch serves classes from `bin/` and can therefore mask whether a class is actually packaged into the jar. Changes of this kind should be validated from a product export, not only from a self-hosted launch. diff --git a/dev-docs/Includes/RCPUtil/RCPUtil-README.adoc b/dev-docs/Includes/RCPUtil/RCPUtil-README.adoc index fb72dea6..d0af0702 100644 --- a/dev-docs/Includes/RCPUtil/RCPUtil-README.adoc +++ b/dev-docs/Includes/RCPUtil/RCPUtil-README.adoc @@ -10,7 +10,7 @@ :xrefstyle: short A small Eclipse RCP utility plugin that provides reusable UI infrastructure -for CIMTool — data binding, form builder, JFace plumbing, and workspace +for CIMTool, data binding, form builder, JFace plumbing, and workspace helpers. It contains no CIM-specific logic and has no dependency on any other in-repository plugin. @@ -25,13 +25,13 @@ separation between Eclipse UI infrastructure and CIM domain logic. Its four exported packages cover distinct concerns: -* *`ui.binding`* — a lightweight data binding framework that connects Eclipse +* *`ui.binding`*: a lightweight data binding framework that connects Eclipse JFace viewers and SWT widgets to model objects, with validation support -* *`ui.builder`* — a form builder framework for constructing editor pages and +* *`ui.builder`*: a form builder framework for constructing editor pages and wizard pages declaratively using a template/assembly pattern -* *`ui.plumbing`* — the underlying observer/controller wiring that drives the +* *`ui.plumbing`*: the underlying observer/controller wiring that drives the binding and builder frameworks -* *`ui.util`* — miscellaneous Eclipse UI utilities (icon cache, selection +* *`ui.util`*: miscellaneous Eclipse UI utilities (icon cache, selection provider, wizard launcher, UI thread tickler) A single utility class, `util.Jobs`, provides Eclipse workspace job helpers @@ -107,22 +107,22 @@ It depends only on standard Eclipse platform bundles: | Bundle | What RCPUtil uses from it | `org.eclipse.core.runtime` -| `IProgressMonitor`, `CoreException`, `IStatus` — used by `Jobs.java` for +| `IProgressMonitor`, `CoreException`, `IStatus`: used by `Jobs.java` for workspace runnable execution | `org.eclipse.core.resources` -| `IWorkspaceRunnable`, workspace resource APIs — used by `Jobs.java` +| `IWorkspaceRunnable`, workspace resource APIs: used by `Jobs.java` | `org.eclipse.jface` | JFace viewers (`IStructuredContentProvider`, `ILabelProvider`), actions, - resources — core of the binding and builder frameworks + resources, core of the binding and builder frameworks | `org.eclipse.ui.workbench` -| `IWorkbenchPage`, `IEditorPart`, `IViewPart` — used by editor and view +| `IWorkbenchPage`, `IEditorPart`, `IViewPart`: used by editor and view base classes | `org.eclipse.ui.forms` -| `FormToolkit`, `ScrolledForm`, `Section`, `FormPage` — the Forms UI toolkit +| `FormToolkit`, `ScrolledForm`, `Section`, `FormPage`: the Forms UI toolkit used by `FurnishedEditor` and `FurnishedMultiEditor` |=== @@ -133,15 +133,15 @@ It depends only on standard Eclipse platform bundles: The `ui.builder` package provides a declarative pattern for constructing Eclipse Forms-based editor pages and wizard pages. The key classes are: -* `Template` — a subclass declares the layout of a form page by overriding +* `Template`: a subclass declares the layout of a form page by overriding `defineContent()`, placing widget declarations in a grid. Each declaration specifies a widget type, its label, and a binding key. -* `Assembly` — takes a `Template` and instantiates the declared widgets into +* `Assembly`: takes a `Template` and instantiates the declared widgets into an SWT `Composite`, applying the generated `GridLayout`. It is the concrete SWT container that appears in the editor or wizard. -* `FurnishedEditor` / `FurnishedMultiEditor` / `FurnishedWizardPage` — base +* `FurnishedEditor` / `FurnishedMultiEditor` / `FurnishedWizardPage`: base classes that wire a `Template` to an `Assembly` and connect the `Controller` (from `ui.plumbing`) to the assembled bindings. Subclasses in `CIMToolPlugin` extend these to build all of the profile, model, and mapping editor pages. @@ -169,17 +169,17 @@ The `ui.binding` package connects SWT widgets to model data: === Relationship to Other Projects -* *CIMToolPlugin* — the primary consumer. All editors, wizard pages, views, +* *CIMToolPlugin*: the primary consumer. All editors, wizard pages, views, and property pages in `CIMToolPlugin` use `FurnishedEditor`, `FurnishedWizardPage`, and the binding framework from RCPUtil. `IconCache` and `GeneralIconCache` are used by `CIMToolPlugin`'s icon infrastructure. -* *com.cimphony.cimtoole* — uses RCPUtil base classes for its wizards +* *com.cimphony.cimtoole*: uses RCPUtil base classes for its wizards (`ExportEcore`, `ImportRegistrySchema`). -* *CIMToolTest* — the `WorkbenchTest` base class depends on RCPUtil's +* *CIMToolTest*: the `WorkbenchTest` base class depends on RCPUtil's workbench utilities for UI test setup. -* *Kena* — no dependency on RCPUtil. +* *Kena*: no dependency on RCPUtil. -* *CIMUtil* — no dependency on RCPUtil. +* *CIMUtil*: no dependency on RCPUtil. diff --git a/dev-docs/Includes/RCPUtil/RCPUtil-README.md b/dev-docs/Includes/RCPUtil/RCPUtil-README.md index a6f9046a..13dff778 100644 --- a/dev-docs/Includes/RCPUtil/RCPUtil-README.md +++ b/dev-docs/Includes/RCPUtil/RCPUtil-README.md @@ -1,7 +1,7 @@ # RCPUtil A small Eclipse RCP utility plugin that provides reusable UI infrastructure -for CIMTool — data binding, form builder, JFace plumbing, and workspace +for CIMTool, data binding, form builder, JFace plumbing, and workspace helpers. It contains no CIM-specific logic and has no dependency on any other in-repository plugin. @@ -16,10 +16,10 @@ separation between Eclipse UI infrastructure and CIM domain logic. Its four exported packages cover distinct concerns: -- **`ui.binding`** — a lightweight data binding framework that connects Eclipse JFace viewers and SWT widgets to model objects, with validation support -- **`ui.builder`** — a form builder framework for constructing editor pages and wizard pages declaratively using a template/assembly pattern -- **`ui.plumbing`** — the underlying observer/controller wiring that drives the binding and builder frameworks -- **`ui.util`** — miscellaneous Eclipse UI utilities (icon cache, selection provider, wizard launcher, UI thread tickler) +- **`ui.binding`**: a lightweight data binding framework that connects Eclipse JFace viewers and SWT widgets to model objects, with validation support +- **`ui.builder`**: a form builder framework for constructing editor pages and wizard pages declaratively using a template/assembly pattern +- **`ui.plumbing`**: the underlying observer/controller wiring that drives the binding and builder frameworks +- **`ui.util`**: miscellaneous Eclipse UI utilities (icon cache, selection provider, wizard launcher, UI thread tickler) A single utility class, `util.Jobs`, provides Eclipse workspace job helpers and is exported under the `au.com.langdale.util` package namespace alongside @@ -91,11 +91,11 @@ It depends only on standard Eclipse platform bundles: | Bundle | What RCPUtil uses from it | | --- | --- | -| `org.eclipse.core.runtime` | `IProgressMonitor`, `CoreException`, `IStatus` — used by `Jobs.java` for workspace runnable execution | -| `org.eclipse.core.resources` | `IWorkspaceRunnable`, workspace resource APIs — used by `Jobs.java` | -| `org.eclipse.jface` | JFace viewers (`IStructuredContentProvider`, `ILabelProvider`), actions, resources — core of the binding and builder frameworks | -| `org.eclipse.ui.workbench` | `IWorkbenchPage`, `IEditorPart`, `IViewPart` — used by editor and view base classes | -| `org.eclipse.ui.forms` | `FormToolkit`, `ScrolledForm`, `Section`, `FormPage` — the Forms UI toolkit used by `FurnishedEditor` and `FurnishedMultiEditor` | +| `org.eclipse.core.runtime` | `IProgressMonitor`, `CoreException`, `IStatus`: used by `Jobs.java` for workspace runnable execution | +| `org.eclipse.core.resources` | `IWorkspaceRunnable`, workspace resource APIs: used by `Jobs.java` | +| `org.eclipse.jface` | JFace viewers (`IStructuredContentProvider`, `ILabelProvider`), actions, resources: core of the binding and builder frameworks | +| `org.eclipse.ui.workbench` | `IWorkbenchPage`, `IEditorPart`, `IViewPart`: used by editor and view base classes | +| `org.eclipse.ui.forms` | `FormToolkit`, `ScrolledForm`, `Section`, `FormPage`: the Forms UI toolkit used by `FurnishedEditor` and `FurnishedMultiEditor` | @@ -104,9 +104,9 @@ It depends only on standard Eclipse platform bundles: The `ui.builder` package provides a declarative pattern for constructing Eclipse Forms-based editor pages and wizard pages: -- **`Template`** — a subclass declares the layout of a form page by overriding `defineContent()`, placing widget declarations in a grid. Each declaration specifies a widget type, its label, and a binding key. -- **`Assembly`** — takes a `Template` and instantiates the declared widgets into an SWT `Composite`, applying the generated `GridLayout`. It is the concrete SWT container that appears in the editor or wizard. -- **`FurnishedEditor` / `FurnishedMultiEditor` / `FurnishedWizardPage`** — base classes that wire a `Template` to an `Assembly` and connect the `Controller` (from `ui.plumbing`) to the assembled bindings. Subclasses in `CIMToolPlugin` extend these to build all of the profile, model, and mapping editor pages. +- **`Template`**: a subclass declares the layout of a form page by overriding `defineContent()`, placing widget declarations in a grid. Each declaration specifies a widget type, its label, and a binding key. +- **`Assembly`**: takes a `Template` and instantiates the declared widgets into an SWT `Composite`, applying the generated `GridLayout`. It is the concrete SWT container that appears in the editor or wizard. +- **`FurnishedEditor` / `FurnishedMultiEditor` / `FurnishedWizardPage`**: base classes that wire a `Template` to an `Assembly` and connect the `Controller` (from `ui.plumbing`) to the assembled bindings. Subclasses in `CIMToolPlugin` extend these to build all of the profile, model, and mapping editor pages. This pattern means that the layout and binding of an editor page is declared once in the `Template` subclass, and the framework handles SWT widget creation, layout, data binding, and refresh automatically. @@ -126,8 +126,8 @@ between bindings so that changing one widget can refresh others. ## Relationship to Other Projects -- **CIMToolPlugin** — the primary consumer. All editors, wizard pages, views, and property pages in `CIMToolPlugin` use `FurnishedEditor`, `FurnishedWizardPage`, and the binding framework from RCPUtil. `IconCache` and `GeneralIconCache` are used by `CIMToolPlugin`'s icon infrastructure. -- **com.cimphony.cimtoole** — uses RCPUtil base classes for its wizards (`ExportEcore`, `ImportRegistrySchema`). -- **CIMToolTest** — the `WorkbenchTest` base class depends on RCPUtil's workbench utilities for UI test setup. -- **Kena** — no dependency on RCPUtil. -- **CIMUtil** — no dependency on RCPUtil. +- **CIMToolPlugin**: the primary consumer. All editors, wizard pages, views, and property pages in `CIMToolPlugin` use `FurnishedEditor`, `FurnishedWizardPage`, and the binding framework from RCPUtil. `IconCache` and `GeneralIconCache` are used by `CIMToolPlugin`'s icon infrastructure. +- **com.cimphony.cimtoole**: uses RCPUtil base classes for its wizards (`ExportEcore`, `ImportRegistrySchema`). +- **CIMToolTest**: the `WorkbenchTest` base class depends on RCPUtil's workbench utilities for UI test setup. +- **Kena**: no dependency on RCPUtil. +- **CIMUtil**: no dependency on RCPUtil. diff --git a/dev-docs/Includes/cimtool-cli/cimtool-cli-README.adoc b/dev-docs/Includes/cimtool-cli/cimtool-cli-README.adoc index 6311732d..dd43c0f5 100644 --- a/dev-docs/Includes/cimtool-cli/cimtool-cli-README.adoc +++ b/dev-docs/Includes/cimtool-cli/cimtool-cli-README.adoc @@ -12,7 +12,7 @@ A standalone Maven project that assembles the CIMTool command-line interface into a single self-contained executable uber JAR (`cimtool-cli.jar`) using the Maven Shade plugin. While the CIMTool Eclipse RCP application is currently -released for Windows only — with macOS and Linux under evaluation — `cimtool-cli.jar` +released for Windows only, with macOS and Linux under evaluation, `cimtool-cli.jar` has no Eclipse or UI dependencies and can be run headless on any platform where Java 11 or later is available. @@ -55,16 +55,16 @@ only*. | Maven | 3.9 or later -| Eclipse PDE product export | Required before running the install script — provides `kena.jar` and `cimutil.jar` from versioned plugin folders in the `plugins/` directory +| Eclipse PDE product export | Required before running the install script: provides `kena.jar` and `cimutil.jar` from versioned plugin folders in the `plugins/` directory |=== ==== Eclipse PDE Product Export Dependency This project sources `kena.jar` and `cimutil.jar` from a CIMTool Eclipse PDE product export. These JARs are *not* generated by Maven and are *not* taken from -the Eclipse workspace `bin/` directories — they must come from a full PDE product -export performed as described in `CIMToolProduct/CIMToolProduct-README` under the -*Phase 2 — PDE Product Export* section. +the Eclipse workspace `bin/` directories, but from a full PDE product export +performed as described in `CIMToolProduct/CIMToolProduct-README` under the +*Phase 2: PDE Product Export* section. After the export completes, the `plugins\` directory under the export root will contain versioned plugin folders including: @@ -122,7 +122,7 @@ CIMTool/ -=== Dependency Management — Local File Repository +=== Dependency Management: Local File Repository [NOTE] ==== @@ -164,7 +164,7 @@ directory inside `cimtool-cli/` is declared as a standard Maven repository in ---- All dependencies are then declared as normal Maven dependencies with no `system` -scope or `systemPath` — m2e resolves them cleanly against `lib-repo/` with no +scope or `systemPath`, m2e resolves them cleanly against `lib-repo/` with no errors or warnings. ==== Populating lib-repo/ @@ -172,7 +172,7 @@ errors or warnings. [NOTE] ==== *Release context:* For official releases, `install-jars.bat` is invoked -automatically by `release-cimtool.bat` — no manual action is needed. +automatically by `release-cimtool.bat`, with no manual action needed. The instructions below apply to *local development only*. ==== @@ -186,7 +186,7 @@ cd cimtool-cli install-jars.bat D:\CIMTool-Releases\CIMTool-2.3.0 ---- -*Path contains spaces — wrap in double quotes:* +*Path contains spaces, wrap in double quotes:* ---- cd cimtool-cli install-jars.bat "D:\My Releases\CIMTool-2.3.0" @@ -254,7 +254,7 @@ skips it rather than aborting, so you can see all missing files in a single run. | First-time project setup | Run install script once after Eclipse PDE export -| New CIMTool PDE product export — *local dev only* +| New CIMTool PDE product export: *local dev only* | Re-run install script with the new export root path. For official releases this is handled automatically by `release-cimtool.bat`. @@ -262,7 +262,7 @@ skips it rather than aborting, so you can see all missing files in a single run. | Re-run install script and answer `Y` at the vendor JAR prompt | Another developer clones the repo -| No action needed — `lib-repo/` is committed +| No action needed: `lib-repo/` is committed |=== ==== Committing lib-repo/ to Source Control @@ -278,7 +278,7 @@ are current. The install script only needs to be re-run when the underlying JARs `install-jars.bat` automatically, which may update `lib-repo/` if Kena or CIMUtil versions have changed. Any resulting changes to `lib-repo/` must be committed back to master via Pull Request *after* the build completes and *before* the release -tag is created. See the *Phase 4 — Post-Build and Publishing* section in +tag is created. See the *Phase 4: Post-Build and Publishing* section in `CIMToolProduct/CIMToolProduct-README` for the full sequencing details. ==== @@ -288,13 +288,13 @@ tag is created. See the *Phase 4 — Post-Build and Publishing* section in ==== Local development build -*Step 1 — Populate `lib-repo/` after each PDE product export:* +*Step 1: Populate `lib-repo/` after each PDE product export:* ---- cd cimtool-cli install-jars.bat ---- -*Step 2 — Build the uber JAR:* +*Step 2: Build the uber JAR:* ---- cd cimtool-cli mvn clean package @@ -386,7 +386,8 @@ java -jar target/cimtool-cli.jar --help ===== Informational Options -These options are standalone — they print output and exit immediately without performing any transformation. +These options are standalone, printing output and exiting immediately without +performing any transformation. [cols="2,1,4", options="header"] |=== @@ -422,7 +423,7 @@ These options are standalone — they print output and exit immediately without | Yes | Root directory of the CIMTool project. Must contain `.cimtool-settings` and `.builder-preferences`, and may optionally contain `.cimtool-global-preferences`. The CLI reads schema file locations from - `.cimtool-settings`, builder configurations from `.builder-preferences`, and — when present — global + `.cimtool-settings`, builder configurations from `.builder-preferences`, and, when present, global preference values (e.g. PlantUML diagram style settings) from `.cimtool-global-preferences`; built-in defaults are used if that file is absent. @@ -441,7 +442,7 @@ These options are standalone — they print output and exit immediately without | `-b` | No | Builder name from the bundled catalog (e.g. `xsd`, `json-schema-draft-07`, `legacy-rdfs`). Overrides - the builders configured on each profile. Works for all builder types — both XSLT-based (`TEXT`, `XSD`, + the builders configured on each profile. Works for all builder types, both XSLT-based (`TEXT`, `XSD`, `TRANSFORM`) and Java-based (`JAVA`). Mutually exclusive with `--xslt`. | `--xslt ` @@ -515,7 +516,7 @@ These options are standalone — they print output and exit immediately without | XSLT-based; produces XML output without additional post-processing | `JAVA` -| Java-based; uses CIMTool generator classes directly — no XSLT stylesheet involved +| Java-based; uses CIMTool generator classes directly: no XSLT stylesheet involved |=== The `JAVA` builders (`xml`, `ttl`, `simple-flat-owl`, `simple-owl`, `legacy-rdfs`, @@ -525,7 +526,7 @@ previously executable only within the Eclipse desktop application. Beginning wit ==== Common Usage Examples -*Minimum valid invocation — process all profiles using their configured builders:* +*Minimum valid invocation, process all profiles using their configured builders:* ---- java -jar cimtool-cli.jar --project-dir .\MyProject ---- @@ -536,7 +537,7 @@ java -jar cimtool-cli.jar -pd .\MyProject The CLI reads project settings from `.\MyProject`, processes every `.owl` file in `.\MyProject\Profiles`, and for each profile runs whichever builders are configured on it. Generated artifacts are written to `.\MyProject\Profiles` alongside the source -`.owl` files — the same default behavior as the desktop application. +`.owl` files, the same default behavior as the desktop application. *Transform a single profile using a named builder:* ---- @@ -698,17 +699,17 @@ The debug configuration enables the following: Log output (warnings, errors, debug messages) is written to `stderr` and progress messages to `stdout`. The commands below capture both streams together. -*Linux / macOS* — writes to file and shows output on screen simultaneously: +*Linux / macOS*: writes to file and shows output on screen simultaneously: ---- java -Dlogback.configurationFile=./logback-debug.xml -jar cimtool-cli.jar [options...] 2>&1 | tee debug.log ---- -*Windows Command Prompt* — writes to file only (no simultaneous screen output): +*Windows Command Prompt*: writes to file only (no simultaneous screen output): ---- java -Dlogback.configurationFile=.\logback-debug.xml -jar cimtool-cli.jar [options...] > debug.log 2>&1 ---- -*Windows PowerShell* — writes to file and shows output on screen simultaneously: +*Windows PowerShell*: writes to file and shows output on screen simultaneously: ---- java -Dlogback.configurationFile=.\logback-debug.xml -jar cimtool-cli.jar [options...] 2>&1 | Tee-Object -FilePath debug.log ---- @@ -735,14 +736,14 @@ names and levels to focus on specific subsystems. `BuilderRegistry` loads builder configurations and XSLT stylesheets at runtime via classpath resource lookups. Two configuration files are loaded: -* `builders.json` — XSLT-based builder catalog (`TEXT`, `XSD`, `TRANSFORM` types), +* `builders.json`: XSLT-based builder catalog (`TEXT`, `XSD`, `TRANSFORM` types), loaded via `getResourceAsStream("/builders.json")` -* `java-builders.json` — Java-based builder catalog (`JAVA` type), +* `java-builders.json`: Java-based builder catalog (`JAVA` type), loaded via `getResourceAsStream("/java-builders.json")` Both files are loaded into a single unified `TreeMap`, producing one alphabetically sorted registry. XSLT stylesheets are loaded via `getResourceAsStream("/" + xslFileName)`. -All of these resources must reside at the *classpath root* of the uber JAR — not +All of these resources must reside at the *classpath root* of the uber JAR, not under a `builders/` subdirectory. This is achieved by declaring `CIMUtil/builders/` itself (not its parent) as the @@ -775,7 +776,7 @@ contributing JAR before assembly. ===== Is This a Security Concern? -No — stripping signatures is not a security concern for this use case, and here +No, stripping signatures is not a security concern for this use case, and here is why. *What JAR signing actually protects:* JAR signing allows a consumer to verify that @@ -783,22 +784,22 @@ a JAR came from a specific publisher and that its contents have not been tampere with since signing. The signature is mathematically bound to the exact byte contents of the original JAR file. -*Why stripping is necessary and unavoidable:* When Maven Shade merges 25 JARs into -one uber JAR, the contents of each contributing JAR are extracted and repacked into -a new ZIP structure. This invalidates every original signature unconditionally — -regardless of whether anything malicious occurred. There is no way to produce a -valid shaded uber JAR that preserves the original signatures. The only two outcomes -are: (1) strip the signatures and the uber JAR works correctly, or (2) leave the -signatures and the JVM throws a `SecurityException` on startup because the signatures -no longer match the repacked contents. Every uber JAR produced by Maven Shade or any -equivalent shading tool strips signatures — this is standard, expected, and -unavoidable. +*Why stripping is necessary and unavoidable:* When Maven Shade merges 25 JARs +into one uber JAR, the contents of each contributing JAR are extracted and +repacked into a new ZIP structure. This invalidates every original signature +unconditionally, regardless of whether anything malicious occurred. There is no +way to produce a valid shaded uber JAR that preserves the original signatures. +The only two outcomes are: (1) strip the signatures and the uber JAR works +correctly, or (2) leave the signatures and the JVM throws a `SecurityException` +on startup because the signatures no longer match the repacked contents. Every +uber JAR produced by Maven Shade or any equivalent shading tool strips +signatures, which is standard, expected, and unavoidable. *What you lose and whether it matters:* Stripping gives up the ability to verify at runtime that e.g. `saxon-he-10.8.jar` was genuinely published by Saxonica unmodified. However, that trust decision was already made implicitly when the JARs were added to -the project. Additionally, the JVM security manager — the runtime mechanism that -actually enforced JAR signature verification — was deprecated in Java 17 and removed +the project. Additionally, the JVM security manager, the runtime mechanism that +actually enforced JAR signature verification, was deprecated in Java 17 and removed in Java 21, meaning runtime signature enforcement no longer exists on Java 20+ regardless. Finally, JAR signing was originally designed to protect sandboxed environments such as browser applets and Java Web Start applications. Neither of @@ -832,10 +833,10 @@ update accordingly. ==== Overview `cimtool-cli` is an externally published, publicly distributed artifact. All -officially released builds must be signed using the UCA Users Group EV certificate -on the IdenTrust SafeNet hardware token. Signing is a release-only operation -performed by the CIMTool project lead — it is not part of the normal developer -build workflow. +officially released builds must be signed using the UCA Users Group EV +certificate on the IdenTrust SafeNet hardware token. Signing is a release-only +operation performed by the CIMTool project lead, not as part of the normal +developer build workflow. For local development and testing, the unsigned uber JAR produced by `mvn clean package` is fully functional. The JVM does not require a JAR to be @@ -845,10 +846,10 @@ signed in order to execute it via `java -jar`. Signing of `cimtool-cli.jar` for official releases is handled automatically by `CIMToolProduct/release-cimtool.bat`. That script orchestrates the complete -release pipeline for both CIMToolProduct and cimtool-cli — it invokes -`install-jars.bat`, runs `mvn clean package`, signs the resulting uber JAR via -PKCS#11 using the IdenTrust EV hardware token, deploys the signed JAR to `dist/`, -and generates the `dist/cimtool-cli.jar.sha256` checksum file. +release pipeline for both CIMToolProduct and cimtool-cli, invoking +`install-jars.bat`, running `mvn clean package`, and signing the resulting uber +JAR via PKCS#11 using the IdenTrust EV hardware token, deploys the signed JAR to +`dist/`, and generates the `dist/cimtool-cli.jar.sha256` checksum file. See `CIMToolProduct/CIMToolProduct-README` for the full release signing procedure, prerequisites, and the complete step-by-step walkthrough. @@ -856,7 +857,7 @@ prerequisites, and the complete step-by-step walkthrough. ==== Verifying the Release Signature To verify the signed JAR use Eclipse Temurin's `jarsigner` (not Zulu or other -OpenJDK distributions — see the CIMToolProduct-README Prerequisites section for +OpenJDK distributions, see the CIMToolProduct-README Prerequisites section for the reason): ---- @@ -872,6 +873,6 @@ with since signing. The signing script embeds a trusted RFC 3161 timestamp from IdenTrust's TSA server (`http://timestamp.identrust.com`). This ensures the signature remains verifiable -indefinitely — even after the EV signing certificate expires. See +indefinitely, even after the EV signing certificate expires. See `CIMToolProduct/CIMToolProduct-README` for a full explanation of how timestamped signatures work and why they remain valid after certificate expiry. diff --git a/dev-docs/Includes/cimtool-cli/cimtool-cli-README.md b/dev-docs/Includes/cimtool-cli/cimtool-cli-README.md index c27d0036..809431a7 100644 --- a/dev-docs/Includes/cimtool-cli/cimtool-cli-README.md +++ b/dev-docs/Includes/cimtool-cli/cimtool-cli-README.md @@ -3,7 +3,7 @@ A standalone Maven project that assembles the CIMTool command-line interface into a single self-contained executable uber JAR (`cimtool-cli.jar`) using the Maven Shade plugin. While the CIMTool Eclipse RCP application is currently -released for Windows only — with macOS and Linux under evaluation — `cimtool-cli.jar` +released for Windows only, with macOS and Linux under evaluation, `cimtool-cli.jar` has no Eclipse or UI dependencies and can be run headless on any platform where Java 11 or later is available. @@ -39,14 +39,13 @@ The CLI entry point is `au.com.langdale.profiles.cl.CIMToolCLI`, which lives in | ------------------ | ------------------------------------------------------------ | | JDK | 11 or later | | Maven | 3.9 or later | -| Eclipse PDE product export | Required before running the install script — provides `kena.jar` and `cimutil.jar` from versioned plugin folders in the `plugins/` directory | +| Eclipse PDE product export | Required before running the install script: provides `kena.jar` and `cimutil.jar` from versioned plugin folders in the `plugins/` directory | ### Eclipse PDE Product Export Dependency This project sources `kena.jar` and `cimutil.jar` from a CIMTool Eclipse PDE product export. These JARs are **not** generated by Maven and are **not** taken -from the Eclipse workspace `bin/` directories — they must come from a full PDE -product export performed as described in `CIMToolProduct/CIMToolProduct-README` +from the Eclipse workspace `bin/` directories, but from a full PDE product export performed as described in `CIMToolProduct/CIMToolProduct-README` under the **PDE Product Export** section. After the export completes, the `plugins\` directory under the export root will @@ -105,9 +104,9 @@ CIMTool/ -## Dependency Management — Local File Repository +## Dependency Management: Local File Repository -> **Note — Keeping vendored dependencies in sync:** When a third-party dependency used by the CLI is added, removed, or upgraded, update `pom.xml`, both `install-jars.bat` and `install-jars.sh`, and regenerate `lib-repo/` together in the same change. See the [Vendored Library Change Checklist](../CIMToolProduct/CIMToolProduct-README.md#maintaining-vendored-third-party-libraries) in the CIMToolProduct documentation for the full repository-wide reference chain. +> **Note: Keeping vendored dependencies in sync:** When a third-party dependency used by the CLI is added, removed, or upgraded, update `pom.xml`, both `install-jars.bat` and `install-jars.sh`, and regenerate `lib-repo/` together in the same change. See the [Vendored Library Change Checklist](../CIMToolProduct/CIMToolProduct-README.md#maintaining-vendored-third-party-libraries) in the CIMToolProduct documentation for the full repository-wide reference chain. ### Why a Local Maven File Repository? @@ -139,13 +138,13 @@ directory inside `cimtool-cli/` is declared as a standard Maven repository in ``` All dependencies are then declared as normal Maven dependencies with no `system` -scope or `systemPath` — m2e resolves them cleanly against `lib-repo/` with no +scope or `systemPath`, m2e resolves them cleanly against `lib-repo/` with no errors or warnings. ### Populating lib-repo/ > **Release context:** For official releases, `install-jars.bat` is invoked -> automatically by `release-cimtool.bat` — no manual action is needed. +> automatically by `release-cimtool.bat`, with no manual action needed. > The instructions below apply to **local development only**. The `lib-repo/` directory is populated by running the provided install script, which @@ -158,7 +157,7 @@ cd cimtool-cli install-jars.bat D:\CIMTool-Releases\CIMTool-2.3.0 ``` -**Path contains spaces — wrap in double quotes:** +**Path contains spaces, wrap in double quotes:** ``` cd cimtool-cli install-jars.bat "D:\My Releases\CIMTool-2.3.0" @@ -208,9 +207,9 @@ skips it rather than aborting, so you can see all missing files in a single run. | Situation | Action Required | | ------------------------------------------------------------ | ------------------------------------------- | | First-time project setup | Run install script once after Eclipse PDE export | -| New CIMTool PDE product export — **local dev only** | Re-run install script with the new export root path. For official releases this is handled automatically by `release-cimtool.bat`. | +| New CIMTool PDE product export: **local dev only** | Re-run install script with the new export root path. For official releases this is handled automatically by `release-cimtool.bat`. | | Vendored JARs in `Kena/lib/` or `CIMUtil/lib/` updated | Re-run install script and answer `Y` at the vendor JAR prompt | -| Another developer clones the repo | No action needed — `lib-repo/` is committed | +| Another developer clones the repo | No action needed: `lib-repo/` is committed | ### Committing lib-repo/ to Source Control @@ -223,7 +222,7 @@ are current. The install script only needs to be re-run when the underlying JARs > `install-jars.bat` automatically, which may update `lib-repo/` if Kena or CIMUtil > versions have changed. Any resulting changes to `lib-repo/` must be committed back > to master via Pull Request **after** the build completes and **before** the release -> tag is created. See the **Phase 4 — Post-Build and Publishing** section in +> tag is created. See the **Phase 4: Post-Build and Publishing** section in > `CIMToolProduct/CIMToolProduct-README` for the full sequencing details. @@ -232,13 +231,13 @@ are current. The install script only needs to be re-run when the underlying JARs ### Local development build -**Step 1 — Populate `lib-repo/` after each PDE product export:** +**Step 1: Populate `lib-repo/` after each PDE product export:** ``` cd cimtool-cli install-jars.bat ``` -**Step 2 — Build the uber JAR:** +**Step 2: Build the uber JAR:** ``` cd cimtool-cli mvn clean package @@ -306,7 +305,7 @@ java -jar target/cimtool-cli.jar --help #### Informational Options -These options are standalone — they print output and exit immediately without performing any transformation. +These options are standalone, printing output and exiting immediately without performing any transformation. | Option | Short form | Description | | ------ | ---------- | ----------- | @@ -318,10 +317,10 @@ These options are standalone — they print output and exit immediately without | Option | Short form | Required | Description | | ------ | ---------- | -------- | ----------- | -| `--project-dir ` | `-pd` | Yes | Root directory of the CIMTool project. Must contain `.cimtool-settings` and `.builder-preferences`, and may optionally contain `.cimtool-global-preferences`. The CLI reads schema file locations from `.cimtool-settings`, builder configurations from `.builder-preferences`, and — when present — global preference values (e.g. PlantUML diagram style settings) from `.cimtool-global-preferences`; built-in defaults are used if that file is absent. | +| `--project-dir ` | `-pd` | Yes | Root directory of the CIMTool project. Must contain `.cimtool-settings` and `.builder-preferences`, and may optionally contain `.cimtool-global-preferences`. The CLI reads schema file locations from `.cimtool-settings`, builder configurations from `.builder-preferences`, and: when present: global preference values (e.g. PlantUML diagram style settings) from `.cimtool-global-preferences`; built-in defaults are used if that file is absent. | | `--profile ` | `-p` | No | Single `.owl` profile file to transform. If omitted, all `.owl` files in `/Profiles` are processed. | | `--output ` | `-o` | Optional when `--project-dir` is specified | Output directory for generated artifacts. Defaults to `/Profiles` when not specified. | -| `--builder ` | `-b` | No | Builder name from the bundled catalog (e.g. `xsd`, `json-schema-draft-07`, `legacy-rdfs`). Overrides the builders configured on each profile. Works for all builder types — both XSLT-based (`TEXT`, `XSD`, `TRANSFORM`) and Java-based (`JAVA`). Mutually exclusive with `--xslt`. | +| `--builder ` | `-b` | No | Builder name from the bundled catalog (e.g. `xsd`, `json-schema-draft-07`, `legacy-rdfs`). Overrides the builders configured on each profile. Works for all builder types: both XSLT-based (`TEXT`, `XSD`, `TRANSFORM`) and Java-based (`JAVA`). Mutually exclusive with `--xslt`. | | `--xslt ` | `-x` | No | Path to a custom XSLT stylesheet not in the bundled catalog. Requires `--output-ext`. Mutually exclusive with `--builder`. | | `--output-ext ` | `-oe` | Required when `--xslt` is used | Output file extension for artifacts produced by a custom `--xslt` stylesheet (without the leading dot). Not required when using `--builder` or profile-configured builders. | @@ -349,13 +348,13 @@ These options are standalone — they print output and exit immediately without | `TEXT` | XSLT-based; produces text output with indentation post-processing applied | | `XSD` | XSLT-based; produces XSD schemas with XML Schema validation of the output | | `TRANSFORM` | XSLT-based; produces XML output without additional post-processing | -| `JAVA` | Java-based; uses CIMTool generator classes directly — no XSLT stylesheet involved | +| `JAVA` | Java-based; uses CIMTool generator classes directly: no XSLT stylesheet involved | The `JAVA` builders (`xml`, `ttl`, `simple-flat-owl`, `simple-owl`, `legacy-rdfs`, `simple-flat-owl-augmented`, `simple-owl-augmented`, `legacy-rdfs-augmented`) were previously executable only within the Eclipse desktop application. Beginning with the 2.3.0 release they are fully supported by the CLI. ### Common Usage Examples -**Minimum valid invocation — process all profiles using their configured builders:** +**Minimum valid invocation, process all profiles using their configured builders:** ``` java -jar cimtool-cli.jar --project-dir .\MyProject ``` @@ -363,7 +362,7 @@ java -jar cimtool-cli.jar --project-dir .\MyProject java -jar cimtool-cli.jar -pd .\MyProject ``` -The CLI reads project settings from `.\MyProject`, processes every `.owl` file in `.\MyProject\Profiles`, and for each profile runs whichever builders are configured on it. Generated artifacts are written to `.\MyProject\Profiles` alongside the source `.owl` files — the same default behavior as the desktop application. +The CLI reads project settings from `.\MyProject`, processes every `.owl` file in `.\MyProject\Profiles`, and for each profile runs whichever builders are configured on it. Generated artifacts are written to `.\MyProject\Profiles` alongside the source `.owl` files, the same default behavior as the desktop application. **Transform a single profile using a named builder:** ``` @@ -491,17 +490,17 @@ The debug configuration enables the following: Log output (warnings, errors, debug messages) is written to `stderr` and progress messages to `stdout`. The commands below capture both streams together. -**Linux / macOS** — writes to file and shows output on screen simultaneously: +**Linux / macOS**: writes to file and shows output on screen simultaneously: ``` java -Dlogback.configurationFile=./logback-debug.xml -jar cimtool-cli.jar [options...] 2>&1 | tee debug.log ``` -**Windows Command Prompt** — writes to file only (no simultaneous screen output): +**Windows Command Prompt**: writes to file only (no simultaneous screen output): ``` java -Dlogback.configurationFile=.\logback-debug.xml -jar cimtool-cli.jar [options...] > debug.log 2>&1 ``` -**Windows PowerShell** — writes to file and shows output on screen simultaneously: +**Windows PowerShell**: writes to file and shows output on screen simultaneously: ``` java -Dlogback.configurationFile=.\logback-debug.xml -jar cimtool-cli.jar [options...] 2>&1 | Tee-Object -FilePath debug.log ``` @@ -527,10 +526,10 @@ names and levels to focus on specific subsystems. `BuilderRegistry` loads builder configurations and XSLT stylesheets at runtime via classpath resource lookups. Two configuration files are loaded: -- `builders.json` — XSLT-based builder catalog (`TEXT`, `XSD`, `TRANSFORM` types), loaded via `getResourceAsStream("/builders.json")` -- `java-builders.json` — Java-based builder catalog (`JAVA` type), loaded via `getResourceAsStream("/java-builders.json")` +- `builders.json`: XSLT-based builder catalog (`TEXT`, `XSD`, `TRANSFORM` types), loaded via `getResourceAsStream("/builders.json")` +- `java-builders.json`: Java-based builder catalog (`JAVA` type), loaded via `getResourceAsStream("/java-builders.json")` -Both files are loaded into a single unified `TreeMap`, producing one alphabetically sorted registry. XSLT stylesheets are loaded via `getResourceAsStream("/" + xslFileName)`. All of these resources must reside at the **classpath root** of the uber JAR — not under a `builders/` subdirectory. +Both files are loaded into a single unified `TreeMap`, producing one alphabetically sorted registry. XSLT stylesheets are loaded via `getResourceAsStream("/" + xslFileName)`. All of these resources must reside at the **classpath root** of the uber JAR, not under a `builders/` subdirectory. This is achieved by declaring `CIMUtil/builders/` itself (not its parent) as the resource root via `build-helper-maven-plugin` in `pom.xml`. This causes Maven to @@ -562,7 +561,7 @@ contributing JAR before assembly. #### Is This a Security Concern? -No — stripping signatures is not a security concern for this use case, and here +No, stripping signatures is not a security concern for this use case, and here is why. **What JAR signing actually protects:** JAR signing allows a consumer to verify that @@ -572,20 +571,19 @@ of the original JAR file. **Why stripping is necessary and unavoidable:** When Maven Shade merges 25 JARs into one uber JAR, the contents of each contributing JAR are extracted and repacked into -a new ZIP structure. This invalidates every original signature unconditionally — +a new ZIP structure. This invalidates every original signature unconditionally, regardless of whether anything malicious occurred. There is no way to produce a valid shaded uber JAR that preserves the original signatures. The only two outcomes are: (1) strip the signatures and the uber JAR works correctly, or (2) leave the signatures and the JVM throws a `SecurityException` on startup because the signatures no longer match the repacked contents. Every uber JAR produced by Maven Shade or any -equivalent shading tool strips signatures — this is standard, expected, and -unavoidable. +equivalent shading tool strips signatures, which is standard, expected, and unavoidable. **What you lose and whether it matters:** Stripping gives up the ability to verify at runtime that e.g. `saxon-he-10.8.jar` was genuinely published by Saxonica unmodified. However, that trust decision was already made implicitly when the JARs were added to -the project. Additionally, the JVM security manager — the runtime mechanism that -actually enforced JAR signature verification — was deprecated in Java 17 and removed +the project. Additionally, the JVM security manager, the runtime mechanism that +actually enforced JAR signature verification, was deprecated in Java 17 and removed in Java 21, meaning runtime signature enforcement no longer exists on Java 20+ regardless. Finally, JAR signing was originally designed to protect sandboxed environments such as browser applets and Java Web Start applications. Neither of @@ -621,8 +619,7 @@ update accordingly. `cimtool-cli` is an externally published, publicly distributed artifact. All officially released builds must be signed using the UCA Users Group EV certificate on the IdenTrust SafeNet hardware token. Signing is a release-only operation -performed by the CIMTool project lead — it is not part of the normal developer -build workflow. +performed by the CIMTool project lead, not as part of the normal developer build workflow. For local development and testing, the unsigned uber JAR produced by `mvn clean package` is fully functional. The JVM does not require a JAR to be @@ -632,8 +629,7 @@ signed in order to execute it via `java -jar`. Signing of `cimtool-cli.jar` for official releases is handled automatically by `CIMToolProduct/release-cimtool.bat`. That script orchestrates the complete -release pipeline for both CIMToolProduct and cimtool-cli — it invokes -`install-jars.bat`, runs `mvn clean package`, signs the resulting uber JAR via +release pipeline for both CIMToolProduct and cimtool-cli, invoking `install-jars.bat`, running `mvn clean package`, and signing the resulting uber JAR via PKCS#11 using the IdenTrust EV hardware token, deploys the signed JAR to `dist/`, and generates the `dist/cimtool-cli.jar.sha256` checksum file. @@ -643,7 +639,7 @@ prerequisites, and the complete step-by-step walkthrough. ### Verifying the Release Signature To verify the signed JAR use Eclipse Temurin's `jarsigner` (not Zulu or other -OpenJDK distributions — see the CIMToolProduct-README Prerequisites section for +OpenJDK distributions, see the CIMToolProduct-README Prerequisites section for the reason): ``` @@ -659,6 +655,6 @@ with since signing. The signing script embeds a trusted RFC 3161 timestamp from IdenTrust's TSA server (`http://timestamp.identrust.com`). This ensures the signature remains verifiable -indefinitely — even after the EV signing certificate expires. See +indefinitely, even after the EV signing certificate expires. See `CIMToolProduct/CIMToolProduct-README` for a full explanation of how timestamped signatures work and why they remain valid after certificate expiry. diff --git a/dev-docs/Includes/com.cimphony.cimtoole/com.cimphony.cimtoole-README.adoc b/dev-docs/Includes/com.cimphony.cimtoole/com.cimphony.cimtoole-README.adoc index 6d184c65..61f71b40 100644 --- a/dev-docs/Includes/com.cimphony.cimtoole/com.cimphony.cimtoole-README.adoc +++ b/dev-docs/Includes/com.cimphony.cimtoole/com.cimphony.cimtoole-README.adoc @@ -19,13 +19,13 @@ output from CIM profiles. === Overview -`com.cimphony.cimtoole` is a pure extension plugin — it contributes no new +`com.cimphony.cimtoole` is a pure extension plugin that contributes no new extension points of its own and carries no application state. All of its functionality is exposed through the two extension points defined by `CIMToolPlugin`: -* `au.com.langdale.cimtoole.model_parser` — registers two Ecore model parsers -* `au.com.langdale.cimtoole.profile_buildlet` — registers the Ecore buildlet +* `au.com.langdale.cimtoole.model_parser`: registers two Ecore model parsers +* `au.com.langdale.cimtoole.profile_buildlet`: registers the Ecore buildlet It also contributes standard Eclipse UI extension points for import and export wizards and for associating the `Model Browser` editor with Ecore file types. @@ -82,7 +82,7 @@ com.cimphony.cimtoole/ | `au.com.langdale.kena` | `Require-Bundle` -| RDF graph API — `OntModel`, `Resource`, graph traversal +| RDF graph API: `OntModel`, `Resource`, graph traversal | `au.com.langdale.rcputil` | `Require-Bundle` @@ -90,15 +90,15 @@ com.cimphony.cimtoole/ | `org.eclipse.emf.ecore` | `Require-Bundle` -| EMF core Ecore metamodel — `EPackage`, `EClass`, `EAttribute`, `EReference` +| EMF core Ecore metamodel: `EPackage`, `EClass`, `EAttribute`, `EReference` | `org.eclipse.emf.ecore.xmi` | `Require-Bundle` -| EMF XMI serialization — reading and writing `.ecore` resource files +| EMF XMI serialization: reading and writing `.ecore` resource files | `org.eclipse.emf` | `Require-Bundle` -| EMF runtime — `ResourceSet`, `Resource`, URI handling +| EMF runtime: `ResourceSet`, `Resource`, URI handling | `org.eclipse.ui`, `org.eclipse.ui.forms` | `Require-Bundle` @@ -126,12 +126,12 @@ CIM schema sources: | `com.cimphony.cimtoole.ecore_parser` | `.ecore` -| `EcoreExtractor` — reads an EMF `.ecore` file and converts it to a Kena +| `EcoreExtractor`: reads an EMF `.ecore` file and converts it to a Kena `OntModel` representing the CIM schema | `com.cimphony.cimtoole.ecore_registry_parser` | `.ecore-registry` -| `EcoreRegistryExtractor` — reads schema from the EMF `EPackage.Registry` +| `EcoreRegistryExtractor`: reads schema from the EMF `EPackage.Registry` (the runtime registry of all loaded Ecore packages) rather than from a file |=== @@ -144,7 +144,7 @@ Registers one profile buildlet that adds Ecore output to the CIMBuilder: | Buildlet ID | What it produces | `com.cimphony.cimtoole.ecore_buildlet` -| `EcoreBuildlet` — transforms a CIM profile OWL model into an `.ecore` file +| `EcoreBuildlet`: transforms a CIM profile OWL model into an `.ecore` file using EMF serialization, producing an Ecore metamodel corresponding to the profiled subset of the CIM |=== @@ -152,13 +152,13 @@ Registers one profile buildlet that adds Ecore output to the CIMBuilder: ==== org.eclipse.ui.importWizards Registers **Import Schema from Registry** (`ImportRegistrySchema`) under the -CIMTool wizard category — allows importing an EMF registry-registered Ecore +CIMTool wizard category; allows importing an EMF registry-registered Ecore package directly as a CIM schema without requiring a `.ecore` file on disk. ==== org.eclipse.ui.exportWizards Registers **Export merged schema as Ecore** (`ExportEcore`) under the CIMTool -wizard category — exports the merged CIM schema (background model) from a +wizard category; exports the merged CIM schema (background model) from a CIMTool project as an `.ecore` file. ==== org.eclipse.ui.editors @@ -171,22 +171,22 @@ CIMTool project uses the Model Browser editor. === Relationship to Other Projects -* *CIMToolPlugin* — the host plugin. `com.cimphony.cimtoole` depends on +* *CIMToolPlugin*: the host plugin. `com.cimphony.cimtoole` depends on `au.com.langdale.cimtoole` both for its extension points and for reusing `InfoModelEditor` as the editor for Ecore files. It cannot be loaded without `CIMToolPlugin` present. -* *CIMUtil* — provides the profile model (`ProfileModel`, `OntModel`) that +* *CIMUtil*: provides the profile model (`ProfileModel`, `OntModel`) that `EcoreExtractor` and `EcoreBuildlet` operate on. The Ecore generation logic in `EcoreGenerator` reads the profile's OWL classes and properties and maps them to EMF `EClass` and `EAttribute` / `EReference` equivalents. -* *Kena* — the `OntModel` and related RDF graph API types used by `EcoreExtractor` +* *Kena*: the `OntModel` and related RDF graph API types used by `EcoreExtractor` and `EcoreGenerator` come from Kena via `Import-Package` declarations. -* *CIMToolFeature* — lists `com.cimphony.cimtoole` as one of the plugins in +* *CIMToolFeature*: lists `com.cimphony.cimtoole` as one of the plugins in its feature. The feature is currently dormant (see `CIMToolFeature-README.adoc`), but this plugin itself is fully active. -* *CIMToolProduct* — `CIMTool.product` includes `com.cimphony.cimtoole` in its +* *CIMToolProduct*: `CIMTool.product` includes `com.cimphony.cimtoole` in its plugin list, so it is shipped in every CIMTool distribution. diff --git a/dev-docs/Includes/com.cimphony.cimtoole/com.cimphony.cimtoole-README.md b/dev-docs/Includes/com.cimphony.cimtoole/com.cimphony.cimtoole-README.md index 479a1855..9d23c794 100644 --- a/dev-docs/Includes/com.cimphony.cimtoole/com.cimphony.cimtoole-README.md +++ b/dev-docs/Includes/com.cimphony.cimtoole/com.cimphony.cimtoole-README.md @@ -10,13 +10,12 @@ output from CIM profiles. ## Overview -`com.cimphony.cimtoole` is a pure extension plugin — it contributes no new -extension points of its own and carries no application state. All of its +`com.cimphony.cimtoole` is a pure extension plugin that contributes no new extension points of its own and carries no application state. All of its functionality is exposed through the two extension points defined by `CIMToolPlugin`: -- `au.com.langdale.cimtoole.model_parser` — registers two Ecore model parsers -- `au.com.langdale.cimtoole.profile_buildlet` — registers the Ecore buildlet +- `au.com.langdale.cimtoole.model_parser`: registers two Ecore model parsers +- `au.com.langdale.cimtoole.profile_buildlet`: registers the Ecore buildlet It also contributes standard Eclipse UI extension points for import and export wizards and for associating the `Model Browser` editor with Ecore file types. @@ -61,11 +60,11 @@ com.cimphony.cimtoole/ | --- | --- | --- | | `au.com.langdale.cimtoole` | `Require-Bundle` | CIMToolPlugin extension points (`model_parser`, `profile_buildlet`) and base editor class (`InfoModelEditor`) reused for Ecore file types | | `au.com.langdale.cimutil` | `Require-Bundle` | Profile model classes and Kena graph API used by `EcoreExtractor` and `EcoreBuildlet` to read and write CIM profile OWL models | -| `au.com.langdale.kena` | `Require-Bundle` | RDF graph API — `OntModel`, `Resource`, graph traversal | +| `au.com.langdale.kena` | `Require-Bundle` | RDF graph API: `OntModel`, `Resource`, graph traversal | | `au.com.langdale.rcputil` | `Require-Bundle` | Eclipse RCP UI utilities used by wizard base classes | -| `org.eclipse.emf.ecore` | `Require-Bundle` | EMF core Ecore metamodel — `EPackage`, `EClass`, `EAttribute`, `EReference` | -| `org.eclipse.emf.ecore.xmi` | `Require-Bundle` | EMF XMI serialization — reading and writing `.ecore` resource files | -| `org.eclipse.emf` | `Require-Bundle` | EMF runtime — `ResourceSet`, `Resource`, URI handling | +| `org.eclipse.emf.ecore` | `Require-Bundle` | EMF core Ecore metamodel: `EPackage`, `EClass`, `EAttribute`, `EReference` | +| `org.eclipse.emf.ecore.xmi` | `Require-Bundle` | EMF XMI serialization: reading and writing `.ecore` resource files | +| `org.eclipse.emf` | `Require-Bundle` | EMF runtime: `ResourceSet`, `Resource`, URI handling | | `org.eclipse.ui`, `org.eclipse.ui.forms` | `Require-Bundle` | Eclipse workbench and forms UI APIs for wizards and dialogs | | `org.eclipse.core.resources`, `org.eclipse.core.runtime` | `Require-Bundle` | Eclipse workspace resources and runtime platform APIs | @@ -81,8 +80,8 @@ Registers two model parsers that allow CIMTool to import Ecore models as CIM sch | Parser ID | File Extension | Implementation | | --- | --- | --- | -| `com.cimphony.cimtoole.ecore_parser` | `.ecore` | `EcoreExtractor` — reads an EMF `.ecore` file and converts it to a Kena `OntModel` representing the CIM schema | -| `com.cimphony.cimtoole.ecore_registry_parser` | `.ecore-registry` | `EcoreRegistryExtractor` — reads schema from the EMF `EPackage.Registry` (the runtime registry of all loaded Ecore packages) rather than from a file | +| `com.cimphony.cimtoole.ecore_parser` | `.ecore` | `EcoreExtractor`: reads an EMF `.ecore` file and converts it to a Kena `OntModel` representing the CIM schema | +| `com.cimphony.cimtoole.ecore_registry_parser` | `.ecore-registry` | `EcoreRegistryExtractor`: reads schema from the EMF `EPackage.Registry` (the runtime registry of all loaded Ecore packages) rather than from a file | ### au.com.langdale.cimtoole.profile_buildlet @@ -90,15 +89,15 @@ Registers one profile buildlet that adds Ecore output to the CIMBuilder: | Buildlet ID | What it produces | | --- | --- | -| `com.cimphony.cimtoole.ecore_buildlet` | `EcoreBuildlet` — transforms a CIM profile OWL model into an `.ecore` file using EMF serialization, producing an Ecore metamodel corresponding to the profiled subset of the CIM | +| `com.cimphony.cimtoole.ecore_buildlet` | `EcoreBuildlet`: transforms a CIM profile OWL model into an `.ecore` file using EMF serialization, producing an Ecore metamodel corresponding to the profiled subset of the CIM | ### org.eclipse.ui.importWizards -Registers **Import Schema from Registry** (`ImportRegistrySchema`) under the CIMTool wizard category — allows importing an EMF registry-registered Ecore package directly as a CIM schema without requiring a `.ecore` file on disk. +Registers **Import Schema from Registry** (`ImportRegistrySchema`) under the CIMTool wizard category, which allows importing an EMF registry-registered Ecore package directly as a CIM schema without requiring a `.ecore` file on disk. ### org.eclipse.ui.exportWizards -Registers **Export merged schema as Ecore** (`ExportEcore`) under the CIMTool wizard category — exports the merged CIM schema (background model) from a CIMTool project as an `.ecore` file. +Registers **Export merged schema as Ecore** (`ExportEcore`) under the CIMTool wizard category, which exports the merged CIM schema (background model) from a CIMTool project as an `.ecore` file. ### org.eclipse.ui.editors @@ -108,8 +107,8 @@ Associates the existing `InfoModelEditor` (defined in `CIMToolPlugin`) with `.ec ## Relationship to Other Projects -- **CIMToolPlugin** — the host plugin. `com.cimphony.cimtoole` depends on `au.com.langdale.cimtoole` both for its extension points and for reusing `InfoModelEditor` as the editor for Ecore files. It cannot be loaded without `CIMToolPlugin` present. -- **CIMUtil** — provides the profile model (`ProfileModel`, `OntModel`) that `EcoreExtractor` and `EcoreBuildlet` operate on. The Ecore generation logic in `EcoreGenerator` reads the profile's OWL classes and properties and maps them to EMF `EClass` and `EAttribute` / `EReference` equivalents. -- **Kena** — the `OntModel` and related RDF graph API types used by `EcoreExtractor` and `EcoreGenerator` come from Kena via `Import-Package` declarations. -- **CIMToolFeature** — lists `com.cimphony.cimtoole` as one of the plugins in its feature. The feature is currently dormant (see `CIMToolFeature-README.adoc`), but this plugin itself is fully active. -- **CIMToolProduct** — `CIMTool.product` includes `com.cimphony.cimtoole` in its plugin list, so it is shipped in every CIMTool distribution. +- **CIMToolPlugin**: the host plugin. `com.cimphony.cimtoole` depends on `au.com.langdale.cimtoole` both for its extension points and for reusing `InfoModelEditor` as the editor for Ecore files. It cannot be loaded without `CIMToolPlugin` present. +- **CIMUtil**: provides the profile model (`ProfileModel`, `OntModel`) that `EcoreExtractor` and `EcoreBuildlet` operate on. The Ecore generation logic in `EcoreGenerator` reads the profile's OWL classes and properties and maps them to EMF `EClass` and `EAttribute` / `EReference` equivalents. +- **Kena**: the `OntModel` and related RDF graph API types used by `EcoreExtractor` and `EcoreGenerator` come from Kena via `Import-Package` declarations. +- **CIMToolFeature**: lists `com.cimphony.cimtoole` as one of the plugins in its feature. The feature is currently dormant (see `CIMToolFeature-README.adoc`), but this plugin itself is fully active. +- **CIMToolProduct**: `CIMTool.product` includes `com.cimphony.cimtoole` in its plugin list, so it is shipped in every CIMTool distribution. diff --git a/dev-docs/Includes/introduction.adoc b/dev-docs/Includes/introduction.adoc index e6625aec..a35b6f51 100644 --- a/dev-docs/Includes/introduction.adoc +++ b/dev-docs/Includes/introduction.adoc @@ -4,25 +4,25 @@ This document is the developer documentation for CIMTool, the open-source platform maintained by the UCA International Users Group for authoring CIM (Common Information Model) profiles and generating the artifacts derived from them. It is written for the -developers who build, extend, package, and release CIMTool — contributors working in +developers who build, extend, package, and release CIMTool, contributors working in the source tree, not end users authoring profiles. Documentation on using CIMTool itself lives separately on the project website at https://cimtool.ucaiug.io/[cimtool.ucaiug.io]. CIMTool is structured as a suite of Eclipse PDE plugins and supporting projects that together produce a standalone Rich Client Platform (RCP) application, along with a -companion command-line tool. Because that structure spans many cooperating projects — -the core plugin, shared utilities, the RDF engine, the product and feature -definitions, the CLI, and others — this document is assembled modularly: each project -contributes its own README, and those READMEs are included here into a single -reference. Each README also stands alone in its project directory for developers -working within that one component. +companion command-line tool. Because that structure spans many cooperating projects +(the core plugin, shared utilities, the RDF engine, the product and feature +definitions, the CLI, and others), this document is assembled modularly with each +project contributing its own README, and those READMEs are included here into a +single reference. Each README also stands alone in its project directory for +developers working within that one component. Each project section describes that component's purpose, its place in the overall architecture, its dependencies on other projects and on vendored third-party libraries, and the conventions that govern how it is built and maintained. -Cross-cutting concerns that span multiple projects — the build and release pipeline, -code signing, the unified logging architecture, and the dependency vendoring model — +Cross-cutting concerns that span multiple projects, the build and release pipeline, +code signing, the unified logging architecture, and the dependency vendoring model are documented where they are owned, with cross-references from the projects they affect. diff --git a/dev-docs/Includes/io.ucaiug.slf4j.logback.binding/io.ucaiug.slf4j.logback.binding-README.adoc b/dev-docs/Includes/io.ucaiug.slf4j.logback.binding/io.ucaiug.slf4j.logback.binding-README.adoc index 994eb1b5..f87ff8dd 100644 --- a/dev-docs/Includes/io.ucaiug.slf4j.logback.binding/io.ucaiug.slf4j.logback.binding-README.adoc +++ b/dev-docs/Includes/io.ucaiug.slf4j.logback.binding/io.ucaiug.slf4j.logback.binding-README.adoc @@ -10,13 +10,13 @@ :xrefstyle: short A minimal OSGi fragment bundle that wires SLF4J 2.x to Logback as its logging -provider in the CIMTool Eclipse RCP product. Without this bundle, SLF4J permanently -binds to its built-in NOP implementation and all SLF4J-native log events from -vendored libraries (Saxon-HE, m2e/Aether, UCanAccess, and others) are silently -discarded — `logs/cimtool.log` is created by Logback but remains empty. With this -bundle in place those events flow through Logback into `logs/cimtool.log`, -completing the unified single-file logging pipeline together with the JUL bridge -(`jul-to-slf4j`) installed by `CIMToolPlugin`. +provider in the CIMTool Eclipse RCP product. Without this bundle, SLF4J +permanently binds to its built-in NOP implementation and all SLF4J-native log +events from vendored libraries (Saxon-HE, m2e/Aether, UCanAccess, and others) +are silently discarded, and `logs/cimtool.log` is created by Logback but remains +empty. With this bundle in place those events flow through Logback into +`logs/cimtool.log`, completing the unified single-file logging pipeline together +with the JUL bridge (`jul-to-slf4j`) installed by `CIMToolPlugin`. @@ -47,19 +47,21 @@ JUL is bridged to SLF4J at startup by `SLF4JBridgeHandler` installed in through SLF4J -> Logback into `logs/cimtool.log`. Log4j 1.x calls are intercepted by `log4j-over-slf4j` in Kena's `Bundle-ClassPath` and routed into SLF4J. -SLF4J 2.x provider discovery fails silently in OSGi due to classloader isolation. -SLF4J uses `ServiceLoader` to discover its logging provider at runtime. On a standard -flat classpath this works transparently — `ServiceLoader` scans all -`META-INF/services/` files reachable from a single classloader and finds Logback's -registration. In OSGi, every bundle has its own isolated classloader and can only see -packages it explicitly imports. When SLF4J calls `ServiceLoader.load()` to find its -provider, the calling classloader is `slf4j.api`'s own bundle classloader — which has -no visibility into the `ch.qos.logback.classic` bundle. `ServiceLoader` finds nothing, -and SLF4J permanently binds to its built-in NOP (no-operation) implementation — all +SLF4J 2.x provider discovery fails silently in OSGi due to classloader +isolation. SLF4J uses `ServiceLoader` to discover its logging provider at +runtime. On a standard flat classpath this works transparently, with +`ServiceLoader` scanning all `META-INF/services/` files reachable from a single +classloader and finds Logback's registration. In OSGi, every bundle has its own +isolated classloader and can only see packages it explicitly imports. When SLF4J +calls `ServiceLoader.load()` to find its provider, the calling classloader is +`slf4j.api`'s own bundle classloader, which has no visibility into the +`ch.qos.logback.classic` bundle. `ServiceLoader` finds nothing, and SLF4J +permanently binds to its built-in NOP (no-operation) implementation, and all SLF4J-native log events are silently discarded for the lifetime of the JVM. This bundle solves the problem by attaching as an OSGi fragment to `slf4j.api`, which -merges its `META-INF/services/` registration directly into `slf4j.api`'s classloader -so `ServiceLoader` finds `LogbackServiceProvider` at the moment SLF4J initialises. +merges its `META-INF/services/` registration directly into `slf4j.api`'s +classloader so `ServiceLoader` finds `LogbackServiceProvider` at the moment +SLF4J initialises. === Why a Fragment Bundle? @@ -71,24 +73,24 @@ An OSGi *fragment bundle* shares its host bundle's classloader. By declaring `Fragment-Host: slf4j.api`, this bundle's contents become part of `slf4j.api`'s classloader. This means the `META-INF/services/org.slf4j.spi.SLF4JServiceProvider` file inside this fragment is visible when `ServiceLoader` scans `slf4j.api`'s -classloader — so it finds `LogbackServiceProvider` and SLF4J binds to Logback +classloader, so it finds `LogbackServiceProvider` and SLF4J binds to Logback correctly. `DynamicImport-Package: ch.qos.logback.classic.spi` allows the classloader to -resolve `LogbackServiceProvider`'s class at runtime without creating static package -wiring that could introduce split-package conflicts with other bundles. Specifically, -a static `Import-Package: ch.qos.logback.classic.spi` would create a wiring conflict -on the `org.xml.sax` package — both `slf4j.api` and the Logback classic bundle export -it, and a static import would cause OSGi to fail to resolve the bundle entirely, -breaking `XMIModel` initialisation at startup. +resolve `LogbackServiceProvider`'s class at runtime without creating static +package wiring that could introduce split-package conflicts with other bundles. +Specifically, a static `Import-Package: ch.qos.logback.classic.spi` would create +a wiring conflict on the `org.xml.sax` package, since both `slf4j.api` and the +Logback classic bundle export it, and a static import would cause OSGi to fail +to resolve the bundle entirely, breaking `XMIModel` initialisation at startup. This approach: -* Requires *no bytecode weaving* — unlike Apache Aries SPI Fly, no class +* Requires *no bytecode weaving*, so unlike Apache Aries SPI Fly, no class modification at runtime occurs -* Has *no impact on security scanning tools* — the bundle contains only metadata +* Has *no impact on security scanning tools*, since the bundle contains only metadata files, no executable code -* Is *self-contained* — two metadata files and no JAR dependencies +* Is *self-contained*, two metadata files and no JAR dependencies * Is *version-controlled* as part of the CIMTool repo alongside all other dependencies @@ -101,8 +103,8 @@ implementation and is the "official" solution to this class of problem. It was evaluated and rejected for CIMTool for one practical reason: SPI Fly uses ASM bytecode weaving to intercept `ServiceLoader.load()` calls at class-load time. Security tools including Malwarebytes flag this behavior as a -`Malware.Ransom.Agent.Generic` threat because the behavioral signature — an -application that loads and modifies bytecodes dynamically at runtime — is +`Malware.Ransom.Agent.Generic` threat because the behavioral signature, an +application that loads and modifies bytecodes dynamically at runtime, is indistinguishable from ransomware to a heuristic scanner. Since CIMTool is deployed in utility companies with enterprise security policies, this is not acceptable. @@ -134,20 +136,20 @@ Fragment-Host: slf4j.api DynamicImport-Package: ch.qos.logback.classic.spi ---- -*`Fragment-Host: slf4j.api`* — declares this as a fragment of the `slf4j.api` +*`Fragment-Host: slf4j.api`*: declares this as a fragment of the `slf4j.api` OSGi bundle. The fragment's classpath contents (including `META-INF/services/`) are merged into `slf4j.api`'s classloader at framework startup. When SLF4J calls `ServiceLoader.load(SLF4JServiceProvider.class)` the services file is now visible and `LogbackServiceProvider` is discovered. -*`DynamicImport-Package: ch.qos.logback.classic.spi`* — allows the classloader -to load `ch.qos.logback.classic.spi.LogbackServiceProvider` at runtime when +*`DynamicImport-Package: ch.qos.logback.classic.spi`*: allows the classloader to +load `ch.qos.logback.classic.spi.LogbackServiceProvider` at runtime when ServiceLoader attempts to instantiate it. Dynamic imports are resolved lazily at class-load time rather than at bundle resolution time, so they do not affect the OSGi package wiring graph. A static `Import-Package` here would create a -split-package conflict on `org.xml.sax` — both `slf4j.api` and the Logback classic -bundle export it — which would prevent bundle resolution entirely and break -`XMIModel` initialisation at CIMTool startup. +split-package conflict on `org.xml.sax`, since both `slf4j.api` and the Logback +classic bundle export it, which would prevent bundle resolution entirely and +break `XMIModel` initialisation at CIMTool startup. @@ -160,10 +162,10 @@ line: ch.qos.logback.classic.spi.LogbackServiceProvider ---- -This is standard Java `ServiceLoader` registration. In a flat classpath environment -this file would be picked up automatically from Logback's JAR. In OSGi it is -invisible across bundle boundaries — this fragment makes it visible by placing it -on `slf4j.api`'s classloader. +This is standard Java `ServiceLoader` registration. In a flat classpath +environment this file would be picked up automatically from Logback's JAR. In +OSGi it is invisible across bundle boundaries, so this fragment makes it visible +by placing it on `slf4j.api`'s classloader. @@ -178,7 +180,7 @@ section: ---- The `fragment="true"` attribute tells the PDE exporter to include this bundle as -a fragment in the exported product. No start level configuration is needed — +a fragment in the exported product. No start level configuration is needed; fragment bundles attach to their host automatically at framework startup before any bundle activators run, which ensures SLF4J finds Logback before any other bundle triggers SLF4J initialization. @@ -198,11 +200,11 @@ entries in its MANIFEST. It wires to two platform bundles via OSGi manifest head | SLF4J API | `slf4j.api` -| `Fragment-Host` — this bundle is a fragment of `slf4j.api` and shares its classloader +| `Fragment-Host`: this bundle is a fragment of `slf4j.api` and shares its classloader | Logback Classic | `ch.qos.logback.classic` -| `DynamicImport-Package: ch.qos.logback.classic.spi` — resolved lazily at class-load +| `DynamicImport-Package: ch.qos.logback.classic.spi`: resolved lazily at class-load time to instantiate `LogbackServiceProvider` |=== @@ -213,7 +215,7 @@ at export time. Neither is vendored in this project. This project vendors *no third-party libraries*. It contains no JAR files and declares no `Bundle-ClassPath` entries. The project consists entirely of OSGi -metadata — `META-INF/MANIFEST.MF`, +metadata, `META-INF/MANIFEST.MF`, `META-INF/services/org.slf4j.spi.SLF4JServiceProvider`, and `build.properties`. diff --git a/dev-docs/Includes/io.ucaiug.slf4j.logback.binding/io.ucaiug.slf4j.logback.binding-README.md b/dev-docs/Includes/io.ucaiug.slf4j.logback.binding/io.ucaiug.slf4j.logback.binding-README.md index 13cb7e19..ee73ef55 100644 --- a/dev-docs/Includes/io.ucaiug.slf4j.logback.binding/io.ucaiug.slf4j.logback.binding-README.md +++ b/dev-docs/Includes/io.ucaiug.slf4j.logback.binding/io.ucaiug.slf4j.logback.binding-README.md @@ -3,8 +3,7 @@ A minimal OSGi fragment bundle that wires SLF4J 2.x to Logback as its logging provider in the CIMTool Eclipse RCP product. Without this bundle, SLF4J permanently binds to its built-in NOP implementation and all SLF4J-native log events from -vendored libraries (Saxon-HE, m2e/Aether, UCanAccess, and others) are silently -discarded — `logs/cimtool.log` is created by Logback but remains empty. With this +vendored libraries (Saxon-HE, m2e/Aether, UCanAccess, and others) are silently discarded, and `logs/cimtool.log` is created by Logback but remains empty. With this bundle in place those events flow through Logback into `logs/cimtool.log`, completing the unified single-file logging pipeline together with the JUL bridge (`jul-to-slf4j`) installed by `CIMToolPlugin`. @@ -23,20 +22,19 @@ application uses three distinct logging APIs: | Log4j 1.x | Apache Jena (via Kena) | 1.2.x (intercepted by `log4j-over-slf4j`) | JUL is bridged to SLF4J at startup by `SLF4JBridgeHandler` installed in -`CIMToolPlugin.configureLogging()` — all three logging sources therefore flow +`CIMToolPlugin.configureLogging()`: all three logging sources therefore flow through SLF4J → Logback into `logs/cimtool.log`. Log4j 1.x calls are intercepted by `log4j-over-slf4j` in Kena's `Bundle-ClassPath` and routed into SLF4J. SLF4J 2.x provider discovery fails silently in OSGi due to classloader isolation. SLF4J uses `ServiceLoader` to discover its logging provider at runtime. On a standard -flat classpath this works transparently — `ServiceLoader` scans all +flat classpath this works transparently, with `ServiceLoader` scanning all `META-INF/services/` files reachable from a single classloader and finds Logback's registration. In OSGi, every bundle has its own isolated classloader and can only see packages it explicitly imports. When SLF4J calls `ServiceLoader.load()` to find its -provider, the calling classloader is `slf4j.api`'s own bundle classloader — which has +provider, the calling classloader is `slf4j.api`'s own bundle classloader, which has no visibility into the `ch.qos.logback.classic` bundle. `ServiceLoader` finds nothing, -and SLF4J permanently binds to its built-in NOP (no-operation) implementation — all -SLF4J-native log events are silently discarded for the lifetime of the JVM. This +and SLF4J permanently binds to its built-in NOP (no-operation) implementation, and all SLF4J-native log events are silently discarded for the lifetime of the JVM. This bundle solves the problem by attaching as an OSGi fragment to `slf4j.api`, which merges its `META-INF/services/` registration directly into `slf4j.api`'s classloader so `ServiceLoader` finds `LogbackServiceProvider` at the moment SLF4J initialises. @@ -51,24 +49,22 @@ An OSGi **fragment bundle** shares its host bundle's classloader. By declaring `Fragment-Host: slf4j.api`, this bundle's contents become part of `slf4j.api`'s classloader. This means the `META-INF/services/org.slf4j.spi.SLF4JServiceProvider` file inside this fragment is visible when `ServiceLoader` scans `slf4j.api`'s -classloader — so it finds `LogbackServiceProvider` and SLF4J binds to Logback +classloader, so it finds `LogbackServiceProvider` and SLF4J binds to Logback correctly. `DynamicImport-Package: ch.qos.logback.classic.spi` allows the classloader to resolve `LogbackServiceProvider`'s class at runtime without creating static package wiring that could introduce split-package conflicts with other bundles. Specifically, -a static `Import-Package: ch.qos.logback.classic.spi` would create a wiring conflict -on the `org.xml.sax` package — both `slf4j.api` and the Logback classic bundle export -it, and a static import would cause OSGi to fail to resolve the bundle entirely, +a static `Import-Package: ch.qos.logback.classic.spi` would create a wiring conflict on the `org.xml.sax` package, since both `slf4j.api` and the Logback classic bundle export it, and a static import would cause OSGi to fail to resolve the bundle entirely, breaking `XMIModel` initialisation at startup. This approach: -- Requires **no bytecode weaving** — unlike Apache Aries SPI Fly, no class +- Requires **no bytecode weaving**, so unlike Apache Aries SPI Fly, no class modification at runtime occurs -- Has **no impact on security scanning tools** — the bundle contains only metadata +- Has **no impact on security scanning tools**, since the bundle contains only metadata files, no executable code -- Is **self-contained** — two metadata files and no JAR dependencies +- Is **self-contained**, two metadata files and no JAR dependencies - Is **version-controlled** as part of the CIMTool repo alongside all other dependencies @@ -81,8 +77,8 @@ implementation and is the "official" solution to this class of problem. It was evaluated and rejected for CIMTool for one practical reason: SPI Fly uses ASM bytecode weaving to intercept `ServiceLoader.load()` calls at class-load time. Security tools including Malwarebytes flag this behavior as a -`Malware.Ransom.Agent.Generic` threat because the behavioral signature — an -application that loads and modifies bytecodes dynamically at runtime — is +`Malware.Ransom.Agent.Generic` threat because the behavioral signature, an +application that loads and modifies bytecodes dynamically at runtime, is indistinguishable from ransomware to a heuristic scanner. Since CIMTool is deployed in utility companies with enterprise security policies, this is not acceptable. @@ -114,19 +110,19 @@ Fragment-Host: slf4j.api DynamicImport-Package: ch.qos.logback.classic.spi ``` -**`Fragment-Host: slf4j.api`** — declares this as a fragment of the `slf4j.api` +**`Fragment-Host: slf4j.api`**: declares this as a fragment of the `slf4j.api` OSGi bundle. The fragment's classpath contents (including `META-INF/services/`) are merged into `slf4j.api`'s classloader at framework startup. When SLF4J calls `ServiceLoader.load(SLF4JServiceProvider.class)` the services file is now visible and `LogbackServiceProvider` is discovered. -**`DynamicImport-Package: ch.qos.logback.classic.spi`** — allows the classloader +**`DynamicImport-Package: ch.qos.logback.classic.spi`**: allows the classloader to load `ch.qos.logback.classic.spi.LogbackServiceProvider` at runtime when ServiceLoader attempts to instantiate it. Dynamic imports are resolved lazily at class-load time rather than at bundle resolution time, so they do not affect the OSGi package wiring graph. A static `Import-Package` here would create a -split-package conflict on `org.xml.sax` — both `slf4j.api` and the Logback classic -bundle export it — which would prevent bundle resolution entirely and break +split-package conflict on `org.xml.sax`, since both `slf4j.api` and the Logback classic +bundle export it, which would prevent bundle resolution entirely and break `XMIModel` initialisation at CIMTool startup. @@ -142,7 +138,7 @@ ch.qos.logback.classic.spi.LogbackServiceProvider This is standard Java `ServiceLoader` registration. In a flat classpath environment this file would be picked up automatically from Logback's JAR. In OSGi it is -invisible across bundle boundaries — this fragment makes it visible by placing it +invisible across bundle boundaries, so this fragment makes it visible by placing it on `slf4j.api`'s classloader. @@ -157,7 +153,7 @@ section: ``` The `fragment="true"` attribute tells the PDE exporter to include this bundle as -a fragment in the exported product. No start level configuration is needed — +a fragment in the exported product. No start level configuration is needed; fragment bundles attach to their host automatically at framework startup before any bundle activators run, which ensures SLF4J finds Logback before any other bundle triggers SLF4J initialization. @@ -173,8 +169,8 @@ entries in its MANIFEST. It wires to two platform bundles via OSGi manifest head | Bundle | Symbolic Name | Relationship | | --- | --- | --- | -| SLF4J API | `slf4j.api` | `Fragment-Host` — this bundle is a fragment of `slf4j.api` and shares its classloader | -| Logback Classic | `ch.qos.logback.classic` | `DynamicImport-Package: ch.qos.logback.classic.spi` — resolved lazily at class-load time to instantiate `LogbackServiceProvider` | +| SLF4J API | `slf4j.api` | `Fragment-Host`: this bundle is a fragment of `slf4j.api` and shares its classloader | +| Logback Classic | `ch.qos.logback.classic` | `DynamicImport-Package: ch.qos.logback.classic.spi`: resolved lazily at class-load time to instantiate `LogbackServiceProvider` | Both bundles are Eclipse platform bundles resolved from the active target platform at export time. Neither is vendored in this project. @@ -183,7 +179,7 @@ at export time. Neither is vendored in this project. This project vendors **no third-party libraries**. It contains no JAR files and declares no `Bundle-ClassPath` entries. The project consists entirely of OSGi -metadata — `META-INF/MANIFEST.MF`, `META-INF/services/org.slf4j.spi.SLF4JServiceProvider`, +metadata, `META-INF/MANIFEST.MF`, `META-INF/services/org.slf4j.spi.SLF4JServiceProvider`, and `build.properties`. @@ -219,5 +215,5 @@ SLF4J 2.x → Logback → logs/cimtool.log (same pipeline as above) All three logging sources converge into the single file `logs/cimtool.log`. `logging.properties` is retained only to configure JUL pre-bridge filtering -(`handlers=` empty, `.level=ALL`) — it no longer writes any log output itself. +(`handlers=` empty, `.level=ALL`), and no longer writes any log output itself. `logback.xml` is the single source of truth for all logging configuration. diff --git a/docs/how-to/cimtool-support-for-extension-namespaces.md b/docs/how-to/cimtool-support-for-extension-namespaces.md index c6ad81df..a5315214 100644 --- a/docs/how-to/cimtool-support-for-extension-namespaces.md +++ b/docs/how-to/cimtool-support-for-extension-namespaces.md @@ -33,7 +33,7 @@ An example of a `baseuri` tag on a class in Sparx EA: #### Annotation File -In the edge case where you are working with an XMI file provided by an external party that lacks `baseuri` tagged values, **CIMTool** provides a stopgap mechanism via an annotation file. There is no editor or other GUI for managing namespace information in the annotation file — it is intended solely for situations where you do not control the XMI file and cannot add `baseuri` tags to it directly. +In the edge case where you are working with an XMI file provided by an external party that lacks `baseuri` tagged values, **CIMTool** provides a stopgap mechanism via an annotation file. There is no editor or other GUI for managing namespace information in the annotation file, which is intended solely for situations where you do not control the XMI file and cannot add `baseuri` tags to it directly. The annotation file should be placed in the project's `Schema` folder where the XMI file is located. It must have the same base name as the XMI file with a `.annotation` extension instead of `.xmi`. @@ -61,7 +61,7 @@ Has the same effect as attaching a `baseuri` tag to the Extensions package with ## Option 2: Using a Sparx EA Project File Schema -When your project uses a Sparx EA project file (`.eap`, `.eapx`, `.qea`, or `.qeax`) directly as its schema, two approaches are available for assigning URI namespaces to extension elements. These two approaches are **mutually exclusive** — **CIMTool** determines which is in effect based solely on whether a `.namespaces` file is present in the project's `Schema` folder. +When your project uses a Sparx EA project file (`.eap`, `.eapx`, `.qea`, or `.qeax`) directly as its schema, two approaches are available for assigning URI namespaces to extension elements. These two approaches are **mutually exclusive**, with **CIMTool** determining which is in effect based solely on whether a `.namespaces` file is present in the project's `Schema` folder. ### Approach 1: UML Tag: `baseuri` @@ -102,13 +102,13 @@ C:\ └── ... ``` -The screenshot below shows an example of both files as they appear in the **CIMTool** Project Explorer — the `.namespaces` file alongside its corresponding `.qea` EA project file (identified by the Sparx EA icon): +The screenshot below shows an example of both files as they appear in the **CIMTool** Project Explorer, the `.namespaces` file alongside its corresponding `.qea` EA project file (identified by the Sparx EA icon): ![CIMTool Project Explorer showing .namespaces file alongside EA project file schema](../images/CIMToolProjectExplorerNamespacesFile.png) !!! warning "Naming convention and file location are required for correct import" - The `.namespaces` file must be manually created — it is not created or managed by **CIMTool**. It must be named exactly the same as the EA project file it defines mappings for (with a `.namespaces` extension in place of `.qea`, `.eap`, etc.) and co-located with that EA project file on the file system prior to import. When **CIMTool** imports a schema — whether importing a new schema or re-importing an existing one — it automatically detects any co-located `.namespaces` file and imports it into the project's `Schema` folder alongside the EA project file. + The `.namespaces` file must be manually created, not created or managed by **CIMTool**. It must be named exactly the same as the EA project file it defines mappings for (with a `.namespaces` extension in place of `.qea`, `.eap`, etc.) and co-located with that EA project file on the file system prior to import. When **CIMTool** imports a schema, whether importing a new schema or re-importing an existing one, it automatically detects any co-located `.namespaces` file and imports it into the project's `Schema` folder alongside the EA project file. When present in the project's `Schema` folder, all `baseuri` tagged values defined in the UML are ignored and the stereotype-to-namespace mappings in the file take effect instead. Deleting the `.namespaces` file from the `Schema` folder causes **CIMTool** to revert to honoring `baseuri` tagged values in the UML when present. @@ -140,7 +140,7 @@ When a `.namespaces` file is in effect, **CIMTool** resolves the namespace for e When using the `<>` or `<>` extension patterns, it is safest practice to always model extension associations between **two** `<>` classes rather than between a `<>` class and a normative CIM class directly. - Modeling an association from a `<>` class to a normative CIM class is technically valid — **CIMTool** will process and namespace it correctly — however, the direction of the association determines which package owns it. An association drawn *from* an extension class *to* a normative class is implicitly owned by the extension package and exports correctly. If that direction is inadvertently reversed, ownership shifts to the normative side and the association will be silently dropped when exporting the extensions package. + Modeling an association from a `<>` class to a normative CIM class is technically valid, and **CIMTool** will process and namespace it correctly. However, the direction of the association determines which package owns it. An association drawn *from* an extension class *to* a normative class is implicitly owned by the extension package and exports correctly. If that direction is inadvertently reversed, ownership shifts to the normative side and the association will be silently dropped when exporting the extensions package. When both endpoints are `<>` classes, the association is unambiguously owned by the extensions package regardless of the direction in which it was drawn, completely eliminating the risk of silent loss on export. This is especially important in model upgrade and migration scenarios, where a dropped association may not be discovered until after the migration to a new CIM version is complete. @@ -156,7 +156,7 @@ When a `.namespaces` file is in effect, **CIMTool** resolves the namespace for e !!! note - **Stereotype names** in the mappings file are case-insensitive. The entries `NC`, `nc`, and `Nc` are all treated as equivalent — you may use whichever form matches how the stereotype appears in your UML model. + **Stereotype names** in the mappings file are case-insensitive. The entries `NC`, `nc`, and `Nc` are all treated as equivalent, so you may use whichever form matches how the stereotype appears in your UML model. **Namespace URIs** are case-sensitive. Verify that each URI in the mappings file exactly matches the case used in your UML model. For example, `http://iec.ch/TC57/CIM100#` and `http://iec.ch/TC57/cim100#` are treated as distinct namespaces. diff --git a/docs/how-to/modeling-cim-extensions.md b/docs/how-to/modeling-cim-extensions.md index 37ec8f88..a34f02f8 100644 --- a/docs/how-to/modeling-cim-extensions.md +++ b/docs/how-to/modeling-cim-extensions.md @@ -1,6 +1,6 @@ # Modeling CIM Extensions: Shadow Extension Classes and Mix-Ins -The CIM is routinely extended by standards bodies, transmission system operators, and individual organizations to address domain-specific requirements not covered by the normative model. A well-established pattern for modeling such extensions — particularly when attributes or associations need to be contributed to an existing normative CIM class under a distinct namespace — is the use of **shadow classes**. +The CIM is routinely extended by standards bodies, transmission system operators, and individual organizations to address domain-specific requirements not covered by the normative model. A well-established pattern for modeling such extensions, particularly when attributes or associations need to be contributed to an existing normative CIM class under a distinct namespace, is the use of **shadow classes**. **CIMTool** 2.3.0 introduces formal support for this pattern through two new UML stereotypes: `<>` and `<>`. These stereotypes are designed to be fully compatible with the extension modeling conventions described in the [CIM Modeling Guide Section 6.1.2](https://cim-mg.ucaiug.io/latest/section6-cim-uml-extension-rules-and-recommendations/#custom-cim-extensions) (Custom CIM Extensions). A future release of the CIM Modeling Guide will be updated to reflect how these stereotypes complement and support the existing guidelines and conventions specifically within the context where the direct use of Sparx EA project files is preferred. @@ -12,7 +12,7 @@ For details on how extension namespaces are assigned in **CIMTool**, see [CIMToo ## What Is a Shadow Class? -A shadow class is not a real class in the model in the conventional sense. Rather, it is a construct that "shadows" a normative CIM class, contributing attributes or associations to that class under a different namespace. When **CIMTool** processes a shadow class with merging enabled, it transparently folds the shadow class's members into the normative CIM class in its internal representation — the shadow class itself disappears, and its attributes and associations appear as members of the normative class but in the extension namespace. +A shadow class is not a real class in the model in the conventional sense. Rather, it is a construct that "shadows" a normative CIM class, contributing attributes or associations to that class under a different namespace. When **CIMTool** processes a shadow class with merging enabled, it transparently folds the shadow class's members into the normative CIM class in its internal representation. The shadow class itself disappears, and its attributes and associations appear as members of the normative class but in the extension namespace. The practical outcome is illustrated in the following instance data example, where the European `shortName` and `energyIdentCodeEic` attributes are contributed to `IdentifiedObject` under the `eu:` namespace: @@ -33,7 +33,7 @@ The practical outcome is illustrated in the following instance data example, whe ## Three Modeling Variants -**CIMTool** recognises three variants of the shadow class pattern. All three produce the same merging behavior when the merge setting is enabled — the difference is purely in how the shadow class is declared in the UML. +**CIMTool** recognises three variants of the shadow class pattern. All three produce the same merging behavior when the merge setting is enabled, differing only in how the shadow class is declared in the UML. ### Variant 1: Explicit `<>` Stereotype @@ -45,11 +45,11 @@ In the example above, `ExtEuIdentifiedObject` shadows `IdentifiedObject`. Its `s !!! note - When viewing a UML diagram containing a `<>` class, the generalization relationship from the shadow class to the normative CIM class may at first glance appear to introduce multiple inheritance on that normative class. This appearance is intentional by design and is not conventional multiple inheritance in the broader UML sense. The [CIM Modeling Guide Section 5.10](https://cim-mg.ucaiug.io/latest/section5-cim-uml-modeling-rules-and-recommendations/#inheritance-rules) states that *"the use of multiple inheritance is not allowed (except as specified for extensions)"*, and [Section 6.1.2](https://cim-mg.ucaiug.io/latest/section6-cim-uml-extension-rules-and-recommendations/#custom-cim-extensions) explicitly acknowledges that *"the standard CIM class will now have multiple inheritance"* as a result of the shadow class pattern — noting this as a sanctioned exception specific to extension modeling. When processed by **CIMTool** with merging enabled, the shadow class is dissolved entirely and its members are folded directly into the normative class, so the apparent multiple inheritance relationship exists only transiently in the UML and has no bearing on the generated artifacts. + When viewing a UML diagram containing a `<>` class, the generalization relationship from the shadow class to the normative CIM class may at first glance appear to introduce multiple inheritance on that normative class. This appearance is intentional by design and is not conventional multiple inheritance in the broader UML sense. The [CIM Modeling Guide Section 5.10](https://cim-mg.ucaiug.io/latest/section5-cim-uml-modeling-rules-and-recommendations/#inheritance-rules) states that *"the use of multiple inheritance is not allowed (except as specified for extensions)"*, and [Section 6.1.2](https://cim-mg.ucaiug.io/latest/section6-cim-uml-extension-rules-and-recommendations/#custom-cim-extensions) explicitly acknowledges that *"the standard CIM class will now have multiple inheritance"* as a result of the shadow class pattern, noting this as a sanctioned exception specific to extension modeling. When processed by **CIMTool** with merging enabled, the shadow class is dissolved entirely and its members are folded directly into the normative class, so the apparent multiple inheritance relationship exists only transiently in the UML and has no bearing on the generated artifacts. ### Variant 2: Same-Named Class with a Distinct Namespace -The shadow class is given the exact same name as the normative CIM class it shadows. **CIMTool** implicitly identifies it as a shadow class because it has an identical name but a different namespace — that namespace being determined by whichever mechanism is in use for the project: either a `baseuri` tagged value on the class (highlighted in the example below) or a stereotype-to-namespace mapping defined in a `.namespaces` file for the schema. No explicit `<>` stereotype is required for **CIMTool** to recognise this variant. Note that this variant is the one with the longest history while variants #1 and #2 added in recent years are what you will see most commonly used in current models used with CIMTool. +The shadow class is given the exact same name as the normative CIM class it shadows. **CIMTool** implicitly identifies it as a shadow class because it has an identical name but a different namespace, that namespace being determined by whichever mechanism is in use for the project: either a `baseuri` tagged value on the class (highlighted in the example below) or a stereotype-to-namespace mapping defined in a `.namespaces` file for the schema. No explicit `<>` stereotype is required for **CIMTool** to recognise this variant. Note that this variant is the one with the longest history while variants #1 and #2 added in recent years are what you will see most commonly used in current models used with CIMTool. ![Shadow class using same name as normative class with distinct baseuri](../images/ShadowExtensionSameNamedClass.png) @@ -75,7 +75,7 @@ The merge setting is available on the "Import Initial Schema" step of the **New ### After Project Creation -The setting can also be changed after a project has been created via the project's "Properties" dialog, accessible by right-clicking the project in the Project Explorer and selecting "Properties". In practice this is rarely needed — the most common scenario is correcting an initial import where the setting was inadvertently left unchecked. +The setting can also be changed after a project has been created via the project's "Properties" dialog, accessible by right-clicking the project in the Project Explorer and selecting "Properties". In practice this is rarely needed, the most common scenario being correcting an initial import where the setting was inadvertently left unchecked. !!! note @@ -97,10 +97,10 @@ When merging is enabled and the schema is imported, shadow class members appear The extension modeling conventions underpinning the shadow class pattern are described in detail in the [CIM Modeling Guide](https://cim-mg.ucaiug.io/latest/), specifically: -- [Section 6.1.2 — Custom CIM Extensions](https://cim-mg.ucaiug.io/latest/section6-cim-uml-extension-rules-and-recommendations/#custom-cim-extensions): covers the use of shadow classes, the `<>` generalization stereotype, and association modeling guidance for extensions. -- [Section 6.6 — Association Extension Rules](https://cim-mg.ucaiug.io/latest/section6-cim-uml-extension-rules-and-recommendations/#association-extension-rules): covers Rule204 and best practices for modeling associations between extension classes and normative CIM classes. +- [Section 6.1.2: Custom CIM Extensions](https://cim-mg.ucaiug.io/latest/section6-cim-uml-extension-rules-and-recommendations/#custom-cim-extensions): covers the use of shadow classes, the `<>` generalization stereotype, and association modeling guidance for extensions. +- [Section 6.6: Association Extension Rules](https://cim-mg.ucaiug.io/latest/section6-cim-uml-extension-rules-and-recommendations/#association-extension-rules): covers Rule204 and best practices for modeling associations between extension classes and normative CIM classes. -For guidance on assigning extension namespaces in **CIMTool** — including the `baseuri` tagged value and the stereotype-to-namespace mappings file introduced in 2.3.0 — see [CIMTool Support for Extension Namespaces](cimtool-support-for-extension-namespaces.md). +For guidance on assigning extension namespaces in **CIMTool**, including the `baseuri` tagged value and the stereotype-to-namespace mappings file introduced in 2.3.0, see [CIMTool Support for Extension Namespaces](cimtool-support-for-extension-namespaces.md). !!! note diff --git a/docs/how-to/profile-real-time-preview.md b/docs/how-to/profile-real-time-preview.md index 9f686343..60b9c287 100644 --- a/docs/how-to/profile-real-time-preview.md +++ b/docs/how-to/profile-real-time-preview.md @@ -28,7 +28,7 @@ well beyond the visible area of the view. !!! note - The **Profile Real-Time Preview** view is distinct from the **PlantUML Svg** view that also appears in the default workbench layout (outlined in blue in the screenshot above). The **PlantUML Svg** view is a general-purpose PlantUML renderer that displays whatever `.puml` file is currently open or selected in the editor. The **Profile Real-Time Preview**, by contrast, is purpose-built for profile design work: it automatically tracks the active profile and regenerates its diagram on every save — no manual file selection is required. + The **Profile Real-Time Preview** view is distinct from the **PlantUML Svg** view that also appears in the default workbench layout (outlined in blue in the screenshot above). The **PlantUML Svg** view is a general-purpose PlantUML renderer that displays whatever `.puml` file is currently open or selected in the editor. The **Profile Real-Time Preview**, by contrast, is purpose-built for profile design work: it automatically tracks the active profile and regenerates its diagram on every save, with no manual file selection required. Beyond visualizing the profile's structure, the Profile Real-Time Preview serves a second purpose that is especially valuable when building large or complex @@ -40,8 +40,8 @@ them only after a lengthy, systematic post-completion review. Because the two views serve different purposes, they can be used together. The **PlantUML Svg** view can be repositioned within the workbench by dragging its tab to a different panel, making it possible to display both views -simultaneously side by side. The screenshot below illustrates this arrangement -— and demonstrates the key difference between them: the Profile Real-Time Preview +simultaneously side by side. The screenshot below illustrates this arrangement, +and demonstrates the key difference between them: the Profile Real-Time Preview (left) renders definition errors using distinct visual cues, flagging issues within the profile definition. The PlantUML Svg view (right), rendering the same profile as a standard diagram, shows no such indicator even though the @@ -52,7 +52,7 @@ Click on the image to present a larger view. [![image](../images/ProfileRealTimePreview-PlantUML-SplitView.png)](../images/ProfileRealTimePreview-PlantUML-SplitView.png "The Profile Real-Time Preview (left) surfacing definition errors using distinct visual cues; the PlantUML Svg view (right) rendering the same profile as a standard diagram with no error indicators") Historically, validating a large profile required a meticulous inspection of -every class, attribute, and association definition in the profile editor — a +every class, attribute, and association definition in the profile editor, a process that was time-consuming and error-prone precisely because definition problems had no visible presence in the workspace. The Profile Real-Time Preview eliminates that burden by making errors immediately visible each time the @@ -61,7 +61,7 @@ profile is saved. ## Diagram Style and Target Schema Type -A CIM profile definition is shaped by its intended target artifact — the type +A CIM profile definition is shaped by its intended target artifact, the type of schema or serialization format the profile is ultimately meant to produce. The style of diagram rendered by the Profile Real-Time Preview reflects this: **CIMTool** generates a PlantUML diagram appropriate for the profile's target @@ -69,8 +69,8 @@ schema type, and it is within that diagram that any definition errors will be visualized. When a new project is created, the diagram style defaults to `puml-rdfs-t2b`. -If the project is primarily targeting a different schema type — for example, -XSD — the default should be overridden by updating the project-level preference. +If the project is primarily targeting a different schema type (for example, +XSD), the default should be overridden by updating the project-level preference. Right-click the project in the **Project Explorer**, select **Properties**, navigate to **CIMTool**, and select the appropriate diagram style from the **Diagram Style** dropdown. For an XSD-oriented project, for instance, @@ -96,7 +96,7 @@ Click on the image to present a larger view. This project-level setting applies as the default for all profiles in the project. It can be overridden on a per-profile basis from within the profile's -own properties. The layout orientation — top-to-bottom or left-to-right — is a +own properties. The layout orientation, top-to-bottom or left-to-right, is a presentational preference and has no effect on the content of the diagram or the errors it surfaces. @@ -110,8 +110,8 @@ errors are visualized within it and how to resolve each one. ## Working with the Preview on a Second Monitor The **Profile Real-Time Preview** view can be detached from the workbench -entirely and moved to a separate window — for example, onto a second monitor -— by dragging its tab away from its current panel and releasing it outside the +entirely and moved to a separate window (for example, onto a second monitor) +by dragging its tab away from its current panel and releasing it outside the workbench boundary. Once detached, the view can be maximized to fill the full screen, giving the diagram the maximum possible space while leaving the profile editor and the rest of the workbench fully accessible on the primary monitor. @@ -124,7 +124,7 @@ Click on the image to present a larger view. [![image](../images/ProfileRealTimePreview-DualMonitors.gif)](../images/ProfileRealTimePreview-DualMonitors.gif "Detaching and maximizing the Profile Real-Time Preview within a dual monitor configuration") The next set of screenshots are used for illustration purposes and show a profile -that contains a wide range of profile errors — each numbered 1 through 8 for reference. +that contains a wide range of profile errors, each numbered 1 through 8 for reference. Click on the image to present a larger view. @@ -142,7 +142,7 @@ style. ## RDFS Profile Definition Style An RDFS-style profile definition targets RDF Schema artifact generation -conforming to **IEC 61970-501:2016** — *Energy management system application +conforming to **IEC 61970-501:2016**, *Energy management system application program interface (EMS-API) – Part 501: Common Information Model Resource Description Framework (CIM RDF) schema*. When the diagram style is set to `puml-rdfs-t2b` or `puml-rdfs-l2r`, the Profile Real-Time Preview renders a PlantUML @@ -155,7 +155,7 @@ below in sequence, using a deliberately constructed profile that contains each type of error so they can be illustrated and resolved one by one. -### Issue 1 — Abstract Class with No Concrete Child Classes +### Issue 1: Abstract Class with No Concrete Child Classes #### What the diagram shows @@ -174,13 +174,13 @@ Preview flags it with two distinct visual cues: declared as 'concrete'."* The note callout is particularly useful in large profiles where it may not be -immediately obvious why a class has been flagged — it tells you exactly what +immediately obvious why a class has been flagged, telling you exactly what the problem is and what your options are to resolve it, without requiring you to inspect the profile definition manually. #### What it means -An abstract class in an RDFS profile definition exists to be specialized — it +An abstract class in an RDFS profile definition exists to be specialized, and it is expected to have at least one concrete subclass through which instances are actually typed. A profile that includes an abstract class with no concrete child classes creates an ambiguity in the generated RDFS artifact: the class is @@ -191,20 +191,20 @@ error because the resulting artifact would be structurally incomplete. There are three ways to address this error, as the note callout itself states: -1. **Declare the class as concrete** — if the class is appropriate to include +1. **Declare the class as concrete.** If the class is appropriate to include directly in the profile without requiring a subclass, check the **"Make this class concrete"** checkbox on the class's **Restriction** tab in the profile editor. -2. **Add a concrete subclass** — if a suitable subclass exists in the CIM +2. **Add a concrete subclass.** If a suitable subclass exists in the CIM model, add it to the profile and declare it as concrete. This is the preferred resolution when the intent is to preserve the abstract nature of the parent class. -3. **Remove the class from the profile** — if the class is not needed, remove +3. **Remove the class from the profile.** If the class is not needed, remove it from the profile entirely via the **"Add/Remove"** tab. In the example shown here, `Terminal` has no subclasses in the CIM model, so option 2 is not available. The fix applied in the animated GIF below is -option 1 — navigating to `Terminal` via the profile editor's **Restriction** +option 1, navigating to `Terminal` via the profile editor's **Restriction** tab and checking **"Make this class concrete"**. Click on the image to present a larger view. @@ -214,12 +214,12 @@ Click on the image to present a larger view. #### Result After saving the profile the diagram refreshes automatically. Navigating to -`Terminal` in the updated diagram confirms the error has been resolved — the +`Terminal` in the updated diagram confirms the error has been resolved. The note callout is no longer present and `Terminal` now appears rendered in the standard **yellow** convention for concrete classes. -### Issue 2 — Attribute Type Not Selected in the Profile Definition +### Issue 2: Attribute Type Not Selected in the Profile Definition #### What the diagram shows @@ -234,8 +234,8 @@ association from `Measurement` to the `UnitSymbol` class. #### What it means -In the CIM, enumeration and compound types never participate in associations — -they are only ever used as the declared type of an attribute. When **CIMTool** +In the CIM, enumeration and compound types never participate in associations, +and are only ever used as the declared type of an attribute. When **CIMTool** renders a red association between a class and an enumeration or compound type, it is signalling that the attribute exists in the profile but its type has not been properly included in the attribute's definition. The diagram is @@ -266,11 +266,11 @@ Click on the image to present a larger view. After saving the profile the diagram refreshes automatically. The red association from `Measurement` to `UnitSymbol` is gone. The `unitSymbol` attribute now appears correctly as a typed property within the `Measurement` -class — rendered as `unitSymbol: UnitSymbol [1]` — which is the expected +class, rendered as `unitSymbol: UnitSymbol [1]`, which is the expected representation for a properly defined attribute whose type is an enumeration. -### Issue 3 — Association Target End Not Included in the Profile Definition +### Issue 3: Association Target End Not Included in the Profile Definition #### What the diagram shows @@ -283,11 +283,11 @@ for that relationship, the Profile Real-Time Preview renders the association in Note that this error looks visually similar to Issue 2, but its cause is fundamentally different. In Issue 2 the red arc indicated a missing declared type on an attribute. Here, it is representing the **association** between -two classes — `Measurement` and `PowerSystemResource` — and that the `PowerSystemResource` +two classes, `Measurement` and `PowerSystemResource`, and that the `PowerSystemResource` class is already included in the profile, as confirmed by its presence in the **Outline** panel's alphabetical list of currently profiled classes. Because -`PowerSystemResource` is profiled, it appears in the diagram in grey — the -convention used for abstract classes — rather than pink/red, which would +`PowerSystemResource` is profiled, it appears in the diagram in grey, the +convention used for abstract classes, rather than pink/red, which would indicate a class that is entirely absent from the profile. The issue is not that the class is missing; it is that the **association's target end has not been included in the profile definition** for that relationship. @@ -295,7 +295,7 @@ been included in the profile definition** for that relationship. #### What it means In a CIM profile definition, adding an association to the profile is not -sufficient on its own — the target end of the association must also be +sufficient on its own, since the target end of the association must also be explicitly included in the association's definition within the profile. Until that step is completed, **CIMTool** cannot fully resolve the relationship and renders the association in red to make the incomplete definition visible. @@ -322,13 +322,13 @@ Click on the image to present a larger view. #### Result After saving the profile the diagram refreshes automatically. The red association from -`Measurement` to `PowerSystemResource` is replaced by a **grey association** — +`Measurement` to `PowerSystemResource` is replaced by a **grey association**, confirming that the association is now fully and correctly defined within the profile, with `PowerSystemResource` participating as a properly profiled abstract class on the target end of the relationship. -### Issues 4 & 5 — Enumeration Type Not Yet Referenced by Any Attribute in the Profile +### Issues 4 & 5: Enumeration Type Not Yet Referenced by Any Attribute in the Profile #### What the diagram shows @@ -352,7 +352,7 @@ whose declared type is the `UnitMultiplier` enumeration. Both attributes have been added to the profile, but neither has had `UnitMultiplier` selected in the attribute's definition on the **"Add/Remove"** tab. Until at least one of them does so, `UnitMultiplier` remains entirely unresolved and is rendered fully -pink/red. The two red arcs — one from `Measurement` and one from `Control` — +pink/red. The two red arcs, one from `Measurement` and one from `Control`, each represent the same underlying problem on their respective attribute definitions. @@ -362,7 +362,7 @@ Each attribute definition must be completed independently, following the same drill-down pattern as Issue 2. Issue 4 addresses `Measurement`'s `unitMultiplier` attribute first; Issue 5 then addresses `Control`'s. -**Issue 4 — Measurement → unitMultiplier:** +**Issue 4: Measurement → unitMultiplier:** 1. On the **"Add/Remove"** tab, double-click `Measurement` to drill into its member list. @@ -374,12 +374,12 @@ drill-down pattern as Issue 2. Issue 4 addresses `Measurement`'s After saving, the diagram refreshes. The red arc from `Measurement` to `UnitMultiplier` disappears and `unitMultiplier: UnitMultiplier [1]` now appears as a correctly typed property within the `Measurement` class. -Critically, `UnitMultiplier` itself is now rendered in **green** — because +Critically, `UnitMultiplier` itself is now rendered in **green**, because its membership in the profile has been established through `Measurement`'s attribute definition. The red arc from `Control` remains, but `UnitMultiplier` is no longer entirely unresolved. -**Issue 5 — Control → unitMultiplier:** +**Issue 5: Control → unitMultiplier:** 5. Double-click `Control` on the **"Add/Remove"** tab to drill into its member list. @@ -395,13 +395,13 @@ Click on the image to present a larger view. #### Result After the second save the diagram refreshes fully. Both red arcs are gone. -`UnitMultiplier` no longer appears as a standalone class in the diagram — -it is now correctly resolved as the declared type of the `unitMultiplier` +`UnitMultiplier` no longer appears as a standalone class in the diagram, +and is now correctly resolved as the declared type of the `unitMultiplier` attribute on both `Measurement` and `Control`, appearing as a typed property within each class respectively. -### Issue 6 — Abstract Class with Fields Defined +### Issue 6: Abstract Class with Fields Defined #### What the diagram shows @@ -421,18 +421,18 @@ RDFS profile definition. In an RDFS profile definition, an abstract class can serve one of two valid roles: -- **An external reference** — the class is included in the profile not because +- **An external reference**: the class is included in the profile not because instances of it will be fully described within the data exchange, but because other classes need to reference instances of it that exist outside the scope of the exchange. The class acts as a typed pointer to an external resource. - For this role, the class should have **no fields defined** — fields would + For this role, the class should have **no fields defined**, since fields would never be populated in practice and their presence is misleading. -- **A parent class to be specialized** — the class exists to be subclassed by +- **A parent class to be specialized**: the class exists to be subclassed by one or more concrete child classes that inherit its structure. For this role, having fields is appropriate, but the class itself must not be directly - instantiable — it must remain abstract. + instantiable and must remain abstract. -`Asset` is currently abstract with fields defined — it cannot serve as a clean +`Asset` is currently abstract with fields defined, so it cannot serve as a clean external reference (because it has fields) and it cannot serve as a parent class to be specialized (because it has no concrete child classes in the profile). **CIMTool** flags this as a definition error because the intent is ambiguous and @@ -443,16 +443,16 @@ must be resolved explicitly. There are two valid resolutions, depending on the intended role of `Asset` in the profile: -1. **If `Asset` is intended as an external reference** — remove the fields from +1. **If `Asset` is intended as an external reference**: remove the fields from its profile definition via the **"Add/Remove"** tab. Navigate to `Asset` in the member list, select all three fields (`critical`, `initialCondition`, `initialLossOfLife`) in the selected column and remove them. `Asset` will then be a clean abstract class with no fields, appropriate for use as an external reference pointer. -2. **If `Asset` is intended to carry data** — declare it concrete via the +2. **If `Asset` is intended to carry data**: declare it concrete via the **Restriction** tab by checking **"Make this class concrete"**. -In the example shown here, the fix applied is option 1 — removing the three +In the example shown here, the fix applied is option 1, removing the three fields from `Asset`'s profile definition, leaving it as a clean abstract class suited to its role as an external reference. @@ -463,12 +463,12 @@ Click on the image to present a larger view. #### Result After saving the profile the diagram refreshes automatically. `Asset` now -renders in **grey** — the convention for abstract classes — with no fields +renders in **grey**, the convention for abstract classes, with no fields and no note callout. Its role as an external reference is now correctly expressed in the profile definition. -### Issue 7 — Concrete Class with No Fields or Associations +### Issue 7: Concrete Class with No Fields or Associations #### What the diagram shows @@ -481,17 +481,17 @@ class that does."* This is in some ways the mirror image of Issue 6. Where Issue 6 showed an abstract class that had fields it should not have, Issue 7 shows a concrete -class that has **no** fields or associations — and no parent class from which +class that has **no** fields or associations, and no parent class from which to inherit them. #### What it means -A concrete class in an RDFS profile definition is expected to carry substance — +A concrete class in an RDFS profile definition is expected to carry substance: either its own fields or associations, or those inherited from a parent class. A concrete class with none of these has no meaningful content to contribute to a data exchange. As noted in Issue 6, a class that is intended purely as an external reference (a typed pointer to an object existing outside the scope of -the exchange) should have no fields — but for that role, **abstract** is the +the exchange) should have no fields, but for that role, **abstract** is the correct declaration, not concrete. **CIMTool** flags `MeasurementValueSource` because it is concrete, has no @@ -504,19 +504,19 @@ parent class (if it is meant to carry data). There are three valid resolutions, as the note callout itself states: -1. **Declare the class as abstract** — if `MeasurementValueSource` is intended +1. **Declare the class as abstract.** If `MeasurementValueSource` is intended purely as an external reference (a typed pointer to an object existing outside the scope of the exchange), uncheck the **"Make this class concrete"** checkbox on the **Restriction** tab. A clean abstract class with no fields is the correct expression of that role. -2. **Add a parent class** — navigate to `MeasurementValueSource` on the +2. **Add a parent class.** Navigate to `MeasurementValueSource` on the **Restriction** tab and select a super class. This allows the class to remain concrete while inheriting fields from a parent, satisfying the requirement that a concrete class must carry substance. In the example shown here, this - is the fix applied — `IdentifiedObject` is selected as the super class, + is the fix applied, with `IdentifiedObject` selected as the super class, providing inherited fields without requiring any direct field definitions on `MeasurementValueSource` itself. -3. **Add fields or associations directly** — navigate to `MeasurementValueSource` +3. **Add fields or associations directly.** Navigate to `MeasurementValueSource` on the **"Add/Remove"** tab and add one or more fields or associations to its profile definition. @@ -528,12 +528,12 @@ Click on the image to present a larger view. After saving the profile the diagram refreshes automatically. `MeasurementValueSource` now renders as a **yellow** concrete class with no -note callout — the pink/red coloring is gone and the error is resolved. By +note callout. The pink/red coloring is gone and the error is resolved. By inheriting from `IdentifiedObject`, it now has a parent class that provides the substance required of a concrete class in an RDFS profile definition. -### Issue 8 — Isolated Abstract Class with No Parent, Child, or Associations +### Issue 8: Isolated Abstract Class with No Parent, Child, or Associations #### What the diagram shows @@ -552,14 +552,14 @@ connecting it to any other class in the profile. An abstract class exists to be specialized or referenced through its relationships. If a class has no parent to inherit from, no child classes to specialize it, and no associations connecting it to anything else in the -profile, it is completely isolated — there is no path through which it could +profile, it is completely isolated, with no path through which it could ever be instantiated or referenced in a data exchange. In this state, the class serves no purpose in the profile regardless of what fields it carries. Declaring it **concrete** resolves this because it changes the class's role entirely: instead of requiring specialization or indirect reference, it becomes directly instantiable. Instances of a concrete class can be included in a data -exchange as standalone objects — a legitimate and meaningful role even without +exchange as standalone objects, a legitimate and meaningful role even without parent, child, or association relationships. The presence of fields (`direction` and `geoInfoReference`) confirms that `Location` is intended to carry data, making concrete the appropriate declaration. @@ -568,14 +568,14 @@ carry data, making concrete the appropriate declaration. There are two valid resolutions, as the note callout itself states: -1. **Declare the class as concrete** — navigate to `Location` on the +1. **Declare the class as concrete.** Navigate to `Location` on the **Restriction** tab and check the **"Make this class concrete"** checkbox. Since `Location` already has fields defined (`direction` and - `geoInfoReference`), declaring it concrete is sufficient — it gains a + `geoInfoReference`), declaring it concrete is sufficient, and it gains a legitimate role as a directly instantiable class whose instances can participate in a data exchange. No further changes to the profile definition are needed. This is the fix applied in the example shown here. -2. **Remove the class from the profile** — if `Location` is not needed, remove +2. **Remove the class from the profile.** If `Location` is not needed, remove it from the profile entirely via the **"Add/Remove"** tab. Click on the image to present a larger view. diff --git a/docs/how-to/using-cimtool-documentation-features.md b/docs/how-to/using-cimtool-documentation-features.md index 9744df12..a48fe044 100644 --- a/docs/how-to/using-cimtool-documentation-features.md +++ b/docs/how-to/using-cimtool-documentation-features.md @@ -4,7 +4,7 @@ These features address a need that profile authors have long had: producing human-readable specifications that stay in step with the profile itself. Rather than maintaining documentation separately and by hand, you can write custom content within **CIMTool** and author expanded documentation at the level of individual profile elements. **CIMTool** builders aid in generating modularized documentation components that, in turn, can then be included in master documents. -All of this is built on [AsciiDoc](https://asciidoc.org/), a concise, plain-text authoring format designed for technical documentation. AsciiDoc content is easy to write, friendly to version control, and can be published to multiple output formats. The documentation **CIMTool** generates from a profile is AsciiDoc, the content you author within **CIMTool** is AsciiDoc, and the bundled editor renders AsciiDoc previews — so establishing a working familiarity with the AsciiDoc format is helpful. This page closes with an [AsciiDoc Syntax Quick Reference](#asciidoc-syntax-quick-reference) to get you started. +All of this is built on [AsciiDoc](https://asciidoc.org/), a concise, plain-text authoring format designed for technical documentation. AsciiDoc content is easy to write, friendly to version control, and can be published to multiple output formats. The documentation **CIMTool** generates from a profile is AsciiDoc, the content you author within **CIMTool** is AsciiDoc, and the bundled editor renders AsciiDoc previews, so establishing a working familiarity with the AsciiDoc format is helpful. This page closes with an [AsciiDoc Syntax Quick Reference](#asciidoc-syntax-quick-reference) to get you started. What follows is a walk through where documentation lives in a project, how to author it at the various levels in a profile, what types of AsciiDoc builders currently ship with **CIMTool** and the type of documentation they produce, and finally, using the new publicly available [CGMES-CIM17](https://github.com/cimug-org/CGMES-CIM17) sample project as a working example, how to assemble a complete master document. @@ -25,34 +25,34 @@ The five folders, shown in the **Project Explorer** above are: | **Incremental** | For CIM XML incremental files in RDF format, with a `.xml` extension. Used when validating CIM/XML instance models in CIMTool. | | **Instances** | For CIM XML instance files in RDF format, with a `.xml` extension. Used when validating CIM/XML differences models in CIMTool.| | **Profiles** | For profile definitions and their generated artifacts. A profile definition itself is stored as an OWL file (`.owl`); the XSD, JSON Schema, RDFS, and other artifacts found in this folder are those generated from the `.owl` definition by **CIMTool**'s builders. Log files identifying errors are written as `.log` text files, and depending on how **CIMTool** is used, HTML, RTF, XML, Java, and SQL files, among other types, may also be hosted here. | -| **Schema** | Contains the schema that profiles are built from. Two formats can be used: a CIM model in XMI format (`.xmi`), generated from the UML model in Sparx EA; or **Enterprise Architect** project files used directly by **CIMTool** — both 32-bit EA15 (`.eap`, `.eapx`) and 64-bit EA16/EA17 (`.qea`, `.qeap`). | +| **Schema** | Contains the schema that profiles are built from. Two formats can be used: a CIM model in XMI format (`.xmi`), generated from the UML model in Sparx EA; or **Enterprise Architect** project files used directly by **CIMTool**, both 32-bit EA15 (`.eap`, `.eapx`) and 64-bit EA16/EA17 (`.qea`, `.qeax`). | The **Documentation** and **Profiles** folders are the two that matter for the purposes of documentation generation: the documentation builders write their generated AsciiDoc output into **Profiles** alongside the OWL profile definitions, while the **Documentation** folder is where you assemble generated content together with end-user written content into a finished document. The remaining sections look at each of these in turn. ## Inside the Documentation Folder -The **Documentation** folder is created with four subfolders, each intended for a specific kind of AsciiDoc-related content. As with the project folders themselves, these subfolders are generated automatically — you do not need to create them by hand. Within the CGMES-CIM17 sample project, each subfolder also contains a small `readme.txt` placeholder describing what belongs within the folder. +The **Documentation** folder is created with four subfolders, each intended for a specific kind of AsciiDoc-related content. As with the project folders themselves, these subfolders are generated automatically, so you do not need to create them by hand. Within the CGMES-CIM17 sample project, each subfolder also contains a small `readme.txt` placeholder describing what belongs within the folder. | Subfolder | Purpose | |---|---| -| **Images** | Image assets referenced from your documents — diagrams, screenshots, logos, and the like. | +| **Images** | Image assets referenced from your documents (diagrams, screenshots, logos, and the like). | | **Includes** | Modular AsciiDoc content files (`.adoc`) intended to be pulled into a master document. | | **Styles** | Custom CSS stylesheets (`.css`) that control the appearance of HTML output. | | **Themes** | Custom theme files (`.yml`) that control the appearance of PDF output. | -The master document itself — the top-level `.adoc` file that aggregates modularized documentation components together — lives at the root of the **Documentation** folder, alongside these four subfolders. Building a master document is covered in detail in [Building a Master Document](#building-a-master-document). +The master document itself, the top-level `.adoc` file that aggregates modularized documentation components together, lives at the root of the **Documentation** folder, alongside these four subfolders. Building a master document is covered in detail in [Building a Master Document](#building-a-master-document). !!! tip - For larger documentation efforts, it is common to organize the **Includes** folder further by creating subfolders beneath it, grouping related modular content into logical units. **CIMTool** places no restrictions on this — the structure beneath **Includes** is yours to arrange in a manner that best meets your documentation needs. + For larger documentation efforts, it is common to organize the **Includes** folder further by creating subfolders beneath it, grouping related modular content into logical units. **CIMTool** places no restrictions on this, and the structure beneath **Includes** is yours to arrange in a manner that best meets your documentation needs. The [CGMES-CIM17](https://github.com/cimug-org/CGMES-CIM17) sample project shows this layout in practice. Its **Documentation** folder holds a master document, `CGMES-Documentation.adoc`, at the root; a set of modular narrative files under **Includes** (an introduction, a CGMES overview, profile-group introductions, a conclusion, and more); a custom HTML stylesheet under **Styles**; and a custom PDF theme under **Themes**. ## The Asciidoctor Eclipse Editor -Authoring and previewing AsciiDoc content within **CIMTool** is handled by the Asciidoctor Eclipse editor, which is bundled with **CIMTool** 2.3.0 out of the box. No separate installation is required — when you open an `.adoc` file in the workbench, the editor is automatically launched for the selected file. +Authoring and previewing AsciiDoc content within **CIMTool** is handled by the Asciidoctor Eclipse editor, which is bundled with **CIMTool** 2.3.0 out of the box. No separate installation is required. When you open an `.adoc` file in the workbench, the editor is automatically launched for the selected file. The editor provides a live, side-by-side preview: your AsciiDoc source on one side and the rendered result on the other. The preview reflects the same AsciiDoc processing **CIMTool** uses elsewhere, so what you see in the editor is a faithful representation of the final output. @@ -111,12 +111,12 @@ Click on the image to present a larger view. ### Configuration Files -When you first open an `.adoc` file, the editor automatically generates an `.asciidoctorconfig.adoc` configuration file. This file establishes the rendering context for documents in its directory and is created and maintained by the editor — you should leave it in place. +When you first open an `.adoc` file, the editor automatically generates an `.asciidoctorconfig.adoc` configuration file. This file establishes the rendering context for documents in its directory and is created and maintained by the editor, so you should leave it in place. ## Adding Documentation to Profile Elements -Beyond authoring standalone narrative content, **CIMTool** lets you attach documentation directly to individual elements of a profile — a class, an enumeration, an attribute, an association role end, and so on. This element-level documentation is carried with the profile and is emitted by the documentation builders into the generated output for that element, so it travels with the profile rather than living in a separate document. +Beyond authoring standalone narrative content, **CIMTool** lets you attach documentation directly to individual elements of a profile: a class, an enumeration, an attribute, an association role end, and so on. This element-level documentation is carried with the profile and is emitted by the documentation builders into the generated output for that element, so it travels with the profile rather than living in a separate document. Two tabs in the profile editor contribute this documentation: the **"Description"** tab, which has been part of **CIMTool** since its inception, and the **"Documentation"** tab, introduced in **CIMTool** 2.3.0. Both accept AsciiDoc, so the formatting and styling described in the [AsciiDoc Syntax Quick Reference](#asciidoc-syntax-quick-reference) applies to the text you enter in either one. @@ -124,8 +124,8 @@ Two tabs in the profile editor contribute this documentation: the **"Description The **"Description"** tab presents two fields for a selected element: -- **Schema Description** — the normative description carried in the source CIM schema (the UML model in the `.qea`, `.eap`, `.xmi`, etc. file). This text is read-only by design: it reflects the definition as it exists in the model and cannot be edited in **CIMTool**. -- **Profile Description** — a field for additional notes you supply. AsciiDoc syntax is honored here, so you can format and style the text. +- **Schema Description**: the normative description carried in the source CIM schema (the UML model in the `.qea`, `.eap`, `.xmi`, etc. file). This text is read-only by design: it reflects the definition as it exists in the model and cannot be edited in **CIMTool**. +- **Profile Description**: a field for additional notes you supply. AsciiDoc syntax is honored here, so you can format and style the text. Click on the image to present a larger view. @@ -135,24 +135,24 @@ Click on the image to present a larger view. The **"Documentation"** tab, new in **CIMTool** 2.3.0, provides a dedicated, full-page area for authoring element documentation in AsciiDoc. -The **"Documentation"** tab was introduced to give authors a substantially larger editing and viewing area than the **"Description"** tab's field affords. A planned future enhancement will embed richer AsciiDoc editing and live preview directly within the **"Documentation"** tab itself — a further reason to favor it for anything beyond a brief note. +The **"Documentation"** tab was introduced to give authors a substantially larger editing and viewing area than the **"Description"** tab's field affords. A planned future enhancement will embed richer AsciiDoc editing and live preview directly within the **"Documentation"** tab itself, a further reason to favor it for anything beyond a brief note. ### Where Your Content Appears -The normative **Schema Description** is non-editable, but you can always supplement or clarify it using the two editable fields above — the **"Description"** tab's Profile Description and the **"Documentation"** tab. You may use either, or both; they are complementary. The one thing to be aware of is where each one lands in the generated output, which depends on the kind of documentation builder you use: +The normative **Schema Description** is non-editable, but you can always supplement or clarify it using the two editable fields above, the **"Description"** tab's Profile Description and the **"Documentation"** tab. You may use either, or both; they are complementary. The one thing to be aware of is where each one lands in the generated output, which depends on the kind of documentation builder you use: - The **Schema Description** and the **Profile Description** always appear together in the element's **description**, with the normative Schema Description first. -- The **"Documentation"** tab content appears in the **description** as well for the standard builders — but for a *mappings* builder it is placed instead in a separate **mapping** column, making the **"Documentation"** tab the natural place to record how an element maps to another information model or third-party system. The builders and the mapping column are covered in [The AsciiDoc Builders](#the-asciidoc-builders). +- The **"Documentation"** tab content appears in the **description** as well for the standard builders, but for a *mappings* builder it is placed instead in a separate **mapping** column, making the **"Documentation"** tab the natural place to record how an element maps to another information model or third-party system. The builders and the mapping column are covered in [The AsciiDoc Builders](#the-asciidoc-builders). ### Documentation in the Generated Output -The following example shows attribute-level documentation flowing through to the generated output. Documentation authored on the **"Documentation"** tab for the `negativeR12` attribute appears in the generated AsciiDoc source and is rendered, in the preview, into the description cell for that attribute — demonstrating the full path from authored text to final output. +The following example shows attribute-level documentation flowing through to the generated output. Documentation authored on the **"Documentation"** tab for the `negativeR12` attribute appears in the generated AsciiDoc source and is rendered, in the preview, into the description cell for that attribute, demonstrating the full path from authored text to final output. Click on the image to present a larger view. [![image](../images/Documentation-AttributeLevel.png)](../images/Documentation-AttributeLevel.png "Documentation authored on the Documentation tab for the negativeR12 attribute, shown in the generated AsciiDoc source and in the rendered preview's description cell") -Because both tabs accept arbitrary AsciiDoc, element documentation is not limited to plain prose. You can introduce your own headings, tables, lists, and other structures, and the documentation builders fold them into the generated document. The example below adds class-level documentation to the abstract class `ACDCTerminal`: a custom sub-section heading and an inlined AsciiDoc table authored on the **"Documentation"** tab. In the generated output, the sub-section appears as a numbered subsection beneath the class — and in the document's table of contents — and the table renders as a titled, formatted table. +Because both tabs accept arbitrary AsciiDoc, element documentation is not limited to plain prose. You can introduce your own headings, tables, lists, and other structures, and the documentation builders fold them into the generated document. The example below adds class-level documentation to the abstract class `ACDCTerminal`: a custom sub-section heading and an inlined AsciiDoc table authored on the **"Documentation"** tab. In the generated output, the sub-section appears as a numbered subsection beneath the class (and in the document's table of contents), and the table renders as a titled, formatted table. Click on the image to present a larger view. @@ -183,7 +183,7 @@ Within each family, the four builders differ by the schema convention the docume ### Choosing Between Article and Inline -Use an **article** builder when you want a self-contained document for a single profile — a standalone specification that can be rendered and distributed on its own. Use an **inline** builder when the profile's documentation is one piece of a larger work — for example, a master document that brings together several profiles along with hand-written narrative. Because an inline fragment has no document title and starts at a section heading, the master document controls the overall structure and the fragment falls into place beneath it. +Use an **article** builder when you want a self-contained document for a single profile, a standalone specification that can be rendered and distributed on its own. Use an **inline** builder when the profile's documentation is one piece of a larger work, such as a master document that brings together several profiles along with hand-written narrative. Because an inline fragment has no document title and starts at a section heading, the master document controls the overall structure and the fragment falls into place beneath it. The element-level documentation described in [Adding Documentation to Profile Elements](#adding-documentation-to-profile-elements) is emitted by these builders into the generated output, regardless of which family you choose. @@ -191,10 +191,38 @@ The element-level documentation described in [Adding Documentation to Profile El The `adoc-article-rdfs-mappings` and `adoc-inline-rdfs-mappings` builders produce the same RDFS documentation as their non-mappings counterparts, with one addition: each class member table includes a dedicated **mapping** column for documenting how each CIM element maps to another information model or third-party system. This column is populated from the element's **"Documentation"** tab, as described in [Adding Documentation to Profile Elements](#adding-documentation-to-profile-elements). Mappings are currently an RDFS-only feature in CIMTool 2.3.0; the XSD and JSON Schema builders will have mappings variant in future releases. +### Annotating Extension Members with Namespace Prefixes + +When a profile draws on attributes and associations from extension namespaces, such as the European (ENTSO-E) extensions to the CIM, the AsciiDoc builders can annotate those members in the generated documentation with a short namespace **prefix**, making it immediately clear which namespace each extension member belongs to. In the example below, the inherited members `eu:energyIdentCodeEic` and `eu:shortName` carry the `eu:` prefix, distinguishing them from the normative CIM members (`mRID`, `description`, `name`), which have none. + +Click on the image to present a larger view. + +[![image](../images/Documentation-NamespacePrefixes.png)](../images/Documentation-NamespacePrefixes.png "Generated documentation for the BusNameMarker class: the eu: prefix annotates the European extension members energyIdentCodeEic and shortName, distinguishing them from the normative CIM members") + +These prefixes come from a **namespace-prefixes mappings file**, a distinct file from the stereotype-to-namespace `.namespaces` file described in [CIMTool Support for Extension Namespaces](cimtool-support-for-extension-namespaces.md). Where the `.namespaces` file maps stereotypes to namespaces during schema import, the `.namespace-prefixes` file maps each namespace to the prefix the builders should use when annotating members in that namespace. + +The file follows the same naming and import conventions as the `.namespaces` file: it is named identically to the EA project file used as the project's schema but with a `.namespace-prefixes` extension, co-located with that schema file in the **Schema** folder, and automatically imported alongside the schema when a project is created or its schema is (re-)imported. Each line is a simple `=` mapping (lines beginning with `#` are comments): + +``` +nc=http://entsoe.eu/ns/nc# +eu=http://iec.ch/TC57/CIM100-European# +eumd=http://entsoe.eu/ns/Metadata-European# +``` + +With this mapping in effect, any member resolved to the `http://iec.ch/TC57/CIM100-European#` namespace is annotated with the `eu:` prefix in the generated documentation, as shown above. + +!!! note + + The `.namespace-prefixes` file is independent of the stereotype-to-namespace `.namespaces` file and does not require a `.namespaces` file to be present. It applies regardless of how the model's namespaces were defined, whether through a `.namespaces` file or through `baseuri` tagged values (see [CIMTool Support for Extension Namespaces](cimtool-support-for-extension-namespaces.md) for both approaches). It is, however, honored only when the project's schema is an **Enterprise Architect** project file (`.eap`, `.eapx`, `.qea`, `.qeax`); it has no effect when the schema is imported in XMI format (`.xmi` or `.owl`). + +!!! note + + The `.namespace-prefixes` file is optional and is used only by the AsciiDoc builders to annotate generated documentation; it does not affect the profile definition itself. Both namespace prefixes and namespace URIs are case-sensitive (per the W3C *Namespaces in XML* specification) and are compared character by character (`http://www.example.org/wine` and `http://www.Example.org/wine` are distinct namespaces), so ensure each URI in the file exactly matches the namespace used in your model. + ## Building a Master Document -A *master document* is a top-level AsciiDoc file that assembles a complete, publishable document from smaller pieces — hand-written narrative, generated profile documentation, diagrams, and supporting assets. It lives at the root of the **Documentation** folder and uses AsciiDoc's `include::` directive to pull in content from elsewhere in the project. +A *master document* is a top-level AsciiDoc file that assembles a complete, publishable document from smaller pieces: hand-written narrative, generated profile documentation, diagrams, and supporting assets. It lives at the root of the **Documentation** folder and uses AsciiDoc's `include::` directive to pull in content from elsewhere in the project. The publicly available [CGMES-CIM17](https://github.com/cimug-org/CGMES-CIM17) sample project is a complete, worked example of this approach, and the rest of this section walks through how its master document, `CGMES-Documentation.adoc`, is put together. It is a recommended starting point for anyone looking to build their own modularized documentation. @@ -216,14 +244,14 @@ Two things are worth highlighting here. First, `:doctype: book` selects the Asci !!! note - Within a **CIMTool** project, the `{docdir}` attribute always resolves to the **project root**. The Asciidoctor editor runs with the project root as its base directory, so every path attribute above is written relative to that root — `{docdir}/Profiles`, `{docdir}/Documentation/Includes`, and so on — regardless of the fact that the master document itself lives in the **Documentation** folder. A leading `./` resolves from the same project root, so the `./Profiles/...` paths you will see in **CIMTool**'s generated artifacts and the `{docdir}/Profiles/...` paths you write in a master document point to the same place; `{docdir}/` is simply the explicit, self-documenting form recommended when authoring. Writing your own master-document paths this way ensures they resolve correctly. + Within a **CIMTool** project, the `{docdir}` attribute always resolves to the **project root**. The Asciidoctor editor runs with the project root as its base directory, so every path attribute above is written relative to that root (`{docdir}/Profiles`, `{docdir}/Documentation/Includes`, and so on) regardless of the fact that the master document itself lives in the **Documentation** folder. A leading `./` resolves from the same project root, so the `./Profiles/...` paths you will see in **CIMTool**'s generated artifacts and the `{docdir}/Profiles/...` paths you write in a master document point to the same place; `{docdir}/` is simply the explicit, self-documenting form recommended when authoring. Writing your own master-document paths this way ensures they resolve correctly. ### Assembling the Content With the path attributes defined, the body of the master document is largely a sequence of `include::` directives that interleave two kinds of content: -- **Hand-written narrative** from the **Includes** subfolder — introductions, overviews, and connecting prose — referenced via the `{includedir}` attribute. -- **Generated profile documentation** from the **Profiles** folder — the `.inline-rdfs.adoc` fragments produced by the AsciiDoc builders — referenced via the `{profilesdir}` attribute. +- **Hand-written narrative** from the **Includes** subfolder (introductions, overviews, and connecting prose) referenced via the `{includedir}` attribute. +- **Generated profile documentation** from the **Profiles** folder, the `.inline-rdfs.adoc` fragments produced by the AsciiDoc builders, referenced via the `{profilesdir}` attribute. A simplified excerpt illustrates the pattern: @@ -241,7 +269,7 @@ include::{profilesdir}/CGMES-Operation.inline-rdfs.adoc[] include::{includedir}/conclusion.adoc[] ``` -Because the included profile fragments are produced by *inline* builders they carry no document title of their own. However, they do generate their own section heading at the correct level — so they slot neatly beneath the master document's structure rather than competing with it. The narrative includes and the generated profile sections combine into a single, continuously document with appropriate page number automatically assigned across the document. +Because the included profile fragments are produced by *inline* builders they carry no document title of their own. However, they do generate their own section heading at the correct level, so they slot neatly beneath the master document's structure rather than competing with it. The narrative includes and the generated profile sections combine into a single, continuously document with appropriate page number automatically assigned across the document. ### The Rendered Result @@ -253,7 +281,7 @@ Click on the image to present a larger view. [![image](../images/MasterDocument-HTML.png)](../images/MasterDocument-HTML.png "The assembled CGMES Profiles Guide rendered to HTML, showing the table of contents, a generated profile section, and an embedded PlantUML class diagram") -The same document rendered to PDF produces a paginated, book-style specification — here, a multi-hundred-page guide assembled entirely from the project's narrative includes and generated profile documentation: +The same document rendered to PDF produces a paginated, book-style specification, in this case a multi-hundred-page guide assembled entirely from the project's narrative includes and generated profile documentation: Click on the image to present a larger view. @@ -262,7 +290,7 @@ Click on the image to present a larger view. ## AsciiDoc Syntax Quick Reference -This quick reference covers the AsciiDoc syntax you are most likely to use when authoring **CIMTool** documentation — in the **"Description"** and **"Documentation"** tabs, in **Includes** content, and in a master document. Each entry shows a brief example and links to the corresponding page in the official Asciidoctor documentation, where the full set of options is described. A few entries marked *(CIMTool-specific)* describe patterns particular to **CIMTool** projects and are documented more fully here, as they have no direct equivalent in the general AsciiDoc reference. +This quick reference covers the AsciiDoc syntax you are most likely to use when authoring **CIMTool** documentation: in the **"Description"** and **"Documentation"** tabs, in **Includes** content, and in a master document. Each entry shows a brief example and links to the corresponding page in the official Asciidoctor documentation, where the full set of options is described. A few entries marked *(CIMTool-specific)* describe patterns particular to **CIMTool** projects and are documented more fully here, as they have no direct equivalent in the general AsciiDoc reference. The examples below are a quick reference only. For the complete, authoritative AsciiDoc syntax documentation, see the [AsciiDoc Syntax Quick Reference](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/) at the Asciidoctor documentation site, which this reference draws on. @@ -326,7 +354,7 @@ The examples below are a quick reference only. For the complete, authoritative A | `. item` | Ordered list item (`..`, `...` for nesting) | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/lists/ordered/) | | `* [ ] item` / `* [*] item` | Checklist item, unchecked / checked | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/lists/checklist/) | | `term:: description` | Description (definition) list | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/lists/description/) | -| `+` *(on its own line)* | List continuation — attach another block to a list item | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/lists/continuation/) | +| `+` *(on its own line)* | List continuation: attach another block to a list item | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/lists/continuation/) | ### Links & Cross References @@ -356,7 +384,7 @@ The `plantuml::` block macro embeds a PlantUML diagram, rendering a `.puml` file plantuml::./Profiles/CGMES-ShortCircuit.rdfs-t2b.puml[format=svg, align=center] ``` -The line beginning with a dot (`.ShortCircuit Profile`) is the optional diagram title. The macro target is the `.puml` file to render — resolved from the project root, the same base used everywhere in a **CIMTool** project — and the bracketed attributes control the output: `format=svg` renders to SVG (sharp at any zoom), and `align=center` centers the diagram. +The line beginning with a dot (`.ShortCircuit Profile`) is the optional diagram title. The macro target is the `.puml` file to render (resolved from the project root, the same base used everywhere in a **CIMTool** project), and the bracketed attributes control the output: `format=svg` renders to SVG (sharp at any zoom), and `align=center` centers the diagram. ### Include Directives @@ -367,7 +395,7 @@ The line beginning with a dot (`.ShortCircuit Profile`) is the optional diagram | `include::file.adoc[tag=name]` | Include only a tagged region | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/directives/include-tagged-regions/) | | `include::file.adoc[leveloffset=+1]` | Shift the included content's heading levels | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/directives/include-with-leveloffset/) | -In a **CIMTool** master document — content you author yourself — `include::` directives are written project-root-relative using the `{docdir}` attribute (or path attributes derived from it, such as `{includedir}` and `{profilesdir}`). This is how a master document pulls in both hand-written narrative and generated profile documentation: +In a **CIMTool** master document, content you author yourself, `include::` directives are written project-root-relative using the `{docdir}` attribute (or path attributes derived from it, such as `{includedir}` and `{profilesdir}`). This is how a master document pulls in both hand-written narrative and generated profile documentation: ```asciidoc include::{docdir}/Documentation/Includes/introduction.adoc[] @@ -389,8 +417,8 @@ The first line includes a hand-written narrative file from the **Includes** subf | Syntax | Description | Reference | |---|---|---| | `` `+literal+` `` | Inline literal monospace (no substitutions) | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/text/literal-monospace/) | -| `....` block | Literal block — text shown verbatim | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/verbatim/literal-blocks/) | -| `----` block | Listing block — preformatted code or output | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/verbatim/listing-blocks/) | +| `....` block | Literal block: text shown verbatim | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/verbatim/literal-blocks/) | +| `----` block | Listing block: preformatted code or output | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/verbatim/listing-blocks/) | | `[source,xml]` + `----` block | Source block with language for syntax highlighting | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/verbatim/source-blocks/) | | `<1>` *(in code)* + `<1> note` | Callouts annotating lines of a code block | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/verbatim/callouts/) | @@ -409,10 +437,10 @@ The first line includes a hand-written narrative file from the **Includes** subf | Syntax | Description | Reference | |---|---|---| -| `****` block | Sidebar — set-apart auxiliary content | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/blocks/sidebars/) | +| `****` block | Sidebar: set-apart auxiliary content | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/blocks/sidebars/) | | `====` block | Example block | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/blocks/example-blocks/) | | `____` block | Blockquote | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/blocks/blockquotes/) | -| `--` block | Open block — a general-purpose container | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/blocks/open-blocks/) | +| `--` block | Open block: a general-purpose container | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/blocks/open-blocks/) | ### Comments @@ -441,5 +469,5 @@ These attributes, set in a master document's header, control the appearance of g | `--` | Replaced with an em dash (—) | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/subs/replacements/) | | `->` `=>` `<-` `<=` | Replaced with arrows (→, ⇒, ←, ⇐) | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/subs/replacements/) | | `\` *(before markup)* | Backslash escapes the character that follows | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/subs/prevent/) | -| `+text+` | Inline passthrough — render text without substitutions | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/pass/pass-macro/) | +| `+text+` | Inline passthrough: render text without substitutions | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/pass/pass-macro/) | | `&#NNN;` | Named, decimal, or hexadecimal character reference | [→ Docs](https://docs.asciidoctor.org/asciidoc/latest/subs/replacements/) | diff --git a/docs/images/Documentation-NamespacePrefixes.png b/docs/images/Documentation-NamespacePrefixes.png new file mode 100644 index 00000000..15b39078 Binary files /dev/null and b/docs/images/Documentation-NamespacePrefixes.png differ diff --git a/docs/index.md b/docs/index.md index 3aab1eb2..1aaa4a23 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,8 @@ # Welcome -**CIMTool** is an open source platform that provides a comprehensive technical foundation for the creation, development, and maintenance of IEC standards-compliant data exchange profiles based on the Common Information Model (CIM). Rather than a single-purpose utility, CIMTool delivers an integrated environment where profile definition, schema generation, documentation, and validation converge — enabling organizations to manage the full lifecycle of CIM-based interoperability artifacts from a single platform. +**CIMTool** is an open source platform that provides a comprehensive technical foundation for the creation, development, and maintenance of IEC standards-compliant data exchange profiles based on the Common Information Model (CIM). Rather than a single-purpose utility, CIMTool delivers an integrated environment where profile definition, schema generation, documentation, and validation converge, enabling organizations to manage the full lifecycle of CIM-based interoperability artifacts from a single platform. -Designed for the IEC standards community, utility enterprises, systems integrators, software developers, and data architects, **CIMTool** supports standards-based interoperability across the power systems domain. Its built-in schema builders automatically generate fully compliant output — including RDFS profiles (per IEC 61970-501 and -552), XML schemas (per IEC 62361-100), and JSON schemas (per the IEC 62361-104 draft specification) — eliminating the risk and effort associated with manual schema creation. +Designed for the IEC standards community, utility enterprises, systems integrators, software developers, and data architects, **CIMTool** supports standards-based interoperability across the power systems domain. Its built-in schema builders automatically generate fully compliant output, including RDFS profiles (per IEC 61970-501 and -552), XML schemas (per IEC 62361-100), and JSON schemas (per the IEC 62361-104 draft specification). This eliminates the risk and effort associated with manual schema creation. [![image](./images/CIMToolScreenshot.png)](./images/CIMToolScreenshot.png "CIMTool") diff --git a/docs/release-notes.md b/docs/release-notes.md index c9f04462..5240895d 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -40,10 +40,10 @@ Enhancement [Issue #188](https://github.com/cimug-org/CIMTool/issues/188): The **CIMantic Graphs** builders (`cimantic-graphs.xsl` and `cimantic-graphs-init.xsl`) have been updated with the latest changes provided by **PNNL**, adding support for `Identity.identifier`. Enhancement [Issue #195](https://github.com/cimug-org/CIMTool/issues/195): -The artefact builders have been decoupled from the Eclipse desktop application so they can be run standalone and maintained independently. A new command-line interface, **cimtool-cli**, packages the **CIMTool** transform engine into a self-contained executable JAR that runs profile transformations and generates artefacts headlessly — without launching the Eclipse workbench — enabling **CIMTool** builders to be incorporated into automated and continuous-integration pipelines. +The artefact builders have been decoupled from the Eclipse desktop application so they can be run standalone and maintained independently. A new command-line interface, **cimtool-cli**, packages the **CIMTool** transform engine into a self-contained executable JAR that runs profile transformations and generates artefacts headlessly, without launching the Eclipse workbench, enabling **CIMTool** builders to be incorporated into automated and continuous-integration pipelines. Enhancement [Issue #202](https://github.com/cimug-org/CIMTool/issues/202): -A new C# Entity Framework builder (`csharp-ef-rdfs.xsl`) has been added to **CIMTool's** builder library. This builder generates C# entity classes for Microsoft's Entity Framework Core — an open-source object-relational mapper (ORM) for .NET that lets developers work with a database through C# objects rather than writing raw SQL. Entity relationships and constraints are configured using the Entity Framework Core **Fluent API**, giving precise control over table mappings, foreign keys, and cascade behaviours, and the generated classes support LINQ-based querying of CIM profile instances. +A new C# Entity Framework builder (`csharp-ef-rdfs.xsl`) has been added to **CIMTool's** builder library. This builder generates C# entity classes for Microsoft's Entity Framework Core, an open-source object-relational mapper (ORM) for .NET that lets developers work with a database through C# objects rather than writing raw SQL. Entity relationships and constraints are configured using the Entity Framework Core **Fluent API**, giving precise control over table mappings, foreign keys, and cascade behaviours, and the generated classes support LINQ-based querying of CIM profile instances. Enhancement [Issue #203](https://github.com/cimug-org/CIMTool/issues/203): **CIMTool** now supports per-diagram **PlantUML** configuration overrides through `.pumlconfig` files. While global preferences control default diagram generation behavior, users can place diagram-specific configuration files in the same directory as the profile to override settings for individual diagrams. This allows fine-tuned control over layout, styling, and rendering options on a per-diagram basis, supporting complex documentation scenarios where different diagrams require different visual treatments. @@ -52,7 +52,7 @@ Enhancement [Issue #204](https://github.com/cimug-org/CIMTool/issues/204): **CIMTool** now supports shadow class (also called "mix-in") extensions when profiling directly from Enterprise Architect project files (`.eap`, `.qea`, `.qeax`). Shadow classes are a lightweight EA extension mechanism that lets modelers add attributes to existing classes without modifying the original class definition. **CIMTool** now recognizes these extensions during profiling and includes them according to the profile's configuration, enabling extension-modeling workflows where organizations can layer additional attributes onto standard CIM classes while maintaining clear separation between normative and extended content. Enhancement [Issue #207](https://github.com/cimug-org/CIMTool/issues/207): -The intermediary XML format that **CIMTool** generates as input to its XSLT builders has been enhanced with `PrimitiveType` and `CompoundType` elements, providing richer semantic information about CIM datatypes. Builders — including custom user-defined XSLT builders — can now distinguish simple primitives (such as String or Integer) from compound types (such as EmailAddress), enabling more accurate, type-aware code generation and documentation. +The intermediary XML format that **CIMTool** generates as input to its XSLT builders has been enhanced with `PrimitiveType` and `CompoundType` elements, providing richer semantic information about CIM datatypes. Builders, including custom user-defined XSLT builders, can now distinguish simple primitives (such as String or Integer) from compound types (such as EmailAddress), enabling more accurate, type-aware code generation and documentation. Enhancement [Issue #217](https://github.com/cimug-org/CIMTool/issues/217): The SQL builder (`sql.xsl`) has been significantly enhanced to support `<>` types with dedicated tables and proper foreign key relationships. When generating database schemas, the builder now creates separate tables for compound types (such as ActivePower, Voltage, etc.) and establishes foreign key constraints from classes that use these compounds. For example, a class with an ActivePower attribute will have a foreign key to the ActivePower compound table. Additionally, foreign key indexes are automatically generated to optimize query performance. This enhancement enables full relational database representation of CIM profiles with proper normalization of compound types. @@ -94,7 +94,7 @@ Enhancement [Issue #246](https://github.com/cimug-org/CIMTool/issues/246): **CIMTool** now supports profiling `<>` classes as anonymous inner type definitions, similar to existing enumeration support. Additionally, compounds can now be duplicated when the "Allow multiple profiles per class" checkbox is enabled. The UI has been updated to display compounds in both the right-hand pane and the multiple profiles panel. The internal XML format now includes a new `a:SimpleCompound` element representing anonymous compound definitions. All relevant builders (including PlantUML XSD builders) have been updated to support this new element type, with corresponding documentation updates to the CIMTool Builders companion site. Enhancement [Issue #247](https://github.com/cimug-org/CIMTool/issues/247): -**CIMTool** and its XSD schema builders now support generating CIM properties as XSD attributes (in addition to the default XSD elements) and XSD attribute groups. A property can be tagged with the new `XSDattribute` stereotype on the "Stereotypes" tab — enabled for properties whose type is an enumeration or a CIM primitive — to emit it as an XSD attribute, while the new `XSDattributeGroup` stereotype on a class emits its properties as a named XSD attribute group. The `xsd.xsl` and `xsd-part100-ed2.xsl` builders and the XSD **PlantUML** diagram builders have been updated accordingly. This capability was driven by collaboration with **WG 61850** toward automating generation of **IEC 61850-6** SCL XSD schemas. +**CIMTool** and its XSD schema builders now support generating CIM properties as XSD attributes (in addition to the default XSD elements) and XSD attribute groups. A property can be tagged with the new `XSDattribute` stereotype on the "Stereotypes" tab, enabled for properties whose type is an enumeration or a CIM primitive, to emit it as an XSD attribute, while the new `XSDattributeGroup` stereotype on a class emits its properties as a named XSD attribute group. The `xsd.xsl` and `xsd-part100-ed2.xsl` builders and the XSD **PlantUML** diagram builders have been updated accordingly. This capability was driven by collaboration with **WG 61850** toward automating generation of **IEC 61850-6** SCL XSD schemas. Enhancement [Issue #250](https://github.com/cimug-org/CIMTool/issues/250): The XSD and JSON schema builders now support generating **CodeLists** as defined in **IEC 62361-100** (XSD) and **IEC 62361-104** (JSON Schema). A new `CodeList` stereotype, assignable to an enumeration on the "Stereotypes" tab, instructs the `xsd.xsl`, `xsd-part100-ed2.xsl`, `json-schema-draft-07.xsl`, and `json-schema-draft-2020-12.xsl` builders to emit a CodeList in preference to a standard enumeration. The **PlantUML** diagram builders have been updated to visualize CodeList-tagged enumerations. @@ -127,7 +127,7 @@ Defect [Issue #244](https://github.com/cimug-org/CIMTool/issues/244): The `profile-doc-rtf.xsl` Word document builder had two critical issues affecting output quality. First, the builder was consuming carriage return/line feed characters from UML documentation, causing separate paragraphs to concatenate incorrectly in type definitions and table cells. Second, legacy `.eap` and `.xmi` schemas containing non-ASCII symbols (such as the degree symbol °) were not properly encoded, resulting in corrupted documentation. The builder has been corrected to preserve paragraph breaks and properly handle character encoding for all symbols, ensuring accurate documentation generation from any CIM schema version. Defect [Issue #249](https://github.com/cimug-org/CIMTool/issues/249): -When a base CIM XMI and an extension XMI were imported together, extension attributes and associations added to a base CIM class were incorrectly tagged with the CIM namespace rather than the extension namespace — both in the profile properties shown in **CIMTool** and in generated artefacts such as XSD. (SimpleType definitions were already tagged correctly.) This has been corrected so that all extension elements carry the extension namespace. +When a base CIM XMI and an extension XMI were imported together, extension attributes and associations added to a base CIM class were incorrectly tagged with the CIM namespace rather than the extension namespace, both in the profile properties shown in **CIMTool** and in generated artefacts such as XSD. (SimpleType definitions were already tagged correctly.) This has been corrected so that all extension elements carry the extension namespace. ### Release 2.2.0 [01-Oct-2024] diff --git a/docs/schemaops/cimtool-cli.md b/docs/schemaops/cimtool-cli.md index 94300ae3..75499de1 100644 --- a/docs/schemaops/cimtool-cli.md +++ b/docs/schemaops/cimtool-cli.md @@ -1,21 +1,21 @@ # Using CIMTool in CI/CD Pipelines with cimtool-cli -**CIMTool** has a companion standalone command-line tool — `cimtool-cli.jar` — that exposes **CIMTool**'s full artifact generation capabilities outside of the Eclipse desktop application. Beginning with the **CIMTool** 2.3.0 release, it is distributed as a separate optional download alongside each **CIMTool** release and runs headless on any platform where Java 11 or later is available, with no Eclipse installation, OSGi runtime, or workspace required. +**CIMTool** has a companion standalone command-line tool, `cimtool-cli.jar`, that exposes **CIMTool**'s full artifact generation capabilities outside of the Eclipse desktop application. Beginning with the **CIMTool** 2.3.0 release, it is distributed as a separate optional download alongside each **CIMTool** release and runs headless on any platform where Java 11 or later is available, with no Eclipse installation, OSGi runtime, or workspace required. -This opens up a *SchemaOps* workflow: the practice of treating your CIM schema and profile set as versioned source artifacts that can be checked into a repository and processed automatically as part of a CI/CD pipeline — in the same way DevOps treats application source code. +This opens up a *SchemaOps* workflow: the practice of treating your CIM schema and profile set as versioned source artifacts that can be checked into a repository and processed automatically as part of a CI/CD pipeline, in the same way DevOps treats application source code. ## What is SchemaOps? -SchemaOps applies the principles of DevOps — automation, reproducibility, version control, and pipeline-driven delivery — to the lifecycle of CIM schemas, profiles, and the artifacts derived from them. +SchemaOps applies the principles of DevOps (automation, reproducibility, version control, and pipeline-driven delivery) to the lifecycle of CIM schemas, profiles, and the artifacts derived from them. With a SchemaOps pipeline you can: - Check in a Sparx EA project file (`.qea`) or a **CIMTool** project directory as the authoritative schema source -- Trigger `cimtool-cli.jar` on commit or pull request — pointing it at the project directory — to regenerate all profile artifacts (XSD, JSON Schema, RDFS/OWL, AsciiDoc documentation fragments, PlantUML diagrams, and so on) -- Feed those generated artifacts downstream to other tools — for example, invoke the Asciidoctor command-line toolchain to combine a master document with the generated fragments and produce a final HTML5 or PDF output, then deploy that output to a corporate intranet +- Trigger `cimtool-cli.jar` on commit or pull request, pointing it at the project directory, to regenerate all profile artifacts (XSD, JSON Schema, RDFS/OWL, AsciiDoc documentation fragments, PlantUML diagrams, and so on) +- Feed those generated artifacts downstream to other tools: for example, invoke the Asciidoctor command-line toolchain to combine a master document with the generated fragments and produce a final HTML5 or PDF output, then deploy that output to a corporate intranet - Or use `cimtool-cli.jar` to generate LinkML artifacts from **CIMTool** profiles, then pass those generated LinkML artifacts downstream to LinkML tooling to produce code, documentation, or further derivative artifacts -Because `cimtool-cli.jar` runs on Linux, macOS, and Windows, you can integrate it with any CI/CD system — GitHub Actions, GitLab CI, Jenkins, Azure Pipelines, or any shell-based automation. +Because `cimtool-cli.jar` runs on Linux, macOS, and Windows, you can integrate it with any CI/CD system: GitHub Actions, GitLab CI, Jenkins, Azure Pipelines, or any shell-based automation. ## Prerequisites @@ -29,18 +29,18 @@ If Java is not available, download and install a distribution such as [Eclipse T ## Downloading cimtool-cli.jar -`cimtool-cli.jar` is an optional download co-deployed alongside the **CIMTool** Windows application on the [CIMTool GitHub Releases page](https://github.com/cimug-org/CIMTool/releases). It is a separate artifact from the **CIMTool** application ZIP — download only what you need. Each release provides the following files: +`cimtool-cli.jar` is an optional download co-deployed alongside the **CIMTool** Windows application on the [CIMTool GitHub Releases page](https://github.com/cimug-org/CIMTool/releases). It is a separate artifact from the **CIMTool** application ZIP, so download only what you need. Each release provides the following files: -- `CIMTool-X.Y.Z-win32.win32.x86_64.zip` — the **CIMTool** Eclipse desktop application (Windows only) -- `cimtool-cli.jar` — the standalone cross-platform CLI tool -- `cimtool-cli.jar.sha256` — SHA-256 checksum for verifying the download -- `logback-debug.xml` — an optional diagnostic logging configuration file (see [Logging and Diagnostics](#logging-and-diagnostics)) +- `CIMTool-X.Y.Z-win32.win32.x86_64.zip`: the **CIMTool** Eclipse desktop application (Windows only) +- `cimtool-cli.jar`: the standalone cross-platform CLI tool +- `cimtool-cli.jar.sha256`: SHA-256 checksum for verifying the download +- `logback-debug.xml`: an optional diagnostic logging configuration file (see [Logging and Diagnostics](#logging-and-diagnostics)) Download `cimtool-cli.jar` and, optionally, `logback-debug.xml` and place them in the same directory. !!! note - If you are optionally interested in verifying the signature on the downloaded JAR, you will need a JDK that includes the `jarsigner` command-line tool. Note that `jarsigner` is a JDK tool — it is not included in a JRE-only installation. [Eclipse Temurin](https://adoptium.net/) is the recommended JDK distribution for this purpose, as other OpenJDK distributions (such as Zulu) may behave differently when verifying signatures produced with an EV certificate. To verify: + If you are optionally interested in verifying the signature on the downloaded JAR, you will need a JDK that includes the `jarsigner` command-line tool. Note that `jarsigner` is a JDK tool, not included in a JRE-only installation. [Eclipse Temurin](https://adoptium.net/) is the recommended JDK distribution for this purpose, as other OpenJDK distributions (such as Zulu) may behave differently when verifying signatures produced with an EV certificate. To verify: ```bat "C:\Program Files\Eclipse Adoptium\jdk-20.0.2.9-hotspot\bin\jarsigner.exe" ^ @@ -63,25 +63,25 @@ java -jar cimtool-cli.jar --version ### Informational Options -These options are standalone — they print output and exit immediately. No other options are required or processed when you use them. +These options are standalone, printing output and exiting immediately. No other options are required or processed when you use them. | Option | Short form | Description | |---|---|---| | `--help` | `-h` | Prints a summary of all available options and exits. | | `--version` | `-v` | Prints the CLI version (e.g. `CIMTool CLI version 2.3.0`) read from the JAR manifest and exits. | -| `--list-builders` | `-l` | Prints the names, type indicators, and output file extensions of all builders bundled in the JAR and exits. Each builder is shown with a type in parentheses — `(JAVA)`, `(TEXT)`, `(XSD)`, or `(TRANSFORM)` — identifying its implementation type. Use this to discover the exact builder name to pass to `--builder`. | +| `--list-builders` | `-l` | Prints the names, type indicators, and output file extensions of all builders bundled in the JAR and exits. Each builder is shown with a type in parentheses, such as `(JAVA)`, `(TEXT)`, `(XSD)`, or `(TRANSFORM)`, identifying its implementation type. Use this to discover the exact builder name to pass to `--builder`. | ### Transformation Options #### `--project-dir ` / `-pd` *(required)* -Point this to the root directory of your **CIMTool** project — the folder that contains the `Schema`, `Profiles`, `Instances`, `Incremental`, and (optionally) `Documentation` subfolders, as well as the project settings files. +Point this to the root directory of your **CIMTool** project, the folder that contains the `Schema`, `Profiles`, `Instances`, `Incremental`, and (optionally) `Documentation` subfolders, as well as the project settings files. ```bat --project-dir .\MyProject ``` -Your project directory must contain `.cimtool-settings` and `.builder-preferences` files, and may optionally contain a `.cimtool-global-preferences` file. All of these are created automatically by **CIMTool** when a project is created, loaded, or imported in the desktop application. The CLI reads your schema file locations from `.cimtool-settings`, your builder configurations from `.builder-preferences`, and — when present — any global preference values (such as PlantUML diagram style settings) from `.cimtool-global-preferences`. If `.cimtool-global-preferences` is absent, built-in defaults are used for those values. +Your project directory must contain `.cimtool-settings` and `.builder-preferences` files, and may optionally contain a `.cimtool-global-preferences` file. All of these are created automatically by **CIMTool** when a project is created, loaded, or imported in the desktop application. The CLI reads your schema file locations from `.cimtool-settings`, your builder configurations from `.builder-preferences`, and, when present, any global preference values (such as PlantUML diagram style settings) from `.cimtool-global-preferences`. If `.cimtool-global-preferences` is absent, built-in defaults are used for those values. !!! note @@ -115,17 +115,17 @@ When `--project-dir` is specified and `--output` is omitted, the CLI defaults to #### `--builder ` / `-b` *(optional)* -Specify a builder by name to override the builders configured on each profile. The name must exactly match one of the builder names returned by `--list-builders` (e.g. `xsd`, `linkml`, `json-schema-draft-07`, `legacy-rdfs`). This option works for all builder types — both XSLT-based builders (`TEXT`, `XSD`, `TRANSFORM`) and Java-based builders (`JAVA`). +Specify a builder by name to override the builders configured on each profile. The name must exactly match one of the builder names returned by `--list-builders` (e.g. `xsd`, `linkml`, `json-schema-draft-07`, `legacy-rdfs`). This option works for all builder types: both XSLT-based builders (`TEXT`, `XSD`, `TRANSFORM`) and Java-based builders (`JAVA`). ```bat --builder xsd ``` -If you omit this option, the CLI uses whichever builders are already enabled on each profile in **CIMTool**. This is the recommended approach for pipeline use — configure your builders on profiles in the desktop application, then let the CLI execute them without needing to name each one explicitly. `--builder` and `--xslt` are mutually exclusive — specifying both results in an invalid arguments error (exit code `1`). +If you omit this option, the CLI uses whichever builders are already enabled on each profile in **CIMTool**. This is the recommended approach for pipeline use: configure your builders on profiles in the desktop application, then let the CLI execute them without needing to name each one explicitly. `--builder` and `--xslt` are mutually exclusive, and specifying both results in an invalid arguments error (exit code `1`). #### `--xslt ` / `-x` *(optional)* -Use this option to apply a custom XSLT stylesheet that is not part of the bundled builder catalog. When you use `--xslt` you must also supply `--output-ext`. `--xslt` and `--builder` are mutually exclusive — specifying both results in an invalid arguments error (exit code `1`). +Use this option to apply a custom XSLT stylesheet that is not part of the bundled builder catalog. When you use `--xslt` you must also supply `--output-ext`. `--xslt` and `--builder` are mutually exclusive, and specifying both results in an invalid arguments error (exit code `1`). ```bat --xslt .\my-custom-transform.xsl @@ -167,7 +167,7 @@ Specify the path to a plain text file containing your single-line copyright noti --copyright-single-line .\copyright-single.txt ``` -You can specify both `--copyright-multi-line` and `--copyright-single-line` together — both files are loaded and applied. Neither can be combined with `--copyright-defaults`. +You can specify both `--copyright-multi-line` and `--copyright-single-line` together, and both files are loaded and applied. Neither can be combined with `--copyright-defaults`. ### JVM System Properties @@ -175,7 +175,7 @@ Pass these to the JVM before `-jar` rather than as CLI arguments. #### `-Dcimtool.debug` *(optional)* -By default, when the CLI exits with a transformation error only the exception message is printed. Set this property to any non-null value to additionally print the full Java stack trace to `stderr`, which is useful when diagnosing an unexpected crash at the CLI level. This property has no effect on Logback log levels and does not enable verbose output from the parsing or interpretation pipeline — for that level of detail, see [Logging and Diagnostics](#logging-and-diagnostics). +By default, when the CLI exits with a transformation error only the exception message is printed. Set this property to any non-null value to additionally print the full Java stack trace to `stderr`, which is useful when diagnosing an unexpected crash at the CLI level. This property has no effect on Logback log levels and does not enable verbose output from the parsing or interpretation pipeline. For that level of detail, see [Logging and Diagnostics](#logging-and-diagnostics). ```bat java -Dcimtool.debug=true -jar cimtool-cli.jar [options...] @@ -183,7 +183,7 @@ java -Dcimtool.debug=true -jar cimtool-cli.jar [options...] #### `-Dlogback.configurationFile=` *(optional)* -Use this property to override the production Logback configuration bundled inside the JAR with an external configuration file. The `logback-debug.xml` file distributed on the release page is the recommended starting point — see [Logging and Diagnostics](#logging-and-diagnostics) for full details. +Use this property to override the production Logback configuration bundled inside the JAR with an external configuration file. The `logback-debug.xml` file distributed on the release page is the recommended starting point. See [Logging and Diagnostics](#logging-and-diagnostics) for full details. ```bat java -Dlogback.configurationFile=.\logback-debug.xml -jar cimtool-cli.jar [options...] @@ -193,7 +193,7 @@ java -Dlogback.configurationFile=.\logback-debug.xml -jar cimtool-cli.jar [optio | Option | Short | Required | Notes | |---|---|---|---| -| `--project-dir` | `-pd` | Yes | Root directory of your **CIMTool** project; must contain `.cimtool-settings` and `.builder-preferences` (`.cimtool-global-preferences` is optional — built-in defaults are used if it is absent) | +| `--project-dir` | `-pd` | Yes | Root directory of your **CIMTool** project; must contain `.cimtool-settings` and `.builder-preferences` (`.cimtool-global-preferences` is optional, with built-in defaults used if it is absent) | | `--profile` | `-p` | No | Single profile to process; if omitted, all `.owl` files in `/Profiles` are processed | | `--output` | `-o` | Optional when `--project-dir` is specified | Output directory; defaults to `/Profiles` when not specified | | `--builder` | `-b` | No | Overrides profile-configured builders; mutually exclusive with `--xslt` | @@ -215,7 +215,7 @@ The `--list-builders` output shows each builder's type in parentheses. There are | `TEXT` | XSLT-based builders that produce text output with indentation post-processing | `xsd`, `json-schema-draft-07`, `adoc-article-rdfs`, `scala`, `jpa` | | `XSD` | XSLT-based builders that produce XSD schemas with XML Schema validation | `xsd`, `xsd-part100-ed2` | | `TRANSFORM` | XSLT-based builders that produce XML output without additional post-processing | `html`, `rdfs-2020`, `linkml`, `profile-doc-rtf` | -| `JAVA` | Java-based builders that use CIMTool generator classes directly — no XSLT involved | `xml`, `ttl`, `simple-flat-owl`, `simple-owl`, `legacy-rdfs`, `simple-flat-owl-augmented`, `simple-owl-augmented`, `legacy-rdfs-augmented` | +| `JAVA` | Java-based builders that use CIMTool generator classes directly, with no XSLT involved | `xml`, `ttl`, `simple-flat-owl`, `simple-owl`, `legacy-rdfs`, `simple-flat-owl-augmented`, `simple-owl-augmented`, `legacy-rdfs-augmented` | The `(JAVA)` builders were historically executed only within the **CIMTool** Eclipse desktop application. Beginning with the 2.3.0 release they are fully supported by the CLI, enabling headless generation of OWL, RDFS, Turtle, and XML profile serializations as part of a CI/CD pipeline. @@ -223,7 +223,7 @@ The `(JAVA)` builders were historically executed only within the **CIMTool** Ecl !!! note - The examples below use `cimtool-cli.jar` without a path, which assumes the JAR is in your current working directory. In practice, either run the commands from the directory containing the JAR, or substitute the full path to the JAR — for example `"D:\tools\cimtool-cli.jar"`. + The examples below use `cimtool-cli.jar` without a path, which assumes the JAR is in your current working directory. In practice, either run the commands from the directory containing the JAR, or substitute the full path to the JAR, for example `"D:\tools\cimtool-cli.jar"`. ### Generating Artifacts from a Single Profile @@ -249,7 +249,7 @@ The CLI reads the project settings (`.cimtool-settings`, `.builder-preferences`, ### Generating Artifacts from All Profiles -Process all profiles in the project's `Profiles` folder using the builders configured on each — the minimum valid invocation: +Process all profiles in the project's `Profiles` folder using the builders configured on each, the minimum valid invocation: ```bat java -jar cimtool-cli.jar ^ @@ -262,7 +262,7 @@ Short-form equivalent: java -jar cimtool-cli.jar -pd .\MyProject ``` -The CLI reads all project settings from `.\MyProject`, discovers every `.owl` file in `.\MyProject\Profiles`, and for each profile runs whichever builders are enabled on it. Generated artifacts are written alongside the source `.owl` files in `.\MyProject\Profiles` — exactly as the **CIMTool** desktop application does. +The CLI reads all project settings from `.\MyProject`, discovers every `.owl` file in `.\MyProject\Profiles`, and for each profile runs whichever builders are enabled on it. Generated artifacts are written alongside the source `.owl` files in `.\MyProject\Profiles`, exactly as the **CIMTool** desktop application does. With an explicit output directory: @@ -301,7 +301,7 @@ Short-form equivalent: java -jar cimtool-cli.jar -pd .\MyProject -p .\MyProject\Profiles\MyProfile.owl -x .\my-custom-transform.xsl -oe json -o .\output ``` -The CLI applies `my-custom-transform.xsl` to `MyProfile.owl` using the schema and settings from `--project-dir`. The `--output-ext` value determines the output filename — in this case `MyProfile.json` is written to `.\output`. Custom XSLT transforms have access to the same profile model and schema data as any built-in builder. +The CLI applies `my-custom-transform.xsl` to `MyProfile.owl` using the schema and settings from `--project-dir`. The `--output-ext` value determines the output filename. In this case, `MyProfile.json` is written to `.\output`. Custom XSLT transforms have access to the same profile model and schema data as any built-in builder. --- @@ -378,7 +378,7 @@ for %%f in (.\MyProject\Profiles\*.linkml.yaml) do ( !!! note - The LinkML builder must be enabled on each profile individually within **CIMTool** before running `cimtool-cli.jar`. The CLI executes whichever builders are configured on each profile — it does not enable or modify builder settings. + The LinkML builder must be enabled on each profile individually within **CIMTool** before running `cimtool-cli.jar`. The CLI executes whichever builders are configured on each profile and does not enable or modify builder settings. !!! tip "Linux and macOS CI runners" @@ -396,7 +396,7 @@ for %%f in (.\MyProject\Profiles\*.linkml.yaml) do ( ## Logging and Diagnostics -Under normal operation `cimtool-cli.jar` is intentionally quiet. Only genuine warnings and errors appear on the console — schema integrity issues such as missing range types or invalid cardinality declarations. All log output is written to `stderr` so it does not interfere with structured `stdout` output that downstream pipeline tools may consume. +Under normal operation `cimtool-cli.jar` is intentionally quiet. Only genuine warnings and errors appear on the console, schema integrity issues such as missing range types or invalid cardinality declarations. All log output is written to `stderr` so it does not interfere with structured `stdout` output that downstream pipeline tools may consume. ### Enabling Diagnostic Logging @@ -410,21 +410,21 @@ This overrides the production logging configuration bundled inside the JAR witho ### Capturing Log Output to a File -**Linux / macOS** — writes to file and shows output on screen simultaneously: +**Linux / macOS** (writes to file and shows output on screen simultaneously): ```bash java -Dlogback.configurationFile=./logback-debug.xml \ -jar cimtool-cli.jar [options...] 2>&1 | tee debug.log ``` -**Windows Command Prompt** — writes to file only: +**Windows Command Prompt** (writes to file only): ```bat java -Dlogback.configurationFile=.\logback-debug.xml ^ -jar cimtool-cli.jar [options...] > debug.log 2>&1 ``` -**Windows PowerShell** — writes to file and shows output on screen simultaneously: +**Windows PowerShell** (writes to file and shows output on screen simultaneously): ```powershell java -Dlogback.configurationFile=.\logback-debug.xml ` @@ -445,4 +445,4 @@ This flag prints additional diagnostic information at the CLI level only. For ve `cimtool-cli.jar` runs on Windows, Linux, and macOS. The examples on this page use Windows `^` line-continuation syntax for readability. On Linux and macOS, replace `^` with `\` and adjust path separators accordingly. -The **CIMTool** Eclipse desktop application is currently released for Windows only. `cimtool-cli.jar` has no such restriction — it is fully cross-platform and is the recommended approach for integrating **CIMTool**'s artifact generation capabilities into Linux-based CI/CD runners and container environments. +The **CIMTool** Eclipse desktop application is currently released for Windows only. `cimtool-cli.jar` has no such restriction. It is fully cross-platform and is the recommended approach for integrating **CIMTool**'s artifact generation capabilities into Linux-based CI/CD runners and container environments.