Add a "which" command to determine from where a bundle gets a class. (FELIX-2042)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@941496 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/gogo/felixcommands/src/main/java/org/apache/felix/gogo/felixcommands/Activator.java b/gogo/felixcommands/src/main/java/org/apache/felix/gogo/felixcommands/Activator.java
index 9d45ab4..a77b60e 100644
--- a/gogo/felixcommands/src/main/java/org/apache/felix/gogo/felixcommands/Activator.java
+++ b/gogo/felixcommands/src/main/java/org/apache/felix/gogo/felixcommands/Activator.java
@@ -31,7 +31,7 @@
         props.put("osgi.command.function", new String[] {
             "bundlelevel", "frameworklevel", "headers", "help",
             "install", "lb", "refresh", "resolve", "start",
-            "stop", "uninstall", "update" });
+            "stop", "uninstall", "update", "which" });
         bc.registerService(
             Basic.class.getName(), new Basic(bc), props);
 
diff --git a/gogo/felixcommands/src/main/java/org/apache/felix/gogo/felixcommands/Basic.java b/gogo/felixcommands/src/main/java/org/apache/felix/gogo/felixcommands/Basic.java
index 8df0aa2..985c5eb 100644
--- a/gogo/felixcommands/src/main/java/org/apache/felix/gogo/felixcommands/Basic.java
+++ b/gogo/felixcommands/src/main/java/org/apache/felix/gogo/felixcommands/Basic.java
@@ -37,6 +37,7 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleReference;
 import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
@@ -213,11 +214,11 @@
                 Descriptor d = m.getAnnotation(Descriptor.class);
                 if (d == null)
                 {
-                    System.out.println(m.getName());
+                    System.out.println("\n" + m.getName());
                 }
                 else
                 {
-                    System.out.println(m.getName() + " - " + d.description());
+                    System.out.println("\n" + m.getName() + " - " + d.description());
                 }
 
                 // Get flags and options.
@@ -288,7 +289,6 @@
                         System.out.println("      " + it.next() + "   " + it.next());
                     }
                 }
-                System.out.println("");
             }
         }
     }
@@ -734,6 +734,40 @@
         }
     }
 
+    @Descriptor(description="determines from where a bundle loads a class")
+    public void which(
+        @Descriptor(description="target bundle identifier") Long id,
+        @Descriptor(description="target class name") String className)
+    {
+        Bundle bundle = getBundle(m_bc, id);
+        if (bundle == null)
+        {
+            return;
+        }
+        Class clazz = null;
+        try
+        {
+            clazz = bundle.loadClass(className);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            System.out.println("Class not found");
+        }
+        if (clazz.getClassLoader() == null)
+        {
+            System.out.println("Loaded from: boot class loader");
+        }
+        else if (clazz.getClassLoader() instanceof BundleReference)
+        {
+            Bundle p = ((BundleReference) clazz.getClassLoader()).getBundle();
+            System.out.println("Loaded from: " + p);
+        }
+        else
+        {
+            System.out.println("Loaded from: " + clazz.getClassLoader());
+        }
+    }
+
     private static void printBundleList(
         Bundle[] bundles, StartLevel startLevel, PrintStream out, boolean showLoc,
         boolean showSymbolic, boolean showUpdate)