| /***************************************************************************** |
| * Copyright (c) 2020 CEA LIST. |
| * |
| * 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 |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * Contributors: |
| * Ansgar Radermacher ansgar.radermacher@cea.fr |
| * |
| *****************************************************************************/ |
| |
| package org.eclipse.papyrus.robotics.codegen.common.utils |
| |
| import java.util.List |
| import org.eclipse.papyrus.robotics.codegen.common.component.CodeSkeleton |
| import org.eclipse.papyrus.robotics.profile.robotics.components.Activity |
| import org.eclipse.papyrus.robotics.profile.robotics.components.ActivityPort |
| import org.eclipse.papyrus.robotics.profile.robotics.components.ComponentDefinition |
| import org.eclipse.papyrus.robotics.profile.robotics.components.PeriodicTimer |
| import org.eclipse.papyrus.robotics.profile.robotics.functions.FunctionKind |
| import org.eclipse.papyrus.uml.tools.utils.ConnectorUtil |
| import org.eclipse.uml2.uml.Class |
| import org.eclipse.uml2.uml.Port |
| import org.eclipse.uml2.uml.util.UMLUtil |
| |
| import static extension org.eclipse.papyrus.robotics.core.utils.FunctionUtils.getFunctions |
| |
| class ActivityUtils { |
| |
| def static List<Activity> getActivities(Class component) { |
| val cd = UMLUtil.getStereotypeApplication(component, ComponentDefinition) |
| return cd.activities |
| } |
| |
| /** |
| * Return the activity port connected with the passed component port. |
| */ |
| def static ActivityPort getActivityForPort(Class component, Port componentPortUml) { |
| val activityPortUml = getActivityForPortUml(component, componentPortUml) |
| if (activityPortUml !== null) { |
| return UMLUtil.getStereotypeApplication(activityPortUml, ActivityPort) |
| } |
| return null |
| } |
| |
| /** |
| * Return the activity port connected with the passed component port. |
| */ |
| def static Port getActivityForPortUml(Class component, Port componentPortUml) { |
| for (activity : component.activities) { |
| val activityCl = activity.base_Class |
| for (connector : component.ownedConnectors) { |
| if (ConnectorUtil.connectsPort(connector, componentPortUml)) { |
| val end1 = connector.ends.get(0); |
| val end2 = connector.ends.get(1); |
| // the connector end targets a port of the nested activity classifier |
| // (not part) => use owner to navigate to owning activity |
| if (end1.role.owner == activityCl) { |
| return end1.role as Port |
| } |
| if (end2.role.owner == activityCl) { |
| return end2.role as Port; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * return true, if the component has external functions, i.e. empty functions |
| * whose code is not supplied by fragments (opaque behavior) stored in the model |
| */ |
| def static hasExternalCode(Class component) { |
| for (activity : component.activities) { |
| for (function : activity.functions) { |
| if (!function.codeInModel) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * return the name of the component class, in case of a component |
| * with externally defined functions with an _impl postfix |
| */ |
| def static getPostfix(Class component) { |
| if (component.hasExternalCode) { |
| return CodeSkeleton.POSTFIX |
| } |
| return "" |
| } |
| |
| def static hasPeriodicActivities(Class component) { |
| for (activity : component.activities) { |
| if (activity.getFunctions(FunctionKind.PERIODIC).size > 0) { |
| return true; |
| } |
| } |
| return false |
| } |
| |
| /** |
| * return period length of an activity or null, if non-specified |
| */ |
| def static getPeriod(Activity activity) { |
| for (cl : activity.base_Class.nestedClassifiers) { |
| val pt = UMLUtil.getStereotypeApplication(cl, PeriodicTimer) |
| if (pt !== null) { |
| return pt.period; |
| } |
| } |
| return null |
| } |
| } |