I feel I understand the basic mechanics of package merge, mostly thanks to Zito's outstanding paper on the topic:
I'm trying to understand the semantics of merge when nested packages and package imports are involved, specifically with MOF.
Referencing these specifications:
Take as an example MOF's 'Reflection' package, where it is the receiving package and all of UML is the merged package: <mergedPackage href="http://www.omg.org/spec/UML/20131001/UML.xmi#_0"/>
.
I know from the MOF specification document that the Element
and Type
classes will get merged with their UML counterparts in the resulting MOF Reflection package, but I can't find the specific semantic rules of how this result occurs.
Following the transformation rules, the resulting MOF Reflection package would look something like this (many elements removed for clarity):
Package
name="Reflection"
Class
name="Factory" (unchanged from MOF)Class
name="Type" (merged with UML CommonStructure "Type")Class
name="Object" (unchanged from MOF)Class
name="Element" (merged with UML CommonStructure "Element")Package
name="Activities" (nested package will be deep copied from UML since there is no matching nested package in receiving MOF Reflection)Package
name="Values" (nested package will be deep copied...)Package
name="CommonStructure" (nested package will be deep copied...)
Class
name="Element" (ambiguity here - see below)Nested packages are recursively merged, thus since MOF-Reflection does not contain nested packages matching the UML package names, these are deep copied as-is from UML. I note that nested UML packages are omitted in the 'CMOF.ecore' file I look to as an example, but the package merge transformation rules clearly state that nested packages are merged and the CMOF constraints haven no rule that they are removed.
Much thanks
I'm awarding the answer to Axel for helping, and also raising an issue with OMG. Also thanks @querty_so for offering the bounty.
I've reviewed all published papers on package merge, all OMG issues (closed and open, in MOF and UML), and reviewed the UML 2.5.1 specification many times for any clue and simply cannot find any rule that makes the result of the MOF::Reflection merge of UML correct.
I must conclude that the MOF.xmi file is malformed.
I believe that MOF::Reflection::Element and MOF::Reflection::Type should have been defined in a nested package 'MOF::CommonStructure', and not at the root of the MOF::Reflection package. If I understand package merge semantics, this would then properly merge them with UML when the two 'CommonStructure' nested packages match by name, and the UML package's imports at its root package would carry over to MOF::Reflection. Thus, all resulting merged UML elements in the nested packages would be visible with unqualified names in the resulting MOF::Reflection, and Element and Type would be merged without ambiguity or name clashes.
It hard to accept that such a foundational MOF.xmi file has this oversight, but I suppose there are only a handful of people who have ever tried to execute this merge programmatically. In my opinion, defining abstract syntax without proving its 'implementation validity' in a concrete reference implementation will result in this type of situation.
I hope a future commenter will weigh in with more insights to confirm or correct these conclusions.
Update 10.10.22: I got an answer from the chair of the MOF-taskforce. He says, that members are matched and therefore, there is no bug. I think at least the specification leaves room for interpretation here.
In the light of this explanation, I have to revise my answer:
There is no ambiguity: MOF::Reflection::Element is different from MOF::Reflection:CommonStructure::Element. This poses no problem. They have distinct qualified names and it is perfectly clear what you get. The latter refers to the unmerged original version.
There is an example in the specification, that illustrates this (figure 12.2). If you merge Class A from Package P1 into Package P2, then P1::A still refers to the original version.
And in your second example, you have two versions of Comment, one that inherits from MOF::Reflection::CommonStructure::Element and one from MOF::Reflection::Element. The PackageImport doesn't cause a clash, since the clashing elements would simply not be imported:
If indistinguishable Elements would be imported into a Namespace as a consequence of ElementImports or PackageImports, the Elements are not added to the importing Namespace.
So again, there is no ambiguity.
Previous obsolete answer
(I didn't delete it, so that the discussion still makes sense)
I think you found a bug in the MOF-specification. I reported it to the omg: https://issues.omg.org/browse/INBOX-1518
The specification states clearly:
UML 2.5.1 page 245: Imported elements are not merged (unless there is also a PackageMerge to the Package owning the imported element).
update: This refers to elementImport of the receiving Package. Therefore, it doesn't apply here. I was mistaken to cite it here.
The reason why earlier versions of MOF didn't have this problem is that the UML taskforce wanted to avoid the merge relationship in the definition of UML. In UML 2.4 all sub packages were merged into the UML package. In UML 2.5 all sub packages are only imported. It seems this change was overlooked by the MOF taskforce.
So, to make it completely clear: Elements are only merged if both the merged package and the receiving package own a mergeable element with the same name and metatype. If both packages own matching sub packages, this rule is applied recursively.
In order to solve this problem, I suggested to mirror the UML packages in the MOF definition. Until this has been done by the taskforce, you could edit your copy of the MOF.