| /***************************************************************************** |
| * 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 org.eclipse.papyrus.uml.tools.utils.ConnectorUtil |
| import org.eclipse.uml2.uml.Class |
| import org.eclipse.uml2.uml.ConnectorEnd |
| import org.eclipse.uml2.uml.Port |
| import org.eclipse.uml2.uml.Property |
| |
| import static extension org.eclipse.papyrus.robotics.core.utils.InteractionUtils.getCommObject |
| import org.eclipse.papyrus.designer.infra.base.StringConstants |
| |
| /** |
| * A set of utility functions around port and topic names |
| */ |
| class TopicUtils { |
| /** |
| * Return the topic of a port, currently the port name only |
| * |
| * In case of ROS2, this information will be re-mapped in the launch scripts |
| */ |
| static def getTopic(Port port) { |
| port.name |
| } |
| |
| /** |
| * Return true, if the name a port has a qualified name, i.e. has / |
| * |
| * In case of ROS2, this information will be re-mapped in the launch scripts |
| */ |
| static def isQualified(Port port) { |
| return port.name.indexOf(StringConstants.SLASH) != -1 |
| } |
| |
| /** |
| * Return the topic of a pub/subr port, calculates topic from passed |
| * part/port, if provided and from opposite part/port, if required |
| */ |
| static def getTopic(Property part, Port port, ConnectorEnd oppositeEnd) { |
| val oppositePort = oppositeEnd.role as Port |
| if (port.isQualified && oppositePort.isQualified) { |
| if (port.topic != oppositePort.topic) { |
| throw new RuntimeException(String.format( |
| "Trying to connect two different qualified port names: %s with %s", |
| port.topic, oppositePort.topic)) |
| } |
| } |
| if (port.isQualified || port.provideds.size > 0) { |
| getTopic(part, port) |
| } else { |
| getTopic(oppositeEnd.partWithPort, oppositePort) |
| } |
| } |
| |
| /** |
| * Return the topic of a pub/sub port, based on the assumption that the |
| * topic is a concatenation of communication object name and port name |
| * If the port name is already qualified, use this as topic name without |
| * additional qualifications |
| */ |
| static def String getTopic(Property part, Port port) { |
| if (port.isQualified) { |
| port.name |
| } |
| else { |
| '''«part.name»/«port.commObject.name»/«port.name»''' |
| } |
| } |
| |
| /** |
| * Return opposite part, based on the assumption that there is a single port |
| * targeting a port |
| */ |
| static def getOpposite(Class system, Property part, Port port) { |
| for (connector: system.ownedConnectors) { |
| if (ConnectorUtil.connectsPort(connector, port)) { |
| val end = ConnectorUtil.connEndNotPart(connector, part) |
| if (end !== null) { |
| return end |
| } |
| } |
| } |
| return null |
| } |
| } |