You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by hi...@apache.org on 2011/04/28 23:50:33 UTC

svn commit: r1097628 - in /ant/ivy/core/trunk/src/java/org/apache/ivy: core/cache/ osgi/obr/ osgi/updatesite/ plugins/resolver/ util/

Author: hibou
Date: Thu Apr 28 21:50:33 2011
New Revision: 1097628

URL: http://svn.apache.org/viewvc?rev=1097628&view=rev
Log:
* add a method downloadRepositoryResource to the RepositoryCacheManager to managed the cache of any resources related to a repository
* add to ArtifactOrigin new metadata: the last time the artifact was checked to be up to date, and a flag that says if a resource was not found (used to implement downloadRepositoryResource)
* use that cache in the OBRResolver, the MirroredURLResolver and the UpdateSiteLoader

Added:
    ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheResourceOptions.java   (with props)
    ant/ivy/core/trunk/src/java/org/apache/ivy/util/HexEncoder.java   (with props)
Modified:
    ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ArtifactOrigin.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/OBRResolver.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ArtifactOrigin.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ArtifactOrigin.java?rev=1097628&r1=1097627&r2=1097628&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ArtifactOrigin.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ArtifactOrigin.java Thu Apr 28 21:50:33 2011
@@ -52,6 +52,10 @@ public class ArtifactOrigin {
 
     private Artifact artifact;
 
+    private Long lastChecked;
+
+    private boolean exists = true;
+
     /**
      * Create a new instance
      * 
@@ -98,8 +102,31 @@ public class ArtifactOrigin {
         return artifact;
     }
 
+    /**
+     * The last time the resource was checked to be up to date. Maybe <code>null</code> if this information is
+     * not actually used by in some case.
+     * 
+     * @return
+     */
+    public Long getLastChecked() {
+        return lastChecked;
+    }
+
+    public void setLastChecked(Long lastChecked) {
+        this.lastChecked = lastChecked;
+    }
+
+    public boolean isExists() {
+        return exists;
+    }
+
+    public void setExist(boolean exists) {
+        this.exists = exists;
+    }
+
     public String toString() {
-        return "ArtifactOrigin { isLocal=" + isLocal + ", location=" + location + "}";
+        return "ArtifactOrigin { isLocal=" + isLocal + ", location=" + location + ", lastChecked="
+                + lastChecked + ", exists=" + exists + "}";
     }
 
     public boolean equals(Object o) {
@@ -118,6 +145,16 @@ public class ArtifactOrigin {
         if (!location.equals(that.location)) {
             return false;
         }
+        if (lastChecked == null) {
+            if (that.lastChecked != null) {
+                return false;
+            }
+        } else if (!lastChecked.equals(that.lastChecked)) {
+            return false;
+        }
+        if (exists != that.exists) {
+            return false;
+        }
 
         return true;
     }
@@ -126,6 +163,8 @@ public class ArtifactOrigin {
         int result;
         result = (isLocal ? 1 : 0);
         result = MAGIC_HASH_VALUE * result + location.hashCode();
+        result = MAGIC_HASH_VALUE * result + ((lastChecked == null) ? 0 : lastChecked.hashCode());
+        result = MAGIC_HASH_VALUE * result + (exists ? 1 : 0);
         return result;
     }
 }

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheResourceOptions.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheResourceOptions.java?rev=1097628&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheResourceOptions.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheResourceOptions.java Thu Apr 28 21:50:33 2011
@@ -0,0 +1,32 @@
+/*
+ *  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.ivy.core.cache;
+
+public class CacheResourceOptions extends CacheDownloadOptions {
+
+    // by default, a ttl of 1 hour
+    private long ttl = 1000 * 60 * 60;
+
+    public void setTtl(long ttl) {
+        this.ttl = ttl;
+    }
+
+    public long getTtl() {
+        return ttl;
+    }
+}

Propchange: ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheResourceOptions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheResourceOptions.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheResourceOptions.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java?rev=1097628&r1=1097627&r2=1097628&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java Thu Apr 28 21:50:33 2011
@@ -19,11 +19,15 @@ package org.apache.ivy.core.cache;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.text.ParseException;
 import java.util.Date;
 import java.util.Map;
 import java.util.regex.Pattern;
 
+import org.apache.ivy.Ivy;
 import org.apache.ivy.core.IvyPatternHelper;
 import org.apache.ivy.core.module.descriptor.Artifact;
 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
@@ -49,6 +53,7 @@ import org.apache.ivy.plugins.parser.Mod
 import org.apache.ivy.plugins.parser.ParserSettings;
 import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser;
 import org.apache.ivy.plugins.repository.ArtifactResourceResolver;
+import org.apache.ivy.plugins.repository.Repository;
 import org.apache.ivy.plugins.repository.Resource;
 import org.apache.ivy.plugins.repository.ResourceDownloader;
 import org.apache.ivy.plugins.repository.ResourceHelper;
@@ -57,6 +62,7 @@ import org.apache.ivy.plugins.resolver.D
 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
 import org.apache.ivy.util.Checks;
 import org.apache.ivy.util.FileUtil;
+import org.apache.ivy.util.HexEncoder;
 import org.apache.ivy.util.Message;
 import org.apache.ivy.util.PropertiesFile;
 
@@ -72,6 +78,15 @@ public class DefaultRepositoryCacheManag
     
     private static final int DEFAULT_MEMORY_CACHE_SIZE = 150;
     
+    private static MessageDigest SHA_DIGEST;
+    static {
+        try {
+            SHA_DIGEST = MessageDigest.getInstance("SHA1");
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("The SHA1 algorithm is not available in your classpath", e);
+        }
+    }
+    
     private IvySettings settings;
     
     private File basedir;
@@ -444,6 +459,10 @@ public class DefaultRepositoryCacheManag
         PropertiesFile cdf = getCachedDataFile(artifact.getModuleRevisionId());
         cdf.setProperty(getIsLocalKey(artifact), String.valueOf(origin.isLocal()));
         cdf.setProperty(getLocationKey(artifact), origin.getLocation());
+        if (origin.getLastChecked() != null) {
+            cdf.setProperty(getLastCheckedKey(artifact), origin.getLastChecked().toString());
+        }
+        cdf.setProperty(getExistsKey(artifact), Boolean.toString(origin.isExists()));
         cdf.save();
     }
 
@@ -452,6 +471,7 @@ public class DefaultRepositoryCacheManag
         PropertiesFile cdf = getCachedDataFile(artifact.getModuleRevisionId());
         cdf.remove(getLocationKey(artifact));
         cdf.remove(getIsLocalKey(artifact));
+        cdf.remove(getLastCheckedKey(artifact));
         cdf.save();
     }
 
@@ -465,6 +485,9 @@ public class DefaultRepositoryCacheManag
             PropertiesFile cdf = getCachedDataFile(artifact.getModuleRevisionId());
             String location = cdf.getProperty(getLocationKey(artifact));
             String local = cdf.getProperty(getIsLocalKey(artifact));
+            String lastChecked = cdf.getProperty(getLastCheckedKey(artifact));
+            String exists = cdf.getProperty(getExistsKey(artifact));
+
             boolean isLocal = Boolean.valueOf(local).booleanValue();
 
             if (location == null) {
@@ -472,7 +495,15 @@ public class DefaultRepositoryCacheManag
                 return ArtifactOrigin.unkwnown(artifact);
             }
 
-            return new ArtifactOrigin(artifact, isLocal, location);
+            ArtifactOrigin origin = new ArtifactOrigin(artifact, isLocal, location);
+            if (lastChecked != null) {
+                origin.setLastChecked(Long.valueOf(lastChecked));
+            }
+            if (exists != null) {
+                origin.setExist(Boolean.valueOf(exists).booleanValue());
+            }
+
+            return origin;
         } finally {
             unlockMetadataArtifact(mrid);
         }
@@ -510,13 +541,37 @@ public class DefaultRepositoryCacheManag
      * 
      * @param artifact
      *            the artifact to generate the key from. Cannot be null.
-     * @return the key to be used to reference the artifact location.
+     * @return the key to be used to reference the artifact locality.
      */
     private String getIsLocalKey(Artifact artifact) {
         String prefix = getPrefixKey(artifact);
         return prefix + ".is-local";
     }
 
+    /**
+     * Returns the key used to identify the last time the artifact was checked to be up to date.
+     * 
+     * @param artifact
+     *            the artifact to generate the key from. Cannot be null.
+     * @return the key to be used to reference the artifact's last check date.
+     */
+    private String getLastCheckedKey(Artifact artifact) {
+        String prefix = getPrefixKey(artifact);
+        return prefix + ".lastchecked";
+    }
+
+    /**
+     * Returns the key used to identify the existence of the remote artifact.
+     * 
+     * @param artifact
+     *            the artifact to generate the key from. Cannot be null.
+     * @return the key to be used to reference the existence of the artifact.
+     */
+    private String getExistsKey(Artifact artifact) {
+        String prefix = getPrefixKey(artifact);
+        return prefix + ".exists";
+    }
+
     private PropertiesFile getCachedDataFile(ModuleDescriptor md) {
         return getCachedDataFile(md.getResolvedModuleRevisionId());
     }
@@ -854,7 +909,149 @@ public class DefaultRepositoryCacheManag
             unlockMetadataArtifact(mrid);
         }
     }
-    
+
+    public ArtifactDownloadReport downloadRepositoryResource(final Resource resource, String name,
+            String type, String extension, CacheResourceOptions options, Repository repository) {
+
+        String hash = computeResourceNameHash(resource);
+        ModuleRevisionId mrid = ModuleRevisionId.newInstance("_repository_metadata_", hash,
+            Ivy.getWorkingRevision());
+        Artifact artifact = new DefaultArtifact(mrid, null, name, type, extension);
+        final ArtifactDownloadReport adr = new ArtifactDownloadReport(artifact);
+        boolean useOrigin = isUseOrigin();
+
+        try {
+            DownloadListener listener = options.getListener();
+            if (listener != null) {
+                listener.needArtifact(this, artifact);
+            }
+            ArtifactOrigin savedOrigin = getSavedArtifactOrigin(artifact);
+            File archiveFile = getArchiveFileInCache(artifact, savedOrigin, useOrigin);
+
+            ArtifactOrigin origin = new ArtifactOrigin(artifact, resource.isLocal(), resource.getName());
+
+            if (!options.isForce()
+                    // if the local file has been checked to be up to date enough recently, don't download
+                    && checkCacheUptodate(archiveFile, resource, savedOrigin, origin, options.getTtl())) {
+                if (archiveFile.exists()) {
+                    saveArtifactOrigin(artifact, origin);
+                    adr.setDownloadStatus(DownloadStatus.NO);
+                    adr.setSize(archiveFile.length());
+                    adr.setArtifactOrigin(savedOrigin);
+                    adr.setLocalFile(archiveFile);
+                } else {
+                    // we trust the cache to says that the resource doesn't exist
+                    adr.setDownloadStatus(DownloadStatus.FAILED);
+                    adr.setDownloadDetails("Remote resource is known to not exist");
+                }
+            } else {
+                long start = System.currentTimeMillis();
+                origin.setLastChecked(new Long(start));
+                try {
+                    ResolvedResource artifactRef = new ResolvedResource(resource,
+                            Ivy.getWorkingRevision());
+                    if (useOrigin && resource.isLocal()) {
+                        saveArtifactOrigin(artifact, origin);
+                        archiveFile = getArchiveFileInCache(artifact, origin);
+                        adr.setDownloadStatus(DownloadStatus.NO);
+                        adr.setSize(archiveFile.length());
+                        adr.setArtifactOrigin(origin);
+                        adr.setLocalFile(archiveFile);
+                    } else { 
+                        if (listener != null) {
+                            listener.startArtifactDownload(this, artifactRef, artifact, origin);
+                        }
+
+                        // actual download
+                        if (archiveFile.exists()) {
+                            archiveFile.delete();
+                        }
+                        File part = new File(archiveFile.getAbsolutePath() + ".part");
+                        repository.get(resource.getName(), part);
+                        if (!part.renameTo(archiveFile)) {
+                            throw new IOException(
+                                    "impossible to move part file to definitive one: " + part
+                                            + " -> " + archiveFile);
+                        }
+
+                        adr.setSize(archiveFile.length());
+                        saveArtifactOrigin(artifact, origin);
+                        adr.setDownloadTimeMillis(System.currentTimeMillis() - start);
+                        adr.setDownloadStatus(DownloadStatus.SUCCESSFUL);
+                        adr.setArtifactOrigin(origin);
+                        adr.setLocalFile(archiveFile);
+                    }
+                } catch (Exception ex) {
+                    origin.setExist(false);
+                    saveArtifactOrigin(artifact, origin);
+                    adr.setDownloadStatus(DownloadStatus.FAILED);
+                    adr.setDownloadDetails(ex.getMessage());
+                    adr.setDownloadTimeMillis(System.currentTimeMillis() - start);
+                }
+            }
+            if (listener != null) {
+                listener.endArtifactDownload(this, artifact, adr, archiveFile);
+            }
+            return adr;
+        } finally {
+            unlockMetadataArtifact(mrid);
+        }
+    }
+
+    /**
+     * Compute a SHA1 of the resource name, encoded in base64, so we can use it as a file name.
+     * 
+     * @param resource
+     *            the resource which name will be hashed
+     * @return the hash
+     */
+    private String computeResourceNameHash(Resource resource) {
+        byte[] shaDigest;
+        try {
+            shaDigest = SHA_DIGEST.digest(resource.getName().getBytes("UTF-8"));
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("UTF-8 not supported", e);
+        }
+        return HexEncoder.encode(shaDigest);
+    }
+
+    /**
+     * Check that a cached file can be considered up to date and thus not downloaded
+     * 
+     * @param archiveFile
+     *            the file in the cache
+     * @param resource
+     *            the remote resource to check
+     * @param savedOrigin
+     *            the saved origin which contains that last checked date
+     * @param origin
+     *            the origin in which to store the new last checked date
+     * @param ttl
+     *            the time to live to consider the cache up to date
+     * @return <code>true</code> if the cache is considered up to date
+     */
+    private boolean checkCacheUptodate(File archiveFile, Resource resource,
+            ArtifactOrigin savedOrigin, ArtifactOrigin origin, long ttl) {
+        long time = System.currentTimeMillis();
+        if (savedOrigin.getLastChecked() != null
+                && (time - savedOrigin.getLastChecked().longValue()) < ttl) {
+            // still in the ttl period, no need to check, trust the cache
+            if (!archiveFile.exists()) {
+                // but if the local archive doesn't exist, trust the cache only if the cached origin
+                // says that the remote resource doesn't exist either
+                return !savedOrigin.isExists();
+            }
+            return true;
+        }
+        if (!archiveFile.exists()) {
+            // the the file doesn't exist in the cache, obviously not up to date
+            return false;
+        }
+        origin.setLastChecked(new Long(time));
+        // check if the local resource is up to date regarding the remote one
+        return archiveFile.lastModified() >= resource.getLastModified();
+    }
+
     public void originalToCachedModuleDescriptor(
             DependencyResolver resolver, ResolvedResource orginalMetadataRef,
             Artifact requestedMetadataArtifact,
@@ -1173,7 +1370,12 @@ public class DefaultRepositoryCacheManag
         Message.debug("\t\tchangingPattern: " + getChangingPattern());
         Message.debug("\t\tchangingMatcher: " + getChangingMatcherName());
     }
-    
+
+    /**
+     * Resource downloader which makes a copy of the previously existing file before overriding it.
+     * <p>
+     * The backup file can be restored or cleanuped later
+     */
     private final class BackupResourceDownloader implements ResourceDownloader {
         
         private ResourceDownloader delegate;

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java?rev=1097628&r1=1097627&r2=1097628&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java Thu Apr 28 21:50:33 2011
@@ -26,6 +26,8 @@ import org.apache.ivy.core.module.id.Mod
 import org.apache.ivy.core.report.ArtifactDownloadReport;
 import org.apache.ivy.core.resolve.ResolvedModuleRevision;
 import org.apache.ivy.plugins.repository.ArtifactResourceResolver;
+import org.apache.ivy.plugins.repository.Repository;
+import org.apache.ivy.plugins.repository.Resource;
 import org.apache.ivy.plugins.repository.ResourceDownloader;
 import org.apache.ivy.plugins.resolver.DependencyResolver;
 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
@@ -105,6 +107,29 @@ public interface RepositoryCacheManager 
             CacheDownloadOptions options);
 
     /**
+     * Download some repository resource and put it in the cache.
+     * <p>
+     * If the cached version is considered enough up to date, no downloading is done.
+     * 
+     * @param resource
+     *            the resource of the file to put in cache
+     * @param name
+     *            the descriptive name of the resource (helps while manually looking into the cache
+     *            files)
+     * @param type
+     *            the type of the resource (helps while manually looking into the cache files)
+     * @param extension
+     *            the extension of the resource (helps while manually looking into the cache files)
+     * @param options
+     *            a set of options to adjust the download
+     * @param repository
+     *            the repository which resolve the content of the resource
+     * @return a report indicating how the download was performed
+     */
+    public ArtifactDownloadReport downloadRepositoryResource(Resource resource, String name,
+            String type, String extension, CacheResourceOptions options, Repository repository);
+
+    /**
      * Caches an original module descriptor.
      * <p>
      * After this call, the original module descriptor file (with no modification nor conversion)

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/OBRResolver.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/OBRResolver.java?rev=1097628&r1=1097627&r2=1097628&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/OBRResolver.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/OBRResolver.java Thu Apr 28 21:50:33 2011
@@ -25,22 +25,15 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.text.ParseException;
 
-import org.apache.ivy.Ivy;
-import org.apache.ivy.core.cache.CacheDownloadOptions;
-import org.apache.ivy.core.module.descriptor.Artifact;
-import org.apache.ivy.core.module.descriptor.DefaultArtifact;
-import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.core.cache.CacheResourceOptions;
+import org.apache.ivy.core.event.EventManager;
 import org.apache.ivy.core.report.ArtifactDownloadReport;
 import org.apache.ivy.osgi.obr.xml.OBRXMLParser;
 import org.apache.ivy.osgi.repo.RelativeURLRepository;
 import org.apache.ivy.osgi.repo.RepoDescriptorBasedResolver;
-import org.apache.ivy.plugins.repository.ArtifactResourceResolver;
 import org.apache.ivy.plugins.repository.Resource;
-import org.apache.ivy.plugins.repository.ResourceDownloader;
 import org.apache.ivy.plugins.repository.file.FileRepository;
 import org.apache.ivy.plugins.repository.url.URLResource;
-import org.apache.ivy.plugins.resolver.util.ResolvedResource;
-import org.apache.ivy.util.FileUtil;
 import org.xml.sax.SAXException;
 
 public class OBRResolver extends RepoDescriptorBasedResolver {
@@ -91,33 +84,24 @@ public class OBRResolver extends RepoDes
                                 + " couldn't be configured: the base url couldn'd be extracted from the url "
                                 + url + " (" + e.getMessage() + ")");
             }
-            setRepository(new RelativeURLRepository(baseUrl));
+            RelativeURLRepository repo = new RelativeURLRepository(baseUrl);
+            setRepository(repo);
 
-            // get the obr descriptor into the cache
-            ModuleRevisionId mrid = ModuleRevisionId.newInstance("_obr_cache_", getName(),
-                Ivy.getWorkingRevision());
-            Artifact artifact = new DefaultArtifact(mrid, null, "obr", "obr", "xml");
-            CacheDownloadOptions options = new CacheDownloadOptions();
-            ArtifactDownloadReport report = getRepositoryCacheManager().download(artifact,
-                new ArtifactResourceResolver() {
-                    public ResolvedResource resolve(Artifact artifact) {
-                        return new ResolvedResource(new URLResource(url), Ivy.getWorkingRevision());
-                    }
-                }, new ResourceDownloader() {
-                    public void download(Artifact artifact, Resource resource, File dest)
-                            throws IOException {
-                        if (dest.exists()) {
-                            dest.delete();
-                        }
-                        File part = new File(dest.getAbsolutePath() + ".part");
-                        FileUtil.copy(url, part, null);
-                        if (!part.renameTo(dest)) {
-                            throw new IOException(
-                                    "impossible to move part file to definitive one: " + part
-                                            + " -> " + dest);
-                        }
-                    }
-                }, options);
+            ArtifactDownloadReport report;
+            EventManager eventManager = getEventManager();
+            try {
+                if (eventManager != null) {
+                    getRepository().addTransferListener(eventManager);
+                }
+                Resource obrResource = new URLResource(url);
+                CacheResourceOptions options = new CacheResourceOptions();
+                report = getRepositoryCacheManager().downloadRepositoryResource(obrResource, "obr",
+                    "obr", "xml", options, repo);
+            } finally {
+                if (eventManager != null) {
+                    getRepository().removeTransferListener(eventManager);
+                }
+            }
 
             loadRepoFromFile(report.getLocalFile(), repoXmlURL);
 

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java?rev=1097628&r1=1097627&r2=1097628&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java Thu Apr 28 21:50:33 2011
@@ -17,7 +17,7 @@
  */
 package org.apache.ivy.osgi.updatesite;
 
-import java.io.FileNotFoundException;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
@@ -27,6 +27,11 @@ import java.util.Iterator;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
+import org.apache.ivy.core.cache.CacheResourceOptions;
+import org.apache.ivy.core.cache.RepositoryCacheManager;
+import org.apache.ivy.core.event.EventManager;
+import org.apache.ivy.core.report.ArtifactDownloadReport;
+import org.apache.ivy.core.report.DownloadStatus;
 import org.apache.ivy.osgi.core.ExecutionEnvironmentProfileProvider;
 import org.apache.ivy.osgi.p2.P2ArtifactParser;
 import org.apache.ivy.osgi.p2.P2CompositeParser;
@@ -39,13 +44,28 @@ import org.apache.ivy.osgi.updatesite.xm
 import org.apache.ivy.osgi.updatesite.xml.FeatureParser;
 import org.apache.ivy.osgi.updatesite.xml.UpdateSite;
 import org.apache.ivy.osgi.updatesite.xml.UpdateSiteDigestParser;
+import org.apache.ivy.plugins.repository.url.URLRepository;
 import org.apache.ivy.plugins.repository.url.URLResource;
 import org.apache.ivy.util.Message;
-import org.apache.ivy.util.url.URLHandlerRegistry;
 import org.xml.sax.SAXException;
 
 public class UpdateSiteLoader {
 
+    private final RepositoryCacheManager repositoryCacheManager;
+
+    private final URLRepository urlRepository = new URLRepository();
+
+    private final CacheResourceOptions options;
+
+    public UpdateSiteLoader(RepositoryCacheManager repositoryCacheManager,
+            EventManager eventManager, CacheResourceOptions options) {
+        this.repositoryCacheManager = repositoryCacheManager;
+        this.options = options;
+        if (eventManager != null) {
+            urlRepository.addTransferListener(eventManager);
+        }
+    }
+
     public RepoDescriptor load(String url) throws IOException, ParseException, SAXException {
         Message.verbose("Loading the update site " + url);
         // first look for a p2 repository
@@ -117,22 +137,26 @@ public class UpdateSiteLoader {
 
         URL contentUrl = new URL(url + baseName + ".jar");
         URLResource res = new URLResource(contentUrl);
-        if (!res.exists()) {
+
+        ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
+            baseName, baseName, "jar", options, urlRepository);
+
+        if (report.getDownloadStatus() == DownloadStatus.FAILED) {
             // no jar file, try the xml one
             contentUrl = new URL(url + baseName + ".xml");
             res = new URLResource(contentUrl);
 
-            if (!res.exists()) {
+            report = repositoryCacheManager.downloadRepositoryResource(res,
+                baseName, baseName, "xml", options, urlRepository);
+
+            if (report.getDownloadStatus() == DownloadStatus.FAILED) {
                 // no xml either
                 return false;
             }
 
-            Message.verbose("\tReading " + res);
-            // we will then read directly from that input stream
-            readIn = res.openStream();
+            readIn = new FileInputStream(report.getLocalFile());
         } else {
-            Message.verbose("\t\tReading " + res);
-            InputStream in = res.openStream();
+            InputStream in = new FileInputStream(report.getLocalFile());
 
             try {
                 // compressed, let's get the pointer on the actual xml
@@ -160,13 +184,14 @@ public class UpdateSiteLoader {
     private UpdateSite loadSite(String url) throws IOException, ParseException, SAXException {
         String siteUrl = normalizeSiteUrl(url, null);
         URL u = new URL(siteUrl + "site.xml");
-        Message.verbose("\tReading " + url);
-        InputStream in;
-        try {
-            in = URLHandlerRegistry.getDefault().openStream(u);
-        } catch (IOException e) {
+
+        URLResource res = new URLResource(u);
+        ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
+            "site", "updatesite", "xml", options, urlRepository);
+        if (report.getDownloadStatus() == DownloadStatus.FAILED) {
             return null;
         }
+        InputStream in = new FileInputStream(report.getLocalFile());
         try {
             UpdateSite site = EclipseUpdateSiteParser.parse(in);
             site.setUrl(normalizeSiteUrl(site.getUrl(), siteUrl));
@@ -210,12 +235,14 @@ public class UpdateSiteLoader {
         }
         URL digest = new URL(digestUrl);
         Message.verbose("\tReading " + digest);
-        InputStream in;
-        try {
-            in = URLHandlerRegistry.getDefault().openStream(digest);
-        } catch (FileNotFoundException e) {
+
+        URLResource res = new URLResource(digest);
+        ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
+            "digest", "digest", "zip", options, urlRepository);
+        if (report.getDownloadStatus() == DownloadStatus.FAILED) {
             return null;
         }
+        InputStream in = new FileInputStream(report.getLocalFile());
         try {
             ZipInputStream zipped = findEntry(in, "digest.xml");
             if (zipped == null) {
@@ -236,7 +263,14 @@ public class UpdateSiteLoader {
         while (itFeatures.hasNext()) {
             EclipseFeature feature = (EclipseFeature) itFeatures.next();
             URL url = new URL(site.getUrl() + feature.getUrl());
-            InputStream in = URLHandlerRegistry.getDefault().openStream(url);
+
+            URLResource res = new URLResource(url);
+            ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
+                feature.getId(), "feature", "jar", options, urlRepository);
+            if (report.getDownloadStatus() == DownloadStatus.FAILED) {
+                return null;
+            }
+            InputStream in = new FileInputStream(report.getLocalFile());
             try {
                 ZipInputStream zipped = findEntry(in, "feature.xml");
                 if (zipped == null) {

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java?rev=1097628&r1=1097627&r2=1097628&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java Thu Apr 28 21:50:33 2011
@@ -28,20 +28,12 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
-import org.apache.ivy.Ivy;
-import org.apache.ivy.core.cache.CacheDownloadOptions;
-import org.apache.ivy.core.module.descriptor.Artifact;
-import org.apache.ivy.core.module.descriptor.DefaultArtifact;
-import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.core.cache.CacheResourceOptions;
 import org.apache.ivy.core.report.ArtifactDownloadReport;
 import org.apache.ivy.osgi.repo.RelativeURLRepository;
-import org.apache.ivy.plugins.repository.ArtifactResourceResolver;
-import org.apache.ivy.plugins.repository.Resource;
-import org.apache.ivy.plugins.repository.ResourceDownloader;
 import org.apache.ivy.plugins.repository.url.ChainedRepository;
+import org.apache.ivy.plugins.repository.url.URLRepository;
 import org.apache.ivy.plugins.repository.url.URLResource;
-import org.apache.ivy.plugins.resolver.util.ResolvedResource;
-import org.apache.ivy.util.FileUtil;
 import org.apache.ivy.util.Message;
 
 public class MirroredURLResolver extends RepositoryResolver {
@@ -85,30 +77,14 @@ public class MirroredURLResolver extends
     }
 
     private File downloadMirrorList() {
-        ModuleRevisionId mrid = ModuleRevisionId.newInstance("_mirror_list_cache_", getName(),
-            Ivy.getWorkingRevision());
-        Artifact artifact = new DefaultArtifact(mrid, null, "mirrorlist", "text", "txt");
-        CacheDownloadOptions options = new CacheDownloadOptions();
-        ArtifactDownloadReport report = getRepositoryCacheManager().download(artifact,
-            new ArtifactResourceResolver() {
-                public ResolvedResource resolve(Artifact artifact) {
-                    return new ResolvedResource(new URLResource(mirrorListUrl), Ivy
-                            .getWorkingRevision());
-                }
-            }, new ResourceDownloader() {
-                public void download(Artifact artifact, Resource resource, File dest)
-                        throws IOException {
-                    if (dest.exists()) {
-                        dest.delete();
-                    }
-                    File part = new File(dest.getAbsolutePath() + ".part");
-                    FileUtil.copy(mirrorListUrl, part, null);
-                    if (!part.renameTo(dest)) {
-                        throw new IOException("impossible to move part file to definitive one: "
-                                + part + " -> " + dest);
-                    }
-                }
-            }, options);
+        URLRepository urlRepository = new URLRepository();
+        if (getEventManager() != null) {
+            urlRepository.addTransferListener(getEventManager());
+        }
+        URLResource mirrorResource = new URLResource(mirrorListUrl);
+        CacheResourceOptions options = new CacheResourceOptions();
+        ArtifactDownloadReport report = getRepositoryCacheManager().downloadRepositoryResource(
+            mirrorResource, "mirrorlist", "text", "txt", options, urlRepository);
         return report.getLocalFile();
     }
 

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/util/HexEncoder.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/util/HexEncoder.java?rev=1097628&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/util/HexEncoder.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/util/HexEncoder.java Thu Apr 28 21:50:33 2011
@@ -0,0 +1,39 @@
+/*
+ *  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.ivy.util;
+
+/**
+ * Simple encoder of byte arrays into String array using only the hexadecimal alphabet
+ */
+public class HexEncoder {
+
+    private static final char[] ALPHABET = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
+            'b', 'c', 'd', 'e', 'f'};
+
+    public static String encode(byte[] packet) {
+        StringBuffer chars = new StringBuffer(16);
+        for (int i = 0; i < packet.length; i++) {
+            int highBits = (packet[i] & 0xF0) >> 4;
+            int lowBits = packet[i] & 0x0F;
+            chars.append(ALPHABET[highBits]);
+            chars.append(ALPHABET[lowBits]);
+        }
+        return chars.toString();
+    }
+
+}

Propchange: ant/ivy/core/trunk/src/java/org/apache/ivy/util/HexEncoder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ant/ivy/core/trunk/src/java/org/apache/ivy/util/HexEncoder.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision Author HeadURL Id

Propchange: ant/ivy/core/trunk/src/java/org/apache/ivy/util/HexEncoder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain