blob: 1ae2c2275fb24399eb5eadb2ad4349593b9b83df [file] [log] [blame]
/*****************************************************************************
* 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
}
}