Skip to content
This repository was archived by the owner on Oct 21, 2025. It is now read-only.
6 changes: 5 additions & 1 deletion bundles/org.dataflowanalysis.standalone/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ Require-Bundle: org.dataflowanalysis.dfd.datadictionary;bundle-version="2.0.0",
org.dataflowanalysis.pcm.extension.nodecharacteristics;bundle-version="0.1.0",
org.dataflowanalysis.analysis.pcm,
org.palladiosimulator.commons.stoex;bundle-version="5.2.1",
de.uka.ipd.sdq.stoex.analyser;bundle-version="5.2.1"
de.uka.ipd.sdq.stoex.analyser;bundle-version="5.2.1",
com.fasterxml.jackson.core.jackson-core;bundle-version="2.13.2",
com.fasterxml.jackson.core.jackson-annotations;bundle-version="2.13.2",
com.fasterxml.jackson.core.jackson-databind;bundle-version="2.13.2",
org.apache.log4j;bundle-version="1.2.24"
Automatic-Module-Name: DataFlowAnalalysisStandalone
Bundle-RequiredExecutionEnvironment: JavaSE-17
Export-Package:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
package org.dataflowanalysis.standalone.analysis;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.dataflowanalysis.analysis.dfd.DFDDataFlowAnalysisBuilder;
import org.dataflowanalysis.analysis.dfd.resource.DFDModelResourceProvider;
import org.dataflowanalysis.analysis.dfd.simple.DFDSimpleTransposeFlowGraphFinder;
import org.dataflowanalysis.analysis.dsl.AnalysisConstraint;
import org.dataflowanalysis.analysis.dsl.result.DSLResult;
import org.dataflowanalysis.analysis.utils.StringView;
import org.dataflowanalysis.converter.dfd2web.DataFlowDiagramAndDictionary;
import org.dataflowanalysis.converter.dfd2web.DFD2WebConverter;
Expand All @@ -22,12 +16,9 @@
import org.dataflowanalysis.converter.web2dfd.Web2DFDConverter;
import org.dataflowanalysis.converter.web2dfd.WebEditorConverterModel;
import org.dataflowanalysis.converter.web2dfd.model.WebEditorDfd;
import org.dataflowanalysis.converter.web2dfd.model.Child;
import org.dataflowanalysis.converter.web2dfd.model.Annotation;
import org.dataflowanalysis.dfd.datadictionary.DataDictionary;
import org.dataflowanalysis.dfd.datadictionary.datadictionaryPackage;
import org.dataflowanalysis.dfd.dataflowdiagram.DataFlowDiagram;
import org.dataflowanalysis.dfd.dataflowdiagram.Node;
import org.dataflowanalysis.dfd.dataflowdiagram.dataflowdiagramPackage;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
Expand All @@ -37,183 +28,120 @@
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;

public class Converter {

private static final Logger logger = Logger.getLogger(AnalysisConstraint.class);

/**
* Convertes a DFD from the Ecore to the WebEditor Json representation
* @param dfd File where DFD is saved
* @param dd File where DD is saved
* @return Created WebEditor Json representation
*/
public static WebEditorDfd convertDFD(File dfd, File dd){
try {
var converter = new DFD2WebConverter();

ResourceSet rs = new ResourceSetImpl();
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
rs.getPackageRegistry().put(dataflowdiagramPackage.eNS_URI, dataflowdiagramPackage.eINSTANCE);
rs.getPackageRegistry().put(datadictionaryPackage.eNS_URI, datadictionaryPackage.eINSTANCE);

private static final Logger logger = Logger.getLogger(Converter.class);

Resource ddResource = rs.getResource(URI.createFileURI(dd.toString()), true);
Resource dfdResource = rs.getResource(URI.createFileURI(dfd.toString()), true);
System.out.println(dd.toString());
System.out.println(dfd.toString());
EcoreUtil.resolveAll(rs);
EcoreUtil.resolveAll(ddResource);
EcoreUtil.resolveAll(dfdResource);
DataFlowDiagramAndDictionary dfdAndDD = new DataFlowDiagramAndDictionary((DataFlowDiagram)dfdResource.getContents().get(0), (DataDictionary)ddResource.getContents().get(0));

var newJson = converter.convert(dfdAndDD);

return newJson.getModel();

} catch (Exception e) {
e.printStackTrace();
return null;
}
}


/**
* Convertes a Model in PCM representation into a WebEditor Json represenation
* @param usageModelFile File where Usage Model is saved
* @param allocationModelFile File where Allocation Model is saved
* @param nodeCharacteristicsFile File where Node Characteristics Model is saved
* @return Created WebEditor Json representation
*/
public static WebEditorDfd convertPCM(File usageModelFile, File allocationModelFile, File nodeCharacteristicsFile){
try {
var converter = new PCM2DFDConverter();
var dfd = converter.convert(new PCMConverterModel(usageModelFile.toString(), allocationModelFile.toString(), nodeCharacteristicsFile.toString()));


var dfdConverter = new DFD2WebConverter();
dfdConverter.setTransposeFlowGraphFinder(DFDSimpleTransposeFlowGraphFinder.class);
return dfdConverter.convert(dfd).getModel();

} catch (Exception e) {
e.printStackTrace();
}
return null;
}

/**
* Analyzes a Model in WebEditor Json Representation and returns the analyzed Model
* @param webEditorDfd Model to be analyzed
* @return Analyzed Model
*/
public static WebEditorDfd analyzeAnnotate(WebEditorDfd webEditorDfd) {
try {
var webEditorconverter = new Web2DFDConverter();
var dd = webEditorconverter.convert(new WebEditorConverterModel(webEditorDfd));
var dfdConverter = new DFD2WebConverter();
var newJson = dfdConverter.convert(dd).getModel();
if (webEditorDfd.constraints() != null && !webEditorDfd.constraints().isEmpty()) {
var constraints = parseConstraints(webEditorDfd);
var violations = runAnalysis(dd, constraints);
newJson.constraints().addAll(webEditorDfd.constraints()); //Reapply constraints
return annotateViolations(newJson, violations);
}
return newJson;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

/**
* Converts a model in WebEditor Json representation into the DFD metamodel representation and return the DFD files as a concatenated string
* @param webEditorDfd model in WebEditor Json representation to be converted
* @param name Name of the files to be created
* @return Concatenation of DFD and DD files as string
*/
public static String convertToDFDandStringify(WebEditorDfd webEditorDfd, String name) {
try {
var converter = new Web2DFDConverter();
var dfd = converter.convert(new WebEditorConverterModel(webEditorDfd));
String tempDir = System.getProperty("java.io.tmpdir");
var dfdFile = new File(tempDir, name + ".dataflowdiagram");
var ddFile = new File(tempDir, name + ".datadictionary");
dfd.save(dfdFile.getParent(), name);

String dfdContent = Files.readString(dfdFile.toPath());
String ddContent = Files.readString(ddFile.toPath());
/**
* Convertes a DFD from the Ecore to the WebEditor Json representation
* @param dfd File where DFD is saved
* @param dd File where DD is saved
* @return Created WebEditor Json representation
*/
public static WebEditorDfd convertDFD(File dfd, File dd){
var converter = new DFD2WebConverter();

ResourceSet rs = new ResourceSetImpl();
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
rs.getPackageRegistry().put(dataflowdiagramPackage.eNS_URI, dataflowdiagramPackage.eINSTANCE);
rs.getPackageRegistry().put(datadictionaryPackage.eNS_URI, datadictionaryPackage.eINSTANCE);

dfdFile.delete();
ddFile.delete();
return dfdContent + "\n" + ddContent;

} catch (Exception e) {
e.printStackTrace();
return null;
}
}

private static List<AnalysisConstraint> parseConstraints(WebEditorDfd webEditorDfd) {
return webEditorDfd.constraints().stream()
.filter(it -> it.constraint() != null && !it.constraint().isEmpty())
.map(it -> {
return AnalysisConstraint.fromString(new StringView(it.constraint())).getResult();
}).toList();
}

private static List<DSLResult> runAnalysis(DataFlowDiagramAndDictionary dfd, List<AnalysisConstraint> constraints) {
var analysis = new DFDDataFlowAnalysisBuilder()
.standalone()
.modelProjectName(" ")
.useCustomResourceProvider(new DFDModelResourceProvider(dfd.dataDictionary(), dfd.dataFlowDiagram()))
.build();

Resource ddResource = rs.getResource(URI.createFileURI(dd.toString()), true);
Resource dfdResource = rs.getResource(URI.createFileURI(dfd.toString()), true);
EcoreUtil.resolveAll(rs);
EcoreUtil.resolveAll(ddResource);
EcoreUtil.resolveAll(dfdResource);
DataFlowDiagramAndDictionary dfdAndDD = new DataFlowDiagramAndDictionary((DataFlowDiagram)dfdResource.getContents().get(0), (DataDictionary)ddResource.getContents().get(0));

var newJson = converter.convert(dfdAndDD);

return newJson.getModel();
}


/**
* Convertes a Model in PCM representation into a WebEditor Json represenation
* @param usageModelFile File where Usage Model is saved
* @param allocationModelFile File where Allocation Model is saved
* @param nodeCharacteristicsFile File where Node Characteristics Model is saved
* @return Created WebEditor Json representation
*/
public static WebEditorDfd convertPCM(File usageModelFile, File allocationModelFile, File nodeCharacteristicsFile){
var converter = new PCM2DFDConverter();
var dfd = converter.convert(new PCMConverterModel(usageModelFile.toString(), allocationModelFile.toString(), nodeCharacteristicsFile.toString()));


var dfdConverter = new DFD2WebConverter();
dfdConverter.setTransposeFlowGraphFinder(DFDSimpleTransposeFlowGraphFinder.class);
return dfdConverter.convert(dfd).getModel();
}

/**
* Analyzes a Model in WebEditor Json Representation and returns the analyzed Model
* @param webEditorDfd Model to be analyzed
* @return Analyzed Model
*/
public static WebEditorDfd analyzeAnnotate(WebEditorDfd webEditorDfd) {
var webEditorconverter = new Web2DFDConverter();
var dd = webEditorconverter.convert(new WebEditorConverterModel(webEditorDfd));
var dfdConverter = new DFD2WebConverter();
if (webEditorDfd.constraints() != null && !webEditorDfd.constraints().isEmpty()) {
var constraints = parseConstraints(webEditorDfd);
dfdConverter.setConstraints(constraints);
}
var newJson = dfdConverter.convert(dd).getModel();

for (var child : newJson.model().children()) {
if (child.type().startsWith("node") && child.annotations() != null) {
var oldNode = webEditorDfd.model().children().stream().filter(node -> node.id().equals(child.id())).findAny().orElseThrow();
//Necessary if ugly if we want to preserver custom annotations
var annotationsToRemove = oldNode.annotations().stream().filter(a -> a.message().startsWith("Propagated") || a.message().startsWith("Incoming") || a.message().startsWith("Constraint")).toList();
oldNode.annotations().removeAll(annotationsToRemove);
oldNode.annotations().addAll(child.annotations());
}
}
return webEditorDfd;
}

/**
* Converts a model in WebEditor Json representation into the DFD metamodel representation and return the DFD files as a concatenated string
* @param webEditorDfd model in WebEditor Json representation to be converted
* @param name Name of the files to be created
* @return Concatenation of DFD and DD files as string
*/
public static String convertToDFDandStringify(WebEditorDfd webEditorDfd, String name) {
try {
var converter = new Web2DFDConverter();
var dfd = converter.convert(new WebEditorConverterModel(webEditorDfd));
String tempDir = System.getProperty("java.io.tmpdir");
var dfdFile = new File(tempDir, name + ".dataflowdiagram");
var ddFile = new File(tempDir, name + ".datadictionary");
dfd.save(dfdFile.getParent(), name);

String dfdContent = Files.readString(dfdFile.toPath());
String ddContent = Files.readString(ddFile.toPath());

logger.setLevel(Level.DEBUG);

var tfg = analysis.findFlowGraphs();
tfg.evaluate();


return constraints.stream().flatMap(it -> it.findViolations(tfg).stream()).toList();
}

private static WebEditorDfd annotateViolations(WebEditorDfd webEditorDfd, List<DSLResult> violations) {
Map<Child, String> nodeToAnnotationMap = new HashMap<>();

for (int i = 0; i < violations.size(); i++) {
final int index = i;
violations.get(i).getMatchedVertices().stream().forEach(it -> {
var node = webEditorDfd.model().children().stream()
.filter(child -> child.id().equals(((Node)it.getReferencedElement()).getId())).findFirst().orElseThrow();
var annotation = "";
if (nodeToAnnotationMap.containsKey(node)) {
annotation = nodeToAnnotationMap.get(node);
annotation += "\n";
}
annotation += "Constraint " + index + " violated";
nodeToAnnotationMap.put(node, annotation);
});
}

List<Child> newChildren = new ArrayList<>();

for (Child child : webEditorDfd.model().children()) {
if (nodeToAnnotationMap.containsKey(child)) {
StringBuilder builder = new StringBuilder();
if(child.annotation() != null) builder.append(child.annotation().message().toString());
if (builder.toString() != "") builder.append("\n");
builder.append(nodeToAnnotationMap.get(child));

var annotation = new Annotation(builder.toString(), "bolt", "#ff0000");

var newChild = new Child(child.text(), child.labels(), child.ports(), child.id(), child.type(), null, null,annotation, child.children());
newChildren.add(newChild);
}
}

webEditorDfd.model().children().removeAll(nodeToAnnotationMap.keySet());
webEditorDfd.model().children().addAll(newChildren);

return webEditorDfd;
}


dfdFile.delete();
ddFile.delete();
return dfdContent + "\n" + ddContent;

} catch (IOException e) {
e.printStackTrace();
return "Error";
}
}

private static List<AnalysisConstraint> parseConstraints(WebEditorDfd webEditorDfd) {
return webEditorDfd.constraints().stream()
.filter(it -> it.constraint() != null && !it.constraint().isEmpty())
.map(it -> {
StringView string = new StringView("- " + it.name() + ": " + it.constraint().replace("\n", ""));
var constraint = AnalysisConstraint.fromString(string);
if (constraint.failed()) {
logger.error(constraint.getError());
throw new IllegalArgumentException("Unable to parse constraint: " + it.name());
}
var constraint2 = constraint.getResult();
return constraint2;
}).toList();
}
}
Loading