Apply patch FELIX-4492 to improve logging and diagnostics.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1589774 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/resolver/src/main/java/org/apache/felix/resolver/Logger.java b/resolver/src/main/java/org/apache/felix/resolver/Logger.java
index 9eaa212..b652051 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/Logger.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/Logger.java
@@ -18,6 +18,10 @@
  */
 package org.apache.felix.resolver;
 
+import org.osgi.resource.Resource;
+
+import org.osgi.service.resolver.ResolutionException;
+
 /**
  * <p>
  * This class mimics the standard OSGi <tt>LogService</tt> interface. An
@@ -46,10 +50,6 @@
 
     private int m_logLevel = 1;
 
-    private final static int LOGGER_OBJECT_IDX = 0;
-    private final static int LOGGER_METHOD_IDX = 1;
-    private Object[] m_logger = null;
-
     public Logger(int i)
     {
         m_logLevel = i;
@@ -77,6 +77,10 @@
 
     protected void doLog(int level, String msg, Throwable throwable)
     {
+    	if (level > m_logLevel)
+    	{
+    		return;
+    	}
         String s = "";
         s = s + msg;
         if (throwable != null)
@@ -110,13 +114,13 @@
         int level,
         String msg, Throwable throwable)
     {
-        // Save our own copy just in case it changes. We could try to do
-        // more conservative locking here, but let's be optimistic.
-        Object[] logger = m_logger;
-
         if (m_logLevel >= level)
         {
             doLog(level, msg, throwable);
         }
     }
+
+    public void logUsesConstraintViolation(Resource resource, ResolutionException error) {
+        // do nothing by default
+    }
 }
diff --git a/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
index 82d1d4d..56e6df3 100644
--- a/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
+++ b/resolver/src/main/java/org/apache/felix/resolver/ResolverImpl.java
@@ -214,7 +214,7 @@
                     }
                 }
 
-                Collection<Resource> faultyResources = null;
+                Map<Resource, ResolutionException> faultyResources = null;
                 do
                 {
                     rethrow = null;
@@ -230,7 +230,7 @@
                         ? usesPermutations.remove(0)
                         : importPermutations.remove(0);
 //allCandidates.dump();
-                    Collection<Resource> currentFaultyResources = null;
+                    Map<Resource, ResolutionException> currentFaultyResources = null;
                     // Reuse a resultCache map for checking package consistency
                     // for all resources.
                     Map<Resource, Object> resultCache =
@@ -266,9 +266,20 @@
                         {
                             rethrow = ex;
                             if (currentFaultyResources == null) {
-                            	currentFaultyResources = new ArrayList();
+                            	currentFaultyResources = new HashMap<Resource, ResolutionException>();
                             }
-                           	currentFaultyResources.add(resource);
+                            Resource faultyResource = resource;
+                            // check that the faulty requirement is not from a fragment
+                            for (Requirement faultyReq : ex.getUnresolvedRequirements()) {
+                            	if (faultyReq instanceof WrappedRequirement)
+                                {
+                                    faultyResource =
+                                        ((WrappedRequirement) faultyReq)
+                                        .getDeclaredRequirement().getResource();
+                                    break;
+                            	}
+                            }
+                            currentFaultyResources.put(faultyResource, ex);
                         }
                     }
                     if (currentFaultyResources != null) {
@@ -290,7 +301,12 @@
                 if (rethrow != null)
                 {
                     if (faultyResources != null) {
-                        retry = (optionalResources.removeAll(faultyResources) || ondemandFragments.removeAll(faultyResources));
+                    	Set<Resource> resourceKeys = faultyResources.keySet();
+                        retry = (optionalResources.removeAll(resourceKeys) || ondemandFragments.removeAll(resourceKeys));
+                        // log all the resolution exceptions for the uses constraint violations
+                        for (Map.Entry<Resource, ResolutionException> usesError : faultyResources.entrySet()) {
+    						m_logger.logUsesConstraintViolation(usesError.getKey(), usesError.getValue());
+    					}
                     }
                     if (!retry) {
                         throw rethrow;