| /** |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| */ |
| package org.eclipse.papyrus.designer.transformation.library.xtend; |
| |
| import java.util.List; |
| |
| import org.eclipse.uml2.uml.Behavior; |
| import org.eclipse.uml2.uml.BehavioredClassifier; |
| import org.eclipse.uml2.uml.Class; |
| import org.eclipse.uml2.uml.Constraint; |
| import org.eclipse.uml2.uml.OpaqueBehavior; |
| import org.eclipse.uml2.uml.OpaqueExpression; |
| import org.eclipse.uml2.uml.Operation; |
| import org.eclipse.uml2.uml.Parameter; |
| import org.eclipse.uml2.uml.ParameterDirectionKind; |
| import org.eclipse.uml2.uml.Transition; |
| import org.eclipse.uml2.uml.Type; |
| import org.eclipse.uml2.uml.UMLPackage; |
| |
| public class BehaviorUtil { |
| private static final String DEFAULT_LANGUAGE = "C++"; //$NON-NLS-1$ |
| |
| /** |
| * Set the body of an opaque behavior |
| * |
| * @param behavior |
| * an opaque behavior (if not an opaque behavior, the function does nothing) |
| * @param selectLanguage |
| * a selected language or null (in this case, the default language is chosen or the language of the first existing body) |
| * @param textblock |
| * the body of the opaque behavior |
| */ |
| public static void set(Behavior behavior, String selectLanguage, String textblock) { |
| if (behavior instanceof OpaqueBehavior) { |
| OpaqueBehavior ob = (OpaqueBehavior) behavior; |
| if (ob.getLanguages().size() == 0) { |
| ob.getLanguages().add(selectLanguage != null ? selectLanguage : DEFAULT_LANGUAGE); |
| ob.getBodies().add(textblock); |
| } else { |
| int i = 0; |
| for (String language : ob.getLanguages()) { |
| if (selectLanguage == null || selectLanguage.equals(language)) { |
| if (i < ob.getBodies().size()) { |
| ob.getBodies().set(i, textblock); |
| } |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Set the body of an opaque behavior |
| * |
| * @param behavior |
| * an opaque behavior |
| * @param textblock |
| * the body |
| */ |
| public static void set(Behavior behavior, String textblock) { |
| set(behavior, DEFAULT_LANGUAGE, textblock); |
| } |
| |
| /** |
| * Create a new opaque behavior and associate it with an operation (specification) |
| * |
| * @param clazz |
| * a behaviored classifier |
| * @param operation |
| * an operation |
| * @return |
| */ |
| public static OpaqueBehavior createOpaqueBehavior(BehavioredClassifier clazz, Operation operation) { |
| OpaqueBehavior ob = (OpaqueBehavior) clazz.createOwnedBehavior(operation.getName(), UMLPackage.eINSTANCE.getOpaqueBehavior()); |
| ob.setSpecification(operation); |
| return ob; |
| } |
| |
| public static OpaqueBehavior createOpaqueEffect(Transition transition) { |
| OpaqueBehavior ob = (OpaqueBehavior) transition.createEffect("", UMLPackage.eINSTANCE.getOpaqueBehavior()); //$NON-NLS-1$ |
| return ob; |
| } |
| |
| public static OpaqueExpression createOpaqueExpression(Constraint constraint, String guardCode) { |
| OpaqueExpression oe = (OpaqueExpression) constraint.createSpecification("", null, UMLPackage.eINSTANCE.getOpaqueExpression()); //$NON-NLS-1$ |
| oe.getLanguages().add(DEFAULT_LANGUAGE); |
| oe.getBodies().add(guardCode); |
| return oe; |
| } |
| |
| /** |
| * @param constraint |
| * @return first (index 0) body of a constraint specified with an opaque expression |
| */ |
| public static String body(Constraint constraint) { |
| if (constraint.getSpecification() instanceof OpaqueExpression) { |
| OpaqueExpression oe = (OpaqueExpression) constraint.getSpecification(); |
| if (oe.getBodies().size() > 0) { |
| return oe.getBodies().get(0); |
| } |
| } |
| return constraint.getSpecification().stringValue(); |
| } |
| |
| /** |
| * Create an operation with an operation return type |
| * |
| * @param clazz |
| * @param name |
| * @param retType |
| * @return the created operation |
| */ |
| public static Operation createOperation(Class clazz, String name, Type retType) { |
| Operation operation = clazz.createOwnedOperation(name, null, null); |
| if (retType != null) { |
| Parameter parameter = operation.createOwnedParameter("ret", retType); //$NON-NLS-1$ |
| parameter.setDirection(ParameterDirectionKind.RETURN_LITERAL); |
| } |
| return operation; |
| } |
| |
| public static String body(Behavior behavior) { |
| return body(behavior, DEFAULT_LANGUAGE); |
| } |
| |
| /** |
| * Return first body that matches a given language. |
| * |
| * @param behavior |
| * a behavior |
| * @param selectLanguage |
| * the language, if null first body is returned |
| * @return the body |
| */ |
| public static String body(Behavior behavior, String selectLanguage) { |
| if (behavior instanceof OpaqueBehavior) { |
| OpaqueBehavior ob = (OpaqueBehavior) behavior; |
| int i = 0; |
| for (String language : ob.getLanguages()) { |
| if (selectLanguage == null || selectLanguage.equals(language)) { |
| if (i < ob.getBodies().size()) { |
| return ob.getBodies().get(i); |
| } |
| break; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * @param operation |
| * an operation |
| * @param selectLanguage |
| * the language to filter, may be null |
| * @return the body of the first method of the passed operation that has a |
| * non-empty body of the selected language |
| */ |
| public static String body(Operation operation, String selectLanguage) { |
| for (Behavior method : operation.getMethods()) { |
| String body = body(method, selectLanguage); |
| if (body != null) { |
| return body; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * @param operation |
| * an operation |
| * @return the body of the first method of the passed operation that has a |
| * non-empty body |
| */ |
| public static String body(Operation operation) { |
| return body(operation, null); |
| } |
| |
| /** |
| * set the method (body) of an operation |
| * |
| * @param operation |
| * an operation |
| * @param selectLanguage |
| * the language to look for |
| * @param textblock |
| * the body code |
| */ |
| public static void set(Operation operation, String selectLanguage, String textblock) { |
| for (Behavior method : operation.getMethods()) { |
| if (method instanceof OpaqueBehavior) { |
| OpaqueBehavior ob = (OpaqueBehavior) method; |
| if (ob.getLanguages().size() > 0 && (selectLanguage == null || ob.getLanguages().get(0).equals(selectLanguage))) { |
| set(ob, selectLanguage, textblock); |
| return; |
| } |
| } |
| } |
| OpaqueBehavior method = createOpaqueBehavior(operation.getClass_(), operation); |
| set(method, selectLanguage, textblock); |
| } |
| |
| /** |
| * set the method (body) of an operation |
| * |
| * @param operation |
| * an operation |
| * @param textblock |
| * the body code |
| */ |
| public static void set(Operation operation, String textblock) { |
| set(operation, null, textblock); |
| } |
| |
| /** |
| * Append code to existing opaque behavior |
| * |
| * @param behavior |
| * a behavior |
| * @param codeToAppend |
| * the code to append |
| */ |
| public static void appendBody(Behavior behavior, String codeToAppend) { |
| String body = body(behavior, null); |
| if (body != null) { |
| set(behavior, null, body + "\n" + codeToAppend); //$NON-NLS-1$ |
| } else { |
| set(behavior, null, codeToAppend); |
| } |
| } |
| |
| /** |
| * Append code to existing opaque behavior referenced via an operation |
| * |
| * @param operation |
| * an operation |
| * @param codeToAppend |
| * the code to append |
| */ |
| public static void appendBody(Operation operation, String codeToAppend) { |
| List<Behavior> methods = operation.getMethods(); |
| OpaqueBehavior opaque; |
| if (methods.size() > 0 && methods.get(0) instanceof OpaqueBehavior) { |
| opaque = (OpaqueBehavior) methods.get(0); |
| } else { |
| opaque = createOpaqueBehavior(operation.getClass_(), operation); |
| } |
| appendBody(opaque, codeToAppend); |
| } |
| |
| /** |
| * Prefix (add before) code to existing opaque behavior |
| * |
| * @param behavior |
| * a behavior |
| * @param codeToPrefix |
| * the code to prefix |
| */ |
| public static void prefixBody(Behavior behavior, String codeToPrefix) { |
| String body = body(behavior, null); |
| if (body != null) { |
| set(behavior, null, codeToPrefix + "\n" + body); //$NON-NLS-1$ |
| } else { |
| set(behavior, null, codeToPrefix); |
| } |
| } |
| |
| /** |
| * Prefix (add before) code to existing opaque behavior (referenced via an operation) |
| * |
| * @param operation |
| * an operation |
| * @param codeToPrefix |
| * the code to prefix |
| */ |
| public static void prefixBody(Operation operation, String codeToPrefix) { |
| List<Behavior> methods = operation.getMethods(); |
| OpaqueBehavior opaque; |
| if (methods.size() > 0 && methods.get(0) instanceof OpaqueBehavior) { |
| opaque = (OpaqueBehavior) methods.get(0); |
| } else { |
| opaque = createOpaqueBehavior(operation.getClass_(), operation); |
| } |
| prefixBody(opaque, codeToPrefix); |
| } |
| } |