| /***************************************************************************** |
| * Copyright (c) 2019 CEA LIST. |
| * |
| * |
| * 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 |
| * |
| * Contributors: |
| * CEA LIST - Initial API and implementation |
| * |
| *****************************************************************************/ |
| package org.eclipse.papyrus.moka.fmi.ui.util; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.papyrus.moka.fmi.fmiprofile.FMIPort; |
| import org.eclipse.papyrus.moka.ssp.omsimulatorprofile.OMSimulatorBus; |
| import org.eclipse.papyrus.moka.ssp.omsimulatorprofile.util.OMSimulatorProfileUtil; |
| import org.eclipse.papyrus.sysml14.portsandflows.FlowDirection; |
| import org.eclipse.uml2.uml.AggregationKind; |
| import org.eclipse.uml2.uml.Class; |
| import org.eclipse.uml2.uml.Port; |
| import org.eclipse.uml2.uml.Property; |
| import org.eclipse.uml2.uml.Stereotype; |
| import org.eclipse.uml2.uml.util.UMLUtil; |
| |
| class FMUPortHelper { |
| |
| Class type; |
| |
| List<Port> inputBusses = new ArrayList<>(); |
| |
| List<Port> outputorBidiBusses = new ArrayList<>(); |
| List<Port> inputsNotInBus = new ArrayList<>(); |
| List<Port> outputsNotInBus = new ArrayList<>(); |
| |
| Map<Port, List<Port>> portToBusses = new HashMap<>(); |
| |
| Map<String, Port> nameToPort = new HashMap<>(); |
| |
| public FMUPortHelper(Property newPart) { |
| this((Class) newPart.getType()); |
| } |
| |
| public FMUPortHelper(Class fmuType) { |
| type = fmuType; |
| |
| for (Property prop : type.getAllAttributes()) { |
| if (prop instanceof Port) { |
| nameToPort.put(prop.getName(), (Port) prop); |
| OMSimulatorBus bus = UMLUtil.getStereotypeApplication(prop, OMSimulatorBus.class); |
| if (bus != null) { |
| for (Port portInBus : bus.getSignals()) { |
| nameToPort.put(portInBus.getName(), portInBus); |
| List<Port> owningBusList = portToBusses.get(portInBus); |
| if (owningBusList == null) { |
| owningBusList = new ArrayList<>(); |
| portToBusses.put(portInBus, owningBusList); |
| } |
| owningBusList.add(portInBus); |
| } |
| if (bus.getDirection() == FlowDirection.IN) { |
| inputBusses.add((Port) prop); |
| } else { |
| outputorBidiBusses.add((Port) prop); |
| } |
| } |
| |
| } |
| } |
| |
| for (Property prop : type.getAllAttributes()) { |
| if (prop instanceof Port && !portToBusses.containsKey(prop) && !inputBusses.contains(prop) |
| && !outputorBidiBusses.contains(prop)) { |
| FMIPort fmiPort = UMLUtil.getStereotypeApplication(prop, FMIPort.class); |
| nameToPort.put(prop.getName(), (Port) prop); |
| if (fmiPort.getDirection() == FlowDirection.IN) { |
| inputsNotInBus.add((Port) prop); |
| } else { |
| outputsNotInBus.add((Port) prop); |
| } |
| |
| } |
| } |
| } |
| |
| public List<Port> getInputBusses() { |
| return inputBusses; |
| } |
| |
| public List<Port> getOutputorBidiBusses() { |
| return outputorBidiBusses; |
| } |
| |
| public List<Port> getInputsNotInBus() { |
| return inputsNotInBus; |
| } |
| |
| public List<Port> getOutputsNotInBus() { |
| return outputsNotInBus; |
| } |
| |
| public List<Port> getOwningBusses(Port port) { |
| List<Port> result = portToBusses.get(port); |
| if (result == null) { |
| result = new ArrayList<>(); |
| } |
| return result; |
| } |
| |
| public boolean isInput(Port port) { |
| return getInputsNotInBus().contains(port) || getInputBusses().contains(port); |
| } |
| |
| public Port getPortByName(String portName) { |
| return nameToPort.get(portName); |
| } |
| |
| public Collection<Port> getAllPorts(){ |
| return nameToPort.values(); |
| } |
| |
| public void copyMissingBusses(FMUPortHelper otherHelper) { |
| List<Port> otherBusses = new ArrayList<>(otherHelper.getInputBusses()); |
| otherBusses.addAll(otherHelper.getOutputorBidiBusses()); |
| |
| for (Port otherBus : otherBusses) { |
| Port existingBus = getPortByName(otherBus.getName()); |
| if (existingBus == null) { |
| OMSimulatorBus bus = UMLUtil.getStereotypeApplication(otherBus, OMSimulatorBus.class); |
| List<Port> portsToMap = new ArrayList<>(); |
| for (Port mappedPort : bus.getSignals()) { |
| Port existingPort = getPortByName(mappedPort.getName()); |
| if (existingPort != null) { |
| portsToMap.add(existingPort); |
| } |
| } |
| if (portsToMap.size() >0) { |
| Port newBusPort = type.createOwnedPort(otherBus.getName(), otherBus.getType()); |
| newBusPort.setIsBehavior(true); |
| newBusPort.setAggregation(AggregationKind.COMPOSITE_LITERAL); |
| nameToPort.put(newBusPort.getName(), newBusPort); |
| Stereotype busStereo = (Stereotype) type.eResource().getResourceSet().getEObject(OMSimulatorProfileUtil.OMSIMULATOR_BUS_URI, true); |
| OMSimulatorBus newBus = (OMSimulatorBus) newBusPort.applyStereotype(busStereo); |
| newBus.getSignals().addAll(portsToMap); |
| if (bus.getDirection() == FlowDirection.IN) { |
| inputBusses.add(newBusPort); |
| }else { |
| outputorBidiBusses.add(newBusPort); |
| } |
| } |
| } |
| |
| } |
| } |
| } |