incubator-ivy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From xav...@apache.org
Subject svn commit: r600004 [1/2] - in /incubator/ivy/core/trunk: src/java/org/apache/ivy/ src/java/org/apache/ivy/ant/ 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...
Date Fri, 30 Nov 2007 23:00:00 GMT
Author: xavier
Date: Fri Nov 30 14:59:53 2007
New Revision: 600004

URL: http://svn.apache.org/viewvc?rev=600004&view=rev
Log:
- review responsibilities between resolver and cache manager, making cache management slightly more flexible (IVY-399)
- introduce lock strategy, used by CacheManager, not yet fully implemented nor tested (IVY-654)

Added:
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheDownloadOptions.java   (with props)
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DownloadListener.java   (with props)
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/AbstractLockStrategy.java   (with props)
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/ArtifactLockStrategy.java   (with props)
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/FileBasedLockStrategy.java   (with props)
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/LockStrategy.java   (with props)
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/NoLockStrategy.java   (with props)
    incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/lock/
    incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/lock/ArtifactLockStrategyTest.java   (with props)
Modified:
    incubator/ivy/core/trunk/src/java/org/apache/ivy/Ivy.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyPublish.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/Artifact.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultArtifact.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/module/descriptor/MDArtifact.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.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/resolve/DownloadOptions.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolvedModuleRevision.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/settings/IvySettings.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/namespace/NameSpaceHelper.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/ModuleDescriptorParser.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.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/RepositoryResolver.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/util/ResolvedModuleRevisionProxy.java
    incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java
    incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/URLResolverTest.java

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/Ivy.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/Ivy.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/Ivy.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/Ivy.java Fri Nov 30 14:59:53 2007
@@ -57,6 +57,8 @@
 import org.apache.ivy.plugins.matcher.PatternMatcher;
 import org.apache.ivy.plugins.repository.TransferEvent;
 import org.apache.ivy.plugins.repository.TransferListener;
+import org.apache.ivy.plugins.resolver.BasicResolver;
+import org.apache.ivy.plugins.resolver.DependencyResolver;
 import org.apache.ivy.plugins.trigger.Trigger;
 import org.apache.ivy.util.HostUtil;
 import org.apache.ivy.util.Message;
@@ -802,6 +804,13 @@
         for (Iterator iter = triggers.iterator(); iter.hasNext();) {
             Trigger trigger = (Trigger) iter.next();
             eventManager.addIvyListener(trigger, trigger.getEventFilter());
+        }
+        
+        for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
+            DependencyResolver resolver = (DependencyResolver) iter.next();
+            if (resolver instanceof BasicResolver) {
+                ((BasicResolver) resolver).setEventManager(eventManager);
+            }
         }
     }
 

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyPublish.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyPublish.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyPublish.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyPublish.java Fri Nov 30 14:59:53 2007
@@ -452,6 +452,10 @@
         public Map getStandardAttributes() {
             return new HashMap();
         }
+        
+        public boolean isMetadata() {
+            return false;
+        }
     }
 
     public static class ArtifactsPattern {

Added: 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=600004&view=auto
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheDownloadOptions.java (added)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/CacheDownloadOptions.java Fri Nov 30 14:59:53 2007
@@ -0,0 +1,45 @@
+/*
+ *  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 CacheDownloadOptions {
+    private boolean useOrigin = false;
+    private DownloadListener listener = null;
+    private boolean force = false;
+    public boolean isUseOrigin() {
+        return useOrigin;
+    }
+    public CacheDownloadOptions setUseOrigin(boolean useOrigin) {
+        this.useOrigin = useOrigin;
+        return this;
+    }
+    public DownloadListener getListener() {
+        return listener;
+    }
+    public CacheDownloadOptions setListener(DownloadListener listener) {
+        this.listener = listener;
+        return this;
+    }
+    public boolean isForce() {
+        return force;
+    }
+    public CacheDownloadOptions setForce(boolean force) {
+        this.force = force;
+        return this;
+    }
+}

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

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=600004&r1=600003&r2=600004&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 Fri Nov 30 14:59:53 2007
@@ -26,10 +26,17 @@
 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
 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.report.DownloadStatus;
 import org.apache.ivy.core.resolve.DefaultModuleRevision;
 import org.apache.ivy.core.resolve.ResolvedModuleRevision;
+import org.apache.ivy.plugins.lock.LockStrategy;
 import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser;
+import org.apache.ivy.plugins.repository.ArtifactResourceResolver;
+import org.apache.ivy.plugins.repository.ResourceDownloader;
+import org.apache.ivy.plugins.repository.ResourceHelper;
 import org.apache.ivy.plugins.resolver.DependencyResolver;
+import org.apache.ivy.plugins.resolver.util.ResolvedResource;
 import org.apache.ivy.util.Message;
 import org.apache.ivy.util.PropertiesFile;
 
@@ -43,9 +50,11 @@
     }
 
     private CacheSettings settings;
-
+    
     private File cache;
 
+    private LockStrategy lockStrategy;
+
     public CacheManager(CacheSettings settings, File cache) {
         this.settings = settings == null ? IvyContext.getContext().getSettings() : settings;
         if (cache == null) {
@@ -284,7 +293,7 @@
                         Message.debug("\tfound ivy file in cache for " + mrid + " (resolved by "
                                 + resolver.getName() + "): " + ivyFile);
                         return new DefaultModuleRevision(resolver, artResolver, depMD, false,
-                                false, ivyFile.toURL());
+                                false);
                     } else {
                         Message.debug("\tresolver not found: " + resolverName
                                 + " => cannot use cached ivy file for " + mrid);
@@ -313,4 +322,103 @@
         return settings.getResolutionCacheRoot(cache);
     }
 
+    public LockStrategy getLockStrategy() {
+        if (lockStrategy == null) {
+            lockStrategy = settings.getDefaultLockStrategy();
+        }
+        return lockStrategy;
+    }
+    
+    public void setLockStrategy(LockStrategy lockStrategy) {
+        this.lockStrategy = lockStrategy;
+    }
+    
+    public ArtifactDownloadReport download(
+            Artifact artifact, 
+            ArtifactResourceResolver resourceResolver, 
+            ResourceDownloader resourceDownloader, 
+            CacheDownloadOptions options) {
+        final ArtifactDownloadReport adr = new ArtifactDownloadReport(artifact);
+        
+        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");
+        }
+        try {
+            DownloadListener listener = options.getListener();
+            if (listener != null) {
+                listener.needArtifact(this, artifact);
+            }
+            ArtifactOrigin origin = getSavedArtifactOrigin(artifact);
+            // if we can use origin file, we just ask ivy for the file in cache, and it will
+            // return the original one if possible. If we are not in useOrigin mode, we use the
+            // getArchivePath method which always return a path in the actual cache
+            File archiveFile = getArchiveFileInCache(artifact, origin, useOrigin);
+
+            if (archiveFile.exists() && !options.isForce()) {
+                adr.setDownloadStatus(DownloadStatus.NO);
+                adr.setSize(archiveFile.length());
+                adr.setArtifactOrigin(origin);
+            } else {
+                long start = System.currentTimeMillis();
+                try {
+                    ResolvedResource artifactRef = resourceResolver.resolve(artifact);
+                    if (artifactRef != null) {
+                        origin = new ArtifactOrigin(artifactRef.getResource().isLocal(),
+                            artifactRef.getResource().getName());
+                        if (useOrigin && artifactRef.getResource().isLocal()) {
+                            saveArtifactOrigin(artifact, origin);
+                            archiveFile = getArchiveFileInCache(artifact,
+                                origin);
+                            adr.setDownloadStatus(DownloadStatus.NO);
+                            adr.setSize(archiveFile.length());
+                            adr.setArtifactOrigin(origin);
+                        } else {
+                            // refresh archive file now that we better now its origin
+                            archiveFile = getArchiveFileInCache(artifact,
+                                origin, useOrigin);
+                            if (ResourceHelper.equals(artifactRef.getResource(), archiveFile)) {
+                                throw new IllegalStateException("invalid settings for '"
+                                    + resourceResolver
+                                    + "': pointing repository to ivy cache is forbidden !");
+                            } 
+                            if (listener != null) {
+                                listener.startArtifactDownload(this, artifactRef, artifact, origin);
+                            }
+
+                            resourceDownloader.download(
+                                artifact, artifactRef.getResource(), archiveFile);
+                            adr.setSize(archiveFile.length());
+                            saveArtifactOrigin(artifact, origin);
+                            adr.setDownloadTimeMillis(System.currentTimeMillis() - start);
+                            adr.setDownloadStatus(DownloadStatus.SUCCESSFUL);
+                            adr.setArtifactOrigin(origin);
+                        }
+                    } else {
+                        // this exception is catched below and result in a download failed status
+                        throw new Exception("artifact missing");
+                    }
+                } catch (Exception ex) {
+                    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 {
+            lockStrategy.unlockArtifact(artifact, getArchiveFileInCache(artifact));
+        }
+    }
 }

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=600004&r1=600003&r2=600004&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 Fri Nov 30 14:59:53 2007
@@ -20,6 +20,7 @@
 import java.io.File;
 
 import org.apache.ivy.core.module.id.ModuleId;
+import org.apache.ivy.plugins.lock.LockStrategy;
 import org.apache.ivy.plugins.parser.ParserSettings;
 import org.apache.ivy.plugins.resolver.DependencyResolver;
 import org.apache.ivy.plugins.version.VersionMatcher;
@@ -46,4 +47,8 @@
     DependencyResolver getResolver(ModuleId moduleId);
 
     DependencyResolver getResolver(String artResolverName);
+    
+    LockStrategy getLockStrategy(String name);
+    
+    LockStrategy getDefaultLockStrategy();
 }

Added: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DownloadListener.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DownloadListener.java?rev=600004&view=auto
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DownloadListener.java (added)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/cache/DownloadListener.java Fri Nov 30 14:59:53 2007
@@ -0,0 +1,34 @@
+/*
+ *  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 org.apache.ivy.core.module.descriptor.Artifact;
+import org.apache.ivy.core.report.ArtifactDownloadReport;
+import org.apache.ivy.plugins.resolver.util.ResolvedResource;
+
+public interface DownloadListener {
+    public void needArtifact(RepositoryCacheManager cache, Artifact artifact);
+    public void startArtifactDownload(
+            RepositoryCacheManager cache, ResolvedResource rres, 
+            Artifact artifact, ArtifactOrigin origin);
+    public void endArtifactDownload(
+            RepositoryCacheManager cache, Artifact artifact, 
+            ArtifactDownloadReport adr, File archiveFile);
+}

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

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=600004&r1=600003&r2=600004&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 Fri Nov 30 14:59:53 2007
@@ -22,7 +22,10 @@
 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.ResolvedModuleRevision;
+import org.apache.ivy.plugins.repository.ArtifactResourceResolver;
+import org.apache.ivy.plugins.repository.ResourceDownloader;
 
 public interface RepositoryCacheManager {
     public abstract File getRepositoryCacheRoot();
@@ -86,5 +89,25 @@
 
     public abstract ResolvedModuleRevision findModuleInCache(
             ModuleRevisionId mrid, boolean validate);
+    
+    /**
+     * Downloads an artifact to this cache.
+     * 
+     * @param artifact
+     *            the artifact to download
+     * @param resourceResolver
+     *            a resource resolver to use if the artifact needs to be resolved to a Resource for
+     *            downloading
+     * @param resourceDownloader
+     *            a resource downloader to use if actual download of the resource is needed
+     * @param options
+     *            a set of options to adjust the download 
+     * @return a report indicating how the download was performed
+     */
+    public abstract ArtifactDownloadReport download(
+            Artifact artifact, 
+            ArtifactResourceResolver resourceResolver, 
+            ResourceDownloader resourceDownloader, 
+            CacheDownloadOptions options);
 
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/Artifact.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/Artifact.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/Artifact.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/Artifact.java Fri Nov 30 14:59:53 2007
@@ -88,4 +88,13 @@
      * @return the id of the artifact
      */
     ArtifactRevisionId getId();
+    
+    /**
+     * Returns true if this artifact represents a module metadata artifact, false if it's a
+     * published artifact
+     * 
+     * @return true if this artifact represents a module metadata artifact, false if it's a
+     *         published artifact
+     */
+    boolean isMetadata();
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultArtifact.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultArtifact.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultArtifact.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/DefaultArtifact.java Fri Nov 30 14:59:53 2007
@@ -30,30 +30,50 @@
 public class DefaultArtifact extends AbstractArtifact {
 
     public static Artifact newIvyArtifact(ModuleRevisionId mrid, Date pubDate) {
-        return new DefaultArtifact(mrid, pubDate, "ivy", "ivy", "xml");
+        return new DefaultArtifact(mrid, pubDate, "ivy", "ivy", "xml", true);
     }
 
     public static Artifact newPomArtifact(ModuleRevisionId mrid, Date pubDate) {
-        return new DefaultArtifact(mrid, pubDate, mrid.getName(), "pom", "pom");
+        return new DefaultArtifact(mrid, pubDate, mrid.getName(), "pom", "pom", true);
+    }
+
+    public static Artifact cloneWithAnotherExt(Artifact artifact, String newExt) {
+        return cloneWithAnotherTypeAndExt(artifact, artifact.getType(), newExt);
     }
 
     public static Artifact cloneWithAnotherType(Artifact artifact, String newType) {
-        return new DefaultArtifact(artifact.getModuleRevisionId(), artifact.getPublicationDate(),
-                artifact.getName(), newType, artifact.getExt(), artifact.getUrl(), artifact
-                        .getExtraAttributes());
+        return cloneWithAnotherTypeAndExt(artifact, newType, artifact.getExt());
     }
 
     public static Artifact cloneWithAnotherTypeAndExt(Artifact artifact, String newType,
             String newExt) {
-        return new DefaultArtifact(artifact.getModuleRevisionId(), artifact.getPublicationDate(),
-                artifact.getName(), newType, newExt, artifact.getUrl(), artifact
-                        .getExtraAttributes());
+        return new DefaultArtifact(
+            ArtifactRevisionId.newInstance(
+                artifact.getModuleRevisionId(), 
+                artifact.getName(), newType, newExt, 
+                artifact.getExtraAttributes()), 
+            artifact.getPublicationDate(), 
+            artifact.getUrl(), artifact.isMetadata());
+    }
+
+    public static Artifact cloneWithAnotherName(Artifact artifact, String name) {
+        return new DefaultArtifact(
+            ArtifactRevisionId.newInstance(
+                artifact.getModuleRevisionId(), 
+                name, artifact.getType(), artifact.getExt(), 
+                artifact.getExtraAttributes()), 
+            artifact.getPublicationDate(), 
+            artifact.getUrl(), artifact.isMetadata());
     }
 
     public static Artifact cloneWithAnotherMrid(Artifact artifact, ModuleRevisionId mrid) {
-        return new DefaultArtifact(mrid, artifact.getPublicationDate(), artifact.getName(),
-                artifact.getType(), artifact.getExt(), artifact.getUrl(), artifact
-                        .getExtraAttributes());
+        return new DefaultArtifact(
+            ArtifactRevisionId.newInstance(
+                mrid, 
+                artifact.getName(), artifact.getType(), artifact.getExt(), 
+                artifact.getExtraAttributes()), 
+            artifact.getPublicationDate(), 
+            artifact.getUrl(), artifact.isMetadata());
     }
 
     private Date publicationDate;
@@ -61,10 +81,18 @@
     private ArtifactRevisionId arid;
 
     private URL url;
+    
+    private boolean isMetadata = false;
 
-    public DefaultArtifact(ModuleRevisionId mrid, Date publicationDate, String name, String type,
-            String ext) {
+    public DefaultArtifact(ModuleRevisionId mrid, Date publicationDate, 
+            String name, String type, String ext) {
+        this(mrid, publicationDate, name, type, ext, null, null);
+    }
+
+    public DefaultArtifact(ModuleRevisionId mrid, Date publicationDate, 
+            String name, String type, String ext, boolean isMetadata) {
         this(mrid, publicationDate, name, type, ext, null, null);
+        this.isMetadata = isMetadata;
     }
 
     public DefaultArtifact(ModuleRevisionId mrid, Date publicationDate, String name, String type,
@@ -74,24 +102,21 @@
 
     public DefaultArtifact(ModuleRevisionId mrid, Date publicationDate, String name, String type,
             String ext, URL url, Map extraAttributes) {
-        if (mrid == null) {
-            throw new NullPointerException("null mrid not allowed");
+        this(ArtifactRevisionId.newInstance(mrid, name, type, ext, extraAttributes), 
+            publicationDate, url, false);
+    }
+    public DefaultArtifact(
+            ArtifactRevisionId arid, Date publicationDate, URL url, boolean isMetadata) {
+        if (arid == null) {
+            throw new NullPointerException("null arid not allowed");
         }
         if (publicationDate == null) {
             publicationDate = new Date();
         }
-        if (name == null) {
-            throw new NullPointerException("null name not allowed");
-        }
-        if (type == null) {
-            throw new NullPointerException("null type not allowed");
-        }
-        if (ext == null) {
-            throw new NullPointerException("null ext not allowed");
-        }
         this.publicationDate = publicationDate;
-        this.arid = ArtifactRevisionId.newInstance(mrid, name, type, ext, extraAttributes);
+        this.arid = arid;
         this.url = url;
+        this.isMetadata = isMetadata;
     }
 
     public ModuleRevisionId getModuleRevisionId() {
@@ -126,4 +151,7 @@
         return url;
     }
 
+    public boolean isMetadata() {
+        return isMetadata;
+    }
 }

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=600004&r1=600003&r2=600004&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 Fri Nov 30 14:59:53 2007
@@ -208,9 +208,11 @@
     private ModuleDescriptorParser parser;
 
     private Resource resource;
-
+    
     private List excludeRules = new ArrayList(); // List(ExcludeRule)
 
+    private Artifact moduleArtifact;
+
     public DefaultModuleDescriptor(ModuleRevisionId id, String status, Date pubDate) {
         this(id, status, pubDate, false);
     }
@@ -238,6 +240,17 @@
     public DefaultModuleDescriptor(ModuleDescriptorParser parser, Resource res) {
         this.parser = parser;
         resource = res;
+    }
+    
+    public Artifact getMetadataArtifact() {
+        if (moduleArtifact == null) {
+            moduleArtifact = DefaultArtifact.newIvyArtifact(resolvedRevId, publicationDate);
+        }
+        return moduleArtifact;
+    }
+    
+    public void setModuleArtifact(Artifact moduleArtifact) {
+        this.moduleArtifact = moduleArtifact;
     }
 
     public boolean isDefault() {

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/MDArtifact.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/MDArtifact.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/MDArtifact.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/MDArtifact.java Fri Nov 30 14:59:53 2007
@@ -32,7 +32,7 @@
 public class MDArtifact extends AbstractArtifact {
 
     public static Artifact newIvyArtifact(ModuleDescriptor md) {
-        return new MDArtifact(md, "ivy", "ivy", "xml");
+        return new MDArtifact(md, "ivy", "ivy", "xml", true);
     }
 
     private ModuleDescriptor md;
@@ -48,11 +48,19 @@
     private Map extraAttributes = null;
 
     private URL url;
+    
+    private boolean isMetadata = false;
 
     public MDArtifact(ModuleDescriptor md, String name, String type, String ext) {
         this(md, name, type, ext, null, null);
     }
 
+    public MDArtifact(ModuleDescriptor md, 
+            String name, String type, String ext, boolean isMetadata) {
+        this(md, name, type, ext, null, null);
+        this.isMetadata = isMetadata;
+    }
+
     public MDArtifact(ModuleDescriptor md, String name, String type, String ext, URL url,
             Map extraAttributes) {
         if (md == null) {
@@ -113,4 +121,7 @@
         return url;
     }
 
+    public boolean isMetadata() {
+        return isMetadata;
+    }
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/module/descriptor/ModuleDescriptor.java Fri Nov 30 14:59:53 2007
@@ -103,6 +103,13 @@
 
     Artifact[] getArtifacts(String conf);
 
+    /**
+     * Returns all artifacts of this module, excluding the artifact corresponding to the module
+     * descriptor.
+     * 
+     * @return all published artifacts of this module
+     * @see #getMetadataArtifact()
+     */
     Artifact[] getAllArtifacts();
 
     /**
@@ -169,6 +176,19 @@
      * @return
      */
     Resource getResource();
+
+    /**
+     * Returns the Artifact representing this module descriptor itself.
+     * <p>
+     * Even though the module descriptor is never described as a published artifact of a module in
+     * the module descriptor itself, it is often useful to consider it as any other artifact of the
+     * module. This method allows to access to the Artifact object representing this module
+     * descriptor for this purpose.
+     * </p>
+     * 
+     * @return the Artifact representing this module descriptor itself.
+     */
+    Artifact getMetadataArtifact();
 
     /**
      * Returns true if this descriptor contains any exclusion rule

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=600004&r1=600003&r2=600004&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 Fri Nov 30 14:59:53 2007
@@ -32,6 +32,10 @@
 
     private long size;
 
+    private String downloadDetails = "";
+
+    private long downloadTimeMillis;
+
     public ArtifactDownloadReport(Artifact artifact) {
         this.artifact = artifact;
     }
@@ -74,5 +78,34 @@
 
     public ArtifactOrigin getArtifactOrigin() {
         return origin;
+    }
+
+    public void setDownloadDetails(String message) {
+        downloadDetails = message;
+    }
+    
+    public String getDownloadDetails() {
+        return downloadDetails;
+    }
+
+    public void setDownloadTimeMillis(long l) {
+        downloadTimeMillis = l;
+    }
+    
+    public long getDownloadTimeMillis() {
+        return downloadTimeMillis;
+    }
+    
+    public String toString() {
+        if (downloadStatus == DownloadStatus.SUCCESSFUL) {
+            return "[SUCCESSFUL ] " + artifact + " (" + downloadTimeMillis + "ms)";
+        } else if (downloadStatus == DownloadStatus.FAILED) {
+            return "[FAILED     ] " + artifact + " : " + downloadDetails
+                + " (" + downloadTimeMillis + "ms)";
+        } else if (downloadStatus == DownloadStatus.NO) {
+            return "[NOT REQUIRED] " + artifact;
+        } else {
+            return super.toString();
+        }
     }
 }

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=600004&r1=600003&r2=600004&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 Fri Nov 30 14:59:53 2007
@@ -38,16 +38,13 @@
 
     private boolean isSearched;
 
-    private URL localMDUrl;
-
     public DefaultModuleRevision(DependencyResolver resolver, DependencyResolver artifactResolver,
-            ModuleDescriptor descriptor, boolean searched, boolean downloaded, URL localMDUrl) {
+            ModuleDescriptor descriptor, boolean searched, boolean downloaded) {
         this.resolver = resolver;
         this.artifactResolver = artifactResolver;
         this.descriptor = descriptor;
         isSearched = searched;
         isDownloaded = downloaded;
-        this.localMDUrl = localMDUrl;
     }
 
     public DependencyResolver getResolver() {
@@ -91,10 +88,6 @@
 
     public boolean isSearched() {
         return isSearched;
-    }
-
-    public URL getLocalMDUrl() {
-        return localMDUrl;
     }
 
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/DownloadOptions.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/DownloadOptions.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/DownloadOptions.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/DownloadOptions.java Fri Nov 30 14:59:53 2007
@@ -27,8 +27,6 @@
 public class DownloadOptions {
     private RepositoryCacheManager cacheManager;
 
-    private EventManager eventManager = null; // can be null
-
     private boolean useOrigin = false;
 
     public DownloadOptions(IvySettings settings, File cache) {
@@ -36,13 +34,11 @@
     }
 
     public DownloadOptions(RepositoryCacheManager cacheManager) {
-        this(cacheManager, null, false);
+        this(cacheManager, false);
     }
 
-    public DownloadOptions(RepositoryCacheManager cacheManager, EventManager eventManager,
-            boolean useOrigin) {
+    public DownloadOptions(RepositoryCacheManager cacheManager, boolean useOrigin) {
         this.cacheManager = cacheManager;
-        this.eventManager = eventManager;
         this.useOrigin = useOrigin;
     }
 
@@ -52,10 +48,6 @@
 
     public RepositoryCacheManager getCacheManager() {
         return cacheManager;
-    }
-
-    public EventManager getEventManager() {
-        return eventManager;
     }
 
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java Fri Nov 30 14:59:53 2007
@@ -328,7 +328,7 @@
                         .getArtifactResolver();
                 Artifact[] selectedArtifacts = dependencies[i].getSelectedArtifacts(artifactFilter);
                 DownloadReport dReport = resolver.download(selectedArtifacts, new DownloadOptions(
-                        cacheManager, eventManager, useOrigin));
+                        cacheManager, useOrigin));
                 ArtifactDownloadReport[] adrs = dReport.getArtifactsReports();
                 for (int j = 0; j < adrs.length; j++) {
                     if (adrs[j].getDownloadStatus() == DownloadStatus.FAILED) {
@@ -373,7 +373,7 @@
         DependencyResolver resolver = settings.getResolver(artifact.getModuleRevisionId()
                 .getModuleId());
         DownloadReport r = resolver.download(new Artifact[] {artifact}, new DownloadOptions(
-                cacheManager, eventManager, useOrigin));
+                cacheManager, useOrigin));
         return r.getArtifactReport(artifact);
     }
 

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolvedModuleRevision.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolvedModuleRevision.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolvedModuleRevision.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolvedModuleRevision.java Fri Nov 30 14:59:53 2007
@@ -51,6 +51,4 @@
     boolean isDownloaded();
 
     boolean isSearched();
-
-    public URL getLocalMDUrl();
 }

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=600004&r1=600003&r2=600004&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 Fri Nov 30 14:59:53 2007
@@ -65,6 +65,8 @@
 import org.apache.ivy.plugins.latest.LatestRevisionStrategy;
 import org.apache.ivy.plugins.latest.LatestStrategy;
 import org.apache.ivy.plugins.latest.LatestTimeStrategy;
+import org.apache.ivy.plugins.lock.LockStrategy;
+import org.apache.ivy.plugins.lock.NoLockStrategy;
 import org.apache.ivy.plugins.matcher.ExactOrRegexpPatternMatcher;
 import org.apache.ivy.plugins.matcher.ExactPatternMatcher;
 import org.apache.ivy.plugins.matcher.ModuleIdMatcher;
@@ -135,6 +137,9 @@
 
     // Map (String latestStrategyName -> LatestStrategy)
     private Map latestStrategies = new HashMap(); 
+    
+    // Map (String name -> LockStrategy)
+    private Map lockStrategies = new HashMap(); 
 
     // Map (String namespaceName -> Namespace)
     private Map namespaces = new HashMap(); 
@@ -171,6 +176,8 @@
 
     private LatestStrategy defaultLatestStrategy = null;
 
+    private LockStrategy defaultLockStrategy = null;
+
     private ConflictManager defaultConflictManager = null;
 
     private CircularDependencyStrategy circularDependencyStrategy = null;
@@ -853,6 +860,22 @@
         latestStrategies.put(name, latest);
     }
 
+    public void addConfigured(LockStrategy lockStrategy) {
+        addLockStrategy(lockStrategy.getName(), lockStrategy);
+    }
+
+    public LockStrategy getLockStrategy(String name) {
+        if ("default".equals(name)) {
+            return getDefaultLockStrategy();
+        }
+        return (LockStrategy) lockStrategies.get(name);
+    }
+
+    public void addLockStrategy(String name, LockStrategy lockStrategy) {
+        init(lockStrategy);
+        lockStrategies.put(name, lockStrategy);
+    }
+
     public void addConfigured(Namespace ns) {
         addNamespace(ns);
     }
@@ -1067,6 +1090,17 @@
 
     public void setDefaultLatestStrategy(LatestStrategy defaultLatestStrategy) {
         this.defaultLatestStrategy = defaultLatestStrategy;
+    }
+
+    public LockStrategy getDefaultLockStrategy() {
+        if (defaultLockStrategy == null) {
+            defaultLockStrategy = new NoLockStrategy();
+        }
+        return defaultLockStrategy;
+    }
+
+    public void setDefaultLockStrategy(LockStrategy defaultLockStrategy) {
+        this.defaultLockStrategy = defaultLockStrategy;
     }
 
     public void addTrigger(Trigger trigger) {

Added: 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=600004&view=auto
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/AbstractLockStrategy.java (added)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/AbstractLockStrategy.java Fri Nov 30 14:59:53 2007
@@ -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.plugins.lock;
+
+public abstract class AbstractLockStrategy implements LockStrategy {
+    private String name;
+
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+    public String toString() {
+        return name;
+    }
+}

Propchange: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/AbstractLockStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 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=600004&view=auto
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/ArtifactLockStrategy.java (added)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/ArtifactLockStrategy.java Fri Nov 30 14:59:53 2007
@@ -0,0 +1,37 @@
+/*
+ *  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.plugins.lock;
+
+import java.io.File;
+
+import org.apache.ivy.core.module.descriptor.Artifact;
+
+public class ArtifactLockStrategy extends FileBasedLockStrategy {
+    public ArtifactLockStrategy() {
+        setName("artifact-lock");
+    }
+
+    public boolean lockArtifact(Artifact artifact, File artifactFileToDownload) 
+            throws InterruptedException {
+        return acquireLock(new File(artifactFileToDownload.getAbsolutePath() + ".lck"));
+    }
+
+    public void unlockArtifact(Artifact artifact, File artifactFileToDownload) {
+        releaseLock(new File(artifactFileToDownload.getAbsolutePath() + ".lck"));
+    }
+}

Propchange: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/ArtifactLockStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 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=600004&view=auto
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/FileBasedLockStrategy.java (added)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/FileBasedLockStrategy.java Fri Nov 30 14:59:53 2007
@@ -0,0 +1,115 @@
+/*
+ *  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.plugins.lock;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ivy.util.Message;
+
+public abstract class FileBasedLockStrategy extends AbstractLockStrategy {
+    private static final int SLEEP_TIME = 100;
+
+    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";
+    
+    private String fileLockMethod = CREATE_FILE;
+    private long timeout = DEFAULT_TIMEOUT;
+    
+    private Map locks = new HashMap();
+    
+    protected boolean acquireLock(File file) throws InterruptedException {
+        Message.debug("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);
+                        }
+                    }
+                } 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);
+            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) {
+                                locks.put(file, l);
+                                Message.debug("lock acquired on " + file);
+                                return true;
+                            }
+                        } 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);
+            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());
+            }
+        } else {
+            throw new IllegalStateException("unknown lock method " + fileLockMethod);
+        }
+    }
+
+}

Propchange: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/FileBasedLockStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 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=600004&view=auto
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/LockStrategy.java (added)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/LockStrategy.java Fri Nov 30 14:59:53 2007
@@ -0,0 +1,69 @@
+/*
+ *  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.plugins.lock;
+
+import java.io.File;
+
+import org.apache.ivy.core.module.descriptor.Artifact;
+
+/**
+ * A lock strategy determines when and how lock should be performed when downloading data to a
+ * cache.
+ * <p>
+ * Note that some implementations may actually choose to NOT perform locking, when no lock is
+ * necessary (cache not shared). Some other implementations may choose to lock the cache for the
+ * download of a whole module (not possible yet), or at the artifact level.
+ * <p>
+ * </p>
+ * The lock methods should return true when the lock is either actually acquired or not performed by
+ * the strategy.
+ * </p>
+ */
+public interface LockStrategy {
+
+    /**
+     * Returns the name of the strategy
+     * @return the name of the strategy
+     */
+    String getName();
+
+    /**
+     * Performs a lock before downloading the given {@link Artifact} to the given file.
+     * 
+     * @param artifact
+     *            the artifact about to be downloaded
+     * @param artifactFileToDownload
+     *            the file where the artifact will be downloaded
+     * @return true if the artifact is locked, false otherwise
+     * @throws InterruptedException
+     *             if the thread is interrupted while waiting to acquire the lock
+     */
+    boolean lockArtifact(Artifact artifact, File artifactFileToDownload) 
+        throws InterruptedException;
+
+    /**
+     * Release the lock acquired for an artifact download.
+     * 
+     * @param artifact
+     *            the artifact for which the lock was acquired
+     * @param artifactFileToDownload
+     *            the file where the artifact is supposed to have been downloaded
+     */
+    void unlockArtifact(Artifact artifact, File artifactFileToDownload);
+
+}

Propchange: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/LockStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/NoLockStrategy.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/NoLockStrategy.java?rev=600004&view=auto
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/NoLockStrategy.java (added)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/NoLockStrategy.java Fri Nov 30 14:59:53 2007
@@ -0,0 +1,35 @@
+/*
+ *  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.plugins.lock;
+
+import java.io.File;
+
+import org.apache.ivy.core.module.descriptor.Artifact;
+
+public class NoLockStrategy extends AbstractLockStrategy {
+    public NoLockStrategy() {
+        setName("no-lock");
+    }
+
+    public final boolean lockArtifact(Artifact artifact, File artifactFileToDownload) {
+        return true;
+    }
+
+    public final void unlockArtifact(Artifact artifact, File artifactFileToDownload) {
+    }
+}

Propchange: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/lock/NoLockStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/namespace/NameSpaceHelper.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/namespace/NameSpaceHelper.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/namespace/NameSpaceHelper.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/namespace/NameSpaceHelper.java Fri Nov 30 14:59:53 2007
@@ -55,7 +55,7 @@
             return rmr;
         }
         return new DefaultModuleRevision(rmr.getResolver(), rmr.getArtifactResolver(), md, rmr
-                .isSearched(), rmr.isDownloaded(), rmr.getLocalMDUrl());
+                .isSearched(), rmr.isDownloaded());
     }
 
     public static Artifact transform(Artifact artifact, NamespaceTransformer t) {

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/AbstractModuleDescriptorParser.java Fri Nov 30 14:59:53 2007
@@ -26,7 +26,9 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.ivy.core.module.descriptor.Artifact;
 import org.apache.ivy.core.module.descriptor.Configuration;
+import org.apache.ivy.core.module.descriptor.DefaultArtifact;
 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
 import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
@@ -44,6 +46,14 @@
             boolean validate) throws ParseException, IOException {
         return parseDescriptor(ivySettings, descriptorURL, 
             new URLResource(descriptorURL), validate);
+    }
+    
+    public String getType() {
+        return "ivy";
+    }
+    
+    public Artifact getMetadataArtifact(ModuleRevisionId mrid, Resource res) {
+        return DefaultArtifact.newIvyArtifact(mrid, new Date(res.getLastModified()));
     }
 
     protected abstract static class AbstractParser extends DefaultHandler {

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/ModuleDescriptorParser.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/ModuleDescriptorParser.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/ModuleDescriptorParser.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/ModuleDescriptorParser.java Fri Nov 30 14:59:53 2007
@@ -23,7 +23,9 @@
 import java.net.URL;
 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.plugins.repository.Resource;
 
 public interface ModuleDescriptorParser {
@@ -44,4 +46,22 @@
             throws ParseException, IOException;
 
     public boolean accept(Resource res);
+
+    /**
+     * Return the 'type' of module artifacts this parser is parsing
+     * @return the 'type' of module artifacts this parser is parsing
+     */
+    public String getType();
+
+    /**
+     * Returns the module metadata artifact corresponding to the given module revision id that this
+     * parser parses
+     * 
+     * @param res
+     *            the resource for which the module artifact should be returned
+     * @param mrid
+     *            the module revision id for which the module artifact should be returned
+     * @return the module artifact corresponding to the given mrid and resource
+     */
+    public Artifact getMetadataArtifact(ModuleRevisionId mrid, Resource res);
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParser.java Fri Nov 30 14:59:53 2007
@@ -35,6 +35,7 @@
 
 import org.apache.ivy.core.IvyContext;
 import org.apache.ivy.core.IvyPatternHelper;
+import org.apache.ivy.core.module.descriptor.Artifact;
 import org.apache.ivy.core.module.descriptor.Configuration;
 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
 import org.apache.ivy.core.module.descriptor.DefaultDependencyArtifactDescriptor;
@@ -225,8 +226,10 @@
                 type = JAR_EXTENSION;
                 ext = JAR_EXTENSION;
             }
-            md.addArtifact("master", new DefaultArtifact(mrid, getDefaultPubDate(), module,
-                    type, ext));
+            md.setModuleArtifact(
+                DefaultArtifact.newPomArtifact(mrid, getDefaultPubDate()));
+            md.addArtifact("master", 
+                new DefaultArtifact(mrid, getDefaultPubDate(), module, type, ext));
             organisation = null;
             module = null;
             revision = null;
@@ -428,6 +431,7 @@
             if (md.getModuleRevisionId() == null) {
                 return null;
             }
+            
             return md;
         }
         
@@ -550,4 +554,13 @@
     public String toString() {
         return "pom parser";
     }
+
+    public Artifact getMetadataArtifact(ModuleRevisionId mrid, Resource res) {
+        return DefaultArtifact.newPomArtifact(mrid, new Date(res.getLastModified()));
+    }
+    
+    public String getType() {
+        return "pom";
+    }
+
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java Fri Nov 30 14:59:53 2007
@@ -34,6 +34,7 @@
 import org.apache.ivy.core.IvyContext;
 import org.apache.ivy.core.module.descriptor.Configuration;
 import org.apache.ivy.core.module.descriptor.ConfigurationAware;
+import org.apache.ivy.core.module.descriptor.DefaultArtifact;
 import org.apache.ivy.core.module.descriptor.DefaultDependencyArtifactDescriptor;
 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
 import org.apache.ivy.core.module.descriptor.DefaultExcludeRule;
@@ -197,6 +198,9 @@
                 XMLHelper.parse(xmlURL, schemaURL, this);
                 checkConfigurations();
                 replaceConfigurationWildcards();
+                md.setModuleArtifact(
+                    DefaultArtifact.newIvyArtifact(
+                        md.getResolvedModuleRevisionId(), md.getPublicationDate()));
                 if (!artifactsDeclared) {
                     String[] confs = md.getConfigurationsNames();
                     for (int i = 0; i < confs.length; i++) {

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.java
URL: http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.java?rev=600004&r1=600003&r2=600004&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.java (original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.java Fri Nov 30 14:59:53 2007
@@ -35,8 +35,6 @@
 
     private boolean local = true;
 
-    private File transactionDirectory;
-
     public FileRepository() {
         baseDir = null;
     }
@@ -69,8 +67,8 @@
 
     private void copy(File src, File destination, boolean overwrite) throws IOException {
         try {
-            progress.setTotalLength(new Long(src.length()));
-            if (!FileUtil.copy(src, destination, progress, overwrite)) {
+            getProgressListener().setTotalLength(new Long(src.length()));
+            if (!FileUtil.copy(src, destination, getProgressListener(), overwrite)) {
                 if (!overwrite) {
                     throw new IOException("file copy not done from " + src + " to " + destination
                             + ": destination probably already exists and overwrite is false");
@@ -85,8 +83,12 @@
             fireTransferError(ex);
             throw ex;
         } finally {
-            progress.setTotalLength(null);
+            getProgressListener().setTotalLength(null);
         }
+    }
+
+    protected RepositoryCopyProgressListener getProgressListener() {
+        return progress;
     }
 
     public List list(String parent) throws IOException {

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=600004&r1=600003&r2=600004&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 Fri Nov 30 14:59:53 2007
@@ -169,7 +169,7 @@
      */
     public boolean exists(Artifact artifact) {
         DownloadReport dr = download(new Artifact[] {artifact}, new DownloadOptions(
-                CacheManager.getInstance(getSettings()), null, true));
+                CacheManager.getInstance(getSettings()), true));
         ArtifactDownloadReport adr = dr.getArtifactReport(artifact);
         return adr.getDownloadStatus() != DownloadStatus.FAILED;
     }



Mime
View raw message