Author: gscokart
Date: Wed Nov 21 01:04:46 2007
New Revision: 596998

URL: http://svn.apache.org/viewvc?rev=596998&view=rev
Log:
IVY-644 fix NPE in case of eviction by 2 modules on 2 different confs mixed 
with extends

Modified:
    incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNode.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNodeEviction.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/ResolveEngine.java
    
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNode.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNode.java?rev=596998&r1=596997&r2=596998&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNode.java 
(original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNode.java 
Wed Nov 21 01:04:46 2007
@@ -98,6 +98,10 @@
             //CheckStyle:MagicNumber| OFF
             return hash;
         }
+        
+        public String toString() {
+            return "NodeConf(" + conf + ")";
+        }
     }
 
     // //////// CONTEXT
@@ -182,14 +186,21 @@
      */
     public boolean loadData(String rootModuleConf, IvyNode parent, String 
parentConf, String conf,
             boolean shouldBePublic) {
+        Message.debug("loadData of " + this.toString() + " of rootConf=" + 
rootModuleConf);
         if (!isRoot() && (data.getReport() != null)) {
             data.getReport().addDependency(this);
         }
 
         boolean loaded = false;
-        if (!isEvicted(rootModuleConf)
-                && (hasConfigurationsToLoad() || 
!isRootModuleConfLoaded(rootModuleConf))
-                && !hasProblem()) {
+        if (hasProblem()) {
+            Message.debug("Node has problem.  Skip loading");
+            handleConfiguration(loaded, rootModuleConf, parent, parentConf, 
conf, shouldBePublic);
+            return false;
+        } else if (isEvicted(rootModuleConf)) {
+            Message.debug(rootModuleConf + " is evicted.  Skip loading");
+        } else if (!hasConfigurationsToLoad() && 
isRootModuleConfLoaded(rootModuleConf)) {
+            Message.debug(rootModuleConf + " is loaded and no conf to load.  
Skip loading");
+        } else {
             markRootModuleConfLoaded(rootModuleConf);
             if (md == null) {
                 DependencyResolver resolver = 
data.getSettings().getResolver(getModuleId());
@@ -309,11 +320,6 @@
                 loaded = true;
             }
         }
-        if (hasProblem()) {
-            return handleConfiguration(loaded, rootModuleConf, parent, 
parentConf, conf,
-                shouldBePublic)
-                    && loaded;
-        }
         if (!handleConfiguration(loaded, rootModuleConf, parent, parentConf, 
conf, shouldBePublic)) {
             return false;
         }
@@ -347,8 +353,7 @@
                     "impossible to get dependencies when data has not been 
loaded");
         }
         DependencyDescriptor[] dds = md.getDependencies();
-        Collection dependencies = new LinkedHashSet(); // it's important to 
respect dependencies
-        // order
+        Collection dependencies = new LinkedHashSet(); // it's important to 
respect order
         for (int i = 0; i < dds.length; i++) {
             DependencyDescriptor dd = dds[i];
             String[] dependencyConfigurations = 
dd.getDependencyConfigurations(conf, requestedConf);
@@ -547,6 +552,7 @@
         return (String[]) depConfs.toArray(new String[depConfs.size()]);
     }
 
+    //This is never called.  Could we remove it?
     public void discardConf(String rootModuleConf, String conf) {
         Set depConfs = (Set) rootModuleConfs.get(rootModuleConf);
         if (depConfs == null) {
@@ -750,7 +756,13 @@
             // no configuration required => no artifact required
             return new Artifact[0];
         }
+        if (md == null) {
+            throw new IllegalStateException(
+                    "impossible to get artefacts when data has not been 
loaded. IvyNode = "
+                    + this.toString());
+        }
 
+        
         Set artifacts = new HashSet(); // the set we fill before returning
 
         // we check if we have dependencyArtifacts includes description for 
this rootModuleConf
@@ -909,7 +921,8 @@
     public ConflictManager getConflictManager(ModuleId mid) {
         if (md == null) {
             throw new IllegalStateException(
-                    "impossible to get conflict manager when data has not been 
loaded");
+                    "impossible to get conflict manager when data has not been 
loaded. IvyNode = "
+                    + this.toString());
         }
         ConflictManager cm = md.getConflictManager(mid);
         return cm == null ? settings.getConflictManager(mid) : cm;
@@ -1097,7 +1110,9 @@
 
     public void markEvicted(String rootModuleConf, IvyNode node, 
ConflictManager conflictManager,
             Collection resolved) {
-        eviction.markEvicted(rootModuleConf, node, conflictManager, resolved);
+        EvictionData evictionData = new EvictionData(rootModuleConf, node, 
conflictManager,
+                resolved);
+        markEvicted(evictionData);
     }
 
     public void setEvictedNodes(ModuleId moduleId, String rootModuleConf, 
Collection evicted) {

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNodeEviction.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNodeEviction.java?rev=596998&r1=596997&r2=596998&view=diff
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNodeEviction.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/resolve/IvyNodeEviction.java
 Wed Nov 21 01:04:46 2007
@@ -91,6 +91,10 @@
         public String getRootModuleConf() {
             return rootModuleConf;
         }
+
+        public boolean isTransitivelyEvicted() {
+            return parent == null;
+        }
     }
 
     private static final class ModuleIdConf {
@@ -235,9 +239,13 @@
     public boolean isEvicted(String rootModuleConf) {
         cleanEvicted();
         IvyNode root = node.getRoot();
-        return root != node
-                && !root.getResolvedRevisions(node.getId().getModuleId(), 
rootModuleConf).contains(
-                    node.getResolvedId()) && getEvictedData(rootModuleConf) != 
null;
+        ModuleId moduleId = node.getId().getModuleId();
+        Collection resolvedRevisions = root.getResolvedRevisions(moduleId, 
rootModuleConf);
+        EvictionData evictedData = getEvictedData(rootModuleConf);
+        return root != node && evictedData != null 
+            && (!resolvedRevisions.contains(node.getResolvedId())
+                || evictedData.isTransitivelyEvicted()
+               );
     }
 
     public boolean isCompletelyEvicted() {
@@ -271,13 +279,6 @@
                 }
             }
         }
-    }
-
-    public void markEvicted(String rootModuleConf, IvyNode node, 
ConflictManager conflictManager,
-            Collection resolved) {
-        EvictionData evictionData = new EvictionData(rootModuleConf, node, 
conflictManager,
-                resolved);
-        markEvicted(evictionData);
     }
 
     public void markEvicted(EvictionData evictionData) {

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=596998&r1=596997&r2=596998&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
 Wed Nov 21 01:04:46 2007
@@ -548,10 +548,11 @@
         } else {
             Message.verbose("== resolving dependencies for " + node.getId() + 
" [" + conf + "]");
         }
-        resolveConflict(node);
+        resolveConflict(node, conf);
 
         if (node.loadData(conf, shouldBePublic)) {
-            resolveConflict(node);
+            resolveConflict(node, conf); //We just did it. Should it be 
redone? 
+                                   //NB:removing it break a unit test.
             if (!node.isEvicted()) {
                 String[] confs = node.getRealConfs(conf);
                 for (int i = 0; i < confs.length; i++) {
@@ -672,8 +673,8 @@
         return false;
     }
 
-    private void resolveConflict(VisitNode node) {
-        resolveConflict(node, node.getParent(), Collections.EMPTY_SET);
+    private void resolveConflict(VisitNode node, String conf) {
+        resolveConflict(node, node.getParent(), conf,Collections.EMPTY_SET);
     }
 
     /**
@@ -689,7 +690,8 @@
      *            descendants of ancestor)
      * @return true if conflict resolution has been done, false it can't be 
done yet
      */
-    private boolean resolveConflict(VisitNode node, VisitNode ancestor, 
Collection toevict) {
+    private boolean resolveConflict(VisitNode node, VisitNode ancestor, String 
conf,
+            Collection toevict) {
         if (ancestor == null || node == ancestor) {
             return true;
         }
@@ -702,7 +704,7 @@
             // job is done and node is selected, nothing to do for this 
ancestor, but we still have
             // to check higher levels, for which conflict resolution might 
have been impossible
             // before
-            if (resolveConflict(node, ancestor.getParent(), toevict)) {
+            if (resolveConflict(node, ancestor.getParent(), conf, toevict)) {
                 // now that conflict resolution is ok in ancestors
                 // we just have to check if the node wasn't previously evicted 
in root ancestor
                 EvictionData evictionData = 
node.getEvictionDataInRoot(node.getRootModuleConf(),
@@ -730,7 +732,7 @@
             node.getModuleId(), node.getRootModuleConf()));
         
resolvedNodes.addAll(ancestor.getNode().getPendingConflicts(node.getRootModuleConf(),
             node.getModuleId()));
-        Collection conflicts = computeConflicts(node, ancestor, toevict, 
resolvedNodes);
+        Collection conflicts = computeConflicts(node, ancestor, conf, toevict, 
resolvedNodes);
 
         if (settings.debugConflictResolution()) {
             Message.debug("found conflicting revisions for " + node + " in " + 
ancestor + ": "
@@ -788,7 +790,7 @@
             ancestor.getNode().setPendingConflicts(node.getModuleId(), 
node.getRootModuleConf(),
                 Collections.EMPTY_SET);
 
-            return resolveConflict(node, ancestor.getParent(), toevict);
+            return resolveConflict(node, ancestor.getParent(), conf, toevict);
         } else {
             // node has been evicted for the current parent
             if (resolved.isEmpty()) {
@@ -827,7 +829,7 @@
                     IvyNode sel = (IvyNode) iter.next();
                     if (!prevResolved.contains(sel)) {
                         solved &= resolveConflict(node.gotoNode(sel), 
ancestor.getParent(),
-                            toevict);
+                            conf, toevict);
                     }
                 }
             }
@@ -835,8 +837,8 @@
         }
     }
 
-    private Collection computeConflicts(VisitNode node, VisitNode ancestor, 
Collection toevict,
-            Collection resolvedNodes) {
+    private Collection computeConflicts(VisitNode node, VisitNode ancestor, 
String conf,
+            Collection toevict, Collection resolvedNodes) {
         Collection conflicts = new HashSet();
         conflicts.add(node.getNode());
         if (resolvedNodes.removeAll(toevict)) {
@@ -853,14 +855,13 @@
                         .addAll(dep.getResolvedNodes(node.getModuleId(), 
node.getRootModuleConf()));
             }
         } else if (resolvedNodes.isEmpty() && node.getParent() != ancestor) {
-            DependencyDescriptor[] dds = 
ancestor.getDescriptor().getDependencies();
-            for (int i = 0; i < dds.length; i++) {
-                if (dds[i].getDependencyId().equals(node.getModuleId())) {
-                    IvyNode n = 
node.getNode().findNode(dds[i].getDependencyRevisionId());
-                    if (n != null) {
-                        conflicts.add(n);
-                        break;
-                    }
+            //Conflict must only be computed per root configuration at this 
step.
+            Collection ancestorDepIvyNodes = node.getParent().getNode()
+                        .getDependencies(node.getRootModuleConf(), new 
String[] {conf});
+            for (Iterator it = ancestorDepIvyNodes.iterator(); it.hasNext();) {
+                IvyNode ancestorDep = (IvyNode) it.next();
+                if (ancestorDep.getModuleId().equals(node.getModuleId())) {
+                    conflicts.add(ancestorDep);
                 }
             }
         } else {

Modified: 
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java?rev=596998&r1=596997&r2=596998&view=diff
==============================================================================
--- 
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java 
(original)
+++ 
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/resolve/ResolveTest.java 
Wed Nov 21 01:04:46 2007
@@ -18,9 +18,6 @@
 package org.apache.ivy.core.resolve;
 
 import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -35,7 +32,6 @@
 
 import org.apache.ivy.Ivy;
 import org.apache.ivy.TestHelper;
-import org.apache.ivy.core.IvyContext;
 import org.apache.ivy.core.cache.ArtifactOrigin;
 import org.apache.ivy.core.cache.CacheManager;
 import org.apache.ivy.core.module.descriptor.Artifact;
@@ -58,9 +54,7 @@
 import org.apache.ivy.plugins.resolver.DualResolver;
 import org.apache.ivy.plugins.resolver.FileSystemResolver;
 import org.apache.ivy.util.CacheCleaner;
-import org.apache.ivy.util.DefaultMessageLogger;
 import org.apache.ivy.util.FileUtil;
-import org.apache.ivy.util.Message;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.Delete;
 import org.xml.sax.SAXException;
@@ -675,8 +669,6 @@
             ModuleRevisionId.newInstance("org1", "mod1.2", "2.1")).exists());
         assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", 
"jar", "jar").exists());
 
-        assertFalse(cacheManager.getIvyFileInCache(
-            ModuleRevisionId.newInstance("org1", "mod1.2", "2.0")).exists());
         assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", 
"jar", "jar").exists());
     }
 
@@ -1474,7 +1466,7 @@
     public void testTransitiveEviction() throws Exception {
         // mod7.3 depends on mod7.2 v1.0 and on mod7.1 v2.0
         // mod7.2 v1.0 depends on mod7.1 v1.0 (which then should be evicted)
-        // mod7.1 v1.0 depends on mod 1.2 v1.0 (which should be evicted by 
transitivity)
+        // mod7.1 v1.0 depends on mod 1.2 v2.0 (which should be evicted by 
transitivity)
 
         ResolveReport report = ivy.resolve(new 
File("test/repositories/2/mod7.3/ivy-1.0.xml")
                 .toURL(), getResolveOptions(new String[] {"*"}));
@@ -1495,9 +1487,9 @@
             ModuleRevisionId.newInstance("org7", "mod7.1", "2.0")).exists());
         assertTrue(getArchiveFileInCache("org7", "mod7.1", "2.0", "mod7.1", 
"jar", "jar").exists());
 
-        assertTrue(!getArchiveFileInCache("org7", "mod7.1", "1.0", "mod7.1", 
"jar", "jar").exists());
+        assertFalse(getArchiveFileInCache("org7", "mod7.1", "1.0", "mod7.1", 
"jar", "jar").exists());
 
-        assertTrue(!getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", 
"jar", "jar").exists());
+        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", 
"jar", "jar").exists());
     }
 
     public void testTransitiveEviction2() throws Exception {
@@ -1753,15 +1745,15 @@
                 .newInstance("org5", "mod5.1", "4.2")).length);
     }
 
-    /*
+    
     public void testMultipleEviction() throws Exception {
         
         ResolveReport report = ivy.resolve(
             new 
File("test/repositories/1/IVY-644/M1/ivys/ivy-1.0.xml").toURL(),
-            getResolveOptions(new String[] {"*"}));
+            getResolveOptions(new String[] {"test" , "runtime" })); //NB the 
order impact the bug
         assertFalse(report.hasError());
     }
-    */
+    
     
     public void testResolveForce() throws Exception {
         // mod4.1 v 4.2 depends on


Reply via email to