From 69e1b1f83fb0add1b1749662c4acd4754b0fc012 Mon Sep 17 00:00:00 2001 From: Marco Grassi Date: Fri, 25 Jul 2025 09:51:52 +0200 Subject: [PATCH 1/4] ref: helper method rml to mtl --- .../java/com/cefriel/template/utils/Util.java | 41 +++++++++++++++++++ .../java/com/cefriel/template/RMLTests.java | 13 +++--- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/cefriel/template/utils/Util.java b/src/main/java/com/cefriel/template/utils/Util.java index 876fd79..fe8c46d 100644 --- a/src/main/java/com/cefriel/template/utils/Util.java +++ b/src/main/java/com/cefriel/template/utils/Util.java @@ -16,6 +16,7 @@ package com.cefriel.template.utils; +import com.cefriel.template.TemplateExecutor; import com.cefriel.template.TemplateMap; import com.cefriel.template.io.Formatter; import com.cefriel.template.io.Reader; @@ -331,4 +332,44 @@ public static VelocityContext createVelocityContext(Reader reader, TemplateMap t public static VelocityContext createVelocityContext(Map readers, TemplateMap templateMap) { return createVelocityContext(readers, templateMap, new TemplateFunctions()); } + + /** + * Compiles an MTL mapping from the given RML file. + * + * @param mappingRML Path to the RML mapping file. + * @param baseIri Base IRI to use if not found in the mapping. + * @param basePath Base path for output files. + * @param trimTemplate Whether to use the trimmed template. + * @param verbose Enable verbose validation output. + * @return Path to the compiled template. + * @throws Exception if validation or compilation fails. + */ + public static Path compiledMTLMapping(Path mappingRML, String baseIri, Path basePath, boolean trimTemplate, boolean verbose) throws Exception { + Util.validateRML(mappingRML, verbose); + + Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(mappingRML.toString()); + Map compilerReaderMap = new HashMap<>(); + compilerReaderMap.put("reader", compilerReader); + + Path rmlCompilerTemplatePath = trimTemplate + ? Paths.get("rml", "rml-compiler.vm.tmp.vm") + : Paths.get("rml", "rml-compiler.vm"); + RMLCompilerUtils rmlCompilerUtils = new RMLCompilerUtils(); + + Map rmlMap = new HashMap<>(); + String baseIriRML = rmlCompilerUtils.getBaseIRI(mappingRML); + baseIriRML = baseIriRML != null ? baseIriRML : baseIri; + rmlMap.put("baseIRI", baseIriRML); + rmlMap.put("basePath", basePath.toString() + "/"); + + Path compiledTemplatePath = Paths.get(basePath.toString(), "template.rml.vm"); + TemplateExecutor templateExecutor = new TemplateExecutor(false, false, true, null); + return templateExecutor.executeMapping( + compilerReaderMap, + rmlCompilerTemplatePath, + compiledTemplatePath, + rmlCompilerUtils, + new TemplateMap(rmlMap) + ); + } } diff --git a/src/test/java/com/cefriel/template/RMLTests.java b/src/test/java/com/cefriel/template/RMLTests.java index b2322d7..904ec12 100644 --- a/src/test/java/com/cefriel/template/RMLTests.java +++ b/src/test/java/com/cefriel/template/RMLTests.java @@ -54,7 +54,6 @@ public void invalidRMLTest() throws Exception { @Test public void validRMLTest() throws Exception { - String folder = "rml"; String rmlMappings = resolvePath(folder, "mapping.ttl"); @@ -63,17 +62,15 @@ public void validRMLTest() throws Exception { Util.validateRML(Paths.get(rmlMappings), false); Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(rmlMappings); - Path rmlCompiler = Paths.get("rml/rml-compiler.vm"); - Path compiledTemplatePath = Paths.get(resolvePath(folder,"template.rml.vm")); Map rmlMap = new HashMap<>(); - rmlMap.put("basePath", FOLDER); + rmlMap.put("basePath", null); + - TemplateExecutor rmlTemplateExecutor = new TemplateExecutor(false, false, true, null); TemplateExecutor templateExecutor = new TemplateExecutor(false, false, false, null); - rmlTemplateExecutor.executeMapping(Map.of("reader", compilerReader), rmlCompiler, compiledTemplatePath, new RMLCompilerUtils(), new TemplateMap(rmlMap)); - String result = templateExecutor.executeMapping(Map.of("reader", compilerReader), compiledTemplatePath); - Files.delete(compiledTemplatePath); + Path mappingMTL = Util.compiledMTLMapping(Path.of(rmlMappings), null, Path.of(FOLDER), false, false); + String result = templateExecutor.executeMapping(Map.of("reader", compilerReader), mappingMTL); + Files.delete(mappingMTL); Model resultModel = parseRDFString(result); Model expectedOutputModel = parseRDFString(expectedOutput); From 896741c9b84af354460c54d5e2252ff4fedb05a8 Mon Sep 17 00:00:00 2001 From: Marco Grassi Date: Thu, 2 Oct 2025 15:31:12 +0200 Subject: [PATCH 2/4] ref: rmlMapping as InputStream Previously, Path was used, but switching to InputStream simplifies invocation from Chimera without sacrificing performance. --- src/main/java/com/cefriel/template/Main.java | 6 ++- .../java/com/cefriel/template/utils/Util.java | 42 +++++++++---------- .../java/com/cefriel/template/RMLTests.java | 33 +++++++-------- 3 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/cefriel/template/Main.java b/src/main/java/com/cefriel/template/Main.java index ce5d83b..863aff7 100644 --- a/src/main/java/com/cefriel/template/Main.java +++ b/src/main/java/com/cefriel/template/Main.java @@ -29,6 +29,7 @@ import javax.tools.ToolProvider; import java.io.File; import java.io.FileWriter; +import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; import java.nio.file.Files; @@ -181,7 +182,10 @@ public void exec() throws Exception { } } if(compileRML) { - Util.validateRML(templatePath, verbose); + try (InputStream rmlMappingStream = Files.newInputStream(templatePath)) + { + Util.validateRML(rmlMappingStream, verbose); + } Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(templatePath.toString()); Map compilerReaderMap = new HashMap<>(); diff --git a/src/main/java/com/cefriel/template/utils/Util.java b/src/main/java/com/cefriel/template/utils/Util.java index fe8c46d..6506820 100644 --- a/src/main/java/com/cefriel/template/utils/Util.java +++ b/src/main/java/com/cefriel/template/utils/Util.java @@ -200,7 +200,8 @@ public static VelocityEngine createVelocityEngine(boolean templateInResources, b velocityEngine.init(); return velocityEngine; } - public static void validateRML(Path templatePath, boolean verbose) { + + public static void validateRML(InputStream rmlMapping, boolean verbose) { ShaclSail shaclSail = new ShaclSail(new MemoryStore()); SailRepository repository = new SailRepository(shaclSail); @@ -209,33 +210,25 @@ public static void validateRML(Path templatePath, boolean verbose) { try (RepositoryConnection connection = repository.getConnection()) { try (InputStream shapesStream = Util.class.getResourceAsStream("/rml/core.ttl")) { Model rules = Rio.parse(shapesStream, RDFFormat.TURTLE); - // cf. https://github.com/eclipse-rdf4j/rdf4j/discussions/4287 rules.remove(null, SHACL.NAME, null); rules.remove(null, SHACL.DESCRIPTION, null); - connection.begin(); connection.add(rules, RDF4J.SHACL_SHAPE_GRAPH); connection.commit(); } - - // Load RML - try (InputStream dataStream = Files.newInputStream(templatePath)) { - connection.begin(); - connection.add(dataStream, "", org.eclipse.rdf4j.rio.RDFFormat.TURTLE); - - try { - connection.commit(); - log.info("RML validated correctly"); - } catch (RepositoryException exception) { - Throwable cause = exception.getCause(); - log.error("RML not valid"); - if (verbose) - if (cause instanceof ValidationException) { - Model validationReportModel = ((ValidationException) cause).validationReportAsModel(); - Rio.write(validationReportModel, System.out, RDFFormat.TURTLE); - } - throw exception; + connection.begin(); + connection.add(rmlMapping, "", RDFFormat.TURTLE); + try { + connection.commit(); + log.info("RML validated correctly"); + } catch (RepositoryException exception) { + Throwable cause = exception.getCause(); + log.error("RML not valid"); + if (verbose && cause instanceof ValidationException) { + Model validationReportModel = ((ValidationException) cause).validationReportAsModel(); + Rio.write(validationReportModel, System.out, RDFFormat.TURTLE); } + throw exception; } } catch (Exception e) { throw new RuntimeException(e); @@ -244,6 +237,7 @@ public static void validateRML(Path templatePath, boolean verbose) { } } + /** * Creates a new {@link VelocityContext} and populates it with the provided readers, template map, and template functions. * Additionally, it adds a set of common tools for mathematical operations, number formatting, date manipulation, @@ -345,7 +339,11 @@ public static VelocityContext createVelocityContext(Map readers, * @throws Exception if validation or compilation fails. */ public static Path compiledMTLMapping(Path mappingRML, String baseIri, Path basePath, boolean trimTemplate, boolean verbose) throws Exception { - Util.validateRML(mappingRML, verbose); + + try (InputStream mappingRMLStream = Files.newInputStream(mappingRML)) { + Util.validateRML(mappingRMLStream, verbose); + } + Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(mappingRML.toString()); Map compilerReaderMap = new HashMap<>(); diff --git a/src/test/java/com/cefriel/template/RMLTests.java b/src/test/java/com/cefriel/template/RMLTests.java index 904ec12..0d57332 100644 --- a/src/test/java/com/cefriel/template/RMLTests.java +++ b/src/test/java/com/cefriel/template/RMLTests.java @@ -29,6 +29,7 @@ import org.eclipse.rdf4j.rio.helpers.StatementCollector; import org.junit.jupiter.api.Test; +import java.io.InputStream; import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Path; @@ -40,36 +41,34 @@ public class RMLTests { - final static String FOLDER = "src/test/resources/rml/"; - private String resolvePath(String folder, String file) { - return FOLDER + file; - } + final static Path FOLDER = Path.of("src/test/resources/rml/"); @Test public void invalidRMLTest() throws Exception { - String folder = "rml"; - Path rmlMappings = Paths.get(resolvePath(folder, "invalid-mapping.ttl")); - assertThrows(RuntimeException.class, () -> Util.validateRML(rmlMappings, false)); + Path rmlMappings = FOLDER.resolve(Path.of("invalid-mapping.ttl")); + try (InputStream rmlMapping = Files.newInputStream(rmlMappings)) { + assertThrows(RuntimeException.class, + () -> Util.validateRML(rmlMapping, false)); + } } @Test public void validRMLTest() throws Exception { - String folder = "rml"; - String rmlMappings = resolvePath(folder, "mapping.ttl"); - - String expectedOutput = Files.readString(Paths.get(resolvePath(folder, "output.nq"))); + Path rmlMapping = FOLDER.resolve(Path.of("mapping.ttl")); + String expectedOutput = Files.readString(FOLDER.resolve("output.nq")); - Util.validateRML(Paths.get(rmlMappings), false); + try (InputStream rmlMappingStream = Files.newInputStream(rmlMapping)) { + Util.validateRML(rmlMappingStream, false); + } - Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(rmlMappings); + Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(rmlMapping.toString()); Map rmlMap = new HashMap<>(); rmlMap.put("basePath", null); - TemplateExecutor templateExecutor = new TemplateExecutor(false, false, false, null); - Path mappingMTL = Util.compiledMTLMapping(Path.of(rmlMappings), null, Path.of(FOLDER), false, false); - String result = templateExecutor.executeMapping(Map.of("reader", compilerReader), mappingMTL); + Path mappingMTL = Util.compiledMTLMapping(rmlMapping, null, FOLDER, false, false); + String result = templateExecutor.executeMapping(Map.of("reader", compilerReader), FOLDER.resolve(mappingMTL.getFileName())); Files.delete(mappingMTL); Model resultModel = parseRDFString(result); @@ -80,11 +79,9 @@ public void validRMLTest() throws Exception { private static Model parseRDFString(String rdfString) throws Exception { RDFParser rdfParser = Rio.createParser(RDFFormat.NQUADS); - Model model = new TreeModel(); rdfParser.setRDFHandler(new StatementCollector(model)); rdfParser.parse(new StringReader(rdfString), "http://example.com/base/"); return model; } - } \ No newline at end of file From 2561cb9db808f17eca5b35a145315502d92ef6ef Mon Sep 17 00:00:00 2001 From: Marco Grassi Date: Thu, 2 Oct 2025 15:31:12 +0200 Subject: [PATCH 3/4] ref: rmlMapping as InputStream Previously, Path was used, but switching to InputStream simplifies invocation from Chimera without sacrificing performance. --- src/main/java/com/cefriel/template/Main.java | 6 ++- .../template/utils/RMLCompilerUtils.java | 21 ++++---- .../java/com/cefriel/template/utils/Util.java | 48 +++++++++---------- .../java/com/cefriel/template/RMLTests.java | 43 ++++++++--------- 4 files changed, 60 insertions(+), 58 deletions(-) diff --git a/src/main/java/com/cefriel/template/Main.java b/src/main/java/com/cefriel/template/Main.java index ce5d83b..863aff7 100644 --- a/src/main/java/com/cefriel/template/Main.java +++ b/src/main/java/com/cefriel/template/Main.java @@ -29,6 +29,7 @@ import javax.tools.ToolProvider; import java.io.File; import java.io.FileWriter; +import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; import java.nio.file.Files; @@ -181,7 +182,10 @@ public void exec() throws Exception { } } if(compileRML) { - Util.validateRML(templatePath, verbose); + try (InputStream rmlMappingStream = Files.newInputStream(templatePath)) + { + Util.validateRML(rmlMappingStream, verbose); + } Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(templatePath.toString()); Map compilerReaderMap = new HashMap<>(); diff --git a/src/main/java/com/cefriel/template/utils/RMLCompilerUtils.java b/src/main/java/com/cefriel/template/utils/RMLCompilerUtils.java index a3b4ec2..d2e28ab 100644 --- a/src/main/java/com/cefriel/template/utils/RMLCompilerUtils.java +++ b/src/main/java/com/cefriel/template/utils/RMLCompilerUtils.java @@ -209,6 +209,17 @@ public boolean checkReference(String s){ return false; } + public String getBaseIRI(String turtle) { + Pattern p = Pattern.compile("@base <([^<>]*)>"); + Matcher m = p.matcher(turtle); + + if (m.find()) { + return m.group(1); + } else { + return null; + } + } + /** * From rmlmapper ... * @@ -223,15 +234,7 @@ public String getBaseIRI(Path rmlPath) { } catch (IOException e) { turtle = ""; } - - Pattern p = Pattern.compile("@base <([^<>]*)>"); - Matcher m = p.matcher(turtle); - - if (m.find()) { - return m.group(1); - } else { - return null; - } + return getBaseIRI(turtle); } } diff --git a/src/main/java/com/cefriel/template/utils/Util.java b/src/main/java/com/cefriel/template/utils/Util.java index fe8c46d..09239c4 100644 --- a/src/main/java/com/cefriel/template/utils/Util.java +++ b/src/main/java/com/cefriel/template/utils/Util.java @@ -34,6 +34,7 @@ import org.apache.velocity.tools.generic.*; import org.eclipse.rdf4j.common.exception.ValidationException; import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.base.CoreDatatype; import org.eclipse.rdf4j.model.vocabulary.RDF4J; import org.eclipse.rdf4j.model.vocabulary.SHACL; import org.eclipse.rdf4j.repository.RepositoryConnection; @@ -46,6 +47,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -200,7 +202,8 @@ public static VelocityEngine createVelocityEngine(boolean templateInResources, b velocityEngine.init(); return velocityEngine; } - public static void validateRML(Path templatePath, boolean verbose) { + + public static void validateRML(InputStream rmlMapping, boolean verbose) { ShaclSail shaclSail = new ShaclSail(new MemoryStore()); SailRepository repository = new SailRepository(shaclSail); @@ -209,33 +212,25 @@ public static void validateRML(Path templatePath, boolean verbose) { try (RepositoryConnection connection = repository.getConnection()) { try (InputStream shapesStream = Util.class.getResourceAsStream("/rml/core.ttl")) { Model rules = Rio.parse(shapesStream, RDFFormat.TURTLE); - // cf. https://github.com/eclipse-rdf4j/rdf4j/discussions/4287 rules.remove(null, SHACL.NAME, null); rules.remove(null, SHACL.DESCRIPTION, null); - connection.begin(); connection.add(rules, RDF4J.SHACL_SHAPE_GRAPH); connection.commit(); } - - // Load RML - try (InputStream dataStream = Files.newInputStream(templatePath)) { - connection.begin(); - connection.add(dataStream, "", org.eclipse.rdf4j.rio.RDFFormat.TURTLE); - - try { - connection.commit(); - log.info("RML validated correctly"); - } catch (RepositoryException exception) { - Throwable cause = exception.getCause(); - log.error("RML not valid"); - if (verbose) - if (cause instanceof ValidationException) { - Model validationReportModel = ((ValidationException) cause).validationReportAsModel(); - Rio.write(validationReportModel, System.out, RDFFormat.TURTLE); - } - throw exception; + connection.begin(); + connection.add(rmlMapping, "", RDFFormat.TURTLE); + try { + connection.commit(); + log.info("RML validated correctly"); + } catch (RepositoryException exception) { + Throwable cause = exception.getCause(); + log.error("RML not valid"); + if (verbose && cause instanceof ValidationException) { + Model validationReportModel = ((ValidationException) cause).validationReportAsModel(); + Rio.write(validationReportModel, System.out, RDFFormat.TURTLE); } + throw exception; } } catch (Exception e) { throw new RuntimeException(e); @@ -244,6 +239,7 @@ public static void validateRML(Path templatePath, boolean verbose) { } } + /** * Creates a new {@link VelocityContext} and populates it with the provided readers, template map, and template functions. * Additionally, it adds a set of common tools for mathematical operations, number formatting, date manipulation, @@ -344,10 +340,10 @@ public static VelocityContext createVelocityContext(Map readers, * @return Path to the compiled template. * @throws Exception if validation or compilation fails. */ - public static Path compiledMTLMapping(Path mappingRML, String baseIri, Path basePath, boolean trimTemplate, boolean verbose) throws Exception { - Util.validateRML(mappingRML, verbose); - - Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(mappingRML.toString()); + public static Path compiledMTLMapping(InputStream mappingRML, String baseIri, Path basePath, boolean trimTemplate, boolean verbose) throws Exception { + String mappingRMLString = inputStreamToString(mappingRML); + Util.validateRML(new ByteArrayInputStream(mappingRMLString.getBytes(StandardCharsets.UTF_8)), verbose); + Reader compilerReader = TemplateFunctions.getRDFReaderFromString(mappingRMLString, RDFFormat.TURTLE.toString()); Map compilerReaderMap = new HashMap<>(); compilerReaderMap.put("reader", compilerReader); @@ -357,7 +353,7 @@ public static Path compiledMTLMapping(Path mappingRML, String baseIri, Path base RMLCompilerUtils rmlCompilerUtils = new RMLCompilerUtils(); Map rmlMap = new HashMap<>(); - String baseIriRML = rmlCompilerUtils.getBaseIRI(mappingRML); + String baseIriRML = rmlCompilerUtils.getBaseIRI(mappingRMLString); baseIriRML = baseIriRML != null ? baseIriRML : baseIri; rmlMap.put("baseIRI", baseIriRML); rmlMap.put("basePath", basePath.toString() + "/"); diff --git a/src/test/java/com/cefriel/template/RMLTests.java b/src/test/java/com/cefriel/template/RMLTests.java index 904ec12..e51f5e0 100644 --- a/src/test/java/com/cefriel/template/RMLTests.java +++ b/src/test/java/com/cefriel/template/RMLTests.java @@ -29,6 +29,7 @@ import org.eclipse.rdf4j.rio.helpers.StatementCollector; import org.junit.jupiter.api.Test; +import java.io.InputStream; import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Path; @@ -40,51 +41,49 @@ public class RMLTests { - final static String FOLDER = "src/test/resources/rml/"; - private String resolvePath(String folder, String file) { - return FOLDER + file; - } + final static Path FOLDER = Path.of("src/test/resources/rml/"); @Test public void invalidRMLTest() throws Exception { - String folder = "rml"; - Path rmlMappings = Paths.get(resolvePath(folder, "invalid-mapping.ttl")); - assertThrows(RuntimeException.class, () -> Util.validateRML(rmlMappings, false)); + Path rmlMappings = FOLDER.resolve(Path.of("invalid-mapping.ttl")); + try (InputStream rmlMapping = Files.newInputStream(rmlMappings)) { + assertThrows(RuntimeException.class, + () -> Util.validateRML(rmlMapping, false)); + } } @Test public void validRMLTest() throws Exception { - String folder = "rml"; - String rmlMappings = resolvePath(folder, "mapping.ttl"); - - String expectedOutput = Files.readString(Paths.get(resolvePath(folder, "output.nq"))); + Path rmlMapping = FOLDER.resolve(Path.of("mapping.ttl")); + String expectedOutput = Files.readString(FOLDER.resolve("output.nq")); - Util.validateRML(Paths.get(rmlMappings), false); + try (InputStream rmlMappingStream = Files.newInputStream(rmlMapping)) { + Util.validateRML(rmlMappingStream, false); + } - Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(rmlMappings); + Reader compilerReader = TemplateFunctions.getRDFReaderFromFile(rmlMapping.toString()); Map rmlMap = new HashMap<>(); rmlMap.put("basePath", null); - TemplateExecutor templateExecutor = new TemplateExecutor(false, false, false, null); - Path mappingMTL = Util.compiledMTLMapping(Path.of(rmlMappings), null, Path.of(FOLDER), false, false); - String result = templateExecutor.executeMapping(Map.of("reader", compilerReader), mappingMTL); - Files.delete(mappingMTL); + try (InputStream rmlMappingStream = Files.newInputStream(rmlMapping)) { + Path mappingMTL = Util.compiledMTLMapping(rmlMappingStream, null, FOLDER, false, false); + String result = templateExecutor.executeMapping(Map.of("reader", compilerReader), FOLDER.resolve(mappingMTL.getFileName())); + Files.delete(mappingMTL); - Model resultModel = parseRDFString(result); - Model expectedOutputModel = parseRDFString(expectedOutput); + Model resultModel = parseRDFString(result); + Model expectedOutputModel = parseRDFString(expectedOutput); - assert(Models.isomorphic(resultModel, expectedOutputModel)); + assert(Models.isomorphic(resultModel, expectedOutputModel)); + } } private static Model parseRDFString(String rdfString) throws Exception { RDFParser rdfParser = Rio.createParser(RDFFormat.NQUADS); - Model model = new TreeModel(); rdfParser.setRDFHandler(new StatementCollector(model)); rdfParser.parse(new StringReader(rdfString), "http://example.com/base/"); return model; } - } \ No newline at end of file From 60d2634c1df09d1be2b44ccf49bdbf1ba272dd24 Mon Sep 17 00:00:00 2001 From: Marco Grassi Date: Mon, 6 Oct 2025 15:26:02 +0200 Subject: [PATCH 4/4] ref: "" as root path for FileResourceLoader --- src/main/java/com/cefriel/template/utils/Util.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/cefriel/template/utils/Util.java b/src/main/java/com/cefriel/template/utils/Util.java index 57fc699..0350f00 100644 --- a/src/main/java/com/cefriel/template/utils/Util.java +++ b/src/main/java/com/cefriel/template/utils/Util.java @@ -31,6 +31,7 @@ import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; +import org.apache.velocity.runtime.resource.loader.FileResourceLoader; import org.apache.velocity.tools.generic.*; import org.eclipse.rdf4j.common.exception.ValidationException; import org.eclipse.rdf4j.model.Model; @@ -198,6 +199,10 @@ public static VelocityEngine createVelocityEngine(boolean templateInResources, b velocityEngine.setProperty("resource.loaders", "class"); velocityEngine.setProperty("resource.loader.class.class", ClasspathResourceLoader.class.getName()); + } else{ + velocityEngine.setProperty("resource.loaders", "file"); + velocityEngine.setProperty("resource.loader.file.class", FileResourceLoader.class.getName()); + velocityEngine.setProperty("resource.loader.file.path", ""); } velocityEngine.init(); return velocityEngine;