blob: f960a8b0a9499d8873033304a5e81c700e4f7e3d [file] [log] [blame]
/*
* Copyright (c) 2005, 2018 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 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 (CEA) - 327039, 295864, 418466, 433204, 451350, 485756
* Kenn Hussey - 535301
*
*/
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.uml2.uml.Operation;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.ParameterDirectionKind;
import org.eclipse.uml2.uml.RedefinableElement;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.UMLPlugin;
import org.eclipse.uml2.uml.util.UMLValidator;
/**
* <!-- begin-user-doc -->
* A static utility class that provides operations related to '<em><b>Operation</b></em>' model objects.
* <!-- end-user-doc -->
*
* <p>
* The following operations are supported:
* </p>
* <ul>
* <li>{@link org.eclipse.uml2.uml.Operation#validateAtMostOneReturn(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate At Most One Return</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#validateOnlyBodyForQuery(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Only Body For Query</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#getReturnResult() <em>Get Return Result</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#setIsOrdered(boolean) <em>Set Is Ordered</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#setIsUnique(boolean) <em>Set Is Unique</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#setLower(int) <em>Set Lower</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#setType(org.eclipse.uml2.uml.Type) <em>Set Type</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#setUpper(int) <em>Set Upper</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#isOrdered() <em>Is Ordered</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#isUnique() <em>Is Unique</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#getLower() <em>Get Lower</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#returnResult() <em>Return Result</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#getType() <em>Get Type</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#getUpper() <em>Get Upper</em>}</li>
* <li>{@link org.eclipse.uml2.uml.Operation#isConsistentWith(org.eclipse.uml2.uml.RedefinableElement) <em>Is Consistent With</em>}</li>
* </ul>
*
* @generated
*/
public class OperationOperations
extends BehavioralFeatureOperations {
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected OperationOperations() {
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* An Operation can have at most one return parameter; i.e., an owned parameter with the direction set to 'return.'
* self.ownedParameter->select(direction = ParameterDirectionKind::return)->size() <= 1
* @param operation The receiving '<em><b>Operation</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 validateAtMostOneReturn(Operation operation,
DiagnosticChain diagnostics, Map<Object, Object> context) {
boolean result = true;
int count = 0;
for (Parameter ownedParameter : operation.getOwnedParameters()) {
if (ownedParameter
.getDirection() == ParameterDirectionKind.RETURN_LITERAL) {
count++;
}
}
if (count > 1) {
result = false;
if (diagnostics != null) {
diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING,
UMLValidator.DIAGNOSTIC_SOURCE,
UMLValidator.OPERATION__AT_MOST_ONE_RETURN,
UMLPlugin.INSTANCE.getString(
"_UI_Operation_AtMostOneReturn_diagnostic", //$NON-NLS-1$
getMessageSubstitutions(context, operation)),
new Object[]{operation}));
}
}
return result;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* A bodyCondition can only be specified for a query Operation.
* bodyCondition <> null implies isQuery
* @param operation The receiving '<em><b>Operation</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 validateOnlyBodyForQuery(Operation operation,
DiagnosticChain diagnostics, Map<Object, Object> context) {
boolean result = true;
if (operation.getBodyCondition() != null && !operation.isQuery()) {
result = false;
if (diagnostics != null) {
diagnostics.add(new BasicDiagnostic(Diagnostic.WARNING,
UMLValidator.DIAGNOSTIC_SOURCE,
UMLValidator.OPERATION__ONLY_BODY_FOR_QUERY,
UMLPlugin.INSTANCE.getString(
"_UI_Operation_OnlyBodyForQuery_diagnostic", //$NON-NLS-1$
getMessageSubstitutions(context, operation)),
new Object[]{operation}));
}
}
return result;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* If this operation has a return parameter, isOrdered equals the value of isOrdered for that parameter. Otherwise isOrdered is false.
* result = (if returnResult()->notEmpty() then returnResult()-> exists(isOrdered) else false endif)
* <p>From package UML::Classification.</p>
* @param operation The receiving '<em><b>Operation</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean isOrdered(Operation operation) {
Parameter returnResult = operation.getReturnResult();
return returnResult != null
? returnResult.isOrdered()
: false;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* If this operation has a return parameter, isUnique equals the value of isUnique for that parameter. Otherwise isUnique is true.
* result = (if returnResult()->notEmpty() then returnResult()->exists(isUnique) else true endif)
* @param operation The receiving '<em><b>Operation</b></em>' model object.
* <p>From package UML::Classification.</p>
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean isUnique(Operation operation) {
Parameter returnResult = operation.getReturnResult();
return returnResult != null
? returnResult.isUnique()
: true;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* If this operation has a return parameter, type equals the value of type for that parameter. Otherwise type has no value.
* result = (if returnResult()->notEmpty() then returnResult()->any(true).type else null endif)
* @param operation The receiving '<em><b>Operation</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static Type getType(Operation operation) {
Parameter returnResult = operation.getReturnResult();
return returnResult != null
? (Type) returnResult.eGet(UMLPackage.Literals.TYPED_ELEMENT__TYPE,
false)
: null;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query returnResult() returns the set containing the return parameter of the Operation if one exists, otherwise, it returns an empty set
* result = (ownedParameter->select (direction = ParameterDirectionKind::return)->asSet())
* <p>From package UML::Classification.</p>
* @param operation The receiving '<em><b>Operation</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static EList<Parameter> returnResult(Operation operation) {
EList<Parameter> returnResult = new UniqueEList.FastCompare<Parameter>();
for (Parameter ownedParameter : operation.getOwnedParameters()) {
if (ownedParameter
.getDirection() == ParameterDirectionKind.RETURN_LITERAL) {
returnResult.add(ownedParameter);
}
}
return ECollections.unmodifiableEList(returnResult);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public static int getLower(Operation operation) {
Parameter returnResult = operation.getReturnResult();
return returnResult != null
? returnResult.getLower()
: 1;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public static int getUpper(Operation operation) {
Parameter returnResult = operation.getReturnResult();
return returnResult != null
? returnResult.getUpper()
: 1;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public static void setIsOrdered(Operation operation, boolean newIsOrdered) {
Parameter returnResult = operation.getReturnResult();
if (returnResult == null) {
returnResult = operation.createOwnedParameter(null, null);
returnResult.setDirection(ParameterDirectionKind.RETURN_LITERAL);
}
returnResult.setIsOrdered(newIsOrdered);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public static void setIsUnique(Operation operation, boolean newIsUnique) {
Parameter returnResult = operation.getReturnResult();
if (returnResult == null) {
returnResult = operation.createOwnedParameter(null, null);
returnResult.setDirection(ParameterDirectionKind.RETURN_LITERAL);
}
returnResult.setIsUnique(newIsUnique);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public static void setLower(Operation operation, int newLower) {
Parameter returnResult = operation.getReturnResult();
if (returnResult == null) {
returnResult = operation.createOwnedParameter(null, null);
returnResult.setDirection(ParameterDirectionKind.RETURN_LITERAL);
}
returnResult.setLower(newLower);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public static void setUpper(Operation operation, int newUpper) {
Parameter returnResult = operation.getReturnResult();
if (returnResult == null) {
returnResult = operation.createOwnedParameter(null, null);
returnResult.setDirection(ParameterDirectionKind.RETURN_LITERAL);
}
returnResult.setUpper(newUpper);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* Retrieves the (only) return result parameter for this operation.
* @param operation The receiving '<em><b>Operation</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static Parameter getReturnResult(Operation operation) {
for (Parameter ownedParameter : operation.getOwnedParameters()) {
if (ownedParameter
.getDirection() == ParameterDirectionKind.RETURN_LITERAL) {
return ownedParameter;
}
}
return null;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public static void setType(Operation operation, Type newType) {
Parameter returnResult = operation.getReturnResult();
if (returnResult == null) {
returnResult = operation.createOwnedParameter(null, null);
returnResult.setDirection(ParameterDirectionKind.RETURN_LITERAL);
}
returnResult.setType(newType);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* <!-- begin-model-doc -->
* The query isConsistentWith() specifies, for any two Operations in a context in which redefinition is possible, whether redefinition would be consistent. A redefining operation is consistent with a redefined operation if
* it has the same number of owned parameters, and for each parameter the following holds:
*
* - Direction, ordering and uniqueness are the same.
* - The corresponding types are covariant, contravariant or invariant.
* - The multiplicities are compatible, depending on the parameter direction.
* redefiningElement.isRedefinitionContextValid(self)
* result = (redefiningElement.oclIsKindOf(Operation) and
* let op : Operation = redefiningElement.oclAsType(Operation) in
* self.ownedParameter->size() = op.ownedParameter->size() and
* Sequence{1..self.ownedParameter->size()}->
* forAll(i |
* let redefiningParam : Parameter = op.ownedParameter->at(i),
* redefinedParam : Parameter = self.ownedParameter->at(i) in
* (redefiningParam.isUnique = redefinedParam.isUnique) and
* (redefiningParam.isOrdered = redefinedParam. isOrdered) and
* (redefiningParam.direction = redefinedParam.direction) and
* (redefiningParam.type.conformsTo(redefinedParam.type) or
* redefinedParam.type.conformsTo(redefiningParam.type)) and
* (redefiningParam.direction = ParameterDirectionKind::inout implies
* (redefinedParam.compatibleWith(redefiningParam) and
* redefiningParam.compatibleWith(redefinedParam))) and
* (redefiningParam.direction = ParameterDirectionKind::_'in' implies
* redefinedParam.compatibleWith(redefiningParam)) and
* ((redefiningParam.direction = ParameterDirectionKind::out or
* redefiningParam.direction = ParameterDirectionKind::return) implies
* redefiningParam.compatibleWith(redefinedParam))
* ))
* <p>From package UML::Classification.</p>
* @param operation The receiving '<em><b>Operation</b></em>' model object.
* <!-- end-model-doc -->
* @generated NOT
*/
public static boolean isConsistentWith(Operation operation,
RedefinableElement redefiningElement) {
if (redefiningElement instanceof Operation
&& redefiningElement.isRedefinitionContextValid(operation)) {
Operation op = (Operation) redefiningElement;
EList<Parameter> ownedParameters = operation.getOwnedParameters();
int ownedParametersSize = ownedParameters.size();
EList<Parameter> opOwnedParameters = op.getOwnedParameters();
if (ownedParametersSize == opOwnedParameters.size()) {
for (int i = 0; i < ownedParametersSize; i++) {
Parameter redefiningParam = opOwnedParameters.get(i);
Parameter redefinedParam = ownedParameters.get(i);
if (redefiningParam.isUnique() != redefinedParam
.isUnique()) {
return false;
}
if (redefiningParam.isOrdered() != redefinedParam
.isOrdered()) {
return false;
}
ParameterDirectionKind redefiningDirection = redefiningParam
.getDirection();
if (redefiningDirection != redefinedParam.getDirection()) {
return false;
}
if (redefiningDirection == ParameterDirectionKind.INOUT_LITERAL) {
if (!redefiningParam.compatibleWith(redefinedParam)
|| !redefinedParam
.compatibleWith(redefiningParam)) {
return false;
}
} else if (redefiningDirection == ParameterDirectionKind.IN_LITERAL) {
if (!redefinedParam.compatibleWith(redefiningParam)) {
return false;
}
} else {
if (!redefiningParam.compatibleWith(redefinedParam)) {
return false;
}
}
}
return true;
}
}
return false;
}
} // OperationOperations