SLING-8421: Allow artifact providers that work with URLs instead of Files
diff --git a/src/main/java/org/apache/sling/feature/io/file/ArtifactHandler.java b/src/main/java/org/apache/sling/feature/io/file/ArtifactHandler.java
index e1d4ab0..61ea4ee 100644
--- a/src/main/java/org/apache/sling/feature/io/file/ArtifactHandler.java
+++ b/src/main/java/org/apache/sling/feature/io/file/ArtifactHandler.java
@@ -17,6 +17,8 @@
package org.apache.sling.feature.io.file;
import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
/**
* A handler provides a file object for an artifact.
@@ -55,4 +57,16 @@
public File getFile() {
return file;
}
+
+ public URL getLocalURL() {
+ File result = getFile();
+ try
+ {
+ return result != null ? file.toURI().toURL() : null;
+ }
+ catch (MalformedURLException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/src/main/java/org/apache/sling/feature/io/file/ArtifactHandlerDecorator.java b/src/main/java/org/apache/sling/feature/io/file/ArtifactHandlerDecorator.java
new file mode 100644
index 0000000..009cf10
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/io/file/ArtifactHandlerDecorator.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.sling.feature.io.file;
+
+import java.io.File;
+import java.net.URL;
+
+class ArtifactHandlerDecorator extends ArtifactHandler
+{
+ private final ArtifactHandler file;
+
+ /**
+ * Create a new handler.
+ *
+ * @param url The url of the artifact
+ * @param file The file for the artifact
+ */
+ public ArtifactHandlerDecorator(String url, ArtifactHandler file)
+ {
+ super(url, null);
+ this.file = file;
+ }
+
+ @Override
+ public File getFile()
+ {
+ return this.file.getFile();
+ }
+
+ @Override
+ public URL getLocalURL()
+ {
+ return this.file.getLocalURL();
+ }
+}
diff --git a/src/main/java/org/apache/sling/feature/io/file/ArtifactManager.java b/src/main/java/org/apache/sling/feature/io/file/ArtifactManager.java
index 0db5c51..7476691 100644
--- a/src/main/java/org/apache/sling/feature/io/file/ArtifactManager.java
+++ b/src/main/java/org/apache/sling/feature/io/file/ArtifactManager.java
@@ -16,16 +16,17 @@
*/
package org.apache.sling.feature.io.file;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
-import java.nio.file.Files;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
@@ -109,7 +110,7 @@
shutdown();
}
- private final File getArtifactFromProviders(final String url, final String relativeCachePath) throws IOException {
+ private final ArtifactHandler getArtifactFromProviders(final String url, final String relativeCachePath) throws IOException {
final int pos = url.indexOf(":");
final String scheme = url.substring(0, pos);
@@ -120,7 +121,10 @@
if ( provider == null ) {
throw new IOException("No URL provider found for " + url);
}
- return provider.getArtifact(url, relativeCachePath);
+
+ logger.debug("Checking {} to get artifact from {}", provider, url);
+
+ return provider.getArtifactHandler(url, relativeCachePath);
}
/**
@@ -149,11 +153,11 @@
while ( url.charAt(pos) == '/') {
pos++;
}
- final File file = this.getArtifactFromProviders(url, url.substring(pos));
- if ( file == null || !file.exists()) {
+ final ArtifactHandler file = this.getArtifactFromProviders(url, url.substring(pos));
+ if ( file == null ) {
throw new IOException("Artifact " + url + " not found.");
}
- return new ArtifactHandler(url, file);
+ return file;
} else {
// file (either relative or absolute)
@@ -172,23 +176,12 @@
builder.append(path);
final String artifactUrl = builder.toString();
- final int pos = artifactUrl.indexOf(":");
- final String scheme = artifactUrl.substring(0, pos);
- ArtifactProvider handler = this.providers.get(scheme);
- if ( handler == null ) {
- handler = this.providers.get("*");
- }
- if ( handler == null ) {
- throw new IOException("No URL handler found for " + artifactUrl);
- }
+ ArtifactHandler handler = getArtifactFromProviders(artifactUrl, path);
- logger.debug("Checking {} to get artifact from {}", handler, artifactUrl);
-
- final File file = handler.getArtifact(artifactUrl, path);
- if ( file != null ) {
+ if ( handler != null ) {
logger.debug("Found artifact {}", artifactUrl);
- return new ArtifactHandler(artifactUrl, file);
+ return handler;
}
// check for SNAPSHOT
@@ -211,11 +204,11 @@
while ( fullURL.charAt(pos2) == '/') {
pos2++;
}
- final File file2 = this.getArtifactFromProviders(fullURL, path);
- if ( file2 == null || !file2.exists()) {
+ final ArtifactHandler file2 = this.getArtifactFromProviders(fullURL, path);
+ if ( file2 == null) {
throw new IOException("Artifact " + fullURL + " not found.");
}
- return new ArtifactHandler(artifactUrl, file2);
+ return new ArtifactHandlerDecorator(artifactUrl, file2);
}
} catch ( final IOException ignore ) {
// we ignore this but report the original 404
@@ -228,10 +221,11 @@
protected String getFileContents(final ArtifactHandler handler) throws IOException {
final StringBuilder sb = new StringBuilder();
- for(final String line : Files.readAllLines(handler.getFile().toPath())) {
- sb.append(line).append('\n');
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(handler.getLocalURL().openStream(), "UTF-8"))) {
+ for (String line = reader.readLine(); line != null; line = reader.readLine()) {
+ sb.append(line).append('\n');
+ }
}
-
return sb.toString();
}
diff --git a/src/main/java/org/apache/sling/feature/io/file/spi/ArtifactProvider.java b/src/main/java/org/apache/sling/feature/io/file/spi/ArtifactProvider.java
index 75ccd85..62d418c 100644
--- a/src/main/java/org/apache/sling/feature/io/file/spi/ArtifactProvider.java
+++ b/src/main/java/org/apache/sling/feature/io/file/spi/ArtifactProvider.java
@@ -18,6 +18,10 @@
import java.io.File;
import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.sling.feature.io.file.ArtifactHandler;
/**
* The artifact provider is an extension point for providing artifacts
@@ -52,4 +56,14 @@
* @return A file if the artifact exists or {@code null}
*/
File getArtifact(String url, String relativeCachePath);
+
+ default ArtifactHandler getArtifactHandler(String url, String relativeCachePath) {
+ File result = getArtifact(url, relativeCachePath);
+ if (result != null && result.exists()) {
+ return new ArtifactHandler(url, result);
+ }
+ else {
+ return null;
+ }
+ }
}
diff --git a/src/test/java/org/apache/sling/feature/io/file/ArtifactManagerTest.java b/src/test/java/org/apache/sling/feature/io/file/ArtifactManagerTest.java
index 69d9d32..d9aa0f1 100644
--- a/src/test/java/org/apache/sling/feature/io/file/ArtifactManagerTest.java
+++ b/src/test/java/org/apache/sling/feature/io/file/ArtifactManagerTest.java
@@ -76,9 +76,9 @@
when(artifactFile.exists()).thenReturn(true);
final ArtifactProvider provider = mock(ArtifactProvider.class);
- when(provider.getArtifact(REPO + "/group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt", "group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt")).thenReturn(null);
- when(provider.getArtifact(REPO + "/group/artifact/1.0.0-SNAPSHOT/maven-metadata.xml", "org.apache.sling/group/artifact/1.0.0-SNAPSHOT/maven-metadata.xml")).thenReturn(metadataFile);
- when(provider.getArtifact(REPO + "/group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-20160321.103951-1.txt", "group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt")).thenReturn(artifactFile);
+ when(provider.getArtifactHandler(REPO + "/group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt", "group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt")).thenReturn(null);
+ when(provider.getArtifactHandler(REPO + "/group/artifact/1.0.0-SNAPSHOT/maven-metadata.xml", "org.apache.sling/group/artifact/1.0.0-SNAPSHOT/maven-metadata.xml")).thenReturn(new ArtifactHandler(REPO + "/group/artifact/1.0.0-SNAPSHOT/maven-metadata.xml", metadataFile));
+ when(provider.getArtifactHandler(REPO + "/group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-20160321.103951-1.txt", "group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-SNAPSHOT.txt")).thenReturn(new ArtifactHandler(REPO + "/group/artifact/1.0.0-SNAPSHOT/artifact-1.0.0-20160321.103951-1.txt", artifactFile));
final Map<String, ArtifactProvider> providers = new HashMap<>();
providers.put("*", provider);