UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic,...

28
UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003

Transcript of UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic,...

Page 1: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

UML2 Package Merge

Usage scenarios and their effect on XMI and Java API interoperability

Bran Selic, Jim Amsden, Kenn Hussey

Oct, 2003

Page 2: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Package merge specifies how one package extends another by merging its contents

• Package import makes imported elements visible

• Package merge copies non-matching elements and merges matching elements through specialization and redefinitions

• Package merge is a shorthand for defining the same specializations and redefinitions, it does not introduce any new semantics

• A Model can be exchanged using XMI by retaining the package merges, or by transforming them away

Page 3: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

For example, package constructs extends basic by merging its contents with new features

basicconstructs

primitiveTypes

<<import>><<import>>

<<merge>>

Source Merging Package(this is the package that isupdated by the merge)

Target Merged Package

Page 4: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

MOF2 and UML2 Superstructure uses Package Merge to define a number of different modeling languages and compliance levels

• Package merge was introduced to support metamodel reuse

• UML2 was partitioned to support Basic, Constructs, Kernel, and Levels L1, L2, and L3

• Package merge is used to construct the metamodel language at each level by reusing and merging packages

• Levels are specified in UML2 Superstructure, Section 2

• Each level defines a new metamodeling language that has the capabilities of the lower level with additional capabilities

Page 5: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

For example, consider merging package basic into package constructs to produce a new language: “constructs”

basicconstructs

primitiveTypes

<<import>><<import>>

<<merge>>

Source Merging Package(this is the package that isupdated by the merge)

Target Merged Package

UML2 InfrastructureLibrary does not use package merge directly, but was rather produced by applying the package merge rules “by hand” to produce the Constructs model. This example is not intended to be from InfrastructureLibrary, but rather just an illustration of package merge semantics using simple concepts from InfrastructureLibrary.

Page 6: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Package basic is the original metamodel we want to extend

basic is a complete model that may have existing instances (XMI documents) and client applications

Type TypedElement

0..1

+type

0..1

TypedElement

Operation

Class

+ isAbstract : Boolean

0..*

1

+ownedOperation

0..*

+owningClass1

Property

+ isReadOnly : Boolean0..*1

+ownedAttribute

0..*

+owningClass

10..1

1

+opposite 0..1

1

NamedElement

+ name : String

Comment

+ body : String0..*11

+owner

0..*

+doc

Page 7: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Package constructs starts out having only the deltas or extensions we want to add •constructs is an incomplete

model specifying only the new features•constructs could be complete, but the merge result would be the same•For readability, UML2 specifies constructs as a complete model

Type

Class

Property

+ default : String+ isComposite : Boolean = false

0..*0..1

+ownedAttribute

0..*

+owningClass

0..1

Association

20..1

+memberEnd

2

+association

0..1

0..20..1

+ownedEnd

0..2

+owningAssociation

0..1

NamedElement Comment

111

+owner +doc

1

Note the tighter multiplicity

Page 8: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

The merge dependency is converted to an import

•Package basic is unchanged•Package constructs specializes and redefines elements in basic•and contains the new capabilities•The result must have classes from both packages

basicconstructs

primitiveTypes

<<import>><<import>>

<<import>>

Page 9: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

The package merge produces a new complete package constructs that:• specializes and redefines matching elements in basic• includes new elements

Type TypedElement

0..1

+type

0..1

TypedElement

AssociationProperty

+ default : String+ isComposite : Boolean = false+ isReadOnly : Boolean

20..1

+memberEnd

2

+association

0..1

0..20..1

+ownedEnd

0..2

+owningAssociation

0..1

0..1+opposite 0..1

Operation

Class

+ isAbstract : Boolean0..*0..1

+ownedAttribute

0..*

+owningClass

0..1

0..*

1

+ownedOperation

0..*

+owningClass1

Type(from basic)

TypedElement(from basic)

Operation(from basic)

Class

+ isAbstract : Boolean

(from basic)

Property

+ isReadOnly : Boolean

(from basic)

Comment

+ body : String

(from basic)

NamedElement

+ name : String

(from basic)

0..*1

+doc

0..*

+owner

1

Comment

+ body : String

NamedElement

+ name : String11

+doc

1

+owner

1 {redefines doc}

Page 10: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Consider the “compatibility” between basic and constructs

• There may be existing instances of basic XMI documents– XMI is used to interchange data between basic and constructs

based tools

– It must be possible to read the existing XMI documents for basic into the new constructs model

– It must be possible to read new XMI documents for constructs into basic

• There may be existing client applications or tools using the basic API– Existing basic tools should be able to use the constructs API

without change

Page 11: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Here’s an example basic client application that creates an instance of a model

ResourceSet resourceSet=new ResourceSetImpl();Resource resource =

resourceSet.createResource(URI.createFileURI(outputFile));

basic.Class intType = factory.createClass();intType.setName("Integer");resource.getContents().add(intType);basic.Class stringType = factory.createClass();stringType.setName("String");resource.getContents().add(stringType);basic.Class classY = factory.createClass();classY.setName("Y");resource.getContents().add(classY);basic.Class classZ = factory.createClass();classZ.setName("Z");resource.getContents().add(classZ);Property attribY = factory.createProperty();attribY.setName("distinguishedZ");attribY.setType(classZ);classY.getOwnedAttribute().add(attribY);Type attribYType = attribY.getType();buildAssociation(classY, "containedZ", classZ, "y");

protected static void buildAssociation(basic.Class classA, String nameA, basic.Class classB, String nameB )

{Property attribA = factory.createProperty();attribA.setName(nameA);attribA.setType(classB);classA.getOwnedAttribute().add(attribA);Property attribB = factory.createProperty();attribB.setName(nameB);attribB.setType(classA);classB.getOwnedAttribute().add(attribB);attribA.setOpposite(attribB);attribB.setOpposite(attribA);

}

Page 12: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

And the corresponding XMI file for the model<?xml version="1.0" encoding="ASCII"?>

<xmi:XMI xmi:version="2.0" xmlns:xmi=http://www.omg.org/XMI

xmlns:basic="http:///org/omg/uml2/infrastructure/basic">

<basic:Class name="Integer"/>

<basic:Class name="String"/>

<basic:Class name="Y">

<ownedAttribute name="distinguishedZ" type="/3"/>

<ownedAttribute name="containedZ" type="/3" opposite="/3/@ownedAttribute.0"/>

</basic:Class>

<basic:Class name="Z">

<ownedAttribute name="y" type="/2" opposite="/2/@ownedAttribute.1"/>

</basic:Class>

</xmi:XMI>

Page 13: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

The basic XMI file is partially compatible with the constructs XMI because of specialization

• A constructs application can read the basic XMI document

• But the XMI resource would create instances of the basic superclasses, not the constructs subclasses

• A “downcast” model-to-model mapping from basic instances to constructs instances is required in order to use the existing basic model instances in the extended API

• The constructs XSD doesn’t contain some of its redefined constraints because the property is implemented in the basic superclass

Page 14: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

The XMI document for the same model in constructs has a different namespace

<?xml version="1.0" encoding="ASCII"?><xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:constructs="http:///org/omg/uml2/infrastructure/constructs"> <constructs:Class name="Integer"/> <constructs:Class name="String"/> <constructs:Class name="Y"> <ownedAttribute xsi:type="constructs:Property" name="distinguishedZ" type="/3"/> <ownedAttribute xsi:type="constructs:Property" name="containedZ" type="/3" opposite="/3/@ownedAttribute.0"/> </constructs:Class> <constructs:Class name="Z"> <ownedAttribute xsi:type="constructs:Property" name="y" type="/2" opposite="/2/@ownedAttribute.1"/> </constructs:Class></xmi:XMI>

As a result, a basic client cannot import a constructs model with compatible information without doing another model-to-model mapping

Page 15: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

The basic client application is also partially compatible with the constructs API

• The basic application can be compiled with the new constructs API because it specializes basic

• However, in order for the application to use new constructs API, it must:– Change all the package imports from basic to constructs

– Use a different factory for creating model element instances

• This is even if the application doesn’t use any of the new features

Page 16: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

constructs client applications have to do a lot of downcasting because Java can’t implement UML2 redefinition semanticsconstructs.Class classZ = factory.createClass();classZ.setName("Z");resource.getContents().add(classZ);

// Create Association distinguished: Z <-- :YProperty attribY = factory.createProperty();attribY.setName("distinguishedZ");attribY.setType(classZ);classY.getOwnedAttribute().add(attribY);

// get the type of attribY. Type attribYType = (Type)attribY.getType();

•Java cannot hide an inherited member in one subclass, but not another•So we’re forced to remove the redefining property and use the inherited redefined property•Note that we set the type to a constructs Type, but have to downcast because of the package merge. •The result of getType is a basic Type, not a constructs type since the property is inherited•The constructs API can’t override the accessor because Java does not allow method override based on return type

After the many levels of merges in UML2, client developers will never be able to remember what has to be cast to what and when, leading to unexpected results

Page 17: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

In summary, UML2 package merge results in some problems for XSD and Java API generation:

• The API is more complex due to the extra supertypes and redefinitions– After merging, the XMI file for all of UML2 is 10231943 bytes and takes

about 15 minutes to load into EMF

– L3::Classifier has 35 direct superclasses

– Redefinitions cannot be directly implemented in XML Schema or Java

• Loading an old basic XMI file will produce basic instances, not the new constructs instances– A model-to-model mapping is required to "downcast" the basic instances

to the new constructs modeling language

– Caused by the namespace change in the XMI document

• Any existing basic clients have to be edited to use the new constructs package, even if they don't use any of the new features

Page 18: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Most problems result from the many specializations and redefinitions introduced by package merge:

• Redefinitions are introduced that cannot be handled by current OO programming languages like Java

– Cannot reduce visibility in a subclass– Cannot hide inherited merged property in subclass– Subclass member variable cannot have the same name as a superclass

member variable (unless the superclass member is private)– Java cannot override getter methods based on return type– Java and EMF do not support multiple inheritance of the same property

• Accessors that return elements from constructs have to be downcast because the methods are inherited from the corresponding basic class

• Merged constraints are lost for matching properties because the superclass property is chosen when eliminating the property redefinitions

• Many instances of name collisions arise from introduced multiple inheritance

Page 19: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

And some inconveniences:

• The result of the merge is a single flattened namespace for all classes in the model

• Using any of the inherited superclasses requires the client application to use a fully qualified class name

• All the downcasting required for redefined properties will be impossible to deal with

Page 20: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

MOF2 defines two kinds of package merge: extend and define

• Define merge was introduced in order to specify EMOF

• Extend merge, denoted as a <<merge>> dependency converts the merge into an <<import>> and specializes and redefines the merged elements in the merging package

• Define merge, denoted as a <<combine>> dependency removes the dependency and does not specialize or redefine merged elements

• Extend merge maintains compatibility with the merged elements through generalization and redefinitions

• Define merge maintains compatibility by creating different, backward compatible versions of existing elements

• Define merge produces a simpler model and API – no specializations and redefinitions

Page 21: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Package merge can be view from two perspectives, depending on the direction of the merge

• The merging package defines a new metamodel language in a family of languages– The merging package specifies the new features and merges in the

old– The merge results in a new package representing the new

modeling language

• A new version of the merging package is created by merging in new features– The merging package specifies the old features and merges in the

new features– The merge results in a new version of the original, merging

package

Page 22: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Consider switching the direction of the merge, and changing the type to PackageMergeKind::define

We change the example so package basic is extended by additional features in constructs to produce a new version of

“basic”

Source Merging PackageTarget Merged Package

basicconstructs

primitiveTypes

<<import>><<import>>

<<combine>>

Page 23: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

The package merge is removed

The API can be generated for just basic. There is no need to generate constructs because it is just a fragment model defining new features that were added to basic.

Package basic will also get a new schema - BasicXMI.XSD which has the new features. This would be a new version of the previous BasicXMI.XSD and could be named appropriately to distinguish them, or use some life-cycle management or versioning facility, and perhaps a fragment in the namespace URI.

The “constructs” versionof basic

basic

primitiveTypes

<<import>>

Page 24: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

This produces a new version of the basic package that includes the new features defined in constructs

TypeTypedElement

0..1

+type

0..1

TypedElement

Operation

Class

+ isAbstract : Boolean

0..*

1

+ownedOperation

0..*

+owningClass1

Property

+ isReadOnly : Boolean+ default : String- isComposite : Boolean = false

0..*1

+ownedAttribute

0..*

+owningClass

1

0..1

1

+opposite

0..1

1

Association

20..1

+memberEnd

2

+association

0..1

0..20..1

+ownedEnd

0..2

+owningAssociation

0..1

NamedElement

+ name : StringComment

+ body : String111

+owner +doc

1

Page 25: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

This solution has the same semantics as the extend merge, but has many advantages:

• The API and XSD Schema are much smaller and simpler• There are no redefinitions or property conflicts introduced by multiple

inheritance• The old and new XMI files are identical (for the compatible subset)

– Loading an old basic XMI file will produce new basic instances, not instances from the constructs package

– No model-to-model mapping is required to "downcast" the basic instances to the new constructs modeling language

– The new extended basic will have a new XML schema containing the new features added from constructs

• Existing basic clients don’t have to be edited to use the new basic classes – there’s no namespace change

• Accessors that return elements from constructs have the correct type, there’s no need to downcast

• The API and schema capture the additional merged constraints

Page 26: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

There are a number ways this result could be produced:

1. Change the UML2 model

2. Extend XMI2• Define a new CMOF to EMOF translation algorithm that flattens

the merged class hierarchy

• Not completely semantics preserving

3. Fix during API implementation• Flatten the merged class hierarchy as part of the implementation

of an API for UML2

• Flattening algorithm doesn’t correspond to any UML2 semantics

• Would introduce non-standard mapping resulting in interoperability problems

Page 27: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Changing the UML2 model

• Pick one root package that will be the leaf merging package– Say org.omg.uml2– Initial contents are Basic and anything required from Abstractions– EMOF capabilities can be <<combine>> merged into this too– Or initial contents are just EMOF to get MOF/UML alignment

• Specify new capabilities, extensions, or features as fragment models describing changes to org.omg.uml2

• Change package dependencies to <<combine>> merge extensions into org.omg.uml2

– This may produce additional subpackages which get new features from subsequent merges

• Define each compliance “Level” in a separate model that specifies a set of capabilities/extensions that are to be merged into a UML2 version

• Re-specify InfrastructureLibrary to use the new merge semantics

Page 28: UML2 Package Merge Usage scenarios and their effect on XMI and Java API interoperability Bran Selic, Jim Amsden, Kenn Hussey Oct, 2003.

Additional notes

• Can’t just reverse the direction and change <<merge>> to <<combine>> in UML2 because clean model rules require the merged supertype to be explicitly included in the merging packages

• Package merge isn’t the problem, specialization and redefinitions are. Package merge just creates a lot of them

• API generation approach is to do the flattening algorithm in the generation of the Java API, not as a model-to-model transformation corresponding to any UML2 semantics

• This produces the same result that redoing the UML2 models using <<combine>> instead of <<merge>>