Metadata-Version: 2.4
Name: umlmeta
Version: 0.2.0
Summary: Clean-room Python UML 2.5.1 / SysML v1 metamodel, XMI readers and writers, and the SysML v1 to v2 transformation
Author-email: "Jon R. Fox" <jon.fox@drfox.com>
License-Expression: MPL-2.0
Project-URL: Homepage, https://github.com/mycr0ft/umlmeta
Project-URL: Repository, https://github.com/mycr0ft/umlmeta
Project-URL: Issues, https://github.com/mycr0ft/umlmeta/issues
Project-URL: Changelog, https://github.com/mycr0ft/umlmeta/blob/master/CHANGELOG.md
Keywords: uml,sysml,metamodel,xmi,cmof,emof,modeling,mof,step
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: xmi
Requires-Dist: lxml>=4.9; extra == "xmi"
Provides-Extra: dev
Requires-Dist: lxml>=4.9; extra == "dev"
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

# umlmeta

Clean-room Python implementation of the **UML 2.5.1 metamodel** and the **SysML v1 → v2
transformation**, generated from OMG-published XMI and validated against the
[sysmlpy](https://github.com/mycr0ft/sysmlpy) v2 reader.

No vendor tooling, no UML/SysML libraries — the generated packages are pure
stdlib, and every semantic in them is traceable to an OMG document.

## What's inside

| Piece | What it is | Checks |
|---|---|---|
| `umlmeta.uml25` (src/umlmeta/uml25.py) | UML 2.5.1 metamodel as Python classes — generated by `generate.py` from the OMG UML XMI: 242 metaclasses, 620 reference descriptors, 22 derived unions computed at read time, 328 hidden association ends (the subset/redefine lattice is closed by the generator), 449 OCL constraints carried as metadata | `check.py` 45 |
| `umlmeta.standard_profile`, `umlmeta.sysml`, `umlmeta.uaf`, `umlmeta.uaf13` | StandardProfile + SysML v1 + UAF 1.2 (256) + UAF 1.3 (272) profile stereotypes, generated by `generate_profiles.py`; stereotypes fold their base metaclasses via Python inheritance, including cross-profile folds (UAF generalizes SysML stereotypes, e.g. `Capability(sysml.Block, ...)`); 1.3 adds the Mission-domain stereotypes and carries the `http://www.omg.org/spec/UAF/20241101/UAF` URI | `check_profiles.py` 60 |
| `umlmeta.v1_to_v2` | Clean-room SysML v1 → v2 **textual-notation emitter** anchored to OMG *SysML v2.0 Beta 4, Part 2: SysML v1 to SysML v2 Transformation* (ptc/2025-04-07). Every emitted form is calibrated against sysmlpy; anything without a normative mapping **raises `UnmappedFeature` instead of guessing** | `check_v1_to_v2.py` 47 |
| `umlmeta.xmi21` | XMI 2.1/EMF instance reader (dialect-tolerant: unprefixed containment, EMF feature defaults, cross-file `href` markers, stereotype applications) → feeds the emitter end-to-end | `check_dodaf.py` 32 |
| `umlmeta.mdzip` | MagicDraw/Cameo `.mdzip` scrape + forensics: member inventory, model-snapshot extraction with Nomagic→OMG namespace aliasing, proxy/project-usages (`local:/PROJECT-…` dependencies), version-era fingerprints (ID prefixes like `_2021x_2_…`), and hex/base64 payload extraction (SVG/PNG/JPEG/ZIP) with a manifest | `check_mdzip.py` 28 |
| `umlmeta.mdzip_import` | `.mdzip` → `umlmeta.uml25` objects: merges delta-snapshot members (keep-last dedup), retags Nomagic's XMI-2.0/xsi spellings to the reader's dialect, injects `xmi:type` from tags/features and coerces raw-ID types (metamodel-as-map + property signature), scrubs cross-project/name-typed/profile-layer refs into synthetic external markers, and delegates to `read_xmi21` — provenance (usages, eras) travels with the model | `check_mdzip_import.py` 26 |
| `umlmeta.mdzip_diff` | Semantic diff of two .mdzip files: flatten to (metaclass, qualified-path, feature) records with xmi:ids discarded entirely, then match by qualified path → metaclass+name moved → same-owner similarity → cross-owner same-name similarity, and report added/removed/renamed/moved/feature-changed. Survives TeamworkCloud-style id churn by construction | `check_mdzip_diff.py` 12 |
| `umlmeta.xmi_write` | XMI 2.1/EMF instance writer — the read/write pair round-trips both OMG dialects (DoDAFLibrary 2.1 form and MeasurementsLibrary 2.5.1-era form) with **canonical structural parity** (`canon.py`); writes stereotype applications (both forms, tags, `_URI`/`_EXTENSIONS`-driven) and profile applications; `write_cameo_xmi(...)` adds the Cameo/MagicDraw 2024x dialect (UML 2.5.1 namespace pair, `uml:Model` project wrapper, P10 applications — see `docs/CAMEO_XMI.md`) | `check_xmi_write.py` 48, `check_xmi_cameo.py` 15 |
| `umlmeta.bpmn` | BPMN 2.0.2 metamodel — OMG publishes BPMN as CMOF XMI (`BPMN20.cmof`), not a UML profile; `generate_bpmn.py` is a clean-room CMOF generator: 137 classes, 9 enums, 193 associations, opposite wiring, deliberately NOT UML Elements | `check_bpmn.py` 25 |
| `umlmeta.mm_write` | CMOF writer — reconstructs OMG `BPMN20.cmof` from the generated metamodel with **canonical structural parity** (`canon.py`, member order as set); `_SYNTH` carries the raw serialization forms the runtime tables don't. `write_emof` adds the EMOF dialect (MOF 2.0/XMI §6.5.2 rules: derived and defaults not serialized, no Associations) | `check_cmof_write.py` 20, `check_emof_write.py` 18 |
| `umlmeta.derived` | UML 2.5.1 normative derivations over `umlmeta.uml25` objects (spec OCL anchors): ownership chains, qualified names (template-aware), generalization closures, normative member (inherited/imported), redefinition-aware derived-union evaluation | `check_derived.py` 42 |
| `umlmeta.query` | Query helpers over loaded instance graphs: deterministic containment walk, `find` (metaclass by class or name, stereotype labels, qualified names, predicates), `stereotypes` label resolution | `check_query.py` 19 |
| `umlmeta.sysml2` | SysML v2 abstract syntax (KerML + SysML), generated by `generate_sysml2.py` from the OMG normative CMOF XMI (conformance **R2**): 175 classes, KerML ownership/membership wiring at runtime (OwningMembership/FeatureMembership containment, FeatureTyping typing, Subclassification specialization), derived-union reads (`ownedElement`, `feature`) computed live | `check_sysml2.py` 26 |
| `umlmeta.v1_to_v2_as` | SysML v1 → v2 **abstract-syntax transformer** (conformance **R3**, ptc/2025-04-07 §2): transforms `umlmeta.uml25`+`umlmeta.sysml` objects (R1 artifacts) into `umlmeta.sysml2` objects (R2 artifacts) — Block→PartDefinition, Property→PartUsage/AttributeUsage/OccurrenceUsage via FeatureMembership + FeatureTyping, Generalization→Subclassification, Comment→Documentation; one AS object per v1 element, same honesty rule as the textual emitter | `check_v1_to_v2_as.py` 33 |

**481 checks, all green.** `REPORT.md` is the detailed build journal: dialect facts,
mapping tables with spec anchors, calibration evidence, and honest elisions.

## Quick start

The check suites for the metamodel and profiles are stdlib-only; the emitter
suites validate with [sysmlpy](https://github.com/mycr0ft/sysmlpy) (the
authoritative SysML v2 reader), and the generator/reader need `lxml`:

```bash
python check.py                 # UML metamodel: 45 checks (stdlib only)
python check_profiles.py        # profiles (Std + SysML + UAF 1.2 + UAF 1.3): 60 checks (stdlib only)
python check_bpmn.py            # BPMN 2.0.2 CMOF metamodel: 25 checks (stdlib only)
python check_sysml2.py          # SysML v2 abstract syntax: 26 checks (stdlib only)
python check_emof_write.py      # EMOF writer: 18 checks (stdlib only)
python check_ocl.py             # OCL translation: 19 checks (stdlib only)

# these need the sysmlpy reader and/or the OMG corpora
$SYSMLPY_PYTHON check_v1_to_v2.py    # v1->v2 emitter: 47 checks
$SYSMLPY_PYTHON check_dodaf.py       # XMI end-to-end: 32 checks
                                #   (needs lxml + DoDAFLibrary.xmi, see REPORT Part 4)

# the generators need lxml and write into src/umlmeta/
$LXML_PYTHON generate.py           # regenerate src/umlmeta/uml25.py
$LXML_PYTHON generate_profiles.py  # regenerate the profiles
```

The check scripts print every assertion; a failing assertion names the mapping.
`check_v1_to_v2.py` also writes `vehicle_example_v2.sysml`, `wave3_example_v2.sysml`,
and `wave4_example_v2.sysml` — worked examples of the emitted notation.

## Repo layout

```text
pyproject.toml           distribution "umlmeta", MPL-2.0, src layout
src/umlmeta/             the importable package
  uml25.py               generated UML 2.5.1 metamodel (stdlib-only, self-contained)
  standard_profile.py    generated StandardProfile stereotypes
  sysml.py               generated SysML v1 profile stereotypes
  uaf.py                 generated UAF 1.2 UAFML stereotypes (folds sysml bases)
  uaf13.py               generated UAF 1.3 UAFML stereotypes
  sysml2.py              generated SysML v2 abstract syntax + KerML runtime (R2 artifact)
  bpmn.py                generated BPMN 2.0.2 metamodel (reuses uml25 descriptors)
  v1_to_v2.py            SysML v1 -> v2 textual emitter (mapping authority: ptc/2025-04-07)
  v1_to_v2_as.py         SysML v1 -> v2 abstract-syntax transformer (R3; constructs sysml2)
  xmi21.py               XMI 2.1/EMF instance reader -> uml25 objects
  xmi_write.py           XMI 2.1/EMF instance writer (canonical parity vs OMG corpus)
  mm_write.py            CMOF + EMOF metamodel writers (canonical parity; spec-rule checks)
  derived.py             UML 2.5.1 normative derivations (owners, qualified names, unions)
  query.py               query helpers (walk / find / stereotypes / exists / count)
  canon.py               shared canonical XML comparator (writer oracles)
  ocl_translator.py      clean-room OCL-to-Python translator
  mdzip.py               MagicDraw/Cameo .mdzip scrape + forensics
  mdzip_import.py        .mdzip -> uml25 objects (provenance travels with the model)
  mdzip_diff.py          semantic diff of two .mdzip files
  boxes_view.py          v1 data -> SysML v1 diagrams via diagramboxes
generate.py            UML 2.5.1 metamodel generator (OMG UML.xmi -> src/umlmeta/uml25.py)
generate_profiles.py   profile generator (StandardProfile.xmi, sysml.xmi, UAF.xmi -> src/umlmeta/*.py)
generate_sysml2.py     SysML v2 AS generator (OMG normative CMOF XMI -> src/umlmeta/sysml2.py)
generate_bpmn.py       CMOF generator (OMG BPMN20.cmof -> src/umlmeta/bpmn.py)
check*.py               eighteen check suites (481 checks; corpus suites need /mnt/TBFox, mdzip suites need MDZIP_CORPUS / MDZIP_REVISIONS)
calibrate_v2.py        textual-form calibration harness for sysmlpy
REPORT.md              build journal: dialect facts, mapping tables, evidence
PLAN.md                plan for the exporter/QoL waves (E1-E6: XMI/CMOF/EMOF writers, stereotype writing, derived unions, query helpers)
```

## Install

```bash
pip install umlmeta              # the generated metamodel and the library
pip install "umlmeta[xmi]"       # + lxml, for the XMI/CMOF/EMOF readers and writers
```

The generated metamodel modules are pure stdlib; `lxml` is only needed by the
readers, writers and generators.

```python
from umlmeta import uml25
from umlmeta import derived, query
```

## Clean-room discipline

- The generator and emitter are written from **normative OMG text only**
  (UML 2.5.1 XMI, profile XMI, the ptc/2025-04-07 transformation spec).
  Reference extractions and example XMI corpora are **kept out of the
  repository** (e.g. the local `transition.txt` spec dump is git-ignored).
- The only instance-model corpus used for reader tests is the
  OMG-published `DoDAFLibrary.xmi` (UPDM example). Third-party commercial
  book models are **excluded on copyright grounds**.
- The emitter follows an **honesty rule**: elements with no normative
  mapping raise `UnmappedFeature` naming the v1 metaclass rather than
  guessing, and spec gaps (e.g. ProxyPort, SYSML2_-329) surface as
  explicit comments.

## Related

- [mycr0ft/sysmlpy](https://github.com/mycr0ft/sysmlpy) — the SysML v2
  reader used as the validation oracle for every emitted textual form
- [mycr0ft/ams-gra](https://github.com/mycr0ft/ams-gra) — consumer of the
  emitter (AMS GRA v14.0 SysML v2 model, built via this toolchain)
- [mycr0ft/ams-gra-sysml](https://github.com/mycr0ft/ams-gra-sysml) — the
  SysML v2 model itself

## License

MPL-2.0 — see [LICENSE](LICENSE).
