diff --git a/gradoop-flink/src/main/java/org/gradoop/flink/io/impl/dot/functions/AbstractDotFileFormat.java b/gradoop-flink/src/main/java/org/gradoop/flink/io/impl/dot/functions/AbstractDotFileFormat.java index 08de03d7cfa4..e19feb97aa48 100644 --- a/gradoop-flink/src/main/java/org/gradoop/flink/io/impl/dot/functions/AbstractDotFileFormat.java +++ b/gradoop-flink/src/main/java/org/gradoop/flink/io/impl/dot/functions/AbstractDotFileFormat.java @@ -127,7 +127,7 @@ private void writeEdges(GraphTransaction transaction, StringBuilder builder, Str .append(edge.getTargetId()) .append(suffix) .append(" ["); - // write dot attributes if existent + // write dot attributes if present writeLabel(builder, edge); builder.append("];\n"); } diff --git a/gradoop-flink/src/main/java/org/gradoop/flink/io/impl/dot/functions/DotFileFormatSimple.java b/gradoop-flink/src/main/java/org/gradoop/flink/io/impl/dot/functions/DotFileFormatSimple.java index bdd8e7602298..c5edd2d3b900 100644 --- a/gradoop-flink/src/main/java/org/gradoop/flink/io/impl/dot/functions/DotFileFormatSimple.java +++ b/gradoop-flink/src/main/java/org/gradoop/flink/io/impl/dot/functions/DotFileFormatSimple.java @@ -22,6 +22,8 @@ import org.gradoop.common.model.impl.properties.Property; import org.gradoop.flink.model.impl.layouts.transactional.tuples.GraphTransaction; +import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; + /** * Converts a GraphTransaction to the following .dot format: *

{@code @@ -79,17 +81,17 @@ void writeLabel(StringBuilder builder, Element element) { Properties properties = element.getProperties(); if (properties != null && properties.size() > 0) { - builder.append("label=\"").append(label).append("\""); + builder.append("label=\"").append(escapeJava(label)).append("\""); for (Property property: properties) { builder.append(",") - .append(property.getKey()) + .append(escapeJava(property.getKey())) .append("=\"") - .append(property.getValue().toString()) + .append(escapeJava(property.getValue().toString())) .append("\""); } } else { - builder.append("label=\"").append(label).append("\""); + builder.append("label=\"").append(escapeJava(label)).append("\""); } } } diff --git a/gradoop-flink/src/test/java/org/gradoop/flink/io/impl/dot/DOTDataSinkTest.java b/gradoop-flink/src/test/java/org/gradoop/flink/io/impl/dot/DOTDataSinkTest.java index dc92ad6485fd..02edd4a9689e 100644 --- a/gradoop-flink/src/test/java/org/gradoop/flink/io/impl/dot/DOTDataSinkTest.java +++ b/gradoop-flink/src/test/java/org/gradoop/flink/io/impl/dot/DOTDataSinkTest.java @@ -128,7 +128,7 @@ private void checkWriteOutput(List lines, DOTDataSink.DotFormat format) countSubgraphLines++; } - if (format == DOTDataSink.DotFormat.HTML) { + if (format.equals(DOTDataSink.DotFormat.HTML)) { int index = line.indexOf('&'); if (index != -1) { assertTrue("HTML entity & should have been escaped", line.substring(index).startsWith("&")); diff --git a/gradoop-flink/src/test/java/org/gradoop/flink/io/impl/dot/functions/DotFileFormatSimpleTest.java b/gradoop-flink/src/test/java/org/gradoop/flink/io/impl/dot/functions/DotFileFormatSimpleTest.java index 12fe081b4da5..484321ad1821 100644 --- a/gradoop-flink/src/test/java/org/gradoop/flink/io/impl/dot/functions/DotFileFormatSimpleTest.java +++ b/gradoop-flink/src/test/java/org/gradoop/flink/io/impl/dot/functions/DotFileFormatSimpleTest.java @@ -54,18 +54,21 @@ public void initGraphTransactionMock() { propertiesMap1.put("name", "Tom"); propertiesMap1.put("age", 25); GradoopId idVertex1 = GradoopId.fromString("bbbbbbbbbbbbbbbbbbbbbbbb"); - EPGMVertex vertex1 = new EPGMVertexFactory().initVertex(idVertex1, "Person", Properties.createFromMap(propertiesMap1)); + EPGMVertex vertex1 = new EPGMVertexFactory().initVertex( + idVertex1, "Person", Properties.createFromMap(propertiesMap1)); // init vertex 2 Map propertiesMap2 = new HashMap<>(); propertiesMap2.put("lan", "EN"); GradoopId idVertex2 = GradoopId.fromString("cccccccccccccccccccccccc"); - EPGMVertex vertex2 = new EPGMVertexFactory().initVertex(idVertex2, "Forum", Properties.createFromMap(propertiesMap2)); + EPGMVertex vertex2 = new EPGMVertexFactory().initVertex( + idVertex2, "Forum", Properties.createFromMap(propertiesMap2)); // init vertex 3 Map propertiesMap3 = new HashMap<>(); propertiesMap3.put("name", "Anna"); propertiesMap3.put("age", 27); GradoopId idVertex3 = GradoopId.fromString("dddddddddddddddddddddddd"); - EPGMVertex vertex3 = new EPGMVertexFactory().initVertex(idVertex3, "Person", Properties.createFromMap(propertiesMap3)); + EPGMVertex vertex3 = new EPGMVertexFactory().initVertex( + idVertex3, "Person", Properties.createFromMap(propertiesMap3)); // create vertex set Set vertices = new HashSet<>(); vertices.add(vertex1); @@ -103,11 +106,54 @@ public void testFormat() { "vddddddddddddddddddddddddaaaaaaaaaaaaaaaaaaaaaaaa [label=\"Person\",name=\"Anna\",age=\"27\"];\n" + "vbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaa [label=\"Person\",name=\"Tom\",age=\"25\"];\n" + "vccccccccccccccccccccccccaaaaaaaaaaaaaaaaaaaaaaaa [label=\"Forum\",lan=\"EN\"];\n" + - "vddddddddddddddddddddddddaaaaaaaaaaaaaaaaaaaaaaaa->vbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaa [label=\"knows\"];\n" + - "vccccccccccccccccccccccccaaaaaaaaaaaaaaaaaaaaaaaa->vddddddddddddddddddddddddaaaaaaaaaaaaaaaaaaaaaaaa [label=\"hasModerator\"];\n" + - "vbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaa->vddddddddddddddddddddddddaaaaaaaaaaaaaaaaaaaaaaaa [label=\"knows\"];\n" + + "vddddddddddddddddddddddddaaaaaaaaaaaaaaaaaaaaaaaa->" + + "vbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaa [label=\"knows\"];\n" + + "vccccccccccccccccccccccccaaaaaaaaaaaaaaaaaaaaaaaa->" + + "vddddddddddddddddddddddddaaaaaaaaaaaaaaaaaaaaaaaa [label=\"hasModerator\"];\n" + + "vbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaa->" + + "vddddddddddddddddddddddddaaaaaaaaaaaaaaaaaaaaaaaa [label=\"knows\"];\n" + "}\n"; assertEquals(expected, dotFileFormat.format(transaction)); } + + /** + * Tests whether label and property value strings are being escaped according to java string rules. + */ + @Test + public void testStringEscaping() { + EPGMGraphHead graphHead = new EPGMGraphHeadFactory() + .initGraphHead(GradoopId.fromString("aaaaaaaaaaaaaaaaaaaaaaaa"), "graph"); + + String key = "Title"; + String value = "Why was Wojo occasionally known to say \"I'm too lazy!\"?"; + + // init vertex 1 + Map propertiesMap1 = new HashMap<>(); + propertiesMap1.put(key, value); + GradoopId idVertex1 = GradoopId.fromString("bbbbbbbbbbbbbbbbbbbbbbbb"); + EPGMVertex vertex1 = new EPGMVertexFactory().initVertex( + idVertex1, "weird\nlabe\"l", Properties.createFromMap(propertiesMap1)); + + // create vertex set + Set vertices = new HashSet<>(); + vertices.add(vertex1); + // create empty edge set + Set edges = new HashSet<>(); + + GraphTransaction transactionMock = mock(GraphTransaction.class); + when(transactionMock.getGraphHead()).thenReturn(graphHead); + when(transactionMock.getVertices()).thenReturn(vertices); + when(transactionMock.getEdges()).thenReturn(edges); + + DotFileFormatSimple dotFileFormatSimple = new DotFileFormatSimple(true); + + String expected = "subgraph cluster_gaaaaaaaaaaaaaaaaaaaaaaaa{\n" + + "label=\"graph\";\n" + + "vbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaa [label=\"weird\\nlabe\\\"l\"," + + "Title=\"Why was Wojo occasionally known to say \\\"I'm too lazy!\\\"?\"];\n" + + "}\n"; + + assertEquals(expected, dotFileFormatSimple.format(transactionMock)); + } }