Author: xavier
Date: Fri Feb 23 00:52:49 2007
New Revision: 510875

URL: http://svn.apache.org/viewvc?view=rev&rev=510875
Log:
FIX: LatestRevisionStrategy do not consider all dynamic revisions properly 
(IVY-383) (thanks to John Williams for the unit test)

Added:
    
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/ivy-383.xml
Modified:
    incubator/ivy/core/trunk/CHANGES.txt
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/conflict/LatestConflictManager.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/latest/LatestRevisionStrategy.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/AbstractVersionMatcher.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/ChainVersionMatcher.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/LatestVersionMatcher.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/PatternVersionMatcher.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/SubVersionMatcher.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionMatcher.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionRangeMatcher.java
    
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/LatestConflictManagerTest.java

Modified: incubator/ivy/core/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/CHANGES.txt?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- incubator/ivy/core/trunk/CHANGES.txt (original)
+++ incubator/ivy/core/trunk/CHANGES.txt Fri Feb 23 00:52:49 2007
@@ -13,6 +13,7 @@
 - IMPROVE: Refactoring / documentation / test of matcher package (IVY-375) 
(thanks to Stephane Baillez)
 - IMPROVE: Add a unit test to verify that latest.integration accepts released 
modules (IVY-394) (thanks to Gilles Scokart)
 
+- FIX: LatestRevisionStrategy do not consider all dynamic revisions properly 
(IVY-383) (thanks to John Williams for the unit test)
 - FIX: IOException during publish causes NullPointerException (IVY-371)
 - FIX: Comments in ivy.xml duplicated (IVY-336) (thanks to Gilles Scokart)
 - FIX: Ivy failure when the ivy.xml file contains non US-ASCII characters 
(IVY-346) (thanks to Gilles Scokart)

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/conflict/LatestConflictManager.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/conflict/LatestConflictManager.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/conflict/LatestConflictManager.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/conflict/LatestConflictManager.java
 Fri Feb 23 00:52:49 2007
@@ -43,7 +43,7 @@
         }
 
         public String getRevision() {
-            return _node.getId().getRevision();
+            return _node.getResolvedId().getRevision();
         }
         
         public IvyNode getNode() {

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/latest/LatestRevisionStrategy.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/latest/LatestRevisionStrategy.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/latest/LatestRevisionStrategy.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/latest/LatestRevisionStrategy.java
 Fri Feb 23 00:52:49 2007
@@ -21,6 +21,10 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.ivy.core.IvyContext;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.plugins.version.VersionMatcher;
+
 
 
 
@@ -58,33 +62,15 @@
         DEFAULT_SPECIAL_MEANINGS.put("final", new Integer(2));
     }
 
-    
     /**
-     * Compares two revisions.
+     * Compares two ModuleRevisionId by their revision.
      * Revisions are compared using an algorithm inspired by PHP
-     * version_compare one, unless
-     * a 'latest' revision is found. If the latest revision found
-     * is an absolute latest (latest. like), then it is assumed to be the 
greater.
-     * If a partial latest is found, then it is assumed to be greater
-     * than any matching fixed revision. 
+     * version_compare one. 
      */ 
-    public Comparator COMPARATOR = new Comparator() {
-
-        public int compare(Object o1, Object o2) {
-            String rev1 = ((ArtifactInfo)o1).getRevision();
-            String rev2 = ((ArtifactInfo)o2).getRevision();
-            if (rev1.startsWith("latest")) {
-                return 1;
-            }
-            if (rev1.endsWith("+") && rev2.startsWith(rev1.substring(0, 
rev1.length() - 1))) {
-                return 1;
-            }
-            if (rev2.startsWith("latest")) {
-                return -1;
-            }
-            if (rev2.endsWith("+") && rev1.startsWith(rev2.substring(0, 
rev2.length() - 1))) {
-                return -1;
-            }
+    public final Comparator STATIC_COMPARATOR = new Comparator() {
+       public int compare(Object o1, Object o2) {
+            String rev1 = ((ModuleRevisionId)o1).getRevision();
+            String rev2 = ((ModuleRevisionId)o2).getRevision();
             
             rev1 = rev1.replaceAll("([a-zA-Z])(\\d)", "$1.$2");
             rev1 = rev1.replaceAll("(\\d)([a-zA-Z])", "$1.$2");
@@ -130,10 +116,47 @@
                 return isNumber(parts2[i])?-1:1;
             }
             return 0;
-        }
+       }
 
         private boolean isNumber(String str) {
             return str.matches("\\d+");
+        }
+    };
+
+    
+    /**
+     * Compares two ArtifactInfo by their revision.
+     * Revisions are compared using an algorithm inspired by PHP
+     * version_compare one, unless a dynamic revision is given,
+     * in which case the version matcher is used to perform the comparison. 
+     */ 
+    public Comparator COMPARATOR = new Comparator() {
+
+        public int compare(Object o1, Object o2) {
+            String rev1 = ((ArtifactInfo)o1).getRevision();
+            String rev2 = ((ArtifactInfo)o2).getRevision();
+
+            /* The revisions can still be not resolved, so we use the current 
+             * version matcher to know if one revision is dynamic, and in this 
+             * case if it should be considered greater or lower than the other 
one.
+             * 
+             * Note that if the version matcher compare method returns 0, it's 
because
+             * it's not possible to know which revision is greater. In this 
case we 
+             * consider the dynamic one to be greater, because most of the time
+             * it will then be actually resolved and a real comparison will 
occur.
+             */  
+            VersionMatcher vmatcher = 
IvyContext.getContext().getSettings().getVersionMatcher();
+            ModuleRevisionId mrid1 = ModuleRevisionId.newInstance("", "", 
rev1);
+            ModuleRevisionId mrid2 = ModuleRevisionId.newInstance("", "", 
rev2);
+            if (vmatcher.isDynamic(mrid1)) {
+               int c = vmatcher.compare(mrid1, mrid2, STATIC_COMPARATOR);
+                               return c >= 0? 1 : -1;
+            } else if (vmatcher.isDynamic(mrid2)) {
+               int c = vmatcher.compare(mrid2, mrid1, STATIC_COMPARATOR);
+                               return c >= 0? -1 : 1;
+            }
+            
+            return STATIC_COMPARATOR.compare(mrid1, mrid2);
         }
     
     };

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/AbstractVersionMatcher.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/AbstractVersionMatcher.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/AbstractVersionMatcher.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/AbstractVersionMatcher.java
 Fri Feb 23 00:52:49 2007
@@ -17,6 +17,8 @@
  */
 package org.apache.ivy.plugins.version;
 
+import java.util.Comparator;
+
 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
 import org.apache.ivy.core.module.id.ModuleRevisionId;
 import org.apache.ivy.core.settings.IvySettings;
@@ -48,6 +50,14 @@
 
     public boolean accept(ModuleRevisionId askedMrid, ModuleDescriptor 
foundMD) {
         return accept(askedMrid, foundMD.getResolvedModuleRevisionId());
+    }
+    
+    /**
+     * This method should be overriden in most cases, because it uses the 
default contract
+     * to return 1 when it's not possible to know which revision is greater.
+     */
+    public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid, 
Comparator staticComparator) {
+       return 0;
     }
     
     public String toString() {

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/ChainVersionMatcher.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/ChainVersionMatcher.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/ChainVersionMatcher.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/ChainVersionMatcher.java
 Fri Feb 23 00:52:49 2007
@@ -18,6 +18,7 @@
 package org.apache.ivy.plugins.version;
 
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -65,6 +66,16 @@
             }
         }
         return false;
+    }
+
+    public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid, 
Comparator staticComparator) {
+       for (Iterator iter = _matchers.iterator(); iter.hasNext();) {
+               VersionMatcher matcher = (VersionMatcher)iter.next();
+               if (matcher.isDynamic(askedMrid)) {
+                       return matcher.compare(askedMrid, foundMrid, 
staticComparator);
+               }
+       }
+       throw new IllegalArgumentException("impossible to compare revisions: 
askedMrid is not dynamic: "+askedMrid);
     }
 
     public boolean accept(ModuleRevisionId askedMrid, ModuleRevisionId 
foundMrid) {

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/LatestVersionMatcher.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/LatestVersionMatcher.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/LatestVersionMatcher.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/LatestVersionMatcher.java
 Fri Feb 23 00:52:49 2007
@@ -17,6 +17,8 @@
  */
 package org.apache.ivy.plugins.version;
 
+import java.util.Comparator;
+
 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
 import org.apache.ivy.core.module.id.ModuleRevisionId;
 import org.apache.ivy.core.module.status.StatusManager;
@@ -41,5 +43,14 @@
     public boolean accept(ModuleRevisionId askedMrid, ModuleDescriptor 
foundMD) {
         String askedStatus = 
askedMrid.getRevision().substring("latest.".length());
         return StatusManager.getCurrent().getPriority(askedStatus) >= 
StatusManager.getCurrent().getPriority(foundMD.getStatus());
+    }
+    
+    /**
+     * If we don't need a module descriptor we can consider the dynamic 
revision
+     * to be greater. If we need a module descriptor then we can't know which 
one
+     * is greater and return 0.
+     */
+    public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid, 
Comparator staticComparator) {
+       return needModuleDescriptor(askedMrid, foundMrid)?0:1;
     }
 }

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/PatternVersionMatcher.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/PatternVersionMatcher.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/PatternVersionMatcher.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/PatternVersionMatcher.java
 Fri Feb 23 00:52:49 2007
@@ -34,7 +34,7 @@
 public class PatternVersionMatcher extends AbstractVersionMatcher {
 
        private List _matches = new ArrayList(); 
-       private Map _RevisionMatches = new HashMap();  // revision -> list of 
Match instances
+       private Map _revisionMatches = new HashMap();  // revision -> list of 
Match instances
        private boolean _init = false;
 
        public void addMatch(Match match) {
@@ -45,10 +45,10 @@
                if (!_init) {
                        for (Iterator it = _matches.iterator(); it.hasNext(); ) 
{
                                Match match = (Match) it.next();
-                               List matches = (List) 
_RevisionMatches.get(match.getRevision());
+                               List matches = (List) 
_revisionMatches.get(match.getRevision());
                                if (matches == null) {
                                        matches = new ArrayList();
-                                       
_RevisionMatches.put(match.getRevision(), matches);
+                                       
_revisionMatches.put(match.getRevision(), matches);
                                }
                                matches.add(match);
                        }
@@ -69,7 +69,7 @@
                        revision = revision.substring(0, bracketIndex);
                }
                
-               List matches = (List) _RevisionMatches.get(revision);
+               List matches = (List) _revisionMatches.get(revision);
                
                if (matches != null) {
                        Iterator it = matches.iterator();
@@ -93,7 +93,7 @@
                if (bracketIndex > 0) {
                        revision = revision.substring(0, bracketIndex);
                }
-               return _RevisionMatches.containsKey(revision);
+               return _revisionMatches.containsKey(revision);
        }
 
 }

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/SubVersionMatcher.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/SubVersionMatcher.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/SubVersionMatcher.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/SubVersionMatcher.java
 Fri Feb 23 00:52:49 2007
@@ -17,6 +17,8 @@
  */
 package org.apache.ivy.plugins.version;
 
+import java.util.Comparator;
+
 import org.apache.ivy.core.module.id.ModuleRevisionId;
 
 public class SubVersionMatcher  extends AbstractVersionMatcher {
@@ -31,5 +33,12 @@
     public boolean accept(ModuleRevisionId askedMrid, ModuleRevisionId 
foundMrid) {
         String prefix = askedMrid.getRevision().substring(0, 
askedMrid.getRevision().length() - 1);
         return foundMrid.getRevision().startsWith(prefix);
+    }
+    
+    public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid, 
Comparator staticComparator) {
+       if 
(foundMrid.getRevision().startsWith(askedMrid.getRevision().substring(0, 
askedMrid.getRevision().length() - 1))) {
+               return 1;
+       }
+       return staticComparator.compare(askedMrid, foundMrid);
     }
 }

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionMatcher.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionMatcher.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionMatcher.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionMatcher.java
 Fri Feb 23 00:52:49 2007
@@ -17,6 +17,8 @@
  */
 package org.apache.ivy.plugins.version;
 
+import java.util.Comparator;
+
 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
 import org.apache.ivy.core.module.id.ModuleRevisionId;
 
@@ -73,6 +75,22 @@
      */
     public boolean accept(ModuleRevisionId askedMrid, ModuleDescriptor 
foundMD);
     
+    /**
+     * Compares a dynamic revision (askedMrid) with a static one (foundMrid)
+     * to indicate which one should be considered the greater.
+     * If there is not enough information to know which one is the greater,
+     * the dynamic one should be considered greater and this method should 
return 0.
+     * 
+     * This method should never be called with a askdeMrid for which isDynamic 
+     * returns false.
+     * 
+     * @param askedMrid the dynamic revision to compare
+     * @param foundMrid the static revision to compare
+     * @param staticComparator a comparator which can be used to compare 
static revisions
+     * @return 0 if it's not possible to know which one is greater, greater 
than 0 if askedMrid should be considered greater, lower than 0 if it can't be 
consider greater
+     */
+    public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid, 
Comparator staticComparator);
+
     /**
      * Returns the version matcher name identifying this version matcher
      * @return the version matcher name identifying this version matcher

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionRangeMatcher.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionRangeMatcher.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionRangeMatcher.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/version/VersionRangeMatcher.java
 Fri Feb 23 00:52:49 2007
@@ -161,6 +161,32 @@
        private boolean isUpper(ModuleRevisionId askedMrid, String revision, 
ModuleRevisionId foundMrid, boolean inclusive) {
                return 
COMPARATOR.compare(ModuleRevisionId.newInstance(askedMrid, revision), 
foundMrid) >= (inclusive ? 0 : 1);
        }
+       
+       public int compare(ModuleRevisionId askedMrid, ModuleRevisionId 
foundMrid, Comparator staticComparator) {
+               String revision = askedMrid.getRevision();
+               Matcher m;
+               m = UPPER_INFINITE_RANGE.matcher(revision);
+               if (m.matches()) {
+                       // no upper limit, the dynamic revision can always be 
considered greater
+                       return 1;
+               }
+               String upper;
+               m = FINITE_RANGE.matcher(revision);
+               if (m.matches()) {
+                       upper = m.group(2);
+               } else {
+                       m = LOWER_INFINITE_RANGE.matcher(revision);
+                       if (m.matches()) {
+                               upper = m.group(1);
+                       } else {
+                               throw new IllegalArgumentException("impossible 
to compare: askedMrid is not a dynamic revision: "+askedMrid);
+                       }
+               }
+               int c = 
staticComparator.compare(ModuleRevisionId.newInstance(askedMrid, upper), 
foundMrid);
+               // if the comparison consider them equal, we must return -1, 
because we can't consider the 
+               // dynamic revision to be greater. Otherwise we can safeely 
return the result of the static comparison
+               return c == 0?-1:c;
+       }
 
        public LatestStrategy getLatestStrategy() {
                if (_latestStrategy == null) {

Modified: 
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/LatestConflictManagerTest.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/LatestConflictManagerTest.java?view=diff&rev=510875&r1=510874&r2=510875
==============================================================================
--- 
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/LatestConflictManagerTest.java
 (original)
+++ 
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/LatestConflictManagerTest.java
 Fri Feb 23 00:52:49 2007
@@ -24,6 +24,8 @@
 
 import org.apache.ivy.Ivy;
 import org.apache.ivy.core.cache.CacheManager;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.core.report.ConfigurationResolveReport;
 import org.apache.ivy.core.report.ResolveReport;
 import org.apache.ivy.core.resolve.IvyNode;
 import org.apache.ivy.core.resolve.ResolveOptions;
@@ -61,6 +63,25 @@
                        }
                }
        }
+       
+    // Test case for issue IVY-383
+    public void testIvy383() throws Exception {
+        ResolveReport report =
+            ivy.resolve( LatestConflictManagerTest.class.getResource( 
"ivy-383.xml" ), 
+                       getResolveOptions() );
+        ConfigurationResolveReport defaultReport =
+            report.getConfigurationReport("default");
+        Iterator iter = defaultReport.getModuleRevisionIds().iterator();
+        while (iter.hasNext()) {
+            ModuleRevisionId mrid = (ModuleRevisionId)iter.next();
+            if (mrid.getName().equals("mod1.1")) {
+                assertEquals("1.0", mrid.getRevision());
+            }
+            else if (mrid.getName().equals("mod1.2")) {
+                assertEquals("2.2", mrid.getRevision());
+            }
+        }
+    }
     
     private ResolveOptions getResolveOptions() {
                return new 
ResolveOptions().setCache(CacheManager.getInstance(ivy.getSettings())).setValidate(false);

Added: 
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/ivy-383.xml
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/ivy-383.xml?view=auto&rev=510875
==============================================================================
--- 
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/ivy-383.xml 
(added)
+++ 
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/conflict/ivy-383.xml 
Fri Feb 23 00:52:49 2007
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ivy-module version="1.0"> 
+        <info organisation="apache" module="resolve-latest-conflict" 
revision="1.0" status="release"/>
+        <dependencies>
+            <!-- mod1.1-1.0 depends on mod1.2-2.0 -->
+            <dependency org="org1" name="mod1.1" rev="1.0"/>
+
+            <!-- This should find revision 2.2, but it doesn't
+                 because LatestConflictManager compares "2.0" with
+                 "[2,)" instead of "2.2"! -->
+            <dependency org="org1" name="mod1.2" rev="[2,)"/>
+        </dependencies>
+</ivy-module>


Reply via email to