You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2014/01/15 15:55:50 UTC

svn commit: r1558409 - in /felix/trunk/dependencymanager/shell/src: main/java/org/apache/felix/dm/shell/DMCommand.java test/java/org/apache/felix/dm/shell/DMCommandTest.java

Author: pderop
Date: Wed Jan 15 14:55:49 2014
New Revision: 1558409

URL: http://svn.apache.org/r1558409
Log:
FELIX-4352: committed the jan15.path attached in the felix issue (many thanks Jago !).

Modified:
    felix/trunk/dependencymanager/shell/src/main/java/org/apache/felix/dm/shell/DMCommand.java
    felix/trunk/dependencymanager/shell/src/test/java/org/apache/felix/dm/shell/DMCommandTest.java

Modified: felix/trunk/dependencymanager/shell/src/main/java/org/apache/felix/dm/shell/DMCommand.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/shell/src/main/java/org/apache/felix/dm/shell/DMCommand.java?rev=1558409&r1=1558408&r2=1558409&view=diff
==============================================================================
--- felix/trunk/dependencymanager/shell/src/main/java/org/apache/felix/dm/shell/DMCommand.java (original)
+++ felix/trunk/dependencymanager/shell/src/main/java/org/apache/felix/dm/shell/DMCommand.java Wed Jan 15 14:55:49 2014
@@ -25,6 +25,8 @@ import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map.Entry;
+import java.util.Properties;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.TreeSet;
@@ -512,10 +514,8 @@ public class DMCommand {
     private Set<ComponentId> getTheRootCouses(List<ComponentDeclaration> downComponents) {
         Set<ComponentId> downComponentsRoot = new TreeSet<ComponentId>();
         for (ComponentDeclaration c : downComponents) {
-            ComponentId root = getRoot(downComponents, c, new ArrayList<ComponentId>());
-            if (root != null) {
-                downComponentsRoot.add(root);
-            }
+            List<ComponentId> root = getRoot(downComponents, c, new ArrayList<ComponentId>());
+            downComponentsRoot.addAll(root);
         }
         return downComponentsRoot;
     }
@@ -622,22 +622,25 @@ public class DMCommand {
         return false;
     }
     
-    private ComponentId getRoot(List<ComponentDeclaration> downComponents, ComponentDeclaration c, List<ComponentId> backTrace) {
+    private List<ComponentId> getRoot(List<ComponentDeclaration> downComponents, ComponentDeclaration c, List<ComponentId> backTrace) {
         ComponentDependencyDeclaration[] componentDependencies = c.getComponentDependencies();
         int downDeps = 0;
+        List<ComponentId> result = new ArrayList<ComponentId>();
         for (ComponentDependencyDeclaration cdd : componentDependencies) {
             if (cdd.getState() == ComponentDependencyDeclaration.STATE_UNAVAILABLE_REQUIRED) {
                 downDeps++;
                 // Detect missing configuration dependency
                 if (CONFIGURATION.equals(cdd.getType())) {
                     String bsn = c.getBundleContext().getBundle().getSymbolicName();
-                    return new ComponentId(cdd.getName(), cdd.getType(), bsn);
+                    result.add(new ComponentId(cdd.getName(), cdd.getType(), bsn));
+                    continue;
                 }
 
                 // Detect if the missing dependency is a root cause failure
                 ComponentDeclaration component = getComponentDeclaration(cdd.getName(), downComponents);
                 if (component == null) {
-                    return new ComponentId(cdd.getName(), cdd.getType(), null);
+                    result.add(new ComponentId(cdd.getName(), cdd.getType(), null));
+                    continue;
                 }
                 // Detect circular dependency
                 ComponentId componentId = new ComponentId(cdd.getName(), cdd.getType(), null);
@@ -648,32 +651,71 @@ public class DMCommand {
                         System.out.print(" -> " + cid.getName() + " ");
                     }
                     System.out.println(" -> " + componentId.getName());
-                    return new ComponentId(c.getName(), SERVICE, c.getBundleContext().getBundle().getSymbolicName());
+                    result.add(new ComponentId(c.getName(), SERVICE, c.getBundleContext().getBundle().getSymbolicName()));
+                    continue;
                 }
                 backTrace.add(componentId);
                 return getRoot(downComponents, component, backTrace);
             }
         }
-        if (downDeps > 0) {
-            return new ComponentId(c.getName(), SERVICE, c.getBundleContext().getBundle().getSymbolicName());
+        if (downDeps > 0 && result.isEmpty()) {
+            result.add(new ComponentId(c.getName(), SERVICE, c.getBundleContext().getBundle().getSymbolicName()));
         }
-        return null;
+        return result;
     }
     
-    private ComponentDeclaration getComponentDeclaration(String name, List<ComponentDeclaration> list) {
+    private ComponentDeclaration getComponentDeclaration(final String fullName, List<ComponentDeclaration> list) {
+        String simpleName = getSimpleName(fullName);
+        Properties props = parseProperties(fullName);
         for (ComponentDeclaration c : list) {
-            String serviceName = c.getName();
-            int cuttOff = serviceName.indexOf("(");
+            String serviceNames = c.getName();
+            int cuttOff = serviceNames.indexOf("(");
             if (cuttOff != -1) {
-                serviceName = serviceName.substring(0, cuttOff);
+                serviceNames = serviceNames.substring(0, cuttOff).trim();
             }
-            if (name.equals(serviceName)) {
-                return c;
+            for (String serviceName : serviceNames.split(",")) {
+                if (simpleName.equals(serviceName.trim()) && doPropertiesMatch(props, parseProperties(c.getName()))) {
+                    return c;
+                }
             }
         }
         return null;
     }
     
+    private boolean doPropertiesMatch(Properties need, Properties provide) {
+        for (Entry<Object, Object> entry : need.entrySet()) {
+            Object prop = provide.get(entry.getKey());
+            if (prop == null || !prop.equals(entry.getValue())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private String getSimpleName(String name) {
+        int cuttOff = name.indexOf("(");
+        if (cuttOff != -1) {
+            return name.substring(0, cuttOff).trim();
+        }
+        return name.trim();
+    }
+    
+    private Properties parseProperties(String name) {
+        Properties result = new Properties();
+        int cuttOff = name.indexOf("(");
+        if (cuttOff != -1) {
+            String propsText = name.substring(cuttOff + 1, name.indexOf(")"));
+            String[] split = propsText.split(",");
+            for (String prop : split) {
+                String[] kv = prop.split("=");
+                if (kv.length == 2) {
+                    result.put(kv[0], kv[1]);
+                }
+            }
+        }
+        return result;
+    }
+    
     public static class DependencyManagerSorter implements Comparator<DependencyManager> {
         public int compare(DependencyManager dm1, DependencyManager dm2) {
             long id1 = dm1.getBundleContext().getBundle().getBundleId();

Modified: felix/trunk/dependencymanager/shell/src/test/java/org/apache/felix/dm/shell/DMCommandTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/shell/src/test/java/org/apache/felix/dm/shell/DMCommandTest.java?rev=1558409&r1=1558408&r2=1558409&view=diff
==============================================================================
--- felix/trunk/dependencymanager/shell/src/test/java/org/apache/felix/dm/shell/DMCommandTest.java (original)
+++ felix/trunk/dependencymanager/shell/src/test/java/org/apache/felix/dm/shell/DMCommandTest.java Wed Jan 15 14:55:49 2014
@@ -169,6 +169,62 @@ public class DMCommandTest {
     }
     
     @Test
+    public void testCanFindRootFailureWithSecondair() {
+        setupEmptyBundles();
+        
+        Component component1 = dm.createComponent()
+            .setImplementation(Object.class)
+            .setInterface(Object.class.getName(), null)
+            .add(dm.createServiceDependency().setService(Math.class).setRequired(true));
+        dm.add(component1);
+        
+        Component component2 = dm.createComponent()
+            .setImplementation(Math.class)
+            .setInterface(Math.class.getName(), null)
+            .add(dm.createServiceDependency().setService(Float.class).setRequired(true));
+        dm.add(component2);
+        
+        Component component3 = dm.createComponent()
+            .setImplementation(Object.class)
+            .setInterface(new String[] {Object.class.getName(), Float.class.getName()}, null)
+            .add(dm.createServiceDependency().setService(String.class).setRequired(true));
+        dm.add(component3);
+        
+        dme.wtf();
+        String output = outContent.toString();
+        assertTrue(output.contains("3 missing"));
+        assertTrue(output.contains("java.lang.String"));
+        assertFalse(output.contains("java.lang.Float"));
+        
+        // remove the mess
+        dm.remove(component1);
+        dm.remove(component2);
+        dm.remove(component3);
+    }
+    
+    @Test
+    public void testCanFindRootFailureWithTwoFailures() {
+        setupEmptyBundles();
+        
+        Component component1 = dm.createComponent()
+            .setImplementation(Object.class)
+            .setInterface(Object.class.getName(), null)
+            .add(dm.createServiceDependency().setService(Math.class).setRequired(true))
+            .add(dm.createServiceDependency().setService(Long.class).setRequired(true));
+        dm.add(component1);
+        
+        
+        dme.wtf();
+        String output = outContent.toString();
+        assertTrue(output.contains("1 missing"));
+        assertTrue(output.contains("java.lang.Math"));
+        assertTrue(output.contains("java.lang.Long"));
+        
+        // remove the mess
+        dm.remove(component1);
+    }
+    
+    @Test
     public void testInstalledBundleListing() {
         Bundle bundle1 = mock(Bundle.class);
         when(bundle1.getState()).thenReturn(Bundle.INSTALLED);