Search code examples
umlmeta-object-facility

Package Merge semantics with nested packages and package imports


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.

Background

Referencing these specifications:

  1. MOF 2.5.1 xmi file
  2. UML 2.5.1 xmi file

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):

  1. Package name="Reflection"
    1. Class name="Factory" (unchanged from MOF)
    2. Class name="Type" (merged with UML CommonStructure "Type")
    3. Class name="Object" (unchanged from MOF)
    4. Class name="Element" (merged with UML CommonStructure "Element")
    5. Package name="Activities" (nested package will be deep copied from UML since there is no matching nested package in receiving MOF Reflection)
    6. Package name="Values" (nested package will be deep copied...)
    7. Package name="CommonStructure" (nested package will be deep copied...)
      1. Class name="Element" (ambiguity here - see below)
    8. ... etc.

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.

Ambiguity #1 - Package imports and name matching

  1. I'm assuming that since the UML package imports all of its nested packages to its root package, that the merge will match the names of MOF-Relection-Element with UML-CommonStructure-Element (and the same for Type), even though the definitions are not in the same package scope during merge?
    1. So merge is effectively performed on Namespace.member (which includes imported members), and not on Package.packagedElement?
    2. Examples I've seen indicate that package and element imports are unioned in the resulting package, but including imported elements' names in the name matching isn't described.

Ambiguity #2 - Updating references to resulting element, across package boundaries

  1. What is the transformation rule when the resulting nested package has an element with the same name as one in its outer containing package, as in the case of the resulting Reflection-CommonStructure-Element (and Type)?
    1. The MOF specification document indicates that the goal of using package merge is to add Object as a supertype of all elements, and extend Element with additional capability.
    2. This suggests that the "Element" in the resulting Reflection package must replace all references to a class named "Element", even in nested packages.
    3. I can't find any rules describing this
    4. Do we assume all nested package elements with the same name as the outer package represent the same and are replaced during merge? Or is the Reflection-CommonStructure-Element removed during merge because it is not distinguishable from the outer receiving and resulting element?

Much thanks

MOF Reflection Package Merge Ambiguity

Conclusions

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.


Solution

  • 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.