This is an automated email from the ASF dual-hosted git repository.

jaikiran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ant-ivy.git


The following commit(s) were added to refs/heads/master by this push:
     new 8e2bdfb  IVY-1616 Properly parse the artifact origin location, if the 
location is a file: URI
8e2bdfb is described below

commit 8e2bdfb302f1e3e6e20fc727e1853c5edabdf7d4
Author: Jaikiran Pai <jaiki...@apache.org>
AuthorDate: Mon Mar 29 13:04:56 2021 +0530

    IVY-1616 Properly parse the artifact origin location, if the location is a 
file: URI
---
 asciidoc/release-notes.adoc                        |  1 +
 .../core/cache/DefaultRepositoryCacheManager.java  | 39 ++++++++++++++++++++--
 .../org/apache/ivy/core/resolve/ResolveTest.java   | 28 ++++++++++++++++
 .../repositories/ivysettings-caches-use-origin.xml | 28 ++++++++++++++++
 4 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/asciidoc/release-notes.adoc b/asciidoc/release-notes.adoc
index 493b9db..b7cbd82 100644
--- a/asciidoc/release-notes.adoc
+++ b/asciidoc/release-notes.adoc
@@ -48,6 +48,7 @@ For details about the following changes, check our JIRA 
install at link:https://
 - BREAKING: Removed old fr\jayasoft\ivy\ant\antlib.xml AntLib definition file 
(jira:IVY-1612[])
 - FIX: ResolveEngine resets dictator resolver to null in the global 
configuration (jira:IVY-1618[])
 - FIX: ConcurrentModificationException in MessageLoggerHelper.sumupProblems 
(jira:IVY-1628[])
+- FIX: useOrigin="true" fails with file-based ibiblio (jira:IVY-1616[])
 
 
 - IMPROVEMENT: Ivy command now accepts a URL for the -settings option 
(jira:IVY-1615[])
diff --git 
a/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java 
b/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
index 3206915..497a536 100644
--- a/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
+++ b/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
@@ -21,6 +21,8 @@ import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
@@ -385,7 +387,7 @@ public class DefaultRepositoryCacheManager implements 
RepositoryCacheManager, Iv
     public File getArchiveFileInCache(Artifact artifact, ArtifactOrigin 
origin) {
         File archive = new File(getRepositoryCacheRoot(), 
getArchivePathInCache(artifact, origin));
         if (!archive.exists() && !ArtifactOrigin.isUnknown(origin) && 
origin.isLocal()) {
-            File original = Checks.checkAbsolute(origin.getLocation(), artifact
+            File original = 
Checks.checkAbsolute(parseArtifactOriginFilePath(origin), artifact
                     + " origin location");
             if (original.exists()) {
                 return original;
@@ -407,7 +409,7 @@ public class DefaultRepositoryCacheManager implements 
RepositoryCacheManager, Iv
      */
     private File getArchiveFileInCache(Artifact artifact, ArtifactOrigin 
origin, boolean useOrigin) {
         if (useOrigin && !ArtifactOrigin.isUnknown(origin) && 
origin.isLocal()) {
-            return Checks.checkAbsolute(origin.getLocation(), artifact + " 
origin location");
+            return Checks.checkAbsolute(parseArtifactOriginFilePath(origin), 
artifact + " origin location");
         }
         return new File(getRepositoryCacheRoot(), 
getArchivePathInCache(artifact, origin));
     }
@@ -1533,6 +1535,39 @@ public class DefaultRepositoryCacheManager implements 
RepositoryCacheManager, Iv
     }
 
     /**
+     * If the {@link ArtifactOrigin#getLocation() location of the artifact 
origin} is a
+     * {@code file:} scheme URI, then this method parses that URI and returns 
back the
+     * path of the file it represents. Else returns back {@link 
ArtifactOrigin#getLocation()}
+     * @param origin The artifact origin
+     * @return
+     */
+    private static String parseArtifactOriginFilePath(final ArtifactOrigin 
origin) {
+        if (origin == null || origin.getLocation() == null) {
+            return null;
+        }
+        final String location = origin.getLocation();
+        if (!location.startsWith("file:")) {
+            // no need to parse it into a URI, if it's not a "file" scheme URI
+            return location;
+        }
+        final URI uri;
+        try {
+            uri = new URI(location);
+        } catch (URISyntaxException e) {
+            return location;
+        }
+        if (!uri.isAbsolute()) {
+            // no scheme in URI, just return the original location
+            return location;
+        } else if (uri.getScheme().equals("file")) {
+            // return the file path
+            return uri.getPath();
+        }
+        // not a "file" scheme URI, just return back the original location
+        return location;
+    }
+
+    /**
      * Resource downloader which makes a copy of the previously existing file 
before overriding it.
      * <p>
      * The backup file can be restored or cleaned up later
diff --git a/test/java/org/apache/ivy/core/resolve/ResolveTest.java 
b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
index abeae45..633ca64 100644
--- a/test/java/org/apache/ivy/core/resolve/ResolveTest.java
+++ b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
@@ -6589,6 +6589,34 @@ public class ResolveTest {
         }
     }
 
+
+    /**
+     * Tests that when the internal metadata file containing the artifact 
origin location
+     * points to {@code file:} URI, then the location is correctly parsed.
+     * See IVY-1616
+     */
+    @Test
+    public void testCacheUseOrigin() throws Exception {
+        final Ivy current = new Ivy();
+        current.configure(new 
File("test/repositories/ivysettings-caches-use-origin.xml"));
+        // resolve and download an artifact and let the origin details be 
stored in the internal metadata files
+        // in ivy cache
+        ResolveReport report = 
current.resolve(ModuleRevisionId.newInstance("org.apache",
+                "test","1.0"),
+                getResolveOptions(new String[] {"*"}).setDownload(true), 
false);
+        assertNotNull("Resolve report is null", report);
+        assertFalse("Resolution has errors", report.hasError());
+        // now set the "useOrigin" on caches to true, so that the next 
resolution uses the artifact origin
+        // that was saved in previous resolution
+        current.getSettings().setDefaultUseOrigin(true);
+        // trigger the resolution again
+        report = current.resolve(ModuleRevisionId.newInstance("org.apache",
+                "test","1.0"),
+                getResolveOptions(new String[] {"*"}).setDownload(true), 
false);
+        assertNotNull("Resolve report is null", report);
+        assertFalse("Resolution has errors", report.hasError());
+    }
+
     private void assertJarContains(final File jar, final String jarEntryPath) 
throws IOException {
         try (final JarFile jarFile = new JarFile(jar)) {
             final JarEntry entry = jarFile.getJarEntry(jarEntryPath);
diff --git a/test/repositories/ivysettings-caches-use-origin.xml 
b/test/repositories/ivysettings-caches-use-origin.xml
new file mode 100644
index 0000000..3ca9ead
--- /dev/null
+++ b/test/repositories/ivysettings-caches-use-origin.xml
@@ -0,0 +1,28 @@
+<!--
+   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
+
+     https://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.
+-->
+<ivysettings>
+       <properties file="${ivy.settings.dir}/ivysettings.properties" />
+       <settings defaultResolver="test"/>
+       <caches defaultCacheDir="${cache.dir}"/>
+       <resolvers>
+               <chain name="test">
+                       <ibiblio name="m2-local" m2compatible="true" 
useMavenMetadata="true" root="file:${ivy.settings.dir}/m2" />
+               </chain>
+       </resolvers>
+</ivysettings>

Reply via email to