blob: 1c4960f9245c94ac729f783075e168bba9324676 [file] [log] [blame]
/*****************************************************************************
* 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.ease.fmi;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.papyrus.moka.fmi.fmiprofile.CS_FMU;
import org.eclipse.papyrus.moka.ssp.omsimulatorprofile.BusConnector;
import org.eclipse.papyrus.moka.ssp.omsimulatorprofile.util.OMSimulatorProfileUtil;
import org.eclipse.uml2.uml.AggregationKind;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.ConnectorEnd;
import org.eclipse.uml2.uml.NamedElement;
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;
public class FMISimulatorHandler extends GraphicalElement {
private Class simClass;
private Map<String, FMUInstanceHandler> instanceMap = new HashMap<>();
private List<AbstractConnectorHandler> connectorHandlers = new ArrayList<>();
public FMISimulatorHandler(Class simulatorClass) {
super(simulatorClass);
simClass = simulatorClass;
for (Property prop : simClass.getAllAttributes()) {
CS_FMU fmu = UMLUtil.getStereotypeApplication(prop.getType(), CS_FMU.class);
if (fmu != null) {
instanceMap.put(prop.getName(), new FMUInstanceHandler(this, prop));
}
}
for (Connector connector : simClass.getOwnedConnectors()) {
if (UMLUtil.getStereotypeApplication(connector, BusConnector.class) != null) {
connectorHandlers.add(new BusConnectorHandler(this, connector));
} else {
connectorHandlers.add(new ConnectorHandler(this, connector));
}
}
}
public Class getUMLClass() {
return simClass;
}
public Collection<FMUInstanceHandler> getInstances() {
return instanceMap.values();
}
public List<AbstractConnectorHandler> getConnectors() {
return connectorHandlers;
}
public String getName() {
return simClass.getName();
}
public FMUInstanceHandler instantiateFMU(String fmuQN, String instanceName) {
Collection<NamedElement> fmuTypes = UMLUtil.findNamedElements(simClass.eResource().getResourceSet(), fmuQN);
Class fmuType = null;
FMUInstanceHandler result = null;
for (NamedElement namedElem : fmuTypes) {
if (namedElem instanceof Class && UMLUtil.getStereotypeApplication(namedElem, CS_FMU.class) != null) {
fmuType = (Class) namedElem;
}
}
if (fmuType != null) {
Property fmuProp = simClass.createOwnedAttribute(instanceName, fmuType);
fmuProp.setAggregation(AggregationKind.COMPOSITE_LITERAL);
result = new FMUInstanceHandler(this, fmuProp);
instanceMap.put(instanceName, result);
} else {
throw new RuntimeException("Failed to find FMU type " + fmuQN);
}
return result;
}
public FMUInstanceHandler instantiateFMU(String fmuQN, String instanceName, int x, int y, List<Port> portsToHide) {
FMUInstanceHandler handler = instantiateFMU(fmuQN, instanceName);
handler.createView(x, y, portsToHide);
return handler;
}
public ConnectorHandler addConnection(String sourcePort, String targetPort) {
Connector connector = createUMLConnector(sourcePort, targetPort);
ConnectorHandler result = new ConnectorHandler(this, connector);
return result;
}
public ConnectorHandler addConnection(String sourcePort, String targetPort, boolean createView) {
ConnectorHandler result = addConnection(sourcePort, targetPort);
if (createView) {
result.createView();
}
return result;
}
public BusConnectorHandler addBusConnection(String sourceBus, String targetBus) {
Connector connector = createUMLConnector(sourceBus, targetBus);
connector.applyStereotype((Stereotype) connector.eResource().getResourceSet()
.getEObject(OMSimulatorProfileUtil.OMSIMULATOR_BUS_CONNECTOR_URI, true));
BusConnectorHandler result = new BusConnectorHandler(this, connector);
return result;
}
public BusConnectorHandler addBusConnection(String sourceBus, String targetBus, boolean createView) {
BusConnectorHandler result = addBusConnection(sourceBus, targetBus);
if (createView) {
result.createView();
}
return result;
}
protected Connector createUMLConnector(String sourcePort, String targetPort) {
AbstractPortHandler sourcePortHandler = getInstancePort(sourcePort);
AbstractPortHandler targetPortHandler = getInstancePort(targetPort);
if (sourcePortHandler != null && targetPortHandler != null) {
Connector connector = simClass.createOwnedConnector(sourcePort + "_" + targetPort);
ConnectorEnd sourceEnd = connector.createEnd();
sourceEnd.setPartWithPort(sourcePortHandler.getUMLPart());
sourceEnd.setRole(sourcePortHandler.getUMLPort());
ConnectorEnd targetEnd = connector.createEnd();
targetEnd.setPartWithPort(targetPortHandler.getUMLPart());
targetEnd.setRole(targetPortHandler.getUMLPort());
return connector;
}
System.out.println("ERROR: Failed to create connector between " + sourcePort + " and " + targetPort);
throw new RuntimeException("Failed to create connector between " + sourcePort + " and " + targetPort);
}
public AbstractPortHandler getInstancePort(String portName) {
int dotIndex = portName.indexOf(':');
if (dotIndex == -1) {
throw new RuntimeException("Invalid instance portName " + portName);
}
String instanceName = portName.substring(0, dotIndex);
FMUInstanceHandler instance = getInstance(instanceName);
if (instance != null) {
AbstractPortHandler result = instance.getPortOrBus(portName.substring(dotIndex + 1));
if (result != null) {
return result;
}
}
return null;
}
public FMUInstanceHandler getInstance(String instanceName) {
FMUInstanceHandler result = instanceMap.get(instanceName);
if (result == null) {
// name may have changed, we re-init the map;
updateInstanceMap();
result = instanceMap.get(instanceName);
if (result == null) {
System.out.println("Could not find instance " + instanceName);
throw new RuntimeException("Could not find instance " + instanceName);
}
}
return result;
}
protected void updateInstanceMap() {
List<FMUInstanceHandler> instances = new ArrayList<>(instanceMap.values());
instanceMap.clear();
for (FMUInstanceHandler instance : instances) {
instanceMap.put(instance.getName(), instance);
}
}
public List<IConnectorHandler> getFlattenedConnectors(){
List<IConnectorHandler> result = new ArrayList<>();
for (AbstractConnectorHandler busOrSimpleConnector : connectorHandlers) {
if( busOrSimpleConnector instanceof BusConnectorHandler) {
result.addAll(((BusConnectorHandler) busOrSimpleConnector).getSubConnections());
}else {
result.add(busOrSimpleConnector);
}
}
return result;
}
}