You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ivy-commits@incubator.apache.org by xa...@apache.org on 2007/12/01 19:26:21 UTC

svn commit: r600184 - in /incubator/ivy/core/trunk: src/java/org/apache/ivy/core/cache/ src/java/org/apache/ivy/core/module/descriptor/ src/java/org/apache/ivy/core/report/ src/java/org/apache/ivy/core/resolve/ src/java/org/apache/ivy/core/settings/ sr...

Author: xavier
Date: Sat Dec  1 11:26:20 2007
New Revision: 600184

URL: http://svn.apache.org/viewvc?rev=600184&view=rev
Log:
- improved locking reliability by surrounding more cache related operations with lock (IVY-654)
- moved yet more responsibilities from resolver to cache manager (still on the road to IVY-399)
- review of namespace use in basic resolver: now all logs from the basic resolver should be performed in the system namespace, and the code is less confusing between the system and repository namespace

remaining work: 
- add settings to configure locking and document (IVY-654)
- move more responsibilities to cache manager (checkModified for instance) (IVY-399)

Added:
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheMetadataOptions.java   (with props)
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ModuleDescriptorWriter.java   (with props)
Modified:
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheDownloadOptions.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheManager.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheSettings.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/AbstractArtifact.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/report/ArtifactDownloadReport.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/DefaultModuleRevision.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/settings/IvySettings.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/AbstractLockStrategy.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/ArtifactLockStrategy.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/FileBasedLockStrategy.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/LockStrategy.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/CacheResolver.java
    incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java
    incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/lock/ArtifactLockStrategyTest.java
    incubator/ivy/core/trunk/test/java/org/apache/ivy/util/CacheCleaner.java

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheDownloadOptions.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheDownloadOptions.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheDownloadOptions.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheDownloadOptions.java Sat Dec  1 11:26:20 2007
@@ -17,10 +17,12 @@
  */
 package org.apache.ivy.core.cache;
 
+
 public class CacheDownloadOptions {
     private boolean useOrigin = false;
     private DownloadListener listener = null;
     private boolean force = false;
+    
     public boolean isUseOrigin() {
         return useOrigin;
     }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheManager.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheManager.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheManager.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheManager.java Sat Dec  1 11:26:20 2007
@@ -19,6 +19,11 @@
 
 import java.io.File;
 import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.Date;
 
 import org.apache.ivy.core.IvyContext;
 import org.apache.ivy.core.IvyPatternHelper;
@@ -29,12 +34,19 @@
 import org.apache.ivy.core.report.ArtifactDownloadReport;
 import org.apache.ivy.core.report.DownloadStatus;
 import org.apache.ivy.core.resolve.DefaultModuleRevision;
+import org.apache.ivy.core.resolve.ResolveData;
 import org.apache.ivy.core.resolve.ResolvedModuleRevision;
 import org.apache.ivy.plugins.lock.LockStrategy;
+import org.apache.ivy.plugins.namespace.NameSpaceHelper;
+import org.apache.ivy.plugins.namespace.Namespace;
+import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
+import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
 import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser;
 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.ResourceHelper;
+import org.apache.ivy.plugins.resolver.BasicResolver;
 import org.apache.ivy.plugins.resolver.DependencyResolver;
 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
 import org.apache.ivy.util.Message;
@@ -55,6 +67,9 @@
 
     private LockStrategy lockStrategy;
 
+    // TODO: use different names when we'll be able to have multiple cache managers
+    private String name = "cache"; 
+
     public CacheManager(CacheSettings settings, File cache) {
         this.settings = settings == null ? IvyContext.getContext().getSettings() : settings;
         if (cache == null) {
@@ -261,7 +276,8 @@
                 .getCacheDataFilePattern(), mRevId)), "ivy cached data file for " + mRevId);
     }
 
-    public ResolvedModuleRevision findModuleInCache(ModuleRevisionId mrid, boolean validate) {
+    public ResolvedModuleRevision findModuleInCache(
+            ModuleRevisionId mrid, boolean validate, String expectedResolver) {
         // first, check if it is in cache
         if (!settings.getVersionMatcher().isDynamic(mrid)) {
             File ivyFile = getIvyFileInCache(mrid);
@@ -292,8 +308,17 @@
                     if (resolver != null) {
                         Message.debug("\tfound ivy file in cache for " + mrid + " (resolved by "
                                 + resolver.getName() + "): " + ivyFile);
-                        return new DefaultModuleRevision(resolver, artResolver, depMD, false,
-                                false);
+                        if (expectedResolver != null 
+                                && expectedResolver.equals(resolver.getName())) {
+                            return new DefaultModuleRevision(
+                                resolver, artResolver, depMD, false, false);
+                        } else {
+                            Message.debug(
+                                "found module in cache but with a different resolver: "
+                                + "discarding: " + mrid 
+                                + "; expected resolver=" + expectedResolver 
+                                + "; resolver=" + resolver.getName());                            
+                        }
                     } else {
                         Message.debug("\tresolver not found: " + resolverName
                                 + " => cannot use cached ivy file for " + mrid);
@@ -339,18 +364,14 @@
             ResourceDownloader resourceDownloader, 
             CacheDownloadOptions options) {
         final ArtifactDownloadReport adr = new ArtifactDownloadReport(artifact);
+        boolean useOrigin = options.isUseOrigin();
         
         LockStrategy lockStrategy = getLockStrategy();
         
-        boolean useOrigin = options.isUseOrigin();
-        try {
-            if (!lockStrategy.lockArtifact(artifact, getArchiveFileInCache(artifact))) {
-                adr.setDownloadStatus(DownloadStatus.FAILED);
-                adr.setDownloadDetails("impossible to get artifact lock with " + lockStrategy);
-            }
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt(); // reset interrupt status 
-            throw new RuntimeException("operation interrupted");
+        if (!lockArtifact(artifact)) {
+            adr.setDownloadStatus(DownloadStatus.FAILED);
+            adr.setDownloadDetails("impossible to get artifact lock with " + lockStrategy);
+            return adr;
         }
         try {
             DownloadListener listener = options.getListener();
@@ -367,6 +388,7 @@
                 adr.setDownloadStatus(DownloadStatus.NO);
                 adr.setSize(archiveFile.length());
                 adr.setArtifactOrigin(origin);
+                adr.setDownloadedFile(archiveFile);
             } else {
                 long start = System.currentTimeMillis();
                 try {
@@ -381,6 +403,7 @@
                             adr.setDownloadStatus(DownloadStatus.NO);
                             adr.setSize(archiveFile.length());
                             adr.setArtifactOrigin(origin);
+                            adr.setDownloadedFile(archiveFile);
                         } else {
                             // refresh archive file now that we better now its origin
                             archiveFile = getArchiveFileInCache(artifact,
@@ -401,6 +424,7 @@
                             adr.setDownloadTimeMillis(System.currentTimeMillis() - start);
                             adr.setDownloadStatus(DownloadStatus.SUCCESSFUL);
                             adr.setArtifactOrigin(origin);
+                            adr.setDownloadedFile(archiveFile);
                         }
                     } else {
                         // this exception is catched below and result in a download failed status
@@ -418,7 +442,182 @@
             }
             return adr;
         } finally {
-            lockStrategy.unlockArtifact(artifact, getArchiveFileInCache(artifact));
+            unlockArtifact(artifact);
+        }
+    }
+    
+    private boolean lockArtifact(Artifact artifact) {
+        try {
+            return getLockStrategy().lockArtifact(artifact, getArchiveFileInCache(artifact, null));
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt(); // reset interrupt status 
+            throw new RuntimeException("operation interrupted");
+        }
+    }
+    
+    private void unlockArtifact(Artifact artifact) {
+        getLockStrategy().unlockArtifact(artifact, getArchiveFileInCache(artifact, null));
+    }
+    
+    public void originalToCachedModuleDescriptor(
+            DependencyResolver resolver, ResolvedResource orginalMetadataRef,
+            Artifact requestedMetadataArtifact,
+            ModuleDescriptor md, ModuleDescriptorWriter writer) {
+        Artifact originalMetadataArtifact = getOriginalMetadataArtifact(requestedMetadataArtifact);
+        File mdFileInCache = getIvyFileInCache(md.getResolvedModuleRevisionId());
+
+        if (!lockArtifact(originalMetadataArtifact)) {
+            Message.warn("impossible to get artifact lock for: " + requestedMetadataArtifact);
+            return;
+        }
+        try {
+            writer.write(orginalMetadataRef, md, 
+                getArchiveFileInCache(originalMetadataArtifact), 
+                mdFileInCache);
+
+            saveResolver(md, resolver.getName());
+            saveArtResolver(md, resolver.getName());
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            Message.warn("impossible to put metadata file in cache: " 
+                + (orginalMetadataRef == null 
+                        ? String.valueOf(md.getResolvedModuleRevisionId()) 
+                        : String.valueOf(orginalMetadataRef))
+                + ". " + e.getClass().getName() + ": " + e.getMessage());
+        } finally {
+            unlockArtifact(originalMetadataArtifact);
         }
     }
+    
+    public ResolvedModuleRevision cacheModuleDescriptor(
+            DependencyResolver resolver, final ResolvedResource mdRef, Artifact moduleArtifact, 
+            ResourceDownloader downloader, CacheMetadataOptions options) throws ParseException {
+        ModuleDescriptorParser parser = ModuleDescriptorParserRegistry
+            .getInstance().getParser(mdRef.getResource());
+        Date cachedPublicationDate = null;
+        ArtifactDownloadReport report;
+        ModuleRevisionId mrid = moduleArtifact.getModuleRevisionId();
+        Artifact originalMetadataArtifact = getOriginalMetadataArtifact(moduleArtifact);
+        if (!lockArtifact(originalMetadataArtifact)) {
+            Message.error("impossible to acquire lock for " + originalMetadataArtifact);
+            return null;
+        }
+        try {
+        // now let's see if we can find it in cache and if it is up to date
+        ResolvedModuleRevision rmr = findModuleInCache(
+            mrid, options.isValidate(), resolver.getName());
+        if (rmr != null) {
+            if (rmr.getDescriptor().isDefault() && rmr.getResolver() != this) {
+                Message.verbose("\t" + getName() + ": found revision in cache: " + mrid
+                        + " (resolved by " + rmr.getResolver().getName()
+                        + "): but it's a default one, maybe we can find a better one");
+            } else {
+                if (!options.isCheckmodified() && !options.isChanging()) {
+                    Message.verbose("\t" + getName() + ": revision in cache: " + mrid);
+                    return DefaultModuleRevision.searchedRmr(rmr);
+                }
+                long repLastModified = mdRef.getLastModified();
+                long cacheLastModified = rmr.getDescriptor().getLastModified();
+                if (!rmr.getDescriptor().isDefault() && repLastModified <= cacheLastModified) {
+                    Message.verbose("\t" + getName() + ": revision in cache (not updated): "
+                            + mrid);
+                    return DefaultModuleRevision.searchedRmr(rmr);
+                } else {
+                    Message.verbose("\t" + getName() + ": revision in cache is not up to date: "
+                            + mrid);
+                    if (options.isChanging()) {
+                        // ivy file has been updated, we should see if it has a new publication date
+                        // to see if a new download is required (in case the dependency is a
+                        // changing one)
+                        cachedPublicationDate = rmr.getDescriptor().getResolvedPublicationDate();
+                    }
+                }
+            }
+        }
+
+        // now download module descriptor and parse it
+        report = download(
+            originalMetadataArtifact, 
+            new ArtifactResourceResolver() {
+                public ResolvedResource resolve(Artifact artifact) {
+                    return mdRef;
+                }
+            }, downloader, 
+            new CacheDownloadOptions().setListener(options.getListener()).setForce(true));
+        Message.verbose("\t" + report); 
+        } finally {
+            unlockArtifact(originalMetadataArtifact);
+        }
+
+        if (report.getDownloadStatus() == DownloadStatus.FAILED) {
+            Message.warn("problem while downloading module descriptor: " + mdRef.getResource() 
+                + ": " + report.getDownloadDetails() 
+                + " (" + report.getDownloadTimeMillis() + "ms)");
+            return null;
+        }
+
+        URL cachedMDURL = null;
+        try {
+            cachedMDURL = report.getDownloadedFile().toURL();
+        } catch (MalformedURLException ex) {
+            Message.warn("malformed url exception for original in cache file: " 
+                + report.getDownloadedFile() + ": " + ex.getMessage());
+            return null;
+        }
+        try {
+            ModuleDescriptor md = parser.parseDescriptor(
+                settings, cachedMDURL, mdRef.getResource(), options.isValidate());
+            Message.debug("\t" + getName() + ": parsed downloaded md file for " + mrid 
+                + "; parsed=" + md.getModuleRevisionId());
+
+            // check if we should delete old artifacts
+            boolean deleteOldArtifacts = false;
+            if (cachedPublicationDate != null
+                    && !cachedPublicationDate.equals(md.getResolvedPublicationDate())) {
+                // artifacts have changed, they should be downloaded again
+                Message.verbose(mrid + " has changed: deleting old artifacts");
+                deleteOldArtifacts = true;
+            }
+            if (deleteOldArtifacts) {
+                String[] confs = md.getConfigurationsNames();
+                for (int i = 0; i < confs.length; i++) {
+                    Artifact[] arts = md.getArtifacts(confs[i]);
+                    for (int j = 0; j < arts.length; j++) {
+                        Artifact transformedArtifact = NameSpaceHelper.transform(
+                            arts[j], options.getNamespace().getToSystemTransformer());
+                        ArtifactOrigin origin = getSavedArtifactOrigin(
+                            transformedArtifact);
+                        File artFile = getArchiveFileInCache(
+                            transformedArtifact, origin, false);
+                        if (artFile.exists()) {
+                            Message.debug("deleting " + artFile);
+                            artFile.delete();
+                        }
+                        removeSavedArtifactOrigin(transformedArtifact);
+                    }
+                }
+            } else if (options.isChanging()) {
+                Message.verbose(mrid
+                        + " is changing, but has not changed: will trust cached artifacts if any");
+            }
+            return new DefaultModuleRevision(resolver, resolver, md, true, true);
+        } catch (IOException ex) {
+            Message.warn("io problem while parsing ivy file: " + mdRef.getResource() + ": "
+                    + ex.getMessage());
+            return null;
+        }
+        
+    }
+    
+    public Artifact getOriginalMetadataArtifact(Artifact moduleArtifact) {
+        return DefaultArtifact.cloneWithAnotherName(moduleArtifact, 
+            moduleArtifact.getName() + ".original");
+    }
+
+
+    private String getName() {
+        return name;
+    }
+    
 }

Added: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheMetadataOptions.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheMetadataOptions.java?rev=600184&view=auto
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheMetadataOptions.java (added)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheMetadataOptions.java Sat Dec  1 11:26:20 2007
@@ -0,0 +1,56 @@
+/*
+ *  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;
+
+import org.apache.ivy.plugins.namespace.Namespace;
+
+public class CacheMetadataOptions extends CacheDownloadOptions {
+    private boolean isChanging = false; 
+    private boolean isCheckmodified = false;
+    private boolean validate = false; 
+    private Namespace namespace = Namespace.SYSTEM_NAMESPACE;
+    
+    public boolean isChanging() {
+        return isChanging;
+    }
+    public CacheMetadataOptions setChanging(boolean isChanging) {
+        this.isChanging = isChanging;
+        return this;
+    }
+    public Namespace getNamespace() {
+        return namespace;
+    }
+    public CacheMetadataOptions setNamespace(Namespace namespace) {
+        this.namespace = namespace;
+        return this;
+    }
+    public boolean isValidate() {
+        return validate;
+    }
+    public CacheMetadataOptions setValidate(boolean validate) {
+        this.validate = validate;
+        return this;
+    }
+    public boolean isCheckmodified() {
+        return isCheckmodified;
+    }
+    public CacheMetadataOptions setCheckmodified(boolean isCheckmodified) {
+        this.isCheckmodified = isCheckmodified;
+        return this;
+    }
+}

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

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheSettings.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheSettings.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheSettings.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheSettings.java Sat Dec  1 11:26:20 2007
@@ -51,4 +51,6 @@
     LockStrategy getLockStrategy(String name);
     
     LockStrategy getDefaultLockStrategy();
+    
+    boolean debugLocking();
 }

Added: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ModuleDescriptorWriter.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ModuleDescriptorWriter.java?rev=600184&view=auto
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ModuleDescriptorWriter.java (added)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/ModuleDescriptorWriter.java Sat Dec  1 11:26:20 2007
@@ -0,0 +1,30 @@
+/*
+ *  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;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+
+import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
+import org.apache.ivy.plugins.resolver.util.ResolvedResource;
+
+public interface ModuleDescriptorWriter {
+    public void write(ResolvedResource originalMdResource, ModuleDescriptor md, 
+            File src, File dest) throws IOException, ParseException;
+}

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

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java Sat Dec  1 11:26:20 2007
@@ -18,14 +18,21 @@
 package org.apache.ivy.core.cache;
 
 import java.io.File;
+import java.text.ParseException;
 
 import org.apache.ivy.core.module.descriptor.Artifact;
 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
 import org.apache.ivy.core.module.id.ModuleRevisionId;
 import org.apache.ivy.core.report.ArtifactDownloadReport;
+import org.apache.ivy.core.resolve.ResolveData;
 import org.apache.ivy.core.resolve.ResolvedModuleRevision;
+import org.apache.ivy.plugins.namespace.Namespace;
 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.resolver.BasicResolver;
+import org.apache.ivy.plugins.resolver.DependencyResolver;
+import org.apache.ivy.plugins.resolver.util.ResolvedResource;
 
 public interface RepositoryCacheManager {
     public abstract File getRepositoryCacheRoot();
@@ -87,8 +94,21 @@
 
     public abstract void removeSavedArtifactOrigin(Artifact artifact);
 
+    /**
+     * Search a module descriptor in cache for a mrid
+     * 
+     * @param mrid
+     *            the id of the module to search
+     * @param validate
+     *            true to validate ivy file found in cache before returning
+     * @param expectedResolver
+     *            the resolver with which the md in cache must have been resolved to be returned,
+     *            null if this doesn't matter
+     * @return the ResolvedModuleRevision corresponding to the module found, null if none correct
+     *         has been found in cache
+     */
     public abstract ResolvedModuleRevision findModuleInCache(
-            ModuleRevisionId mrid, boolean validate);
+            ModuleRevisionId mrid, boolean validate, String expectedResolver);
     
     /**
      * Downloads an artifact to this cache.
@@ -110,4 +130,15 @@
             ResourceDownloader resourceDownloader, 
             CacheDownloadOptions options);
 
+    public ResolvedModuleRevision cacheModuleDescriptor(
+            DependencyResolver resolver, ResolvedResource orginalMetadataRef, 
+            Artifact requestedMetadataArtifact, 
+            ResourceDownloader downloader, CacheMetadataOptions options) throws ParseException;
+
+    public Artifact getOriginalMetadataArtifact(Artifact moduleArtifact);
+
+    public void originalToCachedModuleDescriptor(
+            DependencyResolver resolver, ResolvedResource orginalMetadataRef, 
+            Artifact requestedMetadataArtifact, 
+            ModuleDescriptor md, ModuleDescriptorWriter writer);
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/AbstractArtifact.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/AbstractArtifact.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/AbstractArtifact.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/AbstractArtifact.java Sat Dec  1 11:26:20 2007
@@ -56,7 +56,7 @@
     }
 
     public String toString() {
-        return getModuleRevisionId() + "/" + getName() + "." + getExt() + "[" + getType() + "]";
+        return String.valueOf(getId());
     }
 
     public String getAttribute(String attName) {

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultModuleDescriptor.java Sat Dec  1 11:26:20 2007
@@ -211,7 +211,7 @@
     
     private List excludeRules = new ArrayList(); // List(ExcludeRule)
 
-    private Artifact moduleArtifact;
+    private Artifact metadataArtifact;
 
     public DefaultModuleDescriptor(ModuleRevisionId id, String status, Date pubDate) {
         this(id, status, pubDate, false);
@@ -243,14 +243,15 @@
     }
     
     public Artifact getMetadataArtifact() {
-        if (moduleArtifact == null) {
-            moduleArtifact = DefaultArtifact.newIvyArtifact(resolvedRevId, publicationDate);
+        if (metadataArtifact == null) {
+            metadataArtifact = DefaultArtifact.newIvyArtifact(
+                resolvedRevId, resolvedPublicationDate);
         }
-        return moduleArtifact;
+        return metadataArtifact;
     }
     
     public void setModuleArtifact(Artifact moduleArtifact) {
-        this.moduleArtifact = moduleArtifact;
+        this.metadataArtifact = moduleArtifact;
     }
 
     public boolean isDefault() {

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/report/ArtifactDownloadReport.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/report/ArtifactDownloadReport.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/report/ArtifactDownloadReport.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/report/ArtifactDownloadReport.java Sat Dec  1 11:26:20 2007
@@ -17,16 +17,24 @@
  */
 package org.apache.ivy.core.report;
 
+import java.io.File;
+
 import org.apache.ivy.core.cache.ArtifactOrigin;
 import org.apache.ivy.core.module.descriptor.Artifact;
 
 /**
- *
+ * Report on the download of an artifact from a repository to a local (cached) file.
+ * <p>
+ * Note that depending on cache implementation, the artifact may not be actually downloaded, but
+ * used directly from its original location.
+ * </p>
  */
 public class ArtifactDownloadReport {
     private Artifact artifact;
 
     private ArtifactOrigin origin;
+    
+    private File downloadedFile;
 
     private DownloadStatus downloadStatus;
 
@@ -107,5 +115,19 @@
         } else {
             return super.toString();
         }
+    }
+
+    /**
+     * Returns the file where the artifact has been downloaded, or <code>null</code> if and only
+     * if the download failed.
+     * 
+     * @return the file where the artifact has been downloaded
+     */
+    public File getDownloadedFile() {
+        return downloadedFile;
+    }
+
+    public void setDownloadedFile(File downloadedFile) {
+        this.downloadedFile = downloadedFile;
     }
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/DefaultModuleRevision.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/DefaultModuleRevision.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/DefaultModuleRevision.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/DefaultModuleRevision.java Sat Dec  1 11:26:20 2007
@@ -90,4 +90,37 @@
         return isSearched;
     }
 
+    public static ResolvedModuleRevision searchedRmr(final ResolvedModuleRevision rmr) {
+        // delegate all to previously found except isSearched
+        return new ResolvedModuleRevision() {
+            public boolean isSearched() {
+                return true;
+            }
+
+            public boolean isDownloaded() {
+                return rmr.isDownloaded();
+            }
+
+            public ModuleDescriptor getDescriptor() {
+                return rmr.getDescriptor();
+            }
+
+            public Date getPublicationDate() {
+                return rmr.getPublicationDate();
+            }
+
+            public ModuleRevisionId getId() {
+                return rmr.getId();
+            }
+
+            public DependencyResolver getResolver() {
+                return rmr.getResolver();
+            }
+
+            public DependencyResolver getArtifactResolver() {
+                return rmr.getArtifactResolver();
+            }
+        };
+    }
+    
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/settings/IvySettings.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/settings/IvySettings.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/settings/IvySettings.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/settings/IvySettings.java Sat Dec  1 11:26:20 2007
@@ -202,6 +202,8 @@
 
     private StatusManager statusManager;
 
+    private Boolean debugLocking;
+
     public IvySettings() {
         this(new IvyVariableContainerImpl());
     }
@@ -1146,6 +1148,15 @@
                     && Boolean.valueOf(var).booleanValue());
         }
         return debugConflictResolution.booleanValue();
+    }
+
+    public boolean debugLocking() {
+        if (debugLocking == null) {
+            String var = getVariable("ivy.log.locking");
+            debugLocking = Boolean.valueOf(var != null
+                    && Boolean.valueOf(var).booleanValue());
+        }
+        return debugLocking.booleanValue();
     }
 
     public boolean logNotConvertedExclusionRule() {

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/AbstractLockStrategy.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/AbstractLockStrategy.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/AbstractLockStrategy.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/AbstractLockStrategy.java Sat Dec  1 11:26:20 2007
@@ -19,6 +19,15 @@
 
 public abstract class AbstractLockStrategy implements LockStrategy {
     private String name;
+    
+    private boolean debugLocking = false;
+    
+    protected AbstractLockStrategy() {
+    }
+
+    protected AbstractLockStrategy(boolean debugLocking) {
+        this.debugLocking = debugLocking;
+    }
 
     public String getName() {
         return name;
@@ -28,5 +37,8 @@
     }
     public String toString() {
         return name;
+    }
+    public boolean isDebugLocking() {
+        return debugLocking;
     }
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/ArtifactLockStrategy.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/ArtifactLockStrategy.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/ArtifactLockStrategy.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/ArtifactLockStrategy.java Sat Dec  1 11:26:20 2007
@@ -23,6 +23,15 @@
 
 public class ArtifactLockStrategy extends FileBasedLockStrategy {
     public ArtifactLockStrategy() {
+        init();
+    }
+
+    public ArtifactLockStrategy(boolean debugLocking) {
+        super(debugLocking);
+        init();
+    }
+
+    private void init() {
         setName("artifact-lock");
     }
 

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/FileBasedLockStrategy.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/FileBasedLockStrategy.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/FileBasedLockStrategy.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/FileBasedLockStrategy.java Sat Dec  1 11:26:20 2007
@@ -32,84 +32,180 @@
 
     private static final long DEFAULT_TIMEOUT = 2 * 60 * 1000;
 
-    private static final String CREATE_FILE = "create-file";
-    private static final String LOCK_FILE = "lock-file";
+    /**
+     * The locker to use to make file lock attempts.
+     * <p>
+     * Two implementations of FileLocker are provided below, according to our tests the
+     * CreateFileLocker is both performing better and much more reliable than NIOFileLocker.
+     * </p>
+     */
+    private FileLocker locker;
     
-    private String fileLockMethod = CREATE_FILE;
     private long timeout = DEFAULT_TIMEOUT;
     
-    private Map locks = new HashMap();
+    private Map/*<File, Integer>*/ currentLockCounters = new HashMap();
     
+    protected FileBasedLockStrategy() {
+        this(new CreateFileLocker(false), false);
+    }
+
+    protected FileBasedLockStrategy(boolean debugLocking) {
+        this(new CreateFileLocker(debugLocking), debugLocking);
+    }
+
+    protected FileBasedLockStrategy(FileLocker locker, boolean debugLocking) {
+        super(debugLocking);
+        this.locker = locker;
+    }
+
+        
     protected boolean acquireLock(File file) throws InterruptedException {
-        Message.debug("acquiring lock on " + file);
+        if (isDebugLocking()) {
+            Message.info("acquiring lock on " + file);
+        }
         long start = System.currentTimeMillis();
-        if (CREATE_FILE.equals(fileLockMethod)) {
-            do {
-                try {
-                    if (file.getParentFile().exists() || file.getParentFile().mkdirs()) {
-                        if (file.createNewFile()) {
-                            Message.debug("lock acquired on " + file);
-                            return true;
-                        } else {
-                            Message.debug("file creation failed " + file);
+        synchronized (this) {
+            if (hasLock(file)) {
+                incrementLock(file);
+                return true;
+            }
+        }
+        do {
+            if (locker.tryLock(file)) {
+                if (isDebugLocking()) {
+                    Message.info("lock acquired on " + file 
+                        + " in " + (System.currentTimeMillis() - start) + "ms");
+                }
+                incrementLock(file);
+                return true;
+            }
+            Thread.sleep(SLEEP_TIME);
+        } while (System.currentTimeMillis() - start < timeout);
+        return false;
+    }
+
+    protected void releaseLock(File file) {
+        if (decrementLock(file) == 0) {
+            locker.unlock(file);
+            if (isDebugLocking()) {
+                Message.info("lock released on " + file);
+            }
+        }
+    }
+
+    
+    private synchronized boolean hasLock(File file) {
+        Integer c = (Integer) currentLockCounters.get(file);
+        return c != null && c.intValue() > 0;
+    }
+    
+    private synchronized void incrementLock(File file) {
+        Integer c = (Integer) currentLockCounters.get(file);
+        currentLockCounters.put(file, new Integer(c == null ? 1 : c.intValue() + 1));
+    }
+
+    private synchronized int decrementLock(File file) {
+        Integer c = (Integer) currentLockCounters.get(file);
+        int dc = c == null ? 0 : c.intValue() - 1;
+        currentLockCounters.put(file, new Integer(dc));
+        return dc;
+    }
+
+    public static interface FileLocker {
+        boolean tryLock(File f);
+        void unlock(File f);
+    }
+    
+    /**
+     * "locks" a file by creating it if it doesn't exist, relying on the
+     * {@link File#createNewFile()} atomicity.
+     */
+    public static class CreateFileLocker implements FileLocker {
+        private boolean debugLocking;
+
+        public CreateFileLocker(boolean debugLocking) {
+            this.debugLocking = debugLocking;
+        }
+
+        public boolean tryLock(File file) {
+            try {
+                if (file.getParentFile().exists() || file.getParentFile().mkdirs()) {
+                    if (file.createNewFile()) {
+                        return true;
+                    } else {
+                        if (debugLocking) {
+                            Message.info("file creation failed " + file);
                         }
                     }
-                } catch (IOException e) {
-                    // ignored
-                    Message.verbose("file creation failed due to an exception: " 
-                        + e.getMessage() + " (" + file + ")");
                 }
-                Thread.sleep(SLEEP_TIME);
-            } while (System.currentTimeMillis() - start < timeout);
+            } catch (IOException e) {
+                // ignored
+                Message.verbose("file creation failed due to an exception: " 
+                    + e.getMessage() + " (" + file + ")");
+            }
             return false;
-        } else if (LOCK_FILE.equals(fileLockMethod)) {
-            do {
-                try {
-                    if (file.getParentFile().exists() || file.getParentFile().mkdirs()) {
-                        RandomAccessFile raf =
-                            new RandomAccessFile(file, "rw");            
-                        FileChannel channel = raf.getChannel();
-                        try {
-                            FileLock l = channel.tryLock();
-                            if (l != null) {
+        }
+
+        public void unlock(File file) {
+            file.delete();
+        }
+    }
+    /**
+     * Locks a file using the {@link FileLock} mechanism. 
+     */
+    public static class NIOFileLocker implements FileLocker {
+        
+        private Map locks = new HashMap();
+        private boolean debugLocking;
+        
+        public NIOFileLocker(boolean debugLocking) {
+            this.debugLocking = debugLocking;
+        }
+
+        public boolean tryLock(File file) {
+            try {
+                if (file.getParentFile().exists() || file.getParentFile().mkdirs()) {
+                    RandomAccessFile raf =
+                        new RandomAccessFile(file, "rw");            
+                    FileChannel channel = raf.getChannel();
+                    try {
+                        FileLock l = channel.tryLock();
+                        if (l != null) {
+                            synchronized (this) {
                                 locks.put(file, l);
-                                Message.debug("lock acquired on " + file);
-                                return true;
                             }
-                        } finally {
-                            raf.close();
+                            return true;
+                        } else {
+                            if (debugLocking) {
+                                Message.info("failed to acquire lock on " + file);
+                            }
                         }
+                    } finally {
+                        raf.close();
                     }
-                } catch (IOException e) {
-                    // ignored
-                    Message.verbose("file lock failed due to an exception: " 
-                        + e.getMessage() + " (" + file + ")");
                 }
-                Thread.sleep(SLEEP_TIME);
-            } while (System.currentTimeMillis() - start < timeout);
+            } catch (IOException e) {
+                // ignored
+                Message.verbose("file lock failed due to an exception: " 
+                    + e.getMessage() + " (" + file + ")");
+            }
             return false;
-        } else {
-            throw new IllegalStateException("unknown lock method " + fileLockMethod);
         }
-    }
-    
-    protected void releaseLock(File file) {
-        if (CREATE_FILE.equals(fileLockMethod)) {
-            file.delete();
-            Message.debug("lock released on " + file);
-        } else if (LOCK_FILE.equals(fileLockMethod)) {
-            FileLock l = (FileLock) locks.get(file);
-            if (l == null) {
-                throw new IllegalArgumentException("file not previously locked: " + file);
-            }
-            try {
-                l.release();
-            } catch (IOException e) {
-                Message.error("problem while releasing lock on " + file + ": " + e.getMessage());
+
+        public void unlock(File file) {
+            synchronized (this) {
+                FileLock l = (FileLock) locks.get(file);
+                if (l == null) {
+                    throw new IllegalArgumentException("file not previously locked: " + file);
+                }
+                try {
+                    l.release();
+                } catch (IOException e) {
+                    Message.error(
+                        "problem while releasing lock on " + file + ": " + e.getMessage());
+                }
             }
-        } else {
-            throw new IllegalStateException("unknown lock method " + fileLockMethod);
         }
+        
     }
-
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/LockStrategy.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/LockStrategy.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/LockStrategy.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/LockStrategy.java Sat Dec  1 11:26:20 2007
@@ -33,6 +33,10 @@
  * The lock methods should return true when the lock is either actually acquired or not performed by
  * the strategy.
  * </p>
+ * <p>
+ * Locking used in the locking strategy must support reentrant lock. Reentrant locking should be
+ * performed for the whole strategy.
+ * </p>
  */
 public interface LockStrategy {
 

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java Sat Dec  1 11:26:20 2007
@@ -262,25 +262,17 @@
         return NameSpaceHelper.transform(dd, getNamespace().getFromSystemTransformer(), true);
     }
 
+    protected DependencyDescriptor toSystem(DependencyDescriptor dd) {
+        return NameSpaceHelper.transform(dd, getNamespace().getToSystemTransformer(), true);
+    }
+
     protected IvyNode getSystemNode(ResolveData data, ModuleRevisionId resolvedMrid) {
         return data.getNode(toSystem(resolvedMrid));
     }
 
     protected ResolvedModuleRevision findModuleInCache(ResolveData data, ModuleRevisionId mrid) {
-        ResolvedModuleRevision moduleFromCache = data.getCacheManager().findModuleInCache(
-            toSystem(mrid), doValidate(data));
-        if (moduleFromCache == null) {
-            return null;
-        }
-        if ((getName() == null ? moduleFromCache.getResolver().getName() == null : moduleFromCache
-                .getResolver() == null ? false : getName().equals(
-            moduleFromCache.getResolver().getName()))) {
-            return moduleFromCache;
-        } else {
-            Message.debug("found module in cache but with a different resolver: discarding: "
-                    + moduleFromCache);
-            return null;
-        }
+        return data.getCacheManager().findModuleInCache(
+            mrid, doValidate(data), getName());
     }
 
     public String getChangingMatcherName() {

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java Sat Dec  1 11:26:20 2007
@@ -38,7 +38,9 @@
 import org.apache.ivy.core.IvyPatternHelper;
 import org.apache.ivy.core.cache.ArtifactOrigin;
 import org.apache.ivy.core.cache.CacheDownloadOptions;
+import org.apache.ivy.core.cache.CacheMetadataOptions;
 import org.apache.ivy.core.cache.DownloadListener;
+import org.apache.ivy.core.cache.ModuleDescriptorWriter;
 import org.apache.ivy.core.cache.RepositoryCacheManager;
 import org.apache.ivy.core.event.EventManager;
 import org.apache.ivy.core.event.download.EndArtifactDownloadEvent;
@@ -161,94 +163,95 @@
         checkmodified = Boolean.valueOf(check);
     }
 
-    public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
+    public ResolvedModuleRevision getDependency(DependencyDescriptor dde, ResolveData data)
             throws ParseException {
         IvyContext context = IvyContext.pushNewCopyContext();
-        context.setDependencyDescriptor(dd);
+        DependencyDescriptor systemDd = dde;
+        DependencyDescriptor nsDd = fromSystem(dde);
+        context.setDependencyDescriptor(systemDd);
         context.setResolveData(data);
         try {
-            DependencyDescriptor systemDd = dd;
-            dd = fromSystem(dd);
-
             clearIvyAttempts();
             clearArtifactAttempts();
             boolean downloaded = false;
             boolean searched = false;
-            ModuleRevisionId mrid = dd.getDependencyRevisionId();
+            ModuleRevisionId systemMrid = systemDd.getDependencyRevisionId();
+            ModuleRevisionId  nsMrid = nsDd.getDependencyRevisionId();
+            
             // check revision
-            int index = mrid.getRevision().indexOf("@");
-            if (index != -1 && !mrid.getRevision().substring(index + 1).equals(workspaceName)) {
-                Message.verbose("\t" + getName() + ": unhandled revision => " + mrid.getRevision());
+            int index = systemMrid.getRevision().indexOf("@");
+            if (index != -1 && !systemMrid.getRevision().substring(index + 1).equals(workspaceName)) {
+                Message.verbose("\t" + getName() + ": unhandled revision => " + systemMrid.getRevision());
                 return null;
             }
 
-            boolean isDynamic = getSettings().getVersionMatcher().isDynamic(mrid);
+            boolean isDynamic = getSettings().getVersionMatcher().isDynamic(systemMrid);
             if (isDynamic && !acceptLatest()) {
                 Message.error("dynamic revisions not handled by " + getClass().getName()
-                    + ". impossible to resolve " + mrid);
+                    + ". impossible to resolve " + systemMrid);
                 return null;
             }
 
-            boolean isChangingRevision = getChangingMatcher().matches(mrid.getRevision());
-            boolean isChangingDependency = isChangingRevision || dd.isChanging();
+            boolean isChangingRevision = getChangingMatcher().matches(systemMrid.getRevision());
+            boolean isChangingDependency = isChangingRevision || systemDd.isChanging();
 
             // if we do not have to check modified and if the revision is exact and not changing,
             // we first search for it in cache
             ResolvedModuleRevision cachedRmr = null;
             boolean checkedCache = false;
             if (!isDynamic && !isCheckmodified() && !isChangingDependency) {
-                cachedRmr = findModuleInCache(data, mrid);
+                cachedRmr = findModuleInCache(data, systemMrid);
                 checkedCache = true;
                 if (cachedRmr != null) {
                     if (cachedRmr.getDescriptor().isDefault() && cachedRmr.getResolver() != this) {
-                        Message.verbose("\t" + getName() + ": found revision in cache: " + mrid
+                        Message.verbose("\t" + getName() + ": found revision in cache: " + systemMrid
                             + " (resolved by " + cachedRmr.getResolver().getName()
                             + "): but it's a default one, maybe we can find a better one");
                     } else {
-                        Message.verbose("\t" + getName() + ": revision in cache: " + mrid);
-                        return toSystem(cachedRmr);
+                        Message.verbose("\t" + getName() + ": revision in cache: " + systemMrid);
+                        return cachedRmr;
                     }
                 }
             }
             checkInterrupted();
-            ResolvedResource ivyRef = findIvyFileRef(dd, data);
+            ResolvedResource ivyRef = findIvyFileRef(nsDd, data);
             checkInterrupted();
             searched = true;
 
             // get module descriptor
-            ModuleDescriptorParser parser;
-            ModuleDescriptor md;
+            final ModuleDescriptorParser parser;
+            ModuleDescriptor nsMd;
             ModuleDescriptor systemMd = null;
             if (ivyRef == null) {
                 if (!isAllownomd()) {
-                    Message.verbose("\t" + getName() + ": no ivy file found for " + mrid);
+                    Message.verbose("\t" + getName() + ": no ivy file found for " + systemMrid);
                     return null;
                 }
                 parser = XmlModuleDescriptorParser.getInstance();
-                md = DefaultModuleDescriptor.newDefaultInstance(mrid, dd
+                nsMd = DefaultModuleDescriptor.newDefaultInstance(nsMrid, nsDd
                     .getAllDependencyArtifacts());
-                ResolvedResource artifactRef = findFirstArtifactRef(md, dd, data);
+                ResolvedResource artifactRef = findFirstArtifactRef(nsMd, nsDd, data);
                 checkInterrupted();
                 if (artifactRef == null) {
                     Message.verbose("\t" + getName() + ": no ivy file nor artifact found for "
-                        + mrid);
+                        + systemMrid);
                     if (!checkedCache) {
-                        cachedRmr = findModuleInCache(data, mrid);
+                        cachedRmr = findModuleInCache(data, systemMrid);
                     }
                     if (cachedRmr != null) {
-                        Message.verbose("\t" + getName() + ": revision in cache: " + mrid);
-                        return toSystem(cachedRmr);
+                        Message.verbose("\t" + getName() + ": revision in cache: " + systemMrid);
+                        return cachedRmr;
                     }
                     return null;
                 } else {
                     long lastModified = artifactRef.getLastModified();
-                    if (lastModified != 0 && md instanceof DefaultModuleDescriptor) {
-                        ((DefaultModuleDescriptor) md).setLastModified(lastModified);
+                    if (lastModified != 0 && nsMd instanceof DefaultModuleDescriptor) {
+                        ((DefaultModuleDescriptor) nsMd).setLastModified(lastModified);
                     }
-                    Message.verbose("\t" + getName() + ": no ivy file found for " + mrid
+                    Message.verbose("\t" + getName() + ": no ivy file found for " + systemMrid
                         + ": using default data");
                     if (isDynamic) {
-                        md.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(mrid,
+                        nsMd.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(nsMrid,
                             artifactRef.getRevision()));
                     }
                 }
@@ -258,7 +261,7 @@
                     rmr = ((MDResolvedResource) ivyRef).getResolvedModuleRevision();
                 }
                 if (rmr == null) {
-                    rmr = parse(ivyRef, dd, data);
+                    rmr = parse(ivyRef, systemDd, data);
                     if (rmr == null) {
                         return null;
                     }
@@ -266,41 +269,39 @@
                 if (!rmr.isDownloaded()) {
                     return toSystem(rmr);
                 } else {
-                    md = rmr.getDescriptor();
+                    nsMd = rmr.getDescriptor();
                     parser = ModuleDescriptorParserRegistry.getInstance().getParser(
                         ivyRef.getResource());
 
                     // check descriptor data is in sync with resource revision and names
-                    systemMd = toSystem(md);
+                    systemMd = toSystem(nsMd);
                     if (checkconsistency) {
-                        checkDescriptorConsistency(mrid, md, ivyRef);
-                        checkDescriptorConsistency(systemDd.getDependencyRevisionId(), systemMd,
-                            ivyRef);
+                        checkDescriptorConsistency(systemMrid, systemMd, ivyRef);
+                        checkDescriptorConsistency(nsMrid, nsMd, ivyRef);
                     } else {
-                        if (md instanceof DefaultModuleDescriptor) {
-                            String revision = getRevision(ivyRef, mrid, md);
-                            ((DefaultModuleDescriptor) md).setModuleRevisionId(ModuleRevisionId
-                                .newInstance(mrid, revision));
+                        if (nsMd instanceof DefaultModuleDescriptor) {
+                            String revision = getRevision(ivyRef, nsMrid, nsMd);
+                            ((DefaultModuleDescriptor) nsMd).setModuleRevisionId(ModuleRevisionId
+                                .newInstance(nsMrid, revision));
                         } else {
                             Message.warn(
-                                "consistency disabled with instance of non DefaultModuleDescriptor..."
-                                + " module info can't be updated, so consistency check will be done");
-                            checkDescriptorConsistency(mrid, md, ivyRef);
-                            checkDescriptorConsistency(systemDd.getDependencyRevisionId(),
-                                systemMd, ivyRef);
+                              "consistency disabled with instance of non DefaultModuleDescriptor..."
+                              + " module info can't be updated, so consistency check will be done");
+                            checkDescriptorConsistency(nsMrid, nsMd, ivyRef);
+                            checkDescriptorConsistency(systemMrid, systemMd, ivyRef);
                         }
                     }
                 }
             }
 
             if (systemMd == null) {
-                systemMd = toSystem(md);
+                systemMd = toSystem(nsMd);
             }
 
             // resolve revision
-            ModuleRevisionId resolvedMrid = mrid;
+            ModuleRevisionId resolvedMrid = nsMrid;
             if (isDynamic) {
-                resolvedMrid = md.getResolvedModuleRevisionId();
+                resolvedMrid = nsMd.getResolvedModuleRevisionId();
                 if (resolvedMrid.getRevision() == null 
                         || resolvedMrid.getRevision().length() == 0) {
                     if (ivyRef.getRevision() == null || ivyRef.getRevision().length() == 0) {
@@ -311,23 +312,25 @@
                             .getRevision());
                     }
                 }
-                Message.verbose("\t\t[" + resolvedMrid.getRevision() + "] " + mrid.getModuleId());
+                Message.verbose("\t\t[" + toSystem(resolvedMrid).getRevision() + "] " 
+                    + systemMrid.getModuleId());
             }
-            md.setResolvedModuleRevisionId(resolvedMrid);
-            systemMd.setResolvedModuleRevisionId(toSystem(resolvedMrid)); // keep system md in
-            // sync with md
+            nsMd.setResolvedModuleRevisionId(resolvedMrid);
+
+            // keep system md in sync with ns md
+            systemMd.setResolvedModuleRevisionId(toSystem(resolvedMrid)); 
 
             // check module descriptor revision
-            if (!getSettings().getVersionMatcher().accept(mrid, md)) {
+            if (!getSettings().getVersionMatcher().accept(systemMrid, systemMd)) {
                 Message.info("\t" + getName() + ": unacceptable revision => was="
-                    + md.getModuleRevisionId().getRevision() + " required="
-                    + mrid.getRevision());
+                    + systemMd.getModuleRevisionId().getRevision() + " required="
+                    + systemMrid.getRevision());
                 return null;
             }
 
             // resolve and check publication date
             if (data.getDate() != null) {
-                long pubDate = getPublicationDate(md, dd, data);
+                long pubDate = getPublicationDate(systemMd, systemDd, data);
                 if (pubDate > data.getDate().getTime()) {
                     Message.info("\t" + getName() + ": unacceptable publication date => was="
                         + new Date(pubDate) + " required=" + data.getDate());
@@ -335,18 +338,17 @@
                 } else if (pubDate == -1) {
                     Message.info("\t" + getName()
                         + ": impossible to guess publication date: artifact missing for "
-                        + mrid);
+                        + systemMrid);
                     return null;
                 }
-                md.setResolvedPublicationDate(new Date(pubDate));
-                systemMd.setResolvedPublicationDate(new Date(pubDate)); // keep system md in sync
-                // with md
+                nsMd.setResolvedPublicationDate(new Date(pubDate));
+                systemMd.setResolvedPublicationDate(new Date(pubDate)); 
             }
             
-            if (!md.isDefault() 
+            if (!nsMd.isDefault() 
                     && data.getSettings().logNotConvertedExclusionRule() 
-                    && md instanceof DefaultModuleDescriptor) {
-                DefaultModuleDescriptor dmd = (DefaultModuleDescriptor) md;
+                    && nsMd instanceof DefaultModuleDescriptor) {
+                DefaultModuleDescriptor dmd = (DefaultModuleDescriptor) nsMd;
                 if (dmd.isNamespaceUseful()) {
                     Message.warn(
                         "the module descriptor "
@@ -359,41 +361,36 @@
             }
 
             RepositoryCacheManager cacheManager = data.getCacheManager();
-            // TODO: this should be done with a lock on the metadata artifact (moved to the cache manager)
-           try {
-                File ivyFile = cacheManager.getIvyFileInCache(
-                    systemMd.getResolvedModuleRevisionId());
-                if (ivyRef == null) {
-                    // a basic ivy file is written containing default data
-                    XmlModuleDescriptorWriter.write(systemMd, ivyFile);
-                } else {
-                    // copy and update ivy file from source to cache
-                    parser.toIvyFile(
-                        new FileInputStream(
-                            cacheManager.getArchiveFileInCache(
-                                getOriginalMetadataArtifact(
-                                    parser.getMetadataArtifact(
-                                        resolvedMrid, ivyRef.getResource())))), 
-                        ivyRef.getResource(), ivyFile,
-                        systemMd);
-                    long repLastModified = ivyRef.getLastModified();
-                    if (repLastModified > 0) {
-                        ivyFile.setLastModified(repLastModified);
+            
+            // the metadata artifact which was used to cache the original metadata file 
+            Artifact requestedMetadataArtifact = 
+                ivyRef == null 
+                ? systemMd.getMetadataArtifact()
+                : parser.getMetadataArtifact(
+                    ModuleRevisionId.newInstance(systemMrid, ivyRef.getRevision()), 
+                    ivyRef.getResource());
+            
+            cacheManager.originalToCachedModuleDescriptor(this, ivyRef, requestedMetadataArtifact, 
+                    systemMd, new ModuleDescriptorWriter() {
+                public void write(ResolvedResource originalMdResource, ModuleDescriptor md, 
+                        File src, File dest) 
+                        throws IOException, ParseException {
+                    if (originalMdResource == null) {
+                        // a basic ivy file is written containing default data
+                        XmlModuleDescriptorWriter.write(md, dest);
+                    } else {
+                        // copy and update ivy file from source to cache
+                        parser.toIvyFile(
+                            new FileInputStream(src), 
+                            originalMdResource.getResource(), dest,
+                            md);
+                        long repLastModified = originalMdResource.getLastModified();
+                        if (repLastModified > 0) {
+                            dest.setLastModified(repLastModified);
+                        }
                     }
                 }
-            } catch (Exception e) {
-                if (ivyRef == null) {
-                    Message.warn("impossible to create ivy file in cache for module : "
-                        + resolvedMrid);
-                } else {
-                    Message.warn("impossible to copy ivy file to cache: " + ivyRef.getResource()
-                        + ". " + e.getClass().getName() + ": " + e.getMessage());
-                }
-            }
-
-            cacheManager.saveResolver(systemMd, getName());
-            cacheManager.saveArtResolver(systemMd, getName());
-            
+            });            
             
             return new DefaultModuleRevision(this, this, systemMd, searched, downloaded);
         } finally {
@@ -424,9 +421,12 @@
     public ResolvedModuleRevision parse(final ResolvedResource mdRef, DependencyDescriptor dd,
             ResolveData data) throws ParseException {
 
+        DependencyDescriptor nsDd = dd;
+        dd = toSystem(nsDd);
+        
         ModuleRevisionId mrid = dd.getDependencyRevisionId();
-        ModuleDescriptorParser parser = ModuleDescriptorParserRegistry.getInstance().getParser(
-            mdRef.getResource());
+        ModuleDescriptorParser parser = ModuleDescriptorParserRegistry
+                .getInstance().getParser(mdRef.getResource());
         if (parser == null) {
             Message.warn("no module descriptor parser available for " + mdRef.getResource());
             return null;
@@ -435,15 +435,12 @@
         Message.verbose("\t\t=> " + mdRef);
         Message.debug("\tparser = " + parser);
 
-        boolean isChangingRevision = getChangingMatcher().matches(mrid.getRevision());
-        boolean isChangingDependency = isChangingRevision || dd.isChanging();
-        Date cachedPublicationDate = null;
         ModuleRevisionId resolvedMrid = mrid;
 
         // first check if this dependency has not yet been resolved
         if (getSettings().getVersionMatcher().isDynamic(mrid)) {
             resolvedMrid = ModuleRevisionId.newInstance(mrid, mdRef.getRevision());
-            IvyNode node = getSystemNode(data, resolvedMrid);
+            IvyNode node = data.getNode(resolvedMrid);
             if (node != null && node.getModuleRevision() != null) {
                 // this revision has already be resolved : return it
                 if (node.getDescriptor() != null && node.getDescriptor().isDefault()) {
@@ -453,119 +450,22 @@
                 } else {
                     Message.verbose("\t" + getName() + ": revision already resolved: "
                             + resolvedMrid);
-                    return searchedRmr(node.getModuleRevision());
+                    return DefaultModuleRevision.searchedRmr(node.getModuleRevision());
                 }
             }
         }
 
-        // TODO: this should be done while the lock on the original artifact is acquired (in cache manager #download)
-        // now let's see if we can find it in cache and if it is up to date
-        ResolvedModuleRevision rmr = findModuleInCache(data, resolvedMrid);
-        if (rmr != null) {
-            if (rmr.getDescriptor().isDefault() && rmr.getResolver() != this) {
-                Message.verbose("\t" + getName() + ": found revision in cache: " + mrid
-                        + " (resolved by " + rmr.getResolver().getName()
-                        + "): but it's a default one, maybe we can find a better one");
-            } else {
-                if (!isCheckmodified() && !isChangingDependency) {
-                    Message.verbose("\t" + getName() + ": revision in cache: " + mrid);
-                    return searchedRmr(rmr);
-                }
-                long repLastModified = mdRef.getLastModified();
-                long cacheLastModified = rmr.getDescriptor().getLastModified();
-                if (!rmr.getDescriptor().isDefault() && repLastModified <= cacheLastModified) {
-                    Message.verbose("\t" + getName() + ": revision in cache (not updated): "
-                            + resolvedMrid);
-                    return searchedRmr(rmr);
-                } else {
-                    Message.verbose("\t" + getName() + ": revision in cache is not up to date: "
-                            + resolvedMrid);
-                    if (isChangingDependency) {
-                        // ivy file has been updated, we should see if it has a new publication date
-                        // to see if a new download is required (in case the dependency is a
-                        // changing one)
-                        cachedPublicationDate = rmr.getDescriptor().getResolvedPublicationDate();
-                    }
-                }
-            }
-        }
-
-        // now download module descriptor and parse it
         Artifact moduleArtifact = parser.getMetadataArtifact(resolvedMrid, mdRef.getResource());
-        ArtifactDownloadReport report = data.getCacheManager().download(
-            getOriginalMetadataArtifact(moduleArtifact), 
-            new ArtifactResourceResolver() {
-                public ResolvedResource resolve(Artifact artifact) {
-                    return mdRef;
-                }
-            }, downloader, 
-            new CacheDownloadOptions().setListener(downloadListener).setForce(true));
-        Message.verbose("\t" + report);            
-
-        if (report.getDownloadStatus() == DownloadStatus.FAILED) {
-            Message.warn("problem while downloading module descriptor: " + mdRef.getResource() 
-                + ": " + report.getDownloadDetails() 
-                + " (" + report.getDownloadTimeMillis() + "ms)");
-            return null;
-        }
-
-        File originalMDCacheFile = data.getCacheManager().getArchiveFileInCache(
-            report.getArtifact(), report.getArtifactOrigin(), false);
-        URL cachedMDURL = null;
-        try {
-            cachedMDURL = originalMDCacheFile.toURL();
-        } catch (MalformedURLException ex) {
-            Message.warn("malformed url exception for original in cache file: " 
-                + originalMDCacheFile + ": " + ex.getMessage());
-            return null;
-        }
-        try {
-            ModuleDescriptor md = parser.parseDescriptor(
-                data.getSettings(), cachedMDURL, mdRef.getResource(), doValidate(data));
-            Message.debug("\t" + getName() + ": parsed downloaded md file for " + mrid + " parsed="
-                    + md.getModuleRevisionId());
-
-            // check if we should delete old artifacts
-            boolean deleteOldArtifacts = false;
-            if (cachedPublicationDate != null
-                    && !cachedPublicationDate.equals(md.getResolvedPublicationDate())) {
-                // artifacts have changed, they should be downloaded again
-                Message.verbose(dd + " has changed: deleting old artifacts");
-                deleteOldArtifacts = true;
-            }
-            if (deleteOldArtifacts) {
-                String[] confs = rmr.getDescriptor().getConfigurationsNames();
-                for (int i = 0; i < confs.length; i++) {
-                    Artifact[] arts = rmr.getDescriptor().getArtifacts(confs[i]);
-                    for (int j = 0; j < arts.length; j++) {
-                        Artifact transformedArtifact = toSystem(arts[j]);
-                        ArtifactOrigin origin = data.getCacheManager().getSavedArtifactOrigin(
-                            transformedArtifact);
-                        File artFile = data.getCacheManager().getArchiveFileInCache(
-                            transformedArtifact, origin, false);
-                        if (artFile.exists()) {
-                            Message.debug("deleting " + artFile);
-                            artFile.delete();
-                        }
-                        data.getCacheManager().removeSavedArtifactOrigin(transformedArtifact);
-                    }
-                }
-            } else if (isChangingDependency) {
-                Message.verbose(dd
-                        + " is changing, but has not changed: will trust cached artifacts if any");
-            }
-            return new DefaultModuleRevision(this, this, md, true, true);
-        } catch (IOException ex) {
-            Message.warn("io problem while parsing ivy file: " + mdRef.getResource() + ": "
-                    + ex.getMessage());
-            return null;
-        }
-
-    }
-
-    private Artifact getOriginalMetadataArtifact(Artifact moduleArtifact) {
-        return DefaultArtifact.cloneWithAnotherName(moduleArtifact, 
-            moduleArtifact.getName() + ".original");
+        boolean isChangingRevision = getChangingMatcher().matches(mrid.getRevision());
+        boolean isChangingDependency = isChangingRevision || dd.isChanging();
+        return data.getCacheManager().cacheModuleDescriptor(
+            this, mdRef, moduleArtifact, downloader, 
+            (CacheMetadataOptions) new CacheMetadataOptions()
+                .setChanging(isChangingDependency)
+                .setCheckmodified(isCheckmodified())
+                .setValidate(doValidate(data))
+                .setNamespace(getNamespace())
+                .setListener(downloadListener));
     }
 
     protected ResourceMDParser getRMDParser(final DependencyDescriptor dd, final ResolveData data) {
@@ -649,39 +549,6 @@
     protected void clearIvyAttempts() {
         ivyattempts.clear();
         clearArtifactAttempts();
-    }
-
-    protected ResolvedModuleRevision searchedRmr(final ResolvedModuleRevision rmr) {
-        // delegate all to previously found except isSearched
-        return new ResolvedModuleRevision() {
-            public boolean isSearched() {
-                return true;
-            }
-
-            public boolean isDownloaded() {
-                return rmr.isDownloaded();
-            }
-
-            public ModuleDescriptor getDescriptor() {
-                return rmr.getDescriptor();
-            }
-
-            public Date getPublicationDate() {
-                return rmr.getPublicationDate();
-            }
-
-            public ModuleRevisionId getId() {
-                return rmr.getId();
-            }
-
-            public DependencyResolver getResolver() {
-                return rmr.getResolver();
-            }
-
-            public DependencyResolver getArtifactResolver() {
-                return rmr.getArtifactResolver();
-            }
-        };
     }
 
     protected void logIvyAttempt(String attempt) {

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/CacheResolver.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/CacheResolver.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/CacheResolver.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/CacheResolver.java Sat Dec  1 11:26:20 2007
@@ -59,8 +59,8 @@
         // if we do not have to check modified and if the revision is exact and not changing,
         // we first search for it in cache
         if (!getSettings().getVersionMatcher().isDynamic(mrid)) {
-            ResolvedModuleRevision rmr = data.getCacheManager().findModuleInCache(mrid,
-                doValidate(data));
+            ResolvedModuleRevision rmr = data.getCacheManager()
+                .findModuleInCache(mrid, doValidate(data), null);
             if (rmr != null) {
                 Message.verbose("\t" + getName() + ": revision in cache: " + mrid);
                 return rmr;
@@ -84,13 +84,13 @@
                     // this revision has already be resolved : return it
                     Message.verbose("\t" + getName() + ": revision already resolved: "
                             + resolvedMrid);
-                    return searchedRmr(node.getModuleRevision());
+                    return node.getModuleRevision();
                 }
                 ResolvedModuleRevision rmr = data.getCacheManager().findModuleInCache(resolvedMrid,
-                    doValidate(data));
+                    doValidate(data), null);
                 if (rmr != null) {
                     Message.verbose("\t" + getName() + ": revision in cache: " + resolvedMrid);
-                    return searchedRmr(rmr);
+                    return rmr;
                 } else {
                     Message.error("\t" + getName()
                             + ": inconsistent cache: clean it and resolve again");
@@ -114,6 +114,7 @@
                 Message.verbose("\t[NOT REQUIRED] " + artifacts[i]);
                 adr.setDownloadStatus(DownloadStatus.NO);
                 adr.setSize(archiveFile.length());
+                adr.setDownloadedFile(archiveFile);
             } else {
                 logArtifactAttempt(artifacts[i], archiveFile.getAbsolutePath());
                 adr.setDownloadStatus(DownloadStatus.FAILED);

Modified: incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java (original)
+++ incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java Sat Dec  1 11:26:20 2007
@@ -3318,7 +3318,7 @@
         ivy.configure(new File("test/repositories/external-artifacts/ivysettings.xml"));
 
         ResolveReport report = ivy.resolve(new File("test/repositories/external-artifacts/ivy.xml")
-                .toURL(), getResolveOptions(new String[] {"*"}).setValidate(false));
+                .toURL(), getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
         assertFalse(report.hasError());
 
         assertTrue(getArchiveFileInCache("apache", "A", "1.0", "a", "jar", "jar").exists());

Modified: incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/lock/ArtifactLockStrategyTest.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/lock/ArtifactLockStrategyTest.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/lock/ArtifactLockStrategyTest.java (original)
+++ incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/lock/ArtifactLockStrategyTest.java Sat Dec  1 11:26:20 2007
@@ -36,13 +36,11 @@
 import org.apache.ivy.plugins.repository.file.FileRepository;
 import org.apache.ivy.plugins.resolver.FileSystemResolver;
 import org.apache.ivy.util.CopyProgressEvent;
-import org.apache.ivy.util.DefaultMessageLogger;
 import org.apache.ivy.util.FileUtil;
 import org.apache.ivy.util.Message;
 
 public class ArtifactLockStrategyTest extends TestCase {
     protected void setUp() throws Exception {
-        Message.setDefaultLogger(new DefaultMessageLogger(Message.MSG_DEBUG));
         FileUtil.forceDelete(new File("build/test/cache"));
     }
     protected void tearDown() throws Exception {
@@ -57,15 +55,26 @@
         // issues, and not multi thread related issues.
         IvySettings settings1 = new IvySettings();
         IvySettings settings2 = new IvySettings();
-                
+        IvySettings settings3 = new IvySettings();
+
+        // run 3 concurrent resolves, one taking 100ms to download files, one 20ms and one 5ms
+        // the first one do 10 resolves, the second one 20 and the third 50
+        // note that the download time is useful only at the very beginning, then the cached file is used
         ResolveThread t1 = asyncResolve(
-            settings1, createSlowResolver(settings1, 100), "org6#mod6.4;3");
+            settings1, createSlowResolver(settings1, 100), "org6#mod6.4;3", 10);
         ResolveThread t2 = asyncResolve(
-            settings2, createSlowResolver(settings2, 50), "org6#mod6.4;3");
-        t1.join(1000);
-        t2.join(1000);
-        assertFound("org6#mod6.4;3", t1.getResult());
-        assertFound("org6#mod6.4;3", t2.getResult());
+            settings2, createSlowResolver(settings2, 20), "org6#mod6.4;3", 20);
+        ResolveThread t3 = asyncResolve(
+            settings3, createSlowResolver(settings3, 5), "org6#mod6.4;3", 50);
+        t1.join(10000);
+        t2.join(10000);
+        t3.join(10000);
+        assertEquals(10, t1.getCount());
+        assertFound("org6#mod6.4;3", t1.getFinalResult());
+        assertEquals(20, t2.getCount());
+        assertFound("org6#mod6.4;3", t2.getFinalResult());
+        assertEquals(50, t3.getCount());
+        assertFound("org6#mod6.4;3", t3.getFinalResult());
     }    
 
     
@@ -100,8 +109,8 @@
 
     
     private ResolveThread asyncResolve(
-            IvySettings settings, FileSystemResolver resolver, String module) {
-        ResolveThread thread = new ResolveThread(settings, resolver, module);
+            IvySettings settings, FileSystemResolver resolver, String module, int loop) {
+        ResolveThread thread = new ResolveThread(settings, resolver, module, loop);
         thread.start();
         return thread;
     }
@@ -128,28 +137,44 @@
         }
     }
     private class ResolveThread extends Thread {
-        private ResolvedModuleRevision result;
         private IvySettings settings;
         private FileSystemResolver resolver;
         private String module;
+        private int loop;
+
+        private ResolvedModuleRevision finalResult;
+        private int count;
         
-        public ResolveThread(IvySettings settings, FileSystemResolver resolver, String module) {
+        public ResolveThread(IvySettings settings, FileSystemResolver resolver, String module, int loop) {
             this.settings = settings;
             this.resolver = resolver;
             this.module = module;
+            this.loop = loop;
         }
         
-        public ResolvedModuleRevision getResult() {
-            return result;
+        public synchronized ResolvedModuleRevision getFinalResult() {
+            return finalResult;
+        }
+        public synchronized int getCount() {
+            return count;
         }
         public void run() {
-            try {
-                ResolvedModuleRevision rmr = resolveModule(settings, resolver, module);
-                synchronized (this) {
-                    result = rmr;
+            ResolvedModuleRevision rmr = null;
+            for (int i =0; i<loop; i++) {
+                try {
+                    rmr = resolveModule(settings, resolver, module);
+                    if (rmr == null) {
+                        throw new RuntimeException("module not found: " + module);
+                    }
+                    synchronized (this) {
+                        count++;
+                    }
+                } catch (ParseException e) {
+                    Message.info("parse exception "+e);
                 }
-            } catch (ParseException e) {
-                Message.info("parse exception "+e);
+            }
+            synchronized (this) {
+                finalResult = rmr;
             }
         }
     }

Modified: incubator/ivy/core/trunk/test/java/org/apache/ivy/util/CacheCleaner.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/util/CacheCleaner.java?rev=600184&r1=600183&r2=600184&view=diff
==============================================================================
--- incubator/ivy/core/trunk/test/java/org/apache/ivy/util/CacheCleaner.java (original)
+++ incubator/ivy/core/trunk/test/java/org/apache/ivy/util/CacheCleaner.java Sat Dec  1 11:26:20 2007
@@ -21,26 +21,12 @@
 
 public class CacheCleaner {
 
-    /** Delete the directory and all it contains.
+    /** 
+     * Delete the directory and all it contains.
      * Previously, we used the ant delete task, but it occasionaly failed (access denied)
-     * on my machine for unknown reason.  The next code seems to work better (but I don't
-     * see the difference with ant task... 
+     * on my machine for unknown reason.   
      **/
     public static void deleteDir(File toDelete) {
-        if (toDelete.isFile()) {
-            System.out.println("delete file : " + toDelete);
-            toDelete.delete();
-        } else if (toDelete.isDirectory()) {
-            File[] childs = toDelete.listFiles();
-            for (int i = 0; i < childs.length; i++) {
-                deleteDir(childs[i]);
-            }
-            System.out.println("delete dir :" + toDelete);
-            toDelete.delete();
-        }
-        if (toDelete.exists()) {
-            System.out.println("!!! I just deleted '" + toDelete+"', and it is still there !!!");
-        }
+        FileUtil.forceDelete(toDelete);
     }
-
 }