diff --git a/build.gradle b/build.gradle index 9f647f5..72449b8 100644 --- a/build.gradle +++ b/build.gradle @@ -443,6 +443,10 @@ project('cogni-sem') { // spring api('org.springframework.boot:spring-boot-starter') + + // TESTING + testImplementation('org.springframework.boot:spring-boot-starter-test') + testImplementation project(':cogni-libs') } } diff --git a/cogni-sem/src/main/java/zone/cogni/sem/jena/SparqlUtils.java b/cogni-sem/src/main/java/zone/cogni/sem/jena/SparqlUtils.java index 8f3cbcc..fb48a78 100644 --- a/cogni-sem/src/main/java/zone/cogni/sem/jena/SparqlUtils.java +++ b/cogni-sem/src/main/java/zone/cogni/sem/jena/SparqlUtils.java @@ -1,12 +1,16 @@ package zone.cogni.sem.jena; -import org.apache.commons.lang3.StringUtils; - public enum SparqlUtils { ; - public static String escapeLiteral(String literal) { - return StringUtils.replace(literal, "'", "\\'"); - + public static String escapeString(String literal) { + return literal.replace("\\", "\\\\") // Escape backslash, needs to be first otherwise it will escape the backslashes of the already escaped literals + .replace("\t", "\\t") // Escape tab + .replace("\b", "\\b") // Escape backspace + .replace("\n", "\\n") // Escape newline + .replace("\r", "\\r") // Escape carriage return + .replace("\f", "\\f") // Escape formfeed + .replace("'", "\\'") // Escape single quote + .replace("\"", "\\\""); // Escape double quote } } diff --git a/cogni-sem/src/test/java/zone/cogni/sem/jena/SparqlUtilsTest.java b/cogni-sem/src/test/java/zone/cogni/sem/jena/SparqlUtilsTest.java new file mode 100644 index 0000000..c303051 --- /dev/null +++ b/cogni-sem/src/test/java/zone/cogni/sem/jena/SparqlUtilsTest.java @@ -0,0 +1,75 @@ +package zone.cogni.sem.jena; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import zone.cogni.libs.sparqlservice.impl.JenaModelSparqlService; + +public class SparqlUtilsTest { + private static final String URI = "https://fedlex.data.admin.ch/eli/oc/2023/423/legal-analysis"; + private static final String GRAPH_URI = URI + "/graph"; + private final JenaModelSparqlService jenaModelSparqlService = new JenaModelSparqlService(); + + @Test + public void test() { + // test single quotes + testEscape("A\ncomment", '\''); // test newline + testEscape("A\\comment", '\''); // test backslash + testEscape("A\bcomment", '\''); // test backspace + testEscape("I'mAComment", '\''); // test single quote + testEscape("A\fcomment", '\''); // test form feed + testEscape("A\tcomment", '\''); // test tab + testEscape("A\rcomment", '\''); // test carriage return + testEscape("com\"ment", '\''); // test double quotes + testEscape("This\nis\\A\bco'mment\fthat\ttests\rall\"the\tcases", '\''); // test all cases + testEscape("A\\ncomment", '\''); // test mixed case + testEscape("A\b\tcomment", '\''); // test mixed case + + // test double quotes + testEscape("A\ncomment", '\"'); // test newline + testEscape("A\\comment", '\"'); // test backslash + testEscape("A\bcomment", '\"'); // test backspace + testEscape("I'mAComment", '\"'); // test single quote + testEscape("A\fcomment", '\"'); // test form feed + testEscape("A\tcomment", '\"'); // test tab + testEscape("A\rcomment", '\"'); // test carriage return + testEscape("com\"ment", '\"'); // test double quotes + testEscape("This\nis\\A\bco'mment\fthat\ttests\rall\"the\tcases", '\"'); // test all cases + testEscape("A\\ncomment", '\"'); // test mixed case + testEscape("A\b\tcomment", '\"'); // test mixed case + } + + private void testEscape(String value, char quote) { + initializeSource(value, quote); + confirmResult(value); + } + + private void initializeSource(String value, char quote) { + jenaModelSparqlService.executeUpdateQuery( + "PREFIX jolux: " + + "INSERT DATA { " + + " GRAPH <" + GRAPH_URI + "> { " + + " <" + URI + "> a jolux:LegalAnalysis. " + + " <" + URI + "> jolux:impactFromLegalResourceComment " + quote + SparqlUtils.escapeString(value) + quote + + " }" + + "}" + ); + } + + private void confirmResult(String value) { + String query = "PREFIX jolux: \n" + + "SELECT ?comment\n" + + "WHERE {\n" + + " GRAPH <" + GRAPH_URI + "> {\n" + + " <" + URI + "> a jolux:LegalAnalysis ;\n" + + " jolux:impactFromLegalResourceComment ?comment .\n" + + " }\n" + + "}"; + jenaModelSparqlService.executeSelectQuery(query, resultSet -> { + resultSet.forEachRemaining(result -> Assertions.assertEquals(value, result.get("comment") + .asLiteral() + .getValue())); + return null; + }); + jenaModelSparqlService.dropGraph(GRAPH_URI); + } +}