Skip to content

[ENHANCEMENT] Add support for generating a full canonical CIM model interim XML representation #255

Description

@tviegut

Is your feature request related to a problem? Please describe:

CIMTool’s intermediate XML format — the a:Catalog document produced by ProfileSerializer — is the input consumed by all of CIMTool’s built-in builders and any custom XSLT transforms written against it. This format expresses CIM classes, properties, cardinalities, stereotypes, and package structure in a rich, builder-friendly representation. Currently, this format can only be generated for a user-defined profile: the user must explicitly drag classes and properties from the background CIM schema into a profile before any a:Catalog XML can be produced.

A recurring request from the CIMTool user community is for the ability to generate an a:Catalog XML document covering the entire canonical CIM model — not a subset defined by a profile. This would enable authors of large-scale XSLT transforms to write their stylesheets against the full canonical schema representation, using the same intermediate format that all existing builders already consume, without the impractical step of manually selecting every class and property in the profile editor.

Describe the solution you’d like:

The following enhancements are needed to support this feature:

  1. A new SchemaProfileClass class should be introduced in CIMUtil as a subclass of ProfileClass. Rather than scanning owl:Restriction superclasses — which only exist in user-defined profile OWL files — SchemaProfileClass should override internalAnalyse() to derive property membership directly from the background model. Specifically:
  • Properties are discovered via rdfs:domain lookup on the background model, covering both datatype properties (attributes) and object properties (associations).
  • Property cardinalities are read from the UML.schemaMin and UML.schemaMax annotation properties written onto every property resource during schema import from EA project files (*.eap, *.qea) and XMI files.
  • Property ranges are read directly from rdfs:range declarations on each property resource.
  • This approach requires no synthesis of OWL restriction triples and performs no mutation of the background model.
  1. A new FullModelProfileModel class should be introduced in CIMUtil as a subclass of ProfileModel. It should expose an initialize(OntModel backgroundModel) method that accepts the merged background model directly — with no profile OWL file required — and populates the model tree by enumerating all named classes in the background model, creating a SchemaProfileClass instance for each. System infrastructure namespaces (OWL, MESSAGE) should be excluded from enumeration.
  2. The changes to ProfileClass required to support SchemaProfileClass are minimal and deliberate:
  • analyse() should remain final and delegate to a new protected void internalAnalyse() method whose body is identical to the existing analyse() implementation. SchemaProfileClass overrides internalAnalyse() only.
  • The fields props, baseClass, and classes should be promoted to protected visibility to permit assignment from the overriding subclass.
  • analyseBaseClass() should be promoted to protected visibility so that SchemaProfileClass.internalAnalyse() can invoke it for stereotype propagation, consistent with the standard analysis path.
  • The PropertyInfo inner class constructor and its range, min, and max fields should be promoted to package-private visibility. SchemaProfileClass resides in au.com.langdale.profiles and requires direct access to construct and populate PropertyInfo instances.
  • No other changes to ProfileClass are required. The clss and model fields remain private; SchemaProfileClass accesses them via the existing public getSubject() accessor and the derived getSubject().getOntModel() call respectively.
  1. Two latent null-safety defects in ProfileSerializer should be addressed as part of this work, as they are exposed when the full canonical model is serialised. Both occur in emitPrimitive() and emitCIMDatatype() where elem.set() is called with values that can be null when the corresponding annotation is absent from a background model resource:
  • primitive.getString(UML.cimdatatypeMapping) — should default to an empty string when null.
  • primitive.getLabel() / defin.getLabel() — should default to an empty string when null.

Describe alternatives you’ve considered:

Two alternative approaches were evaluated before the solution described above was selected.

The first alternative was to programmatically synthesise a complete profile OWL model by calling Refactory.createCompleteProfile() for every named class in the background model, producing the OWL restriction triples that the existing ProfileClass.analyse() path expects. This approach was discarded because the synthesis cost for a full CIM model (approximately 1,500+ named classes and tens of thousands of properties) is prohibitive, and the synthesised triples add no information beyond what the UML.schemaMin, UML.schemaMax, and rdfs:range annotations already provide.

The second alternative was to add the schema-based analysis path directly inside ProfileClass using a mode flag and an alternate private constructor, rather than introducing a subclass. This approach avoids all visibility changes but conflates two distinct responsibilities within a single class. The subclass design was preferred because it is more cohesive, more testable, and more clearly communicates intent to future maintainers.

Additional context:

The schema.merged-owl file produced by CIMTool’s existing SchemaBuildlet was evaluated as a potential input for this feature. That file is a raw RDF/XML serialisation of the merged background ontology triple store and is structurally unrelated to the a:Catalog XML format. It cannot serve as input to existing XSLT builders and does not address the user need described above.

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationenhancementNew feature or request

Projects

Status
Todo

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions