diff --git a/README.md b/README.md index 18415aa6..2cabf218 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ nothing() ##### `put_filemap` -Defines an external map for [lookup](#lookup) from a file. Maps with more than 2 columns are supported but are reduced to a defined key and a value column. +Defines an external map for [lookup](#lookup) from a file or a URL. Maps with more than 2 columns are supported but are reduced to a defined key and a value column. ```perl put_filemap("", "", sep_char: "\t") diff --git a/metafix/src/main/java/org/metafacture/metafix/Metafix.java b/metafix/src/main/java/org/metafacture/metafix/Metafix.java index 1e2280a6..d4e360e7 100644 --- a/metafix/src/main/java/org/metafacture/metafix/Metafix.java +++ b/metafix/src/main/java/org/metafacture/metafix/Metafix.java @@ -36,6 +36,8 @@ import java.io.Reader; import java.io.StringReader; import java.io.UncheckedIOException; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -56,8 +58,7 @@ * @author Christoph Böhme (Metamorph) * @author Fabian Steeg (Metafix) */ -public class Metafix implements StreamPipe, Maps { - +public class Metafix implements StreamPipe, Maps { // checkstyle-disable-line ClassDataAbstractionCoupling public static final String ARRAY_MARKER = "[]"; public static final String FIX_EXTENSION = ".fix"; public static final String VAR_END = "]"; @@ -148,26 +149,44 @@ public void literal(final String name, final String value) { } public String resolvePath(final String path) { - final Path basePath; + final String resolvedPath; - if (path.startsWith(".")) { - if (fixFile != null) { - basePath = getPath(fixFile).getParent(); + if (isValidUrl(path)) { + resolvedPath = path; + LOG.debug("Resolved path: url = '{}'", resolvedPath); + } + else { + final Path basePath; + + if (path.startsWith(".")) { + if (fixFile != null) { + basePath = getPath(fixFile).getParent(); + } + else { + throw new IllegalArgumentException("Cannot resolve relative path: " + path); + } } else { - throw new IllegalArgumentException("Cannot resolve relative path: " + path); + basePath = getPath(""); } - } - else { - basePath = getPath(""); - } - final String resolvedPath = basePath.resolve(path).normalize().toString(); - LOG.debug("Resolved path: base = '{}', path = '{}', result = '{}'", basePath, path, resolvedPath); + resolvedPath = basePath.resolve(path).normalize().toString(); + LOG.debug("Resolved path: base = '{}', path = '{}', result = '{}'", basePath, path, resolvedPath); + } return resolvedPath; } + private boolean isValidUrl(final String url) { + try { + new URL(url); + return true; + } + catch (final MalformedURLException e) { + return false; + } + } + private Path getPath(final String path) { return Paths.get(path).toAbsolutePath().normalize(); } diff --git a/metafix/src/test/java/org/metafacture/metafix/MetafixLookupTest.java b/metafix/src/test/java/org/metafacture/metafix/MetafixLookupTest.java index 4457f572..67b9fa54 100644 --- a/metafix/src/test/java/org/metafacture/metafix/MetafixLookupTest.java +++ b/metafix/src/test/java/org/metafacture/metafix/MetafixLookupTest.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; +import java.util.Objects; import java.util.stream.Collectors; /** @@ -46,6 +47,8 @@ @ExtendWith(MockitoExtension.class) public class MetafixLookupTest { private static final String CSV_MAP = "src/test/resources/org/metafacture/metafix/maps/test.csv"; + private static final String CSV_PATH = "/maps/test.csv"; + private static final String CSV_URL = "%s" + CSV_PATH; private static final String RDF_MAP = "src/test/resources/org/metafacture/metafix/maps/test.ttl"; private static final String HCRT_RDF_MAP = "src/test/resources/org/metafacture/metafix/maps/hcrt.ttl"; private static final String RDF_PATH = "/maps/rpb.ttl"; @@ -67,20 +70,27 @@ public MetafixLookupTest() { private static void setStubForWireMock() { WIRE_MOCK_SERVER.start(); - final UrlPattern urlPattern = WireMock.urlPathEqualTo(RDF_PATH); + // stubs for RDF + final UrlPattern rdfUrlPattern = WireMock.urlPathEqualTo(RDF_PATH); final String redirectToUrl = "/redirect" + RDF_PATH; final UrlPattern urlPatternRedirectToUrl = WireMock.urlPathEqualTo(redirectToUrl); - - WIRE_MOCK_SERVER.stubFor(WireMock.get(urlPattern) + WIRE_MOCK_SERVER.stubFor(WireMock.get(rdfUrlPattern) .willReturn(WireMock.temporaryRedirect(redirectToUrl))); - - final String responseBody = new BufferedReader(new InputStreamReader( - MetafixLookupTest.class.getResourceAsStream("." + RDF_PATH))).lines().collect(Collectors.joining("\n")); - + final String rdfResponseBody = loadFile(RDF_PATH); WIRE_MOCK_SERVER.stubFor(WireMock.get(urlPatternRedirectToUrl) .willReturn(WireMock.aResponse() .withHeader("Content-Type", "text/turtle") - .withBody(responseBody))); + .withBody(rdfResponseBody))); + + // stub for CSV + final UrlPattern csvUrlPattern = WireMock.urlPathEqualTo(CSV_PATH); + final String csvResponseBody = loadFile(CSV_PATH); + WIRE_MOCK_SERVER.stubFor(WireMock.get(csvUrlPattern).willReturn(WireMock.aResponse().withBody(csvResponseBody))); + } + + private static String loadFile(final String path) { + return new BufferedReader(new InputStreamReader( + Objects.requireNonNull(MetafixLookupTest.class.getResourceAsStream("." + path)))).lines().collect(Collectors.joining("\n")); } @AfterAll @@ -419,6 +429,15 @@ public void csv() { ); } + @Test + public void csvViaUrl() { + final String baseUrl = WIRE_MOCK_SERVER.baseUrl(); + final String mockedCsvUrl = String.format(CSV_URL, baseUrl); + assertMap( + LOOKUP + " '" + mockedCsvUrl + "')" + ); + } + @Test public void tsv() { assertMap(