| /* |
| * Copyright (c) 2005, 2006 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.9 2006/01/05 22:43:25 khussey Exp $ |
| */ |
| package org.eclipse.uml2.uml.internal.operations; |
| |
| import java.util.Iterator; |
| 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.util.InternalEList; |
| |
| import org.eclipse.uml2.uml.Classifier; |
| import org.eclipse.uml2.uml.Dependency; |
| import org.eclipse.uml2.uml.Feature; |
| import org.eclipse.uml2.uml.Generalization; |
| import org.eclipse.uml2.uml.Interface; |
| import org.eclipse.uml2.uml.NamedElement; |
| import org.eclipse.uml2.uml.Operation; |
| import org.eclipse.uml2.uml.Property; |
| import org.eclipse.uml2.uml.Usage; |
| |
| 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>Classifier</b></em>' model objects. |
| * <!-- end-user-doc --> |
| * |
| * <p> |
| * The following operations are supported: |
| * <ul> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#validateNoCyclesInGeneralization(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate No Cycles In Generalization</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#validateGeneralizationHierarchies(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Generalization Hierarchies</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#validateSpecializeType(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Specialize Type</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#validateMapsToGeneralizationSet(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Maps To Generalization Set</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#createGeneralization(org.eclipse.uml2.uml.Classifier) <em>Create Generalization</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#getAllAttributes() <em>Get All Attributes</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#getOperations() <em>Get Operations</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#getAllOperations() <em>Get All Operations</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#getOperation(java.lang.String) <em>Get Operation</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#getGenerals() <em>Get Generals</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#getInheritedMembers() <em>Get Inherited Members</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#allFeatures() <em>All Features</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#parents() <em>Parents</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#inheritableMembers(org.eclipse.uml2.uml.Classifier) <em>Inheritable Members</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#hasVisibilityOf(org.eclipse.uml2.uml.NamedElement) <em>Has Visibility Of</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#conformsTo(org.eclipse.uml2.uml.Classifier) <em>Conforms To</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#inherit(org.eclipse.emf.common.util.EList) <em>Inherit</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#maySpecializeType(org.eclipse.uml2.uml.Classifier) <em>May Specialize Type</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#allParents() <em>All Parents</em>}</li> |
| * <li>{@link org.eclipse.uml2.uml.Classifier#isTemplate() <em>Is Template</em>}</li> |
| * </ul> |
| * </p> |
| * |
| * @generated |
| */ |
| public class ClassifierOperations |
| extends NamespaceOperations { |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| protected ClassifierOperations() { |
| super(); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-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. |
| * not self.allParents()->includes(self) |
| * <!-- end-model-doc --> |
| * @generated |
| */ |
| public static boolean validateNoCyclesInGeneralization( |
| Classifier classifier, DiagnosticChain diagnostics, Map context) { |
| // TODO: implement this method |
| // -> specify the condition that violates the invariant |
| // -> verify the details of the diagnostic, including severity and message |
| // Ensure that you remove @generated or mark it @generated NOT |
| if (false) { |
| if (diagnostics != null) { |
| diagnostics |
| .add(new BasicDiagnostic( |
| Diagnostic.ERROR, |
| UMLValidator.DIAGNOSTIC_SOURCE, |
| UMLValidator.CLASSIFIER__NO_CYCLES_IN_GENERALIZATION, |
| org.eclipse.emf.ecore.plugin.EcorePlugin.INSTANCE |
| .getString( |
| "_UI_GenericInvariant_diagnostic", new Object[]{"validateNoCyclesInGeneralization", org.eclipse.emf.ecore.util.EObjectValidator.getObjectLabel(classifier, context)}), //$NON-NLS-1$ //$NON-NLS-2$ |
| new Object[]{classifier})); |
| } |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * A classifier may only specialize classifiers of a valid type. |
| * self.parents()->forAll(c | self.maySpecializeType(c)) |
| * <!-- end-model-doc --> |
| * @generated |
| */ |
| public static boolean validateSpecializeType(Classifier classifier, |
| DiagnosticChain diagnostics, Map context) { |
| // TODO: implement this method |
| // -> specify the condition that violates the invariant |
| // -> verify the details of the diagnostic, including severity and message |
| // Ensure that you remove @generated or mark it @generated NOT |
| if (false) { |
| if (diagnostics != null) { |
| diagnostics |
| .add(new BasicDiagnostic( |
| Diagnostic.ERROR, |
| UMLValidator.DIAGNOSTIC_SOURCE, |
| UMLValidator.CLASSIFIER__SPECIALIZE_TYPE, |
| org.eclipse.emf.ecore.plugin.EcorePlugin.INSTANCE |
| .getString( |
| "_UI_GenericInvariant_diagnostic", new Object[]{"validateSpecializeType", org.eclipse.emf.ecore.util.EObjectValidator.getObjectLabel(classifier, context)}), //$NON-NLS-1$ //$NON-NLS-2$ |
| new Object[]{classifier})); |
| } |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-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. |
| * not self.allParents()->includes(self) |
| * <!-- end-model-doc --> |
| * @generated |
| */ |
| public static boolean validateGeneralizationHierarchies( |
| Classifier classifier, DiagnosticChain diagnostics, Map context) { |
| // TODO: implement this method |
| // -> specify the condition that violates the invariant |
| // -> verify the details of the diagnostic, including severity and message |
| // Ensure that you remove @generated or mark it @generated NOT |
| if (false) { |
| if (diagnostics != null) { |
| diagnostics |
| .add(new BasicDiagnostic( |
| Diagnostic.ERROR, |
| UMLValidator.DIAGNOSTIC_SOURCE, |
| UMLValidator.CLASSIFIER__GENERALIZATION_HIERARCHIES, |
| org.eclipse.emf.ecore.plugin.EcorePlugin.INSTANCE |
| .getString( |
| "_UI_GenericInvariant_diagnostic", new Object[]{"validateGeneralizationHierarchies", org.eclipse.emf.ecore.util.EObjectValidator.getObjectLabel(classifier, context)}), //$NON-NLS-1$ //$NON-NLS-2$ |
| new Object[]{classifier})); |
| } |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The Classifier that maps to a GeneralizationSet may neither be a specific nor a general Classifier in any of the Generalization relationships defined for that GeneralizationSet. In other words, a power type may not be an instance of itself nor may its instances also be its subclasses. |
| * true |
| * <!-- end-model-doc --> |
| * @generated |
| */ |
| public static boolean validateMapsToGeneralizationSet( |
| Classifier classifier, DiagnosticChain diagnostics, Map context) { |
| // TODO: implement this method |
| // -> specify the condition that violates the invariant |
| // -> verify the details of the diagnostic, including severity and message |
| // Ensure that you remove @generated or mark it @generated NOT |
| if (false) { |
| if (diagnostics != null) { |
| diagnostics |
| .add(new BasicDiagnostic( |
| Diagnostic.ERROR, |
| UMLValidator.DIAGNOSTIC_SOURCE, |
| UMLValidator.CLASSIFIER__MAPS_TO_GENERALIZATION_SET, |
| org.eclipse.emf.ecore.plugin.EcorePlugin.INSTANCE |
| .getString( |
| "_UI_GenericInvariant_diagnostic", new Object[]{"validateMapsToGeneralizationSet", org.eclipse.emf.ecore.util.EObjectValidator.getObjectLabel(classifier, context)}), //$NON-NLS-1$ //$NON-NLS-2$ |
| new Object[]{classifier})); |
| } |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public static Generalization createGeneralization(Classifier classifier, |
| Classifier general) { |
| |
| if (general == null || general == classifier |
| || classifier.allParents().contains(general) |
| || general.allParents().contains(classifier)) { |
| |
| throw new IllegalArgumentException(String.valueOf(general)); |
| } |
| |
| Generalization generalization = classifier.createGeneralization(); |
| generalization.setGeneral(general); |
| |
| return generalization; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public static EList getAllAttributes(Classifier classifier) { |
| EList allAttributes = new UniqueEList(); |
| |
| for (Iterator allFeatures = classifier.allFeatures().iterator(); allFeatures |
| .hasNext();) { |
| |
| Object feature = allFeatures.next(); |
| |
| if (feature instanceof Property) { |
| allAttributes.add(feature); |
| } |
| } |
| |
| return ECollections.unmodifiableEList(allAttributes); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public static EList getOperations(Classifier classifier) { |
| EList operations = new UniqueEList(); |
| |
| for (Iterator features = classifier.getFeatures().iterator(); features |
| .hasNext();) { |
| |
| Object feature = features.next(); |
| |
| if (feature instanceof Operation) { |
| operations.add(feature); |
| } |
| } |
| |
| return ECollections.unmodifiableEList(operations); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public static EList getAllOperations(Classifier classifier) { |
| EList allOperations = new UniqueEList(); |
| |
| for (Iterator allFeatures = classifier.allFeatures().iterator(); allFeatures |
| .hasNext();) { |
| |
| Object feature = allFeatures.next(); |
| |
| if (feature instanceof Operation) { |
| allOperations.add(feature); |
| } |
| } |
| |
| return ECollections.unmodifiableEList(allOperations); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public static Operation getOperation(Classifier classifier, String name) { |
| |
| for (Iterator operations = classifier.getOperations().iterator(); operations |
| .hasNext();) { |
| |
| Operation operation = (Operation) operations.next(); |
| |
| if (safeEquals(operation.getName(), name)) { |
| return operation; |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The query maySpecializeType() determines whether this classifier may have a generalization relationship to classifiers of the specified type. By default a classifier may specialize classifiers of the same or a more general type. It is intended to be redefined by classifiers that have different specialization constraints. |
| * result = self.oclIsKindOf(c.oclType) |
| * <!-- 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 --> |
| * The general classifiers are the classifiers referenced by the generalization relationships. |
| * result = self.parents() |
| * <!-- end-model-doc --> |
| * @generated NOT |
| */ |
| public static EList getGenerals(Classifier classifier) { |
| return classifier.parents(); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The inheritedMember association is derived by inheriting the inheritable members of the parents. |
| * result = self.inherit(self.parents()->collect(p | p.inheritableMembers(self)) |
| * <!-- end-model-doc --> |
| * @generated NOT |
| */ |
| public static EList getInheritedMembers(Classifier classifier) { |
| EList inheritedMembers = new UniqueEList(); |
| |
| for (Iterator parents = classifier.parents().iterator(); parents |
| .hasNext();) { |
| |
| inheritedMembers.addAll(((Classifier) parents.next()) |
| .inheritableMembers(classifier)); |
| } |
| |
| return classifier.inherit(inheritedMembers); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The query allFeatures() gives all of the features in the namespace of the classifier. In general, through mechanisms such as inheritance, this will be a larger set than feature. |
| * result = member->select(oclIsKindOf(Feature)) |
| * <!-- end-model-doc --> |
| * @generated NOT |
| */ |
| public static EList allFeatures(Classifier classifier) { |
| EList allFeatures = new UniqueEList(); |
| |
| for (Iterator members = classifier.getMembers().iterator(); members |
| .hasNext();) { |
| |
| Object member = members.next(); |
| |
| if (member instanceof Feature) { |
| allFeatures.add(member); |
| } |
| } |
| |
| return ECollections.unmodifiableEList(allFeatures); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The query parents() gives all of the immediate ancestors of a generalized Classifier. |
| * result = generalization.general |
| * <!-- end-model-doc --> |
| * @generated NOT |
| */ |
| public static EList parents(Classifier classifier) { |
| EList parents = new UniqueEList(); |
| |
| for (Iterator generalizations = classifier.getGeneralizations() |
| .iterator(); generalizations.hasNext();) { |
| |
| Classifier general = ((Generalization) generalizations.next()) |
| .getGeneral(); |
| |
| if (general != null) { |
| parents.add(general); |
| } |
| } |
| |
| return ECollections.unmodifiableEList(parents); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The query inheritableMembers() gives all of the members of a classifier that may be inherited in one of its descendants, subject to whatever visibility restrictions apply. |
| * c.allParents()->includes(self) |
| * result = member->select(m | c.hasVisibilityOf(m)) |
| * <!-- end-model-doc --> |
| * @generated NOT |
| */ |
| public static EList inheritableMembers(Classifier classifier, Classifier c) { |
| EList inheritableMembers = new UniqueEList(); |
| |
| if (c == classifier || !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 ECollections.unmodifiableEList(inheritableMembers); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The query hasVisibilityOf() determines whether a named element is visible in the classifier. By default all are visible. It is only called when the argument is something owned by a parent. |
| * self.allParents()->collect(c | c.member)->includes(n) |
| * result = if (self.inheritedMember->includes(n)) then (n.visibility <> #private) else true |
| * <!-- 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 (parent != classifier && parent.getMembers().contains(n)) { |
| return n.getVisibility() != VisibilityKind.PRIVATE_LITERAL; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The query conformsTo() gives true for a classifier that defines a type that conforms to another. This is used, for example, in the specification of signature conformance for operations. |
| * result = (self=other) or (self.allParents()->includes(other)) |
| * <!-- end-model-doc --> |
| * @generated NOT |
| */ |
| public static boolean conformsTo(Classifier classifier, Classifier other) { |
| return classifier == other || classifier.allParents().contains(other); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The inherit operation is overridden to exclude redefined properties. |
| * The query inherit() defines how to inherit a set of elements. Here the operation is defined to inherit them all. It is intended to be redefined in circumstances where inheritance is affected by redefinition. |
| * result = inhs |
| * <!-- end-model-doc --> |
| * @generated NOT |
| */ |
| public static EList inherit(Classifier classifier, EList inhs) { |
| return ECollections.unmodifiableEList(inhs); |
| } |
| |
| protected static EList allParents(Classifier classifier, EList allParents) { |
| |
| for (Iterator parents = classifier.parents().iterator(); parents |
| .hasNext();) { |
| |
| Classifier parent = (Classifier) parents.next(); |
| |
| if (allParents.add(parent)) { |
| allParents(parent, allParents); |
| } |
| } |
| |
| return allParents; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The query allParents() gives all of the direct and indirect ancestors of a generalized Classifier. |
| * result = self.parents()->union(self.parents()->collect(p | p.allParents()) |
| * <!-- end-model-doc --> |
| * @generated NOT |
| */ |
| public static EList allParents(Classifier classifier) { |
| return ECollections.unmodifiableEList(allParents(classifier, |
| new UniqueEList())); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * <!-- begin-model-doc --> |
| * The query isTemplate() returns whether this templateable element is actually a template. |
| * result = oclAsType(TemplatableElement).isTemplate() or general->exists(g | g.isTemplate()) |
| * <!-- end-model-doc --> |
| * @generated NOT |
| */ |
| public static boolean isTemplate(Classifier classifier) { |
| |
| if (classifier.getOwnedSignature() == null) { |
| |
| for (Iterator allParents = classifier.allParents().iterator(); allParents |
| .hasNext();) { |
| |
| if (((Classifier) allParents.next()).getOwnedSignature() != null) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| protected static EList getUsedInterfaces(Classifier classifier, |
| EList usedInterfaces) { |
| |
| for (Iterator clientDependencies = classifier.getClientDependencies() |
| .iterator(); clientDependencies.hasNext();) { |
| |
| Dependency dependency = (Dependency) clientDependencies.next(); |
| |
| if (dependency instanceof Usage) { |
| |
| for (Iterator suppliers = ((InternalEList) dependency |
| .getSuppliers()).basicIterator(); suppliers.hasNext();) { |
| |
| Object supplier = suppliers.next(); |
| |
| if (supplier instanceof Interface) { |
| usedInterfaces.add(supplier); |
| } |
| } |
| } |
| } |
| |
| return usedInterfaces; |
| } |
| |
| protected static EList getAllUsedInterfaces(Classifier classifier, |
| EList allUsedInterfaces) { |
| getUsedInterfaces(classifier, allUsedInterfaces); |
| |
| for (Iterator allParents = classifier.allParents().iterator(); allParents |
| .hasNext();) { |
| |
| getUsedInterfaces((Classifier) allParents.next(), allUsedInterfaces); |
| } |
| |
| return allUsedInterfaces; |
| } |
| |
| } // ClassifierOperations |