blob: f9e58c91b106fd994cb6dd80b5df660a2f01d0b8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017-2020 Dortmund University of Applied Sciences and Arts and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dortmund University of Applied Sciences and Arts - initial API and implementation
*******************************************************************************/
package org.eclipse.app4mc.multicore.partitioning.utils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ListIterator;
import org.eclipse.app4mc.amalthea.model.AmaltheaFactory;
import org.eclipse.app4mc.amalthea.model.CommonElements;
import org.eclipse.app4mc.amalthea.model.ProcessPrototype;
import org.eclipse.app4mc.amalthea.model.Runnable;
import org.eclipse.app4mc.amalthea.model.RunnableCall;
import org.eclipse.app4mc.amalthea.model.SWModel;
import org.eclipse.app4mc.amalthea.model.Tag;
import org.eclipse.emf.common.util.EList;
import org.slf4j.LoggerFactory;
public class TagToPP {
private final SWModel swm;
public SWModel getSwm() {
return this.swm;
}
private final CommonElements cem;
public TagToPP(final SWModel sw, final CommonElements ce) {
this.swm = sw;
this.cem = ce;
}
/**
* If Runnables refer a Tag, ProcessPrototypes (named 'Tag_Tagname') are created and TaskRunnableCalls are assigned to those ProcessPrototypes for each
* Runnable that refers this Tag
*
* @return List of ProcessPrototypes
*/
public void createPPsFromTagsSplit() {
if (null == this.cem || null == this.cem.getTags()) {
LoggerFactory.getLogger(TagToPP.class).error("Either no Tags or no CommonElements model existing");
return;
}
if (null == this.swm || null == this.swm.getRunnables()) {
LoggerFactory.getLogger(TagToPP.class).error("Either no Runnables or no software model existing");
return;
}
/* if there are no PPs, create one with all runnables calls */
if (this.swm.getProcessPrototypes().isEmpty() || null == this.swm.getProcessPrototypes()) {
final ProcessPrototype pp = AmaltheaFactory.eINSTANCE.createProcessPrototype();
pp.setName("allRunnables");
for (final Runnable r : this.swm.getRunnables()) {
final RunnableCall trc = AmaltheaFactory.eINSTANCE.createRunnableCall();
trc.setRunnable(r);
pp.getRunnableCalls().add(trc);
}
this.swm.getProcessPrototypes().add(pp);
}
int currentNoTagIndex = -1;
final ListIterator<ProcessPrototype> it = this.swm.getProcessPrototypes().listIterator();
while (it.hasNext()) {
final ProcessPrototype pp = it.next();
currentNoTagIndex = checkRunsInPP(currentNoTagIndex, it, pp);
}
removeEmptyPPs(this.swm.getProcessPrototypes());
}
private int checkRunsInPP(int currentNoTagIndex, final ListIterator<ProcessPrototype> it, final ProcessPrototype pp) {
final HashMap<Tag, Integer> tagPPIndexMap = new HashMap<>();
final ListIterator<RunnableCall> it2 = pp.getRunnableCalls().listIterator();
while (it2.hasNext()) {
final RunnableCall trc = it2.next();
if (null == trc.getRunnable().getTags() || trc.getRunnable().getTags().isEmpty()) {
if (currentNoTagIndex == -1) {
currentNoTagIndex = this.swm.getProcessPrototypes().indexOf(pp);
break;
}
final RunnableCall trc2 = AmaltheaFactory.eINSTANCE.createRunnableCall();
trc2.setRunnable(trc.getRunnable());
this.swm.getProcessPrototypes().get(currentNoTagIndex).getRunnableCalls().add(trc2);
it2.remove();
}
else {
if (tagPPIndexMap.containsKey(trc.getRunnable().getTags().get(0))) {
final RunnableCall trc2 = AmaltheaFactory.eINSTANCE.createRunnableCall();
trc2.setRunnable(trc.getRunnable());
this.swm.getProcessPrototypes().get(tagPPIndexMap.get(trc.getRunnable().getTags().get(0))).getRunnableCalls().add(trc2);
it2.remove();
}
else {
final ProcessPrototype pp2 = AmaltheaFactory.eINSTANCE.createProcessPrototype();
pp2.setName(pp.getName() + "_" + trc.getRunnable().getTags().get(0).getName());
pp2.setActivation(trc.getRunnable().getFirstActivation());
final RunnableCall trc2 = AmaltheaFactory.eINSTANCE.createRunnableCall();
trc2.setRunnable(trc.getRunnable());
pp2.getRunnableCalls().add(trc2);
it2.remove();
it.add(pp2);
tagPPIndexMap.put(trc.getRunnable().getTags().get(0), this.swm.getProcessPrototypes().indexOf(pp2));
}
}
}
return currentNoTagIndex;
}
private void removeEmptyPPs(final EList<ProcessPrototype> processPrototypes) {
final Iterator<ProcessPrototype> it = processPrototypes.iterator();
while (it.hasNext()) {
final ProcessPrototype pp = it.next();
if (pp.getRunnableCalls().isEmpty()) {
it.remove();
}
}
}
}