blob: 42978911b7a1b1fd2dc9e7583af99aa4b201da82 [file] [log] [blame]
/*
* Copyright (c) 2005, 2011 IBM Corporation, CEA, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - initial API and implementation
* Kenn Hussey - 323181
* Kenn Hussey (CEA) - 327039
*
* $Id: NamespaceOperations.java,v 1.16 2010/09/28 21:02:15 khussey Exp $
*/
package org.eclipse.uml2.uml.internal.operations;
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.UniqueEList;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.uml2.common.util.UnionEObjectEList;
import org.eclipse.uml2.uml.ElementImport;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Namespace;
import org.eclipse.uml2.uml.PackageImport;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.UMLPlugin;
import org.eclipse.uml2.uml.VisibilityKind;
import org.eclipse.uml2.uml.util.UMLValidator;
/**
* <!-- begin-user-doc -->
* A static utility class that provides operations related to '<em><b>Namespace</b></em>' model objects.
* <!-- end-user-doc -->
*
* <p>
* The following operations are supported:
* <ul>
* <li>{@link org.eclipse.uml2.uml.Namespace#validateMembersDistinguishable(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Members Distinguishable</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#createElementImport(org.eclipse.uml2.uml.PackageableElement, org.eclipse.uml2.uml.VisibilityKind) <em>Create Element Import</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#createPackageImport(org.eclipse.uml2.uml.Package, org.eclipse.uml2.uml.VisibilityKind) <em>Create Package Import</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#getImportedElements() <em>Get Imported Elements</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#getImportedPackages() <em>Get Imported Packages</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#excludeCollisions(org.eclipse.emf.common.util.EList) <em>Exclude Collisions</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#getNamesOfMember(org.eclipse.uml2.uml.NamedElement) <em>Get Names Of Member</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#importMembers(org.eclipse.emf.common.util.EList) <em>Import Members</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#getImportedMembers() <em>Get Imported Members</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#membersAreDistinguishable() <em>Members Are Distinguishable</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Namespace#getOwnedMembers() <em>Get Owned Members</em>}</li>
* </ul>
* </p>
*
* @generated
*/
public class NamespaceOperations
extends NamedElementOperations {
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected NamespaceOperations() {
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* All the members of a Namespace are distinguishable within it.
* membersAreDistinguishable()
* @param namespace The receiving '<em><b>Namespace</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 validateMembersDistinguishable(Namespace namespace,
DiagnosticChain diagnostics, Map<Object, Object> context) {
boolean result = true;
if (!namespace.membersAreDistinguishable()) {
result = false;
if (diagnostics != null) {
diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING,
UMLValidator.DIAGNOSTIC_SOURCE,
UMLValidator.NAMESPACE__MEMBERS_DISTINGUISHABLE,
UMLPlugin.INSTANCE.getString(
"_UI_Namespace_MembersDistinguishable_diagnostic", //$NON-NLS-1$
getMessageSubstitutions(context, namespace)),
new Object[]{namespace}));
}
}
return result;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Creates an import of the specified element into this namespace with the specified visibility.
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* @param element The element to import.
* @param visibility The visibility for the new element import.
* <!-- end-model-doc -->
* @generated NOT
*/
public static ElementImport createElementImport(Namespace namespace,
PackageableElement element, VisibilityKind visibility) {
if (element == null
|| namespace.getImportedElements().contains(element)) {
throw new IllegalArgumentException(String.valueOf(element));
}
if (visibility == null) {
throw new IllegalArgumentException(String.valueOf(visibility));
}
ElementImport elementImport = namespace.createElementImport(element);
elementImport.setVisibility(visibility);
return elementImport;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Creates an import of the specified package into this namespace with the specified visibility.
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* @param package_ The package to import.
* @param visibility The visibility for the new package import.
* <!-- end-model-doc -->
* @generated NOT
*/
public static PackageImport createPackageImport(Namespace namespace,
org.eclipse.uml2.uml.Package package_, VisibilityKind visibility) {
if (package_ == null
|| namespace.getImportedPackages().contains(package_)) {
throw new IllegalArgumentException(String.valueOf(package_));
}
if (visibility == null) {
throw new IllegalArgumentException(String.valueOf(visibility));
}
PackageImport packageImport = namespace.createPackageImport(package_);
packageImport.setVisibility(visibility);
return packageImport;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves the elements imported by this namespace.
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<PackageableElement> getImportedElements(
Namespace namespace) {
EList<PackageableElement> importedElements = new UniqueEList.FastCompare<PackageableElement>();
for (ElementImport elementImport : namespace.getElementImports()) {
PackageableElement importedElement = elementImport
.getImportedElement();
if (importedElement != null) {
importedElements.add(importedElement);
}
}
return ECollections.unmodifiableEList(importedElements);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves the packages imported by this namespace.
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<org.eclipse.uml2.uml.Package> getImportedPackages(
Namespace namespace) {
EList<org.eclipse.uml2.uml.Package> importedPackages = new UniqueEList.FastCompare<org.eclipse.uml2.uml.Package>();
for (PackageImport packageImport : namespace.getPackageImports()) {
org.eclipse.uml2.uml.Package importedPackage = packageImport
.getImportedPackage();
if (importedPackage != null) {
importedPackages.add(importedPackage);
}
}
return ECollections.unmodifiableEList(importedPackages);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The importedMember property is derived from the ElementImports and the PackageImports. References the PackageableElements that are members of this Namespace as a result of either PackageImports or ElementImports.
* result = self.importMembers(self.elementImport.importedElement.asSet()-
* >union(self.packageImport.importedPackage->collect(p | p.visibleMembers())))
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<PackageableElement> getImportedMembers(
Namespace namespace) {
EList<PackageableElement> importedMembers = new UniqueEList.FastCompare<PackageableElement>();
for (ElementImport elementImport : namespace.getElementImports()) {
PackageableElement importedElement = elementImport
.getImportedElement();
if (importedElement != null) {
importedMembers.add(importedElement);
}
}
for (PackageImport packageImport : namespace.getPackageImports()) {
org.eclipse.uml2.uml.Package importedPackage = packageImport
.getImportedPackage();
if (importedPackage != null) {
importedMembers.addAll(importedPackage.visibleMembers());
}
}
return new UnionEObjectEList<PackageableElement>(
(InternalEObject) namespace,
UMLPackage.Literals.NAMESPACE__IMPORTED_MEMBER,
importedMembers.size(), importedMembers.toArray());
}
protected static EList<String> getNamesOfMember(Namespace namespace,
NamedElement element, EList<Namespace> namespaces,
EList<String> namesOfMember) {
if (!namespaces.contains(namespace)) {
namespaces.add(namespace);
if (namespace.getOwnedMembers().contains(element)) {
String name = element.getName();
if (!isEmpty(name)) {
namesOfMember.add(name);
}
} else {
EList<String> elementImportNames = new UniqueEList<String>();
for (ElementImport elementImport : namespace
.getElementImports()) {
if (elementImport.getImportedElement() == element) {
String name = elementImport.getName();
if (!isEmpty(name)) {
elementImportNames.add(name);
}
}
}
if (elementImportNames.isEmpty()) {
for (PackageImport packageImport : namespace
.getPackageImports()) {
org.eclipse.uml2.uml.Package importedPackage = packageImport
.getImportedPackage();
if (importedPackage != null
&& importedPackage.visibleMembers().contains(
element)) {
getNamesOfMember(importedPackage, element,
namespaces, namesOfMember);
}
}
} else {
namesOfMember.addAll(elementImportNames);
}
}
}
return namesOfMember;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query getNamesOfMember() takes importing into account. It gives back the set of names that an element would have in an importing namespace, either because it is owned, or if not owned then imported individually, or if not individually then from a package.
* The query getNamesOfMember() gives a set of all of the names that a member would have in a Namespace. In general a member can have multiple names in a Namespace if it is imported more than once with different aliases. The query takes account of importing. It gives back the set of names that an element would have in an importing namespace, either because it is owned, or if not owned then imported individually, or if not individually then from a package.
* result = if self.ownedMember ->includes(element)
* then Set{}->include(element.name)
* else let elementImports: ElementImport = self.elementImport->select(ei | ei.importedElement = element) in
* if elementImports->notEmpty()
* then elementImports->collect(el | el.getName())
* else self.packageImport->select(pi | pi.importedPackage.visibleMembers()->includes(element))-> collect(pi | pi.importedPackage.getNamesOfMember(element))
* endif
* endif
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<String> getNamesOfMember(Namespace namespace,
NamedElement element) {
return ECollections.unmodifiableEList(getNamesOfMember(namespace,
element, new UniqueEList.FastCompare<Namespace>(),
new UniqueEList<String>()));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The Boolean query membersAreDistinguishable() determines whether all of the namespace's members are distinguishable within it.
* result = self.member->forAll( memb |
* self.member->excluding(memb)->forAll(other |
* memb.isDistinguishableFrom(other, self)))
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean membersAreDistinguishable(Namespace namespace) {
EList<NamedElement> namespaceMembers = namespace.getMembers();
for (NamedElement member : namespaceMembers) {
for (NamedElement otherMember : namespaceMembers) {
if (member != otherMember
&& !member.isDistinguishableFrom(otherMember, namespace)) {
return false;
}
}
}
return true;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Missing derivation for Namespace::/ownedMember : NamedElement
* true
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<NamedElement> getOwnedMembers(Namespace namespace) {
return namespace.getOwnedMembers();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query importMembers() defines which of a set of PackageableElements are actually imported into the namespace. This excludes hidden ones, i.e., those which have names that conflict with names of owned members, and also excludes elements which would have the same name when imported.
* result = self.excludeCollisions(imps)->select(imp | self.ownedMember->forAll(mem |
* mem.imp.isDistinguishableFrom(mem, self)))
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<PackageableElement> importMembers(Namespace namespace,
EList<PackageableElement> imps) {
EList<PackageableElement> importMembers = new UniqueEList.FastCompare<PackageableElement>();
EList<NamedElement> ownedMembers = namespace.getOwnedMembers();
excludeCollisionsLoop : for (PackageableElement excludeCollision : namespace
.excludeCollisions(imps)) {
for (NamedElement ownedMember : ownedMembers) {
if (!excludeCollision.isDistinguishableFrom(ownedMember,
namespace)) {
continue excludeCollisionsLoop;
}
}
importMembers.add(excludeCollision);
}
return ECollections.unmodifiableEList(importMembers);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query excludeCollisions() excludes from a set of PackageableElements any that would not be distinguishable from each other in this namespace.
* result = imps->reject(imp1 | imps.exists(imp2 | not imp1.isDistinguishableFrom(imp2, self)))
* @param namespace The receiving '<em><b>Namespace</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<PackageableElement> excludeCollisions(
Namespace namespace, EList<PackageableElement> imps) {
EList<PackageableElement> excludeCollisions = new UniqueEList.FastCompare<PackageableElement>();
imps1Loop : for (PackageableElement imp1 : imps) {
for (PackageableElement imp2 : imps) {
if (imp1 != imp2
&& !imp1.isDistinguishableFrom(imp2, namespace)) {
continue imps1Loop;
}
}
excludeCollisions.add(imp1);
}
return ECollections.unmodifiableEList(excludeCollisions);
}
} // NamespaceOperations