blob: b7e4081992bb3f04172b7476b419fd5bf8f875ea [file] [log] [blame]
/*
* Copyright (c) 2005, 2019 IBM Corporation, Embarcadero Technologies, 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:
* IBM - initial API and implementation
* Kenn Hussey (Embarcadero Technologies) - 271470
* Kenn Hussey - 323181, 348433, 535301
* Kenn Hussey (CEA) - 327039, 369492, 313951, 163556, 418466, 447901, 451350, 458658, 485756
* Christian W. Damus (CEA) - 300957, 431998
* Christian W. Damus - 444588
* Alain Le Guennec (Esterel Technologies SAS) - 497153
* Camille Letavernier (EclipseSource) - 545578
*/
package org.eclipse.uml2.uml.internal.operations;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ElementImport;
import org.eclipse.uml2.uml.Enumeration;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.PrimitiveType;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.ProfileApplication;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.UMLPlugin;
import org.eclipse.uml2.uml.PackageImport;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.VisibilityKind;
import org.eclipse.uml2.uml.util.UMLUtil;
import org.eclipse.uml2.uml.util.UMLValidator;
/**
* <!-- begin-user-doc -->
* A static utility class that provides operations related to '<em><b>Package</b></em>' model objects.
* <!-- end-user-doc -->
*
* <p>
* The following operations are supported:
* </p>
* <ul>
* <li>{@link org.eclipse.uml2.uml.Package#validateElementsPublicOrPrivate(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Elements Public Or Private</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#applyProfile(org.eclipse.uml2.uml.Profile) <em>Apply Profile</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#createOwnedClass(java.lang.String, boolean) <em>Create Owned Class</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#createOwnedEnumeration(java.lang.String) <em>Create Owned Enumeration</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#createOwnedInterface(java.lang.String) <em>Create Owned Interface</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#createOwnedPrimitiveType(java.lang.String) <em>Create Owned Primitive Type</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#createOwnedStereotype(java.lang.String, boolean) <em>Create Owned Stereotype</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getAllAppliedProfiles() <em>Get All Applied Profiles</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getAllProfileApplications() <em>Get All Profile Applications</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getAppliedProfile(java.lang.String) <em>Get Applied Profile</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getAppliedProfile(java.lang.String, boolean) <em>Get Applied Profile</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getAppliedProfiles() <em>Get Applied Profiles</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getProfileApplication(org.eclipse.uml2.uml.Profile) <em>Get Profile Application</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getProfileApplication(org.eclipse.uml2.uml.Profile, boolean) <em>Get Profile Application</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#isModelLibrary() <em>Is Model Library</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#isProfileApplied(org.eclipse.uml2.uml.Profile) <em>Is Profile Applied</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#unapplyProfile(org.eclipse.uml2.uml.Profile) <em>Unapply Profile</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#applyProfiles(org.eclipse.emf.common.util.EList) <em>Apply Profiles</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#allApplicableStereotypes() <em>All Applicable Stereotypes</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#containingProfile() <em>Containing Profile</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#makesVisible(org.eclipse.uml2.uml.NamedElement) <em>Makes Visible</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getNestedPackages() <em>Get Nested Packages</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getOwnedStereotypes() <em>Get Owned Stereotypes</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#getOwnedTypes() <em>Get Owned Types</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#visibleMembers() <em>Visible Members</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Package#mustBeOwned() <em>Must Be Owned</em>}</li>
* </ul>
*
* @generated
*/
public class PackageOperations
extends NamespaceOperations {
protected static class StereotypeApplicationCopier
extends EcoreUtil.Copier {
private static final long serialVersionUID = 1L;
@Deprecated
protected final Profile profile;
protected final List<Profile> profiles;
protected final Map<EClass, EClass> targetClasses = new HashMap<EClass, EClass>();
protected final Map<EStructuralFeature, EStructuralFeature> targetFeatures = new HashMap<EStructuralFeature, EStructuralFeature>();
protected StereotypeApplicationCopier(Profile profile) {
this(profile == null
? Collections.<Profile> emptyList()
: Collections.singletonList(profile));
}
protected StereotypeApplicationCopier(List<Profile> profiles) {
super();
this.profiles = profiles;
this.profile = profiles.isEmpty()
? null
: profiles.get(0);
}
@Override
protected EObject createCopy(EObject eObject) {
Element baseElement = getBaseElement(eObject);
return baseElement == null
? super.createCopy(eObject)
: applyStereotype(baseElement, getTarget(eObject.eClass()),
null);
}
@Override
protected EClass getTarget(EClass eClass) {
if (targetClasses.containsKey(eClass)) {
return targetClasses.get(eClass);
}
NamedElement namedElement = getNamedElement(eClass);
EClass definition = (EClass) getDefinition(namedElement);
targetClasses.put(eClass, definition);
if (definition != null) {
return definition;
} else {
String qualifiedName = (namedElement != null)
? getQualifiedName(namedElement)
: getQualifiedName(eClass, NamedElement.SEPARATOR);
throw new IllegalStateException("Definition for class '" //$NON-NLS-1$
+ qualifiedName + "' not found."); //$NON-NLS-1$
}
}
@Override
protected EStructuralFeature getTarget(
EStructuralFeature eStructuralFeature) {
if (targetFeatures.containsKey(eStructuralFeature)) {
return targetFeatures.get(eStructuralFeature);
}
NamedElement namedElement = getNamedElement(eStructuralFeature);
EStructuralFeature definition = (EStructuralFeature) getDefinition(
namedElement);
targetFeatures.put(eStructuralFeature, definition);
if (definition != null) {
return definition;
} else {
String qualifiedName = (namedElement != null)
? getQualifiedName(namedElement)
: getQualifiedName(eStructuralFeature,
NamedElement.SEPARATOR);
throw new IllegalStateException("Definition for property '" //$NON-NLS-1$
+ qualifiedName + "' not found."); //$NON-NLS-1$
}
}
protected NamedElement getNamedElement(ENamedElement element) {
if (element != null) {
for (Profile profile : profiles) {
NamedElement namedElement = UMLUtil.getNamedElement(element,
profile);
if (namedElement != null) {
return namedElement;
}
}
}
return null;
}
protected ENamedElement getDefinition(NamedElement element) {
if (element != null) {
for (Profile profile : profiles) {
ENamedElement definition = profile.getDefinition(element);
if (definition != null) {
return definition;
}
}
}
return null;
}
@Override
protected void copyAttribute(EAttribute eAttribute, EObject eObject,
EObject copyEObject) {
if (!eAttribute.isUnsettable() || eObject.eIsSet(eAttribute)) {
try {
if (UMLUtil.isEnumType(eAttribute.getEType())) {
copyEEnumAttribute(eAttribute, eObject, copyEObject);
} else {
copyEDataTypeAttribute(eAttribute, eObject,
copyEObject);
}
} catch (Exception e) {
handleException(e);
}
}
}
protected void handleException(Exception exception) {
UMLPlugin.INSTANCE.log(exception);
}
protected void copyEDataTypeAttribute(EAttribute eAttribute,
EObject eObject, EObject copyEObject) {
EDataType eDataType = eAttribute.getEAttributeType();
EFactory eFactory = eDataType.getEPackage().getEFactoryInstance();
EAttribute targetEAttribute = (EAttribute) getTarget(eAttribute);
if (targetEAttribute != null && targetEAttribute.isChangeable()) {
EDataType targetEDataType = targetEAttribute
.getEAttributeType();
EFactory targetEFactory = targetEDataType.getEPackage()
.getEFactoryInstance();
if (targetEAttribute.isMany()) {
@SuppressWarnings("unchecked")
EList<Object> copyValues = (EList<Object>) copyEObject
.eGet(targetEAttribute);
if (eAttribute.isMany()) {
EList<?> values = (EList<?>) eObject.eGet(eAttribute);
for (int i = 0, size = values.size(); i < size; i++) {
copyValues.add(i,
targetEFactory.createFromString(targetEDataType,
eFactory.convertToString(eDataType,
values.get(i))));
}
} else {
copyValues.add(targetEFactory.createFromString(
targetEDataType, eFactory.convertToString(eDataType,
eObject.eGet(eAttribute))));
}
} else {
copyEObject.eSet(targetEAttribute,
targetEFactory.createFromString(targetEDataType,
eFactory.convertToString(eDataType,
eAttribute.isMany()
? ((EList<?>) eObject.eGet(eAttribute))
.get(0)
: eObject.eGet(eAttribute))));
}
}
}
protected void copyEEnumAttribute(EAttribute eAttribute,
EObject eObject, EObject copyEObject) {
EAttribute targetEAttribute = (EAttribute) getTarget(eAttribute);
if (targetEAttribute != null && targetEAttribute.isChangeable()) {
EEnum targetEEnum = UMLUtil
.getEnumType(targetEAttribute.getEAttributeType());
if (targetEAttribute.isMany()) {
@SuppressWarnings("unchecked")
EList<Enumerator> copyValues = (EList<Enumerator>) copyEObject
.eGet(targetEAttribute);
if (eAttribute.isMany()) {
@SuppressWarnings("unchecked")
EList<Enumerator> values = (EList<Enumerator>) eObject
.eGet(eAttribute);
for (int i = 0, size = values.size(); i < size; i++) {
EEnumLiteral targetEEnumLiteral = targetEEnum
.getEEnumLiteral(values.get(i).getName());
if (targetEEnumLiteral != null) {
copyValues
.add(targetEEnumLiteral.getInstance());
}
}
} else {
Enumerator value = (Enumerator) eObject
.eGet(eAttribute);
if (value != null) {
EEnumLiteral targetEEnumLiteral = targetEEnum
.getEEnumLiteral(value.getName());
if (targetEEnumLiteral != null) {
copyValues
.add(targetEEnumLiteral.getInstance());
}
}
}
} else {
Enumerator value = (Enumerator) (eAttribute.isMany()
? ((EList<?>) eObject.eGet(eAttribute)).get(0)
: eObject.eGet(eAttribute));
if (value != null) {
EEnumLiteral targetEEnumLiteral = targetEEnum
.getEEnumLiteral(value.getName());
if (targetEEnumLiteral != null) {
copyEObject.eSet(targetEAttribute,
targetEEnumLiteral.getInstance());
}
}
}
}
}
@Override
protected void copyContainment(EReference eReference, EObject eObject,
EObject copyEObject) {
if (eObject.eIsSet(eReference)) {
Object value = eObject.eGet(eReference);
try {
EReference targetEReference = (EReference) getTarget(
eReference);
if (targetEReference != null
&& targetEReference.isChangeable()) {
if (targetEReference.isMany()) {
@SuppressWarnings("unchecked")
EList<EObject> copyValues = (EList<EObject>) copyEObject
.eGet(targetEReference);
if (eReference.isMany()) {
@SuppressWarnings("unchecked")
EList<EObject> values = (EList<EObject>) value;
copyValues.addAll(copyAll(values));
} else if (value != null) {
copyValues.add(copy((EObject) value));
}
} else {
if (eReference.isMany()) {
@SuppressWarnings("unchecked")
EList<EObject> values = (EList<EObject>) value;
copyEObject.eSet(targetEReference,
copy(values.get(0)));
} else {
copyEObject.eSet(targetEReference,
copy((EObject) value));
}
}
}
} catch (Exception e) {
handleException(e);
}
}
}
@Override
protected void copyReference(EReference eReference, EObject eObject,
EObject copyEObject) {
if (eObject.eIsSet(eReference)) {
Object value = eObject.eGet(eReference);
try {
EReference targetEReference = (EReference) getTarget(
eReference);
if (targetEReference != null
&& targetEReference.isChangeable()) {
if (targetEReference.isMany()) {
@SuppressWarnings("unchecked")
InternalEList<EObject> copyValues = (InternalEList<EObject>) copyEObject
.eGet(targetEReference);
if (eReference.isMany()) {
EReference targetEOpposite = targetEReference
.getEOpposite();
int index = 0;
@SuppressWarnings("unchecked")
Iterator<EObject> v = ((EList<EObject>) value)
.iterator();
while (v.hasNext()) {
value = v.next();
EObject copyValue = get(value);
if (copyValue == null) {
if (targetEOpposite == null) {
copyValues.addUnique(index++,
(EObject) value);
}
} else {
if (targetEOpposite != null) {
int position = copyValues
.indexOf(copyValue);
if (position == -1) {
copyValues.addUnique(index++,
copyValue);
} else if (position != index) {
copyValues.move(index++,
copyValue);
}
} else {
copyValues.addUnique(index++,
copyValue);
}
}
}
} else if (value != null) {
EObject copyValue = get(value);
if (copyValue == null) {
if (targetEReference
.getEOpposite() == null) {
copyValues.addUnique((EObject) value);
}
} else {
copyValues.addUnique(copyValue);
}
}
} else {
if (eReference.isMany()) {
@SuppressWarnings("unchecked")
EList<EObject> values = (EList<EObject>) value;
value = values.get(0);
}
Object copyValue = get(value);
if (copyValue == null) {
if (targetEReference.getEOpposite() == null) {
copyEObject.eSet(targetEReference, value);
}
} else {
copyEObject.eSet(targetEReference, copyValue);
}
}
}
} catch (Exception e) {
handleException(e);
}
}
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected PackageOperations() {
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* If an element that is owned by a package has visibility, it is public or private.
* packagedElement->forAll(e | e.visibility<> null implies e.visibility = VisibilityKind::public or e.visibility = VisibilityKind::private)
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param diagnostics The chain of diagnostics to which problems are to be appended.
* @param context The cache of context-specific information.
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean validateElementsPublicOrPrivate(
org.eclipse.uml2.uml.Package package_, DiagnosticChain diagnostics,
Map<Object, Object> context) {
boolean result = true;
for (Element ownedElement : package_.getOwnedElements()) {
if (ownedElement instanceof NamedElement) {
VisibilityKind visibility = ((NamedElement) ownedElement)
.getVisibility();
if (visibility != null
&& visibility != VisibilityKind.PUBLIC_LITERAL
&& visibility != VisibilityKind.PRIVATE_LITERAL) {
result = false;
if (diagnostics == null) {
return result;
} else {
diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING,
UMLValidator.DIAGNOSTIC_SOURCE,
UMLValidator.PACKAGE__ELEMENTS_PUBLIC_OR_PRIVATE,
UMLPlugin.INSTANCE.getString(
"_UI_Package_ElementsPublicOrPrivate_diagnostic", //$NON-NLS-1$
getMessageSubstitutions(context, ownedElement,
package_)),
new Object[]{package_, ownedElement}));
}
}
}
}
return result;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Creates a(n) (abstract) class with the specified name as an owned type of this package.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param name The name for the new class, or null.
* @param isAbstract Whether the new class should be abstract.
* <!-- end-model-doc -->
* @generated NOT
*/
public static org.eclipse.uml2.uml.Class createOwnedClass(
org.eclipse.uml2.uml.Package package_, String name,
boolean isAbstract) {
org.eclipse.uml2.uml.Class ownedClass = (org.eclipse.uml2.uml.Class) package_
.createOwnedType(name, UMLPackage.Literals.CLASS);
ownedClass.setIsAbstract(isAbstract);
return ownedClass;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Creates a enumeration with the specified name as an owned type of this package.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param name The name for the new enumeration, or null.
* <!-- end-model-doc -->
* @generated NOT
*/
public static Enumeration createOwnedEnumeration(
org.eclipse.uml2.uml.Package package_, String name) {
return (Enumeration) package_.createOwnedType(name,
UMLPackage.Literals.ENUMERATION);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Creates a primitive type with the specified name as an owned type of this package.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param name The name for the new primitive type, or null.
* <!-- end-model-doc -->
* @generated NOT
*/
public static PrimitiveType createOwnedPrimitiveType(
org.eclipse.uml2.uml.Package package_, String name) {
return (PrimitiveType) package_.createOwnedType(name,
UMLPackage.Literals.PRIMITIVE_TYPE);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Creates a(n) (abstract) stereotype with the specified name as an owned stereotype of this profile.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param name The name for the new stereotype, or null.
* @param isAbstract Whether the new stereotype should be abstract.
* <!-- end-model-doc -->
* @generated NOT
*/
public static Stereotype createOwnedStereotype(
org.eclipse.uml2.uml.Package package_, String name,
boolean isAbstract) {
Stereotype ownedStereotype = (Stereotype) package_.createOwnedType(name,
UMLPackage.Literals.STEREOTYPE);
ownedStereotype.setIsAbstract(isAbstract);
return ownedStereotype;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Determines whether the specified profile is applied to this package.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param profile The profile in question.
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean isProfileApplied(
org.eclipse.uml2.uml.Package package_, Profile profile) {
return getProfileApplication(package_, profile) != null;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Derivation for Package::/ownedType
* result = (packagedElement->select(oclIsKindOf(Type))->collect(oclAsType(Type))->asSet())
* <p>From package UML::Packages.</p>
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<Type> getOwnedTypes(
org.eclipse.uml2.uml.Package package_) {
return package_.getOwnedTypes();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Applies the current definition of the specified profile to this package and automatically applies required stereotypes in the profile to elements within this package's namespace hieararchy. If a different definition is already applied, automatically migrates any associated stereotype values on a "best effort" basis (matching classifiers and structural features by name).
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param profile The profile to apply.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<EObject> applyProfile(
org.eclipse.uml2.uml.Package package_, Profile profile) {
return applyProfiles(package_, profile == null
? ECollections.<Profile> emptyEList()
: ECollections.singletonEList(profile));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Unapplies the specified profile from this package and automatically unapplies stereotypes in the profile from elements within this package's namespace hieararchy.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param profile The profile to unapply.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<EObject> unapplyProfile(
org.eclipse.uml2.uml.Package package_, Profile profile) {
if (profile == null) {
throw new IllegalArgumentException("null profile"); //$NON-NLS-1$
}
if (package_.getProfileApplication(profile) == null) {
throw new IllegalArgumentException(String.format(
"profile \"%s\" is not applied", profile.getQualifiedName())); //$NON-NLS-1$
}
EList<ProfileApplication> profileApplications = new UniqueEList.FastCompare<ProfileApplication>();
for (TreeIterator<EObject> allContents = getAllContents(package_, true,
false); allContents.hasNext();) {
EObject eObject = allContents.next();
if (eObject instanceof org.eclipse.uml2.uml.Package) {
for (ProfileApplication profileApplication : ((org.eclipse.uml2.uml.Package) eObject)
.getProfileApplications()) {
if (profileApplication.getAppliedProfile() == profile) {
profileApplications.add(profileApplication);
}
}
}
}
destroyAll(profileApplications);
return package_.getAllAppliedProfiles().contains(profile)
? ECollections.<EObject> emptyEList()
: unapplyAllNonApplicableStereotypes(package_);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Applies the current definitions of the specified profiles to this package and automatically applies required stereotypes in the profiles to elements within this package's namespace hieararchy. If different definitions are already applied, automatically migrates any associated stereotype values on a "best effort" basis (matching classifiers and structural features by name).
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param profiles The profiles to apply.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<EObject> applyProfiles(
org.eclipse.uml2.uml.Package package_, EList<Profile> profiles) {
if (profiles == null || profiles.isEmpty()) {
throw new IllegalArgumentException("No profile specified"); //$NON-NLS-1$
}
for (Profile profile : profiles) {
EPackage profileDefinition = profile.getDefinition();
if (profileDefinition == null) {
throw new IllegalArgumentException(
String.format("profile \"%s\" has no Ecore definition", //$NON-NLS-1$
profile.getQualifiedName()));
}
}
for (Profile profile : profiles) {
if (package_.getProfileApplication(profile) == null) {
package_.createProfileApplication().setAppliedProfile(profile);
}
}
EList<EObject> stereotypeApplications = new UniqueEList.FastCompare<EObject>();
StereotypeApplicationCopier copier = new StereotypeApplicationCopier(
profiles);
for (TreeIterator<EObject> allContents = getAllContents(package_, true,
false); allContents.hasNext();) {
EObject eObject = allContents.next();
if (eObject instanceof Element) {
Element element = (Element) eObject;
if (element instanceof org.eclipse.uml2.uml.Package) {
for (ProfileApplication profileApplication : ((org.eclipse.uml2.uml.Package) element)
.getProfileApplications()) {
Profile appliedProfile = profileApplication
.getAppliedProfile();
if (profiles.contains(appliedProfile)) {
EList<EObject> references = getEAnnotation(
profileApplication, UML2_UML_PACKAGE_2_0_NS_URI,
true).getReferences();
if (references.isEmpty()) {
references.add(appliedProfile.getDefinition());
} else {
references.set(0,
appliedProfile.getDefinition());
}
}
}
}
for (EObject stereotypeApplication : element
.getStereotypeApplications()) {
Stereotype stereotype = getStereotype(
stereotypeApplication);
if (stereotype != null
&& profiles.contains(stereotype.getProfile())) {
if (element.isStereotypeApplicable(stereotype)) {
EObject copy = copier.copy(stereotypeApplication);
Resource eResource = stereotypeApplication
.eResource();
if (eResource != null) {
EList<EObject> contents = eResource
.getContents();
if (eResource == copy.eResource()) {
contents.move(
contents.indexOf(stereotypeApplication),
copy);
} else {
contents.set(
contents.indexOf(stereotypeApplication),
copy);
}
}
}
stereotypeApplications.add(stereotypeApplication);
}
}
}
}
copier.copyReferences();
for (EObject key : copier.keySet()) {
EObject copy = copier.get(key);
Resource eResource = key.eResource();
if (eResource instanceof XMLResource) {
XMLResource xmlResource = (XMLResource) eResource;
String id = xmlResource.getID(key);
xmlResource.setID(key, null);
xmlResource.setID(copy, id);
}
for (Setting setting : new ArrayList<EStructuralFeature.Setting>(
getNonNavigableInverseReferences(key))) {
EObject eObject = setting.getEObject();
if (!copier.containsKey(eObject)) {
EStructuralFeature eStructuralFeature = setting
.getEStructuralFeature();
if (eStructuralFeature != null
&& eStructuralFeature.isChangeable()) {
if (eStructuralFeature.isMany()) {
Object value = eObject.eGet(eStructuralFeature);
@SuppressWarnings("unchecked")
EList<EObject> list = ((EList<EObject>) value);
list.set(list.indexOf(key), copy);
} else {
setting.set(copy);
}
}
}
}
}
destroyAll(stereotypeApplications);
for (Profile profile : profiles) {
if (profile.getOwnedExtensions(true).size() > 0) {
return applyAllRequiredStereotypes(package_);
}
}
return ECollections.<EObject> emptyEList();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query allApplicableStereotypes() returns all the directly or indirectly owned stereotypes, including stereotypes contained in sub-profiles.
* result = (let ownedPackages : Bag(Package) = ownedMember->select(oclIsKindOf(Package))->collect(oclAsType(Package)) in
* ownedStereotype->union(ownedPackages.allApplicableStereotypes())->flatten()->asSet()
* )
* <p>From package UML::Packages.</p>
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<Stereotype> allApplicableStereotypes(
org.eclipse.uml2.uml.Package package_) {
return allApplicableStereotypes(package_,
new UniqueEList.FastCompare<Stereotype>());
}
protected static EList<Stereotype> allApplicableStereotypes(
org.eclipse.uml2.uml.Package package_,
EList<Stereotype> allApplicableStereotypes) {
allApplicableStereotypes.addAll(package_.getOwnedStereotypes());
for (org.eclipse.uml2.uml.Package nestedPackage : package_
.getNestedPackages()) {
allApplicableStereotypes(nestedPackage, allApplicableStereotypes);
}
return allApplicableStereotypes;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query containingProfile() returns the closest profile directly or indirectly containing this package (or this package itself, if it is a profile).
* result = (if self.oclIsKindOf(Profile) then
* self.oclAsType(Profile)
* else
* self.namespace.oclAsType(Package).containingProfile()
* endif)
* <p>From package UML::Packages.</p>
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static Profile containingProfile(
org.eclipse.uml2.uml.Package package_) {
return (Profile) (package_ instanceof Profile
? package_
: getOwningElement(package_, UMLPackage.Literals.PROFILE, true));
}
protected static EList<Profile> getAppliedProfiles(
org.eclipse.uml2.uml.Package package_,
EList<Profile> appliedProfiles) {
for (ProfileApplication profileApplication : package_
.getProfileApplications()) {
Profile appliedProfile = profileApplication.getAppliedProfile();
if (appliedProfile != null) {
appliedProfiles.add(appliedProfile);
}
}
return appliedProfiles;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves the profiles that are applied to this package.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<Profile> getAppliedProfiles(
org.eclipse.uml2.uml.Package package_) {
return getAppliedProfiles(package_,
new UniqueEList.FastCompare<Profile>());
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves the profile with the specified qualified name that is applied to this package, or null if no such profile is applied.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param qualifiedName The qualified name of the applied profile to retrieve.
* <!-- end-model-doc -->
* @generated NOT
*/
public static Profile getAppliedProfile(
org.eclipse.uml2.uml.Package package_, String qualifiedName) {
for (ProfileApplication profileApplication : package_
.getProfileApplications()) {
Profile appliedProfile = profileApplication.getAppliedProfile();
if (appliedProfile != null && safeEquals(
appliedProfile.getQualifiedName(), qualifiedName)) {
return appliedProfile;
}
}
return null;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves the profile with the specified qualified name that is applied to this package or any of its nesting packages (if indicated), or null if no such profile is applied.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param qualifiedName The qualified name of the applied profile to retrieve.
* @param recurse Whether to look in nesting packages.
* <!-- end-model-doc -->
* @generated NOT
*/
public static Profile getAppliedProfile(
org.eclipse.uml2.uml.Package package_, String qualifiedName,
boolean recurse) {
Profile appliedProfile = package_.getAppliedProfile(qualifiedName);
if (appliedProfile == null && recurse) {
for (Iterator<org.eclipse.uml2.uml.Package> otherApplyingPackages = ProfileApplicationHelper
.getInstance(package_).getOtherApplyingPackages(package_)
.iterator(); otherApplyingPackages.hasNext()
&& appliedProfile == null;) {
appliedProfile = otherApplyingPackages.next()
.getAppliedProfile(qualifiedName);
}
}
return appliedProfile;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves all the profile applications for this package, including profile applications for its nesting package(s).
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<ProfileApplication> getAllProfileApplications(
org.eclipse.uml2.uml.Package package_) {
EList<ProfileApplication> allProfileApplications = new UniqueEList.FastCompare<ProfileApplication>(
package_.getProfileApplications());
for (org.eclipse.uml2.uml.Package applyingPackage : ProfileApplicationHelper
.getInstance(package_).getOtherApplyingPackages(package_)) {
allProfileApplications
.addAll(applyingPackage.getProfileApplications());
}
return ECollections.unmodifiableEList(allProfileApplications);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves the application of the specified profile to this package, or null if no such profile is applied.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param profile The profile whose application to retrieve.
* <!-- end-model-doc -->
* @generated NOT
*/
public static ProfileApplication getProfileApplication(
org.eclipse.uml2.uml.Package package_, Profile profile) {
for (ProfileApplication profileApplication : package_
.getProfileApplications()) {
if (profileApplication.getAppliedProfile() == profile) {
return profileApplication;
}
}
return null;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves the application of the specified profile to this package or any of its nesting packages (if indicated), or null if no such profile is applied.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param profile The profile whose application to retrieve.
* @param recurse Whether to look in nesting packages.
* <!-- end-model-doc -->
* @generated NOT
*/
public static ProfileApplication getProfileApplication(
org.eclipse.uml2.uml.Package package_, Profile profile,
boolean recurse) {
ProfileApplication profileApplication = package_
.getProfileApplication(profile);
if (profileApplication == null && recurse) {
for (Iterator<org.eclipse.uml2.uml.Package> otherApplyingPackages = ProfileApplicationHelper
.getInstance(package_).getOtherApplyingPackages(package_)
.iterator(); otherApplyingPackages.hasNext()
&& profileApplication == null;) {
profileApplication = otherApplyingPackages.next()
.getProfileApplication(profile);
}
}
return profileApplication;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Creates an interface with the specified name as an owned type of this package.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* @param name The name for the new interface, or null.
* <!-- end-model-doc -->
* @generated NOT
*/
public static Interface createOwnedInterface(
org.eclipse.uml2.uml.Package package_, String name) {
return (Interface) package_.createOwnedType(name,
UMLPackage.Literals.INTERFACE);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Determines whether this package is a model library.
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean isModelLibrary(
org.eclipse.uml2.uml.Package package_) {
return package_.getAppliedStereotype("StandardProfile" //$NON-NLS-1$
+ NamedElement.SEPARATOR + "ModelLibrary") != null; //$NON-NLS-1$
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves all the profiles that are applied to this package, including profiles applied to its nesting package(s).
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<Profile> getAllAppliedProfiles(
org.eclipse.uml2.uml.Package package_) {
EList<Profile> allAppliedProfiles = getAppliedProfiles(package_,
new UniqueEList.FastCompare<Profile>());
for (org.eclipse.uml2.uml.Package applyingPackage : ProfileApplicationHelper
.getInstance(package_).getOtherApplyingPackages(package_)) {
getAppliedProfiles(applyingPackage, allAppliedProfiles);
}
return ECollections.unmodifiableEList(allAppliedProfiles);
}
protected static EList<org.eclipse.uml2.uml.Package> getAllImportedPackages(
org.eclipse.uml2.uml.Package package_,
EList<org.eclipse.uml2.uml.Package> allImportedPackages) {
for (PackageImport packageImport : package_.getPackageImports()) {
if (packageImport
.getVisibility() == VisibilityKind.PUBLIC_LITERAL) {
org.eclipse.uml2.uml.Package importedPackage = packageImport
.getImportedPackage();
if (importedPackage != null
&& allImportedPackages.add(importedPackage)) {
getAllImportedPackages(importedPackage,
allImportedPackages);
}
}
}
return allImportedPackages;
}
protected static EList<PackageableElement> visibleMembers(
org.eclipse.uml2.uml.Package package_,
EList<PackageableElement> visibleMembers) {
for (NamedElement ownedMember : package_.getOwnedMembers()) {
if (ownedMember instanceof PackageableElement && ownedMember
.getVisibility() == VisibilityKind.PUBLIC_LITERAL) {
visibleMembers.add((PackageableElement) ownedMember);
}
}
for (ElementImport elementImport : package_.getElementImports()) {
if (elementImport
.getVisibility() == VisibilityKind.PUBLIC_LITERAL) {
PackageableElement importedElement = elementImport
.getImportedElement();
if (importedElement != null) {
visibleMembers.add(importedElement);
}
}
}
return visibleMembers;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query visibleMembers() defines which members of a Package can be accessed outside it.
* result = (member->select( m | m.oclIsKindOf(PackageableElement) and self.makesVisible(m))->collect(oclAsType(PackageableElement))->asSet())
* <p>From package UML::Packages.</p>
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<PackageableElement> visibleMembers(
org.eclipse.uml2.uml.Package package_) {
EList<PackageableElement> visibleMembers = visibleMembers(package_,
new UniqueEList.FastCompare<PackageableElement>());
for (org.eclipse.uml2.uml.Package importedPackage : getAllImportedPackages(
package_,
new UniqueEList.FastCompare<org.eclipse.uml2.uml.Package>())) {
visibleMembers(importedPackage, visibleMembers);
}
return ECollections.unmodifiableEList(visibleMembers);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query makesVisible() defines whether a Package makes an element visible outside itself. Elements with no visibility and elements with public visibility are made visible.
* member->includes(el)
* result = (ownedMember->includes(el) or
* (elementImport->select(ei|ei.importedElement = VisibilityKind::public)->collect(importedElement.oclAsType(NamedElement))->includes(el)) or
* (packageImport->select(visibility = VisibilityKind::public)->collect(importedPackage.member->includes(el))->notEmpty()))
* <p>From package UML::Packages.</p>
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean makesVisible(org.eclipse.uml2.uml.Package package_,
NamedElement el) {
if (package_.getOwnedMembers().contains(el)) {
return el.getVisibility() == VisibilityKind.PUBLIC_LITERAL;
}
for (ElementImport elementImport : package_.getElementImports()) {
if (safeEquals(elementImport.getImportedElement(), el)) {
return elementImport
.getVisibility() == VisibilityKind.PUBLIC_LITERAL;
}
}
for (PackageImport packageImport : package_.getPackageImports()) {
if (packageImport
.getVisibility() == VisibilityKind.PUBLIC_LITERAL) {
org.eclipse.uml2.uml.Package importedPackage = packageImport
.getImportedPackage();
return importedPackage != null
&& importedPackage.visibleMembers().contains(el);
}
}
return false;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Derivation for Package::/nestedPackage
* result = (packagedElement->select(oclIsKindOf(Package))->collect(oclAsType(Package))->asSet())
* <p>From package UML::Packages.</p>
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<org.eclipse.uml2.uml.Package> getNestedPackages(
org.eclipse.uml2.uml.Package package_) {
return package_.getNestedPackages();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Derivation for Package::/ownedStereotype
* result = (packagedElement->select(oclIsKindOf(Stereotype))->collect(oclAsType(Stereotype))->asSet())
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<Stereotype> getOwnedStereotypes(
org.eclipse.uml2.uml.Package package_) {
return package_.getOwnedStereotypes();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query mustBeOwned() indicates whether elements of this type must have an owner.
* result = (false)
* @param package_ The receiving '<em><b>Package</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean mustBeOwned(org.eclipse.uml2.uml.Package package_) {
return false;
}
protected static boolean containsSpecializations(
org.eclipse.uml2.uml.Package package_, Classifier classifier) {
for (Type ownedType : package_.getOwnedTypes()) {
if (ownedType instanceof Classifier
&& ((Classifier) ownedType).allParents().contains(classifier)) {
return true;
}
}
return false;
}
} // PackageOperations