blob: 4adf614f8af119ad7f467a7b6e5430e3a775c1ab [file] [log] [blame]
/*
* Copyright (c) 2003, 2005 IBM Corporation 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
*
* $Id: ClassifierOperations.java,v 1.11.2.1 2005/08/17 20:53:53 khussey Exp $
*/
package org.eclipse.uml2.internal.operation;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.uml2.Classifier;
import org.eclipse.uml2.Dependency;
import org.eclipse.uml2.Feature;
import org.eclipse.uml2.Generalization;
import org.eclipse.uml2.Interface;
import org.eclipse.uml2.NamedElement;
import org.eclipse.uml2.UML2Plugin;
import org.eclipse.uml2.Usage;
import org.eclipse.uml2.VisibilityKind;
import org.eclipse.uml2.util.UML2Validator;
/**
* <!-- begin-user-doc -->
* A static utility class that provides operations related to '<em><b>Classifier</b></em>' model objects.
* <!-- end-user-doc -->
*
* <p>
* The following operations are supported:
* <ul>
* <li>{@link org.eclipse.uml2.Classifier#allFeatures() <em>All Features</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#validateNoCyclesInGeneralization(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate No Cycles In Generalization</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#validateSpecializeType(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Specialize Type</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#validateInheritedMember(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Inherited Member</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#inheritedMember() <em>Inherited Member</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#parents() <em>Parents</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#allParents() <em>All Parents</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#inheritableMembers(org.eclipse.uml2.Classifier) <em>Inheritable Members</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#hasVisibilityOf(org.eclipse.uml2.NamedElement) <em>Has Visibility Of</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#inherit(java.util.Set) <em>Inherit</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#maySpecializeType(org.eclipse.uml2.Classifier) <em>May Specialize Type</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#general() <em>General</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#validateGeneralEqualsParents(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate General Equals Parents</em>}</li>
* <li>{@link org.eclipse.uml2.Classifier#conformsTo(org.eclipse.uml2.Classifier) <em>Conforms To</em>}</li>
* </ul>
* </p>
*
* @generated not
*/
public final class ClassifierOperations extends UML2Operations {
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public static final String copyright = "Copyright (c) IBM Corporation and others."; //$NON-NLS-1$
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
private ClassifierOperations() {
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* member->select(oclIsKindOf(Feature))
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static Set allFeatures(Classifier classifier) {
Set allFeatures = new HashSet();
for (Iterator members = classifier.getMembers().iterator(); members
.hasNext();) {
NamedElement member = (NamedElement) members.next();
if (Feature.class.isInstance(member)) {
allFeatures.add(member);
}
}
return Collections.unmodifiableSet(allFeatures);
}
/**
* <!-- begin-user-doc -->
* Generalization hierarchies must be directed and acyclical. A classifier
* can not be both a transitively general and transitively specific
* classifier of the same classifier.
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* An invariant constraint based on the following OCL expression:
* <code>
* not self.allParents()->includes(self)
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean validateNoCyclesInGeneralization(Classifier classifier, DiagnosticChain diagnostics, Map context) {
boolean result = true;
if (classifier.allParents().contains(classifier)) {
result = false;
if (null != diagnostics) {
diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING,
UML2Validator.DIAGNOSTIC_SOURCE,
UML2Validator.CLASSIFIER__NO_CYCLES_IN_GENERALIZATION,
UML2Plugin.INSTANCE.getString(
"_UI_Classifier_NoCyclesInGeneralization_diagnostic", //$NON-NLS-1$
getMessageSubstitutions(context, classifier)),
new Object[]{classifier}));
}
}
return result;
}
/**
* <!-- begin-user-doc -->
* A classifier may only specialize classifiers of a valid type.
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* An invariant constraint based on the following OCL expression:
* <code>
* self.parents()->forAll(c | self.maySpecializeType(c))
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean validateSpecializeType(Classifier classifier, DiagnosticChain diagnostics, Map context) {
boolean result = true;
for (Iterator parents = classifier.parents().iterator(); parents
.hasNext();) {
Classifier parent = (Classifier) parents.next();
if (!classifier.maySpecializeType(parent)) {
result = false;
if (null == diagnostics) {
return result;
} else {
diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING,
UML2Validator.DIAGNOSTIC_SOURCE,
UML2Validator.CLASSIFIER__SPECIALIZE_TYPE,
UML2Plugin.INSTANCE.getString(
"_UI_Classifier_SpecializeType_diagnostic", //$NON-NLS-1$
getMessageSubstitutions(context,
classifier, parent)), new Object[]{classifier,
parent}));
}
}
}
return result;
}
/**
* <!-- begin-user-doc -->
* The inherited members are derived by inheriting the inheritable members
* of the parents.
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* An invariant constraint based on the following OCL expression:
* <code>
* self.inheritedMember->includesAll(self.inherit(self.parents()->collect(p | p.inheritableMembers(self)))
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean validateInheritedMember(Classifier classifier, DiagnosticChain diagnostics, Map context) {
boolean result = true;
Set inheritedMember = new HashSet();
for (Iterator parents = classifier.parents().iterator(); parents
.hasNext();) {
inheritedMember.addAll(((Classifier) parents.next())
.inheritableMembers(classifier));
}
if (!classifier.inheritedMember().containsAll(
classifier.inherit(inheritedMember))) {
result = false;
if (null != diagnostics) {
diagnostics.add(new BasicDiagnostic(Diagnostic.ERROR,
UML2Validator.DIAGNOSTIC_SOURCE,
UML2Validator.CLASSIFIER__INHERITED_MEMBER,
UML2Plugin.INSTANCE.getString(
"_UI_Classifier_InheritedMember_diagnostic", //$NON-NLS-1$
getMessageSubstitutions(context, classifier)),
new Object[]{classifier}));
}
}
return result;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* self.inherit(self.parents()->collect(p | p.inheritableMembers(self))
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static Set inheritedMember(Classifier classifier) {
Set inheritedMember = new HashSet();
for (Iterator parents = classifier.parents().iterator(); parents
.hasNext();) {
inheritedMember.addAll(((Classifier) parents.next())
.inheritableMembers(classifier));
}
return classifier.inherit(inheritedMember);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* generalization.general
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static Set parents(Classifier classifier) {
Set parents = new HashSet();
for (Iterator generalizations = classifier.getGeneralizations()
.iterator(); generalizations.hasNext();) {
Classifier general = ((Generalization) generalizations.next())
.getGeneral();
if (null != general) {
parents.add(general);
}
}
return Collections.unmodifiableSet(parents);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* self.parents()->union(self.parents()->collect(p | p.allParents())
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static Set allParents(Classifier classifier) {
Set allParents = new HashSet();
allParentsHelper(classifier, allParents);
return Collections.unmodifiableSet(allParents);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* member->select(m | c.hasVisibilityOf(m))
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static Set inheritableMembers(Classifier classifier, Classifier c) {
Set inheritableMembers = new HashSet();
if (classifier == c || !c.allParents().contains(classifier)
|| classifier.allParents().contains(c)) {
return inheritableMembers;
}
for (Iterator members = classifier.getMembers().iterator(); members
.hasNext();) {
NamedElement member = (NamedElement) members.next();
if (c.hasVisibilityOf(member)) {
inheritableMembers.add(member);
}
}
return Collections.unmodifiableSet(inheritableMembers);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* true
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean hasVisibilityOf(Classifier classifier, NamedElement n) {
for (Iterator allParents = classifier.allParents().iterator(); allParents
.hasNext();) {
Classifier parent = (Classifier) allParents.next();
if (classifier != parent && parent.getMembers().contains(n)) {
return VisibilityKind.PRIVATE_LITERAL != n.getVisibility();
}
}
return false;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* inhs
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static Set inherit(Classifier classifier, Set inhs) {
return Collections.unmodifiableSet(inhs);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* self.oclIsKindOf(c.oclType)
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean maySpecializeType(Classifier classifier, Classifier c) {
return c.eClass().isSuperTypeOf(classifier.eClass());
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* self.parents()
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static Set general(Classifier classifier) {
return classifier.parents();
}
/**
* <!-- begin-user-doc -->
* The general classifiers are the classifiers referenced by the
* generalization relationships.
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* An invariant constraint based on the following OCL expression:
* <code>
* general = self.parents()
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean validateGeneralEqualsParents(Classifier classifier, DiagnosticChain diagnostics, Map context) {
boolean result = true;
if (!classifier.general().equals(classifier.parents())) {
result = false;
if (null != diagnostics) {
diagnostics.add(new BasicDiagnostic(Diagnostic.ERROR,
UML2Validator.DIAGNOSTIC_SOURCE,
UML2Validator.CLASSIFIER__GENERAL_EQUALS_PARENTS,
UML2Plugin.INSTANCE.getString(
"_UI_Classifier_GeneralEqualsParents_diagnostic", //$NON-NLS-1$
getMessageSubstitutions(context, classifier)),
new Object[]{classifier}));
}
}
return result;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A query based on the following OCL expression:
* <code>
* (self=other) or (self.allParents()->includes(other))
* </code>
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean conformsTo(Classifier classifier, Classifier other) {
return classifier == other || classifier.allParents().contains(other);
}
// <!-- begin-custom-operations -->
protected static void allParentsHelper(Classifier classifier, Set allParents) {
for (Iterator parents = classifier.parents().iterator(); parents
.hasNext();) {
Classifier parent = (Classifier) parents.next();
if (!allParents.contains(parent)) {
allParents.add(parent);
allParentsHelper(parent, allParents);
}
}
}
/**
* Creates a generalization between the specified classifier and the
* specified general classifier.
*
* @param classifier
* The classifier from which to create a generalization.
* @param generalClassifier
* The classifier to which to create a generalization.
* @return The new generalization.
* @exception IllegalArgumentException
* If the classifiers are identical or if either of the
* classifiers is already a direct or indirect parent of the
* other.
*/
public static Generalization createGeneralization(Classifier classifier,
Classifier generalClassifier) {
if (null == classifier) {
throw new IllegalArgumentException(String.valueOf(classifier));
}
if (null == generalClassifier || classifier == generalClassifier
|| classifier.allParents().contains(generalClassifier)
|| generalClassifier.allParents().contains(classifier)) {
throw new IllegalArgumentException(String
.valueOf(generalClassifier));
}
Generalization generalization = classifier.createGeneralization();
generalization.setGeneral(generalClassifier);
return generalization;
}
/**
* Retrieves the interfaces on which the specified classifier has a usage
* dependency.
*
* @param classifier
* The classfier for which to retrieve the useed interfaces.
* @return The interfaces used by the specified classifier.
*/
public static Set getUsedInterfaces(Classifier classifier) {
Set usedInterfaces = new HashSet();
if (null != classifier) {
for (Iterator clientDependencies = classifier
.getClientDependencies().iterator(); clientDependencies
.hasNext();) {
Dependency clientDependency = (Dependency) clientDependencies
.next();
if (Usage.class.isInstance(clientDependency)) {
for (Iterator suppliers = clientDependency.getSuppliers()
.iterator(); suppliers.hasNext();) {
NamedElement supplier = (NamedElement) suppliers.next();
if (Interface.class.isInstance(supplier)) {
usedInterfaces.add(supplier);
}
}
}
}
}
return usedInterfaces;
}
// <!-- end-custom-operations -->
} // ClassifierOperations