diff --git a/bundles/org.dataflowanalysis.standalone/META-INF/MANIFEST.MF b/bundles/org.dataflowanalysis.standalone/META-INF/MANIFEST.MF index 91f5849..7dc618d 100644 --- a/bundles/org.dataflowanalysis.standalone/META-INF/MANIFEST.MF +++ b/bundles/org.dataflowanalysis.standalone/META-INF/MANIFEST.MF @@ -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: diff --git a/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/analysis/Converter.java b/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/analysis/Converter.java index bf79a40..76f3c13 100644 --- a/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/analysis/Converter.java +++ b/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/analysis/Converter.java @@ -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; @@ -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; @@ -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 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 runAnalysis(DataFlowDiagramAndDictionary dfd, List 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 violations) { - Map 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 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 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(); + } } diff --git a/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/websocket/WebSocketServerHandler.java b/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/websocket/WebSocketServerHandler.java index 4891e02..47ec1f6 100644 --- a/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/websocket/WebSocketServerHandler.java +++ b/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/websocket/WebSocketServerHandler.java @@ -4,6 +4,9 @@ import java.io.IOException; import java.util.Map; import java.util.HashMap; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; import org.dataflowanalysis.converter.web2dfd.model.WebEditorDfd; import org.dataflowanalysis.standalone.analysis.Converter; import org.eclipse.jetty.websocket.api.Session; @@ -17,6 +20,7 @@ public class WebSocketServerHandler extends WebSocketAdapter { private static Map sessions = new HashMap<>(); private static int index = 0; + private final Logger logger = Logger.getLogger(WebSocketServerHandler.class); /** * Assigns an ID for identification on websocket connection @@ -26,7 +30,7 @@ public class WebSocketServerHandler extends WebSocketAdapter public void onWebSocketConnect(Session sess) { super.onWebSocketConnect(sess); - System.out.println("WS connection established"); + logger.info("WS connection established"); sessions.put(index, sess); try { @@ -48,13 +52,15 @@ public void onWebSocketText(String message) var analysisThread = new Thread(() -> { var id = Integer.parseInt(message.split(":")[0]); String returnMessage = handleIncomingMessage(id, message.substring(message.indexOf(":")+1)); - if (returnMessage != null) { + try { - sessions.get(id).getRemote().sendString(returnMessage); + if (!returnMessage.endsWith("null")) sessions.get(id).getRemote().sendString(returnMessage); + else {sessions.get(id).getRemote().sendString("Error: Unknown Error"); + } } catch (IOException e) { - e.printStackTrace(); + e.printStackTrace(); } - } + }); analysisThread.start(); } @@ -72,19 +78,11 @@ public void onWebSocketError(Throwable cause) cause.printStackTrace(System.err); } - public static void shutDownFrontend() { - for (var sess : sessions.values()) { - try { - sess.getRemote().sendString("Shutdown"); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - private String handleIncomingMessage(int id, String message) { - System.out.println(message); - System.out.println("Message received"); + logger.setLevel(Level.DEBUG); + logger.info("Message received"); + logger.debug(message); + var objectMapper = new ObjectMapper(); WebEditorDfd newJson = null; @@ -102,7 +100,7 @@ else if (message.startsWith("Json2DFD:")) { return name + ":" + Converter.convertToDFDandStringify(webEditorDfd, name); } else if (message.startsWith("DFD:")) { - newJson = safeLoadAndConvertDFDString(message, name); + newJson = safeLoadAndConvertDFDString(message); } else { newJson = safeLoadAndConvertPCMString(message); } @@ -113,16 +111,16 @@ else if (message.startsWith("DFD:")) { try { return name + ":" + objectMapper.writeValueAsString(newJson); } catch (JsonProcessingException e) { - return null; + return "Error:" + " Unable to read Json"; } } - private WebEditorDfd deserializeJsonAndAnnotate(String json) throws IllegalArgumentException{ + private WebEditorDfd deserializeJsonAndAnnotate(String json){ var objectMapper = new ObjectMapper(); WebEditorDfd webEditorDfd; try { webEditorDfd = objectMapper.readValue(json, WebEditorDfd.class); - } catch (Exception e) { + } catch (IOException e) { e.printStackTrace(); throw new IllegalArgumentException("Invalid Json Model"); } @@ -131,12 +129,12 @@ private WebEditorDfd deserializeJsonAndAnnotate(String json) throws IllegalArgum return Converter.analyzeAnnotate(webEditorDfd); } - private WebEditorDfd deserializeJson(String json) throws IllegalArgumentException { + private WebEditorDfd deserializeJson(String json){ var objectMapper = new ObjectMapper(); WebEditorDfd webEditorDfd; try { webEditorDfd = objectMapper.readValue(json, WebEditorDfd.class); - } catch (Exception e) { + } catch (IOException e) { e.printStackTrace(); throw new IllegalArgumentException("Invalid Json Model"); } @@ -145,17 +143,19 @@ private WebEditorDfd deserializeJson(String json) throws IllegalArgumentExceptio return webEditorDfd; } - private WebEditorDfd safeLoadAndConvertDFDString(String message, String name) { + private WebEditorDfd safeLoadAndConvertDFDString(String message) { message = message.replaceFirst("DFD:", ""); + var name = message.split(":")[0]; + message = message.replaceFirst(name + ":", ""); var dfdMessage = message.split("\n:DD:\n")[0]; var ddMessage = message.split("\n:DD:\n")[1]; try { var dfd = createAndWriteTempFile(name + ".dataflowdiagram", dfdMessage); var dd = createAndWriteTempFile(name + ".datadictionary", ddMessage); return Converter.convertDFD(dfd, dd); - } catch (Exception e) { - e.printStackTrace(); - return null; + } catch (IOException e) { + e.printStackTrace(); + throw new IllegalArgumentException("Invalid DFD Model"); } } @@ -188,9 +188,9 @@ private WebEditorDfd safeLoadAndConvertPCMString(String message) { } } return Converter.convertPCM(usageModelFile, allocationFile, nodeCharacteristicsFile); - } catch (Exception e) { + } catch (IOException e) { e.printStackTrace(); - return null; + throw new IllegalArgumentException("Invalid PCM Model"); } } diff --git a/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/websocket/WebSocketServerUtils.java b/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/websocket/WebSocketServerUtils.java index bae1690..8018468 100644 --- a/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/websocket/WebSocketServerUtils.java +++ b/bundles/org.dataflowanalysis.standalone/src/org/dataflowanalysis/standalone/websocket/WebSocketServerUtils.java @@ -44,7 +44,6 @@ private static void startServer() { } catch (Exception e) { - // TODO Auto-generated catch block e.printStackTrace(); } } diff --git a/releng/org.dataflowanalysis.standalone.targetplatform/org.dataflowanalysis.standalone.targetplatform.targetplatform.target b/releng/org.dataflowanalysis.standalone.targetplatform/org.dataflowanalysis.standalone.targetplatform.targetplatform.target index b56c274..6ddbef9 100644 --- a/releng/org.dataflowanalysis.standalone.targetplatform/org.dataflowanalysis.standalone.targetplatform.targetplatform.target +++ b/releng/org.dataflowanalysis.standalone.targetplatform/org.dataflowanalysis.standalone.targetplatform.targetplatform.target @@ -142,18 +142,12 @@ - - - - - - - - - - + + + + \ No newline at end of file