This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-io.git
The following commit(s) were added to refs/heads/master by this push:
new f053f57 Create interface for ArtifactManager
f053f57 is described below
commit f053f57c0aa692495e1a35a04cf668137f633d4c
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Mon Oct 1 12:24:37 2018 +0200
Create interface for ArtifactManager
---
.../apache/sling/feature/io/ArtifactManager.java | 349 +--------------------
...actManager.java => DefaultArtifactManager.java} | 23 +-
...nfig.java => DefaultArtifactManagerConfig.java} | 4 +-
...erTest.java => DefaultArtifactManagerTest.java} | 23 +-
4 files changed, 30 insertions(+), 369 deletions(-)
diff --git a/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
b/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
index d60448f..548f710 100644
--- a/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
+++ b/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
@@ -16,112 +16,16 @@
*/
package org.apache.sling.feature.io;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.io.spi.ArtifactProvider;
-import org.apache.sling.feature.io.spi.ArtifactProviderContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
-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;
-import java.util.ServiceLoader;
+
+import org.apache.sling.feature.io.spi.ArtifactProvider;
/**
* The artifact manager is the central service to get artifacts.
* It uses {@link ArtifactProvider}s to get artifacts. The
* providers are loaded using the service loader.
*/
-public class ArtifactManager implements AutoCloseable {
-
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- /** The map of providers. */
- private final Map<String, ArtifactProvider> providers;
-
- /** The configuration */
- private final ArtifactManagerConfig config;
-
- /**
- * Get an artifact manager based on the configuration
- * @param config The configuration
- * @return The artifact manager
- * @throws IOException If the manager can't be initialized
- */
- public static ArtifactManager getArtifactManager(final
ArtifactManagerConfig config) throws IOException {
- final ServiceLoader<ArtifactProvider> loader =
ServiceLoader.load(ArtifactProvider.class);
- final Map<String, ArtifactProvider> providers = new HashMap<>();
- for(final ArtifactProvider provider : loader) {
- providers.put(provider.getProtocol(), provider);
- }
-
- final String[] repositoryURLs = new
String[config.getRepositoryUrls().length];
- int index = 0;
- for(final String urlString : config.getRepositoryUrls()) {
- repositoryURLs[index] = urlString;
- index++;
- }
- // default
- if ( !providers.containsKey("*") ) {
- providers.put("*", new DefaultArtifactHandler());
- }
-
- return new ArtifactManager(config, providers);
- }
-
- ArtifactManager(final ArtifactManagerConfig config, final Map<String,
ArtifactProvider> providers)
- throws IOException {
- this.config = config;
- this.providers = providers;
- try {
- for(final ArtifactProvider provider : this.providers.values()) {
- provider.init(config);
- }
- } catch ( final IOException io) {
- shutdown();
- throw io;
- }
- }
-
- /**
- * Shutdown the artifact manager.
- */
- public void shutdown() {
- for(final ArtifactProvider provider : this.providers.values()) {
- provider.shutdown();
- }
- this.providers.clear();
- }
-
- @Override
- public void close()
- {
- shutdown();
- }
-
- private final File getArtifactFromProviders(final String url, final String
relativeCachePath) throws IOException {
- final int pos = url.indexOf(":");
- final String scheme = url.substring(0, pos);
-
- ArtifactProvider provider = this.providers.get(scheme);
- if ( provider == null ) {
- provider = this.providers.get("*");
- }
- if ( provider == null ) {
- throw new IOException("No URL provider found for " + url);
- }
- return provider.getArtifact(url, relativeCachePath);
- }
+public interface ArtifactManager extends AutoCloseable {
/**
* Get the full artifact url and file for an artifact.
@@ -129,249 +33,8 @@ public class ArtifactManager implements AutoCloseable {
* @return Absolute url and file in the form of a handler.
* @throws IOException If something goes wrong.
*/
- public ArtifactHandler getArtifactHandler(final String url) throws
IOException {
- logger.debug("Trying to get artifact for {}", url);
-
- final String path;
-
- if ( url.startsWith("mvn:") ) {
- // mvn url
- path = ArtifactId.fromMvnUrl(url).toMvnPath();
-
- } else if ( url.startsWith(":") ) {
- // repository path
- path = url.substring(1);
-
- } else if ( url.indexOf(":/") > 0 ) {
-
- // absolute URL
- int pos = url.indexOf(":/") + 2;
- while ( url.charAt(pos) == '/') {
- pos++;
- }
- final File file = this.getArtifactFromProviders(url,
url.substring(pos));
- if ( file == null || !file.exists()) {
- throw new IOException("Artifact " + url + " not found.");
- }
- return new ArtifactHandler(url, file);
-
- } else {
- // file (either relative or absolute)
- final File f = new File(url);
- if ( !f.exists()) {
- throw new IOException("Artifact " + url + " not found.");
- }
- return new ArtifactHandler(f.toURI().toString(), f);
- }
- logger.debug("Querying repositories for {}", path);
-
- for(final String repoUrl : this.config.getRepositoryUrls()) {
- final StringBuilder builder = new StringBuilder();
- builder.append(repoUrl);
- builder.append('/');
- builder.append(path);
-
- final String artifactUrl = builder.toString();
- final int pos = artifactUrl.indexOf(":");
- final String scheme = artifactUrl.substring(0, pos);
+ ArtifactHandler getArtifactHandler(final String url) throws IOException;
- 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);
- }
-
- logger.debug("Checking {} to get artifact from {}", handler,
artifactUrl);
-
- final File file = handler.getArtifact(artifactUrl, path);
- if ( file != null ) {
- logger.debug("Found artifact {}", artifactUrl);
- return new ArtifactHandler(artifactUrl, file);
- }
-
- // check for SNAPSHOT
- final int lastSlash = artifactUrl.lastIndexOf('/');
- final int startSnapshot = artifactUrl.indexOf("-SNAPSHOT",
lastSlash + 1);
-
- if ( startSnapshot > -1 ) {
- // special snapshot handling
- final String metadataUrl = artifactUrl.substring(0, lastSlash)
+ "/maven-metadata.xml";
- try {
- final ArtifactHandler metadataHandler =
this.getArtifactHandler(metadataUrl);
-
- final String contents = getFileContents(metadataHandler);
-
- final String latestVersion = getLatestSnapshot(contents);
- if ( latestVersion != null ) {
- final String name = artifactUrl.substring(lastSlash);
// includes slash
- final String fullURL = artifactUrl.substring(0,
lastSlash) + name.replace("SNAPSHOT", latestVersion);
- int pos2 = fullURL.indexOf(":/") + 2;
- while ( fullURL.charAt(pos2) == '/') {
- pos2++;
- }
- final File file2 =
this.getArtifactFromProviders(fullURL, path);
- if ( file2 == null || !file2.exists()) {
- throw new IOException("Artifact " + fullURL + "
not found.");
- }
- return new ArtifactHandler(artifactUrl, file2);
- }
- } catch ( final IOException ignore ) {
- // we ignore this but report the original 404
- }
- }
- }
-
- throw new IOException("Artifact " + url + " not found in any
repository.");
- }
-
- 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');
- }
-
- return sb.toString();
- }
-
- public static String getValue(final String xml, final String[] xpath) {
- String value = null;
- int pos = 0;
- for(final String name : xpath) {
- final String element = '<' + name + '>';
-
- pos = xml.indexOf(element, pos);
- if ( pos == -1 ) {
- final String elementWithAttributes = '<' + name + ' ';
- pos = xml.indexOf(elementWithAttributes, pos);
- if ( pos == -1 ) {
- break;
- }
- }
- pos = xml.indexOf('>', pos) + 1;
- }
- if ( pos != -1 ) {
- final int endPos = xml.indexOf("</", pos);
- if ( endPos != -1 ) {
- value = xml.substring(pos, endPos).trim();
- }
- }
- return value;
- }
- public static String getLatestSnapshot(final String mavenMetadata) {
- final String timestamp = getValue(mavenMetadata, new String[]
{"metadata", "versioning", "snapshot", "timestamp"});
- final String buildNumber = getValue(mavenMetadata, new String[]
{"metadata", "versioning", "snapshot", "buildNumber"});
-
- if ( timestamp != null && buildNumber != null ) {
- return timestamp + '-' + buildNumber;
- }
-
- return null;
- }
-
- private static final class DefaultArtifactHandler implements
ArtifactProvider {
-
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- private volatile File cacheDir;
-
- private volatile ArtifactProviderContext config;
-
- @Override
- public String getProtocol() {
- return "*";
- }
-
- @Override
- public void init(final ArtifactProviderContext config) throws
IOException {
- this.cacheDir = config.getCacheDirectory();
- this.config = config;
- }
-
- @Override
- public void shutdown() {
- this.config = null;
- this.cacheDir = null;
- }
-
- @Override
- public File getArtifact(final String url, final String
relativeCachePath) {
- logger.debug("Checking url to be local file {}", url);
- // check if this is already a local file
- try {
- final File f = new File(new URL(url).toURI());
- if ( f.exists() ) {
- this.config.incLocalArtifacts();
- return f;
- }
- return null;
- } catch ( final URISyntaxException ise) {
- // ignore
- } catch ( final IllegalArgumentException iae) {
- // ignore
- } catch ( final MalformedURLException mue) {
- // ignore
- }
- logger.debug("Checking remote url {}", url);
- try {
- // check for url
- if ( url.indexOf(":") == -1 ) {
- return null;
- }
-
- final String filePath = (this.cacheDir.getAbsolutePath() +
File.separatorChar + relativeCachePath).replace('/', File.separatorChar);
- final File cacheFile = new File(filePath);
-
- if ( !cacheFile.exists() ) {
- cacheFile.getParentFile().mkdirs();
- final URL u = new URL(url);
- final URLConnection con = u.openConnection();
- final String userInfo = u.getUserInfo();
- if (userInfo != null) {
- con.addRequestProperty("Authorization", "Basic " +
Base64.getEncoder().encodeToString(u.toURI().getUserInfo().getBytes("UTF-8")));
- }
- con.connect();
-
- final InputStream readIS = con.getInputStream();
- final byte[] buffer = new byte[32768];
- int l;
- OutputStream os = null;
- try {
- os = new FileOutputStream(cacheFile);
- while ( (l = readIS.read(buffer)) >= 0 ) {
- os.write(buffer, 0, l);
- }
- } finally {
- try {
- readIS.close();
- } catch ( final IOException ignore) {
- // ignore
- }
- if ( os != null ) {
- try {
- os.close();
- } catch ( final IOException ignore ) {
- // ignore
-
- }
- }
- }
- this.config.incDownloadedArtifacts();
- } else {
- this.config.incCachedArtifacts();
- }
- return cacheFile;
- } catch ( final Exception e) {
- logger.info("Artifact not found in one repository", e);
- // ignore for now
- return null;
- }
- }
-
- @Override
- public String toString() {
- return "DefaultArtifactHandler";
- }
- }
+ @Override
+ void close();
}
diff --git a/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
b/src/main/java/org/apache/sling/feature/io/DefaultArtifactManager.java
similarity index 96%
copy from src/main/java/org/apache/sling/feature/io/ArtifactManager.java
copy to src/main/java/org/apache/sling/feature/io/DefaultArtifactManager.java
index d60448f..f0988be 100644
--- a/src/main/java/org/apache/sling/feature/io/ArtifactManager.java
+++ b/src/main/java/org/apache/sling/feature/io/DefaultArtifactManager.java
@@ -16,12 +16,6 @@
*/
package org.apache.sling.feature.io;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.io.spi.ArtifactProvider;
-import org.apache.sling.feature.io.spi.ArtifactProviderContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -37,12 +31,18 @@ import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.io.spi.ArtifactProvider;
+import org.apache.sling.feature.io.spi.ArtifactProviderContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* The artifact manager is the central service to get artifacts.
* It uses {@link ArtifactProvider}s to get artifacts. The
* providers are loaded using the service loader.
*/
-public class ArtifactManager implements AutoCloseable {
+public class DefaultArtifactManager implements AutoCloseable, ArtifactManager {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -50,7 +50,7 @@ public class ArtifactManager implements AutoCloseable {
private final Map<String, ArtifactProvider> providers;
/** The configuration */
- private final ArtifactManagerConfig config;
+ private final DefaultArtifactManagerConfig config;
/**
* Get an artifact manager based on the configuration
@@ -58,7 +58,7 @@ public class ArtifactManager implements AutoCloseable {
* @return The artifact manager
* @throws IOException If the manager can't be initialized
*/
- public static ArtifactManager getArtifactManager(final
ArtifactManagerConfig config) throws IOException {
+ public static ArtifactManager getArtifactManager(final
DefaultArtifactManagerConfig config) throws IOException {
final ServiceLoader<ArtifactProvider> loader =
ServiceLoader.load(ArtifactProvider.class);
final Map<String, ArtifactProvider> providers = new HashMap<>();
for(final ArtifactProvider provider : loader) {
@@ -76,10 +76,10 @@ public class ArtifactManager implements AutoCloseable {
providers.put("*", new DefaultArtifactHandler());
}
- return new ArtifactManager(config, providers);
+ return new DefaultArtifactManager(config, providers);
}
- ArtifactManager(final ArtifactManagerConfig config, final Map<String,
ArtifactProvider> providers)
+ DefaultArtifactManager(final DefaultArtifactManagerConfig config, final
Map<String, ArtifactProvider> providers)
throws IOException {
this.config = config;
this.providers = providers;
@@ -129,6 +129,7 @@ public class ArtifactManager implements AutoCloseable {
* @return Absolute url and file in the form of a handler.
* @throws IOException If something goes wrong.
*/
+ @Override
public ArtifactHandler getArtifactHandler(final String url) throws
IOException {
logger.debug("Trying to get artifact for {}", url);
diff --git
a/src/main/java/org/apache/sling/feature/io/ArtifactManagerConfig.java
b/src/main/java/org/apache/sling/feature/io/DefaultArtifactManagerConfig.java
similarity index 97%
rename from src/main/java/org/apache/sling/feature/io/ArtifactManagerConfig.java
rename to
src/main/java/org/apache/sling/feature/io/DefaultArtifactManagerConfig.java
index 5df9ed8..f629908 100644
--- a/src/main/java/org/apache/sling/feature/io/ArtifactManagerConfig.java
+++
b/src/main/java/org/apache/sling/feature/io/DefaultArtifactManagerConfig.java
@@ -25,7 +25,7 @@ import
org.apache.sling.feature.io.spi.ArtifactProviderContext;
/**
* This class holds the configuration of artifact manager.
*/
-public class ArtifactManagerConfig implements ArtifactProviderContext {
+public class DefaultArtifactManagerConfig implements ArtifactProviderContext {
/** The repository urls. */
private volatile String[] repositoryUrls;
@@ -43,7 +43,7 @@ public class ArtifactManagerConfig implements
ArtifactProviderContext {
* Create a new configuration object.
* Set the default values
*/
- public ArtifactManagerConfig() {
+ public DefaultArtifactManagerConfig() {
// set defaults
this.repositoryUrls = new String[] {
"file://" + System.getProperty("user.home") +
"/.m2/repository",
diff --git a/src/test/java/org/apache/sling/feature/io/ArtifactManagerTest.java
b/src/test/java/org/apache/sling/feature/io/DefaultArtifactManagerTest.java
similarity index 90%
rename from src/test/java/org/apache/sling/feature/io/ArtifactManagerTest.java
rename to
src/test/java/org/apache/sling/feature/io/DefaultArtifactManagerTest.java
index f89c40b..a5bfe4c 100644
--- a/src/test/java/org/apache/sling/feature/io/ArtifactManagerTest.java
+++ b/src/test/java/org/apache/sling/feature/io/DefaultArtifactManagerTest.java
@@ -16,23 +16,20 @@
*/
package org.apache.sling.feature.io;
-import org.apache.sling.feature.io.ArtifactHandler;
-import org.apache.sling.feature.io.ArtifactManager;
-import org.apache.sling.feature.io.ArtifactManagerConfig;
-import org.apache.sling.feature.io.spi.ArtifactProvider;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.apache.sling.feature.io.spi.ArtifactProvider;
+import org.junit.Test;
-public class ArtifactManagerTest {
+public class DefaultArtifactManagerTest {
private static final String METADATA = "<metadata
modelVersion=\"1.1.0\">\n" +
"<groupId>org.apache.sling.samples</groupId>\n" +
@@ -59,13 +56,13 @@ public class ArtifactManagerTest {
"</versioning></metadata>";
@Test public void testMetadataParsing() {
- final String version = ArtifactManager.getLatestSnapshot(METADATA);
+ final String version =
DefaultArtifactManager.getLatestSnapshot(METADATA);
assertEquals("20160321.103951-1", version);
}
@Test public void testSnapshotHandling() throws IOException {
final String REPO = "http://org.apache.sling";
- final ArtifactManagerConfig config = mock(ArtifactManagerConfig.class);
+ final DefaultArtifactManagerConfig config =
mock(DefaultArtifactManagerConfig.class);
when(config.getRepositoryUrls()).thenReturn(new String[] {REPO});
final File metadataFile = mock(File.class);
@@ -83,7 +80,7 @@ public class ArtifactManagerTest {
final Map<String, ArtifactProvider> providers = new HashMap<>();
providers.put("*", provider);
- final ArtifactManager mgr = new ArtifactManager(config, providers) {
+ final ArtifactManager mgr = new DefaultArtifactManager(config,
providers) {
@Override
protected String getFileContents(final ArtifactHandler handler)
throws IOException {