Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2023 IBM Corporation, Embarcadero Technologies, CEA, Christian W. Damus, EclipseSource and others.
* Copyright (c) 2005, 2023, 2024 IBM Corporation, Embarcadero Technologies, CEA, Christian W. Damus, EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -19,6 +19,7 @@
* Camille Letavernier (EclipseSource) - 544487, 545578
* Camille Letavernier (EclipseSource) - 544487, 545578
* Eike Stepper - 582622
* Pauline Deville (CEA) - 11
*/
package org.eclipse.uml2.uml.util;

Expand All @@ -27,11 +28,13 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -113,7 +116,6 @@
import org.eclipse.uml2.uml.OpaqueExpression;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.OperationOwner;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageMerge;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.ParameterDirectionKind;
Expand Down Expand Up @@ -693,29 +695,25 @@ public static void setStereotypeApplicationStorage(Element element,
StereotypeApplicationHelper helper = newStorage != null ? null :StereotypeApplicationHelper
.getInstance(outermostPackage);

for (Iterator<EObject> it = outermostPackage.eAllContents(); it
.hasNext();) {
EObject object = it.next();
if (object instanceof Element) {
element = (Element) object;
Set<StereotypeApplicationInformations> stereotypeApplicationsToAdd = new HashSet<UMLUtil.StereotypeApplicationInformations>();
Set<StereotypeApplicationInformations> stereotypeApplicationsToClean = new HashSet<UMLUtil.StereotypeApplicationInformations>();

manageElementForMigrationToNewStereotypeApplicationStorage(newStorage, oldStorage, helper, stereotypeApplicationsToAdd, stereotypeApplicationsToClean, outermostPackage);

for (EObject stereotypeApplication : element
.getStereotypeApplications()) {
Stereotype stereotype = getStereotype(
stereotypeApplication);
for (Iterator<EObject> it = outermostPackage.eAllContents(); it.hasNext();) {
EObject object = it.next();
manageElementForMigrationToNewStereotypeApplicationStorage(newStorage, oldStorage, helper, stereotypeApplicationsToAdd, stereotypeApplicationsToClean, object);
}

if (newStorage != null) {
newStorage.addStereotypeApplication(element,
stereotype, stereotypeApplication);
} else {
helper.addToContainmentList(element,
stereotypeApplication, stereotype);
}
if (newStorage != null) {
for (StereotypeApplicationInformations stereotypeApplicationInfo : stereotypeApplicationsToAdd) {
newStorage.addStereotypeApplication(stereotypeApplicationInfo.element, stereotypeApplicationInfo.stereotype, stereotypeApplicationInfo.stereotypeApplication);
}
}

if (oldStorage != null) {
oldStorage.cleanup(element);
}
}
if (oldStorage != null) {
for (StereotypeApplicationInformations stereotypeApplicationInfo : stereotypeApplicationsToClean) {
oldStorage.cleanup(stereotypeApplicationInfo.element);
}
}

Expand All @@ -732,6 +730,73 @@ public static void setStereotypeApplicationStorage(Element element,
}
}

/**
* The goal of this method is to store in stereotypeApplicationsToAdd and stereotypeApplicationsToClean element that should be
* add of clean according to the given object
*
* @param newStorage
* the new StereotypeApplicationStorage
* @param oldStorage
* the old StereotypeApplicationStorage
* @param helper
* @param stereotypeApplicationsToAdd
* the set of StereotypeApplicationInformations to complete for stereotype application to add
* @param stereotypeApplicationsToClean
* the set of StereotypeApplicationInformations to complete for stereotype application to clean
* @param object
* the optionally stereotyped object
*/
private static void manageElementForMigrationToNewStereotypeApplicationStorage(StereotypeApplicationStorage newStorage, StereotypeApplicationStorage oldStorage, StereotypeApplicationHelper helper,
Set<StereotypeApplicationInformations> stereotypeApplicationsToAdd,
Set<StereotypeApplicationInformations> stereotypeApplicationsToClean, EObject object) {
Element element;
if (object instanceof Element) {
element = (Element) object;

for (EObject stereotypeApplication : element.getStereotypeApplications()) {
Stereotype stereotype = getStereotype(stereotypeApplication);

if (newStorage != null) {
stereotypeApplicationsToAdd.add(new StereotypeApplicationInformations(element, stereotype, stereotypeApplication));
} else {
helper.addToContainmentList(element, stereotypeApplication, stereotype);
}

if (oldStorage != null) {
stereotypeApplicationsToClean.add(new StereotypeApplicationInformations(element, stereotype, stereotypeApplication));
}
}
}
}

/**
* Class to be able to easily manipulate stereotype applications informations
*/
private static class StereotypeApplicationInformations {

/**
*
* Constructor.
*
* @param element
* the stereotyped element
* @param stereotype
* the stereotype applied
* @param stereotypeApplication
* the stereotype application
*/
public StereotypeApplicationInformations(Element element, Stereotype stereotype, EObject stereotypeApplication) {
super();
this.element = element;
this.stereotype = stereotype;
this.stereotypeApplication = stereotypeApplication;
}

private Element element;
private Stereotype stereotype;
private EObject stereotypeApplication;
}

/**
* A storage and retrieval strategy for stereotype application
* {@link EObject objects}.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/*
* Copyright (c) 2023 Eike Stepper (Loehne, Germany), CEA, and others..
* Copyright (c) 2023-2024 Eike Stepper (Loehne, Germany), CEA, and others..
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Eike Stepper - initial API and implementation
* Pauline Deville (CEA) - 13
*/
package org.eclipse.uml2.uml.bug.tests;

Expand Down Expand Up @@ -53,7 +54,9 @@ public class Bug582622StereotypeApplicationStorageTest

private Profile profile;

private Stereotype stereo;
private Stereotype stereoClass;

private Stereotype stereoPackage;

public Bug582622StereotypeApplicationStorageTest() {
super();
Expand Down Expand Up @@ -143,10 +146,15 @@ protected void setUp()
profile.setURI("http://www.eclipse.org/bogus/schema/2013/profile");
res.getContents().add(profile);

Class metaclass = getMetaclass("Class");
profile.createMetaclassReference(metaclass);
stereo = profile.createOwnedStereotype("test", false);
stereo.createExtension(metaclass, false);
Class metaclassClass = getMetaclass("Class");
profile.createMetaclassReference(metaclassClass);
stereoClass = profile.createOwnedStereotype("test_Class", false);
stereoClass.createExtension(metaclassClass, false);

Class metaclassPackage = getMetaclass("Package");
profile.createMetaclassReference(metaclassPackage);
stereoPackage = profile.createOwnedStereotype("test_Package", false);
stereoPackage.createExtension(metaclassPackage, false);

profile.define();
pkg.applyProfile(profile);
Expand Down Expand Up @@ -190,17 +198,17 @@ public void test_applyAndUnapplyStereotype() {
// 2) Apply the stereotype. Verify that the SA is stored in the
// "StereotypeApplications" EAnnotation below the element.

EObject application = fixture.applyStereotype(stereo);
assertTrue(fixture.isStereotypeApplied(stereo));
EObject application = fixture.applyStereotype(stereoClass);
assertTrue(fixture.isStereotypeApplied(stereoClass));
assertURIFragment(
"/0/Foo/%http:%2F%2Fwww.eclipse.org%2Fuml2%2FStereotypeApplications%/@contents.0",
application);
assertEquals(2, fixture.eResource().getContents().size());

// 3) Unapply the stereotype. Verify that the SA is deleted.

fixture.unapplyStereotype(stereo);
assertFalse(fixture.isStereotypeApplied(stereo));
fixture.unapplyStereotype(stereoClass);
assertFalse(fixture.isStereotypeApplied(stereoClass));
assertURIFragment(null, application);
}

Expand All @@ -219,15 +227,15 @@ public void test_applyAndUnapplyStereotype__TestStorage() {
// 2) Apply the stereotype. Verify that the SA is no longer stored in
// the resource's contents list.

EObject application = fixture.applyStereotype(stereo);
assertTrue(fixture.isStereotypeApplied(stereo));
EObject application = fixture.applyStereotype(stereoClass);
assertTrue(fixture.isStereotypeApplied(stereoClass));
assertURIFragment(null, application);
assertEquals(2, fixture.eResource().getContents().size());

// 3) Unapply the stereotype. Verify that the SA is deleted.

fixture.unapplyStereotype(stereo);
assertFalse(fixture.isStereotypeApplied(stereo));
fixture.unapplyStereotype(stereoClass);
assertFalse(fixture.isStereotypeApplied(stereoClass));
assertURIFragment(null, application);
}

Expand All @@ -236,8 +244,8 @@ public void test_migrateStereotypeApplications() {
// 1) Apply the stereotype while no special SA Storage
// is active. Verify that the SA is stored in the resource contents.

EObject application = fixture.applyStereotype(stereo);
assertTrue(fixture.isStereotypeApplied(stereo));
EObject application = fixture.applyStereotype(stereoClass);
assertTrue(fixture.isStereotypeApplied(stereoClass));
assertURIFragment("/2", application);
assertEquals(3, fixture.eResource().getContents().size());

Expand All @@ -251,7 +259,7 @@ public void test_migrateStereotypeApplications() {

UMLUtil.setStereotypeApplicationStorage(fixture,
ContainedByElement.INSTANCE);
assertTrue(fixture.isStereotypeApplied(stereo));
assertTrue(fixture.isStereotypeApplied(stereoClass));
assertURIFragment(
"/0/Foo/%http:%2F%2Fwww.eclipse.org%2Fuml2%2FStereotypeApplications%/@contents.0",
application);
Expand All @@ -265,7 +273,7 @@ public void test_migrateStereotypeApplications() {
// Verify that the SA is stored in the resource contents.

UMLUtil.setStereotypeApplicationStorage(fixture, null);
assertTrue(fixture.isStereotypeApplied(stereo));
assertTrue(fixture.isStereotypeApplied(stereoClass));
assertURIFragment("/2", application);
assertEquals(3, fixture.eResource().getContents().size());

Expand All @@ -275,14 +283,17 @@ public void test_migrateStereotypeApplications() {
}

public void test_migrateStereotypeApplications__TestStorage() {

// 1) Apply the stereotype while no special SA Storage
// 1) Apply stereotypes while no special SA Storage
// is active. Verify that the SA is stored in the resource contents.
Element rootPackage = fixture.getOwner();
assertTrue(rootPackage instanceof Package);
EObject applicationRoot = rootPackage.applyStereotype(stereoPackage);
assertURIFragment("/2", applicationRoot);

EObject application = fixture.applyStereotype(stereo);
assertTrue(fixture.isStereotypeApplied(stereo));
assertURIFragment("/2", application);
assertEquals(3, fixture.eResource().getContents().size());
EObject applicationFixture = fixture.applyStereotype(stereoClass);
assertTrue(fixture.isStereotypeApplied(stereoClass));
assertURIFragment("/3", applicationFixture);
assertEquals(4, fixture.eResource().getContents().size());

StereotypeApplicationStorage storage1 = UMLUtil
.getStereotypeApplicationStorage(fixture);
Expand All @@ -294,8 +305,8 @@ public void test_migrateStereotypeApplications__TestStorage() {

StereotypeApplicationStorage testStorage = UMLUtil
.setStereotypeApplicationStorageID(fixture, TestStorage.ID);
assertTrue(fixture.isStereotypeApplied(stereo));
assertURIFragment(null, application);
assertTrue(fixture.isStereotypeApplied(stereoClass));
assertURIFragment(null, applicationFixture);
assertEquals(2, fixture.eResource().getContents().size());

StereotypeApplicationStorage storage2 = UMLUtil
Expand All @@ -306,9 +317,11 @@ public void test_migrateStereotypeApplications__TestStorage() {
// Verify that the SA is stored in the resource contents.

UMLUtil.setStereotypeApplicationStorage(fixture, null);
assertTrue(fixture.isStereotypeApplied(stereo));
assertURIFragment("/2", application);
assertEquals(3, fixture.eResource().getContents().size());
assertTrue(rootPackage.isStereotypeApplied(stereoPackage));
assertTrue(fixture.isStereotypeApplied(stereoClass));
assertURIFragment("/2", applicationRoot);
assertURIFragment("/3", applicationFixture);
assertEquals(4, fixture.eResource().getContents().size());

StereotypeApplicationStorage storage3 = UMLUtil
.getStereotypeApplicationStorage(fixture);
Expand Down