blob: b5c794a9a9bb383f96233114b9f42a2d72bab55b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020, 2021 Primetals Technologies Austria GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Bianca Wiesmayr
* - initial implementation and documentation
*******************************************************************************/
package org.eclipse.fordiac.ide.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.fordiac.ide.model.data.DataFactory;
import org.eclipse.fordiac.ide.model.data.StructuredType;
import org.eclipse.fordiac.ide.model.libraryElement.Attribute;
import org.eclipse.fordiac.ide.model.libraryElement.Demultiplexer;
import org.eclipse.fordiac.ide.model.libraryElement.Event;
import org.eclipse.fordiac.ide.model.libraryElement.LibraryElementFactory;
import org.eclipse.fordiac.ide.model.libraryElement.Multiplexer;
import org.eclipse.fordiac.ide.model.libraryElement.StructManipulator;
import org.eclipse.fordiac.ide.model.libraryElement.VarDeclaration;
import org.eclipse.fordiac.ide.model.libraryElement.With;
/**
* Helper class for methods that will be - accessed from the model or - used
* directly as static helper methods
*
*/
public class StructManipulation {
public static final String STRUCT_ATTRIBUTE = "StructuredType"; //$NON-NLS-1$
public static final String CHILDREN_ATTRIBUTE = "VisibleChildren"; //$NON-NLS-1$
public static final String DEMUX_NAME = "STRUCT_DEMUX"; //$NON-NLS-1$
public static final String MUX_NAME = "STRUCT_MUX"; //$NON-NLS-1$
public static void setStructTypeElementsAtInterface(StructManipulator muxer, StructuredType newStructType) {
muxer.setStructType(newStructType);
configureAttributes(muxer);
setMemberVariablesAsPorts(muxer, newStructType);
}
private static void configureAttributes(StructManipulator muxer) {
final StructuredType struct = muxer.getStructType();
if (null == struct) {
muxer.deleteAttribute(STRUCT_ATTRIBUTE);
} else {
muxer.setAttribute(STRUCT_ATTRIBUTE, "STRING", struct.getName(), //$NON-NLS-1$
""); //$NON-NLS-1$
}
}
public static void setMemberVariablesAsPorts(StructManipulator muxer, StructuredType newStructType) {
if (muxer instanceof Demultiplexer) {
if (null == newStructType) {
setVariablesAsOutputs(muxer, Collections.emptyList());
} else {
setVariablesAsOutputs(muxer, newStructType.getMemberVariables());
}
}
if (muxer instanceof Multiplexer) {
if (null == newStructType) {
setVariablesAsInputs(muxer, Collections.emptyList(), null);
} else {
setVariablesAsInputs(muxer, newStructType.getMemberVariables(), newStructType);
}
}
}
public static StructuredType collectVisibleChildren(StructManipulator muxer, StructuredType newStructType,
final Attribute attr) {
final StructuredType configuredStruct = DataFactory.eINSTANCE.createStructuredType();
configuredStruct.setName(newStructType.getName());
configuredStruct.setComment(newStructType.getComment());
final List<String> visibleChildrenNames = Arrays
.asList(attr.getValue().trim().split(LibraryElementTags.VARIABLE_SEPARATOR));
final Collection<VarDeclaration> visibleVars = getVarDeclarations(muxer.getStructType(), visibleChildrenNames);
configuredStruct.getMemberVariables().addAll(visibleVars);
return configuredStruct;
}
public static void setVariablesAsInputs(StructManipulator muxer, Collection<VarDeclaration> vars,
StructuredType newStructType) {
// create member variables of struct as data input ports
if (null == newStructType) {
muxer.getInterface().getInputVars().clear();
} else {
final Collection<VarDeclaration> list = EcoreUtil.copyAll(newStructType.getMemberVariables());
list.forEach(varDecl -> {
if (null == muxer.getInterfaceElement(varDecl.getName())) {
varDecl.setIsInput(true);
if (null != varDecl.getValue()) {
// if we have a value set it empty to get rid of default values from the struct
// type
varDecl.getValue().setValue(""); //$NON-NLS-1$
}
}
});
final Event ev = muxer.getInterface().getEventInputs().get(0);
// create with constructs
list.forEach(varDecl -> {
final With with = LibraryElementFactory.eINSTANCE.createWith();
with.setVariables(varDecl);
ev.getWith().add(with);
});
// add data input ports to the interface
muxer.getInterface().getInputVars().addAll(list);
muxer.getInterface().getOutputVars().get(0).setType(newStructType); // there should be only one output
}
}
public static void setVariablesAsOutputs(StructManipulator muxer, Collection<VarDeclaration> vars) {
final Collection<VarDeclaration> list = EcoreUtil.copyAll(vars);
list.forEach(varDecl -> {
varDecl.setIsInput(false);
if (null != varDecl.getValue()) {
// if we have a value set it empty to get rid of default values from the struct
// type
varDecl.getValue().setValue(""); //$NON-NLS-1$
}
});
final List<Event> outputEvents = muxer.getInterface().getEventOutputs();
// create with constructs
list.forEach(varDecl -> {
final With with = LibraryElementFactory.eINSTANCE.createWith();
with.setVariables(varDecl);
outputEvents.forEach(ev -> ev.getWith().add(with));
});
// add data output ports to the interface
muxer.getInterface().getOutputVars().clear();
muxer.getInterface().getOutputVars().addAll(list);
}
private static Collection<VarDeclaration> getVarDeclarations(StructuredType structType, List<String> varDeclNames) {
final List<VarDeclaration> vars = new ArrayList<>();
varDeclNames.forEach(name -> {
final VarDeclaration varDecl = EcoreUtil.copy(findVarDeclarationInStruct(structType, name));
if (null != varDecl) {
varDecl.setName(name);
vars.add(varDecl);
}
});
return vars;
}
public static VarDeclaration findVarDeclarationInStruct(StructuredType struct, String name) {
final String[] subnames = name.split("\\."); //$NON-NLS-1$
List<VarDeclaration> members = struct.getMemberVariables();
VarDeclaration found = null;
for (final String subname : subnames) { //
final Object[] findings = members.stream().filter(var -> var.getName().equals(subname)).toArray();
if (findings.length > 0) {
found = (VarDeclaration) findings[0];
}
if ((null != found) && (found.getType() instanceof StructuredType)) {
members = ((StructuredType) found.getType()).getMemberVariables();
}
}
return found;
}
private StructManipulation() {
throw new UnsupportedOperationException();
}
}