Implement "requires" and "requirers" commands. (FELIX-1009)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@759431 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/Activator.java b/shell/src/main/java/org/apache/felix/shell/impl/Activator.java
index 3e52769..eb83ff6 100644
--- a/shell/src/main/java/org/apache/felix/shell/impl/Activator.java
+++ b/shell/src/main/java/org/apache/felix/shell/impl/Activator.java
@@ -80,7 +80,7 @@
// been registered (i.e., we didn't see their service events).
initializeCommands();
- // Register "exports" command service.
+ // Register "bundlelevel" command service.
context.registerService(
org.apache.felix.shell.Command.class.getName(),
new BundleLevelCommandImpl(m_context), null);
@@ -127,6 +127,16 @@
org.apache.felix.shell.Command.class.getName(),
new RefreshCommandImpl(m_context), null);
+ // Register "requires" command service.
+ context.registerService(
+ org.apache.felix.shell.Command.class.getName(),
+ new RequiresCommandImpl(m_context), null);
+
+ // Register "requirers" command service.
+ context.registerService(
+ org.apache.felix.shell.Command.class.getName(),
+ new RequirersCommandImpl(m_context), null);
+
// Register "resolve" command service.
context.registerService(
org.apache.felix.shell.Command.class.getName(),
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/ExportsCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/ExportsCommandImpl.java
index 3636c99..8db20eb 100644
--- a/shell/src/main/java/org/apache/felix/shell/impl/ExportsCommandImpl.java
+++ b/shell/src/main/java/org/apache/felix/shell/impl/ExportsCommandImpl.java
@@ -55,13 +55,7 @@
// Get package admin service.
ServiceReference ref = m_context.getServiceReference(
org.osgi.service.packageadmin.PackageAdmin.class.getName());
- if (ref == null)
- {
- out.println("PackageAdmin service is unavailable.");
- return;
- }
-
- PackageAdmin pa = (PackageAdmin) m_context.getService(ref);
+ PackageAdmin pa = (ref == null) ? null : (PackageAdmin) m_context.getService(ref);
if (pa == null)
{
out.println("PackageAdmin service is unavailable.");
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/ImportsCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/ImportsCommandImpl.java
index 7be2f29..47e4b38 100644
--- a/shell/src/main/java/org/apache/felix/shell/impl/ImportsCommandImpl.java
+++ b/shell/src/main/java/org/apache/felix/shell/impl/ImportsCommandImpl.java
@@ -19,8 +19,6 @@
package org.apache.felix.shell.impl;
import java.io.PrintStream;
-import java.util.List;
-import java.util.ArrayList;
import java.util.StringTokenizer;
import org.apache.felix.shell.Command;
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/RequirersCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/RequirersCommandImpl.java
new file mode 100644
index 0000000..42107ff
--- /dev/null
+++ b/shell/src/main/java/org/apache/felix/shell/impl/RequirersCommandImpl.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.shell.impl;
+
+import java.io.PrintStream;
+import java.util.StringTokenizer;
+
+import org.apache.felix.shell.Command;
+import org.osgi.framework.*;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.packageadmin.RequiredBundle;
+
+public class RequirersCommandImpl implements Command
+{
+ private BundleContext m_context = null;
+
+ public RequirersCommandImpl(BundleContext context)
+ {
+ m_context = context;
+ }
+
+ public String getName()
+ {
+ return "requirers";
+ }
+
+ public String getUsage()
+ {
+ return "requirers <id> ...";
+ }
+
+ public String getShortDescription()
+ {
+ return "list requiring bundles.";
+ }
+
+ public void execute(String s, PrintStream out, PrintStream err)
+ {
+ // Get package admin service.
+ ServiceReference ref = m_context.getServiceReference(
+ org.osgi.service.packageadmin.PackageAdmin.class.getName());
+ PackageAdmin pa = (ref == null) ? null : (PackageAdmin) m_context.getService(ref);
+ if (pa == null)
+ {
+ out.println("PackageAdmin service is unavailable.");
+ return;
+ }
+
+ // Parse command line.
+ StringTokenizer st = new StringTokenizer(s, " ");
+
+ // Ignore the command name.
+ st.nextToken();
+
+ if (st.hasMoreTokens())
+ {
+ boolean separatorNeeded = false;
+ while (st.hasMoreTokens())
+ {
+ String id = st.nextToken();
+ try
+ {
+ long l = Long.parseLong(id);
+ Bundle bundle = m_context.getBundle(l);
+ RequiredBundle[] rbs = pa.getRequiredBundles(bundle.getSymbolicName());
+ for (int i = 0; (rbs != null) && (i < rbs.length); i++)
+ {
+ if (rbs[i].getBundle() == bundle)
+ {
+ if (separatorNeeded)
+ {
+ out.println("");
+ }
+ printRequiredBundles(out, bundle, rbs[i].getRequiringBundles());
+ separatorNeeded = true;
+ }
+ }
+ }
+ catch (NumberFormatException ex)
+ {
+ err.println("Unable to parse id '" + id + "'.");
+ }
+ catch (Exception ex)
+ {
+ err.println(ex.toString());
+ }
+ }
+ }
+ }
+
+ private void printRequiredBundles(PrintStream out, Bundle target, Bundle[] requirers)
+ {
+ String title = target + " required by:";
+ out.println(title);
+ out.println(Util.getUnderlineString(title));
+ if ((requirers != null) && (requirers.length > 0))
+ {
+ for (int i = 0; i < requirers.length; i++)
+ {
+ out.println(requirers[i]);
+ }
+ }
+ else
+ {
+ out.println("Nothing");
+ }
+ }
+}
\ No newline at end of file
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/RequiresCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/RequiresCommandImpl.java
new file mode 100644
index 0000000..c5b3c57
--- /dev/null
+++ b/shell/src/main/java/org/apache/felix/shell/impl/RequiresCommandImpl.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.shell.impl;
+
+import java.io.PrintStream;
+import java.util.StringTokenizer;
+
+import org.apache.felix.shell.Command;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.packageadmin.RequiredBundle;
+
+public class RequiresCommandImpl implements Command
+{
+ private final BundleContext m_context;
+ private ServiceReference m_ref = null;
+
+ public RequiresCommandImpl(BundleContext context)
+ {
+ m_context = context;
+ }
+
+ public String getName()
+ {
+ return "requires";
+ }
+
+ public String getUsage()
+ {
+ return "requires <id> ...";
+ }
+
+ public String getShortDescription()
+ {
+ return "list required bundles.";
+ }
+
+ public void execute(String s, PrintStream out, PrintStream err)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ");
+
+ // Ignore the command name.
+ st.nextToken();
+
+ if (st.hasMoreTokens())
+ {
+ boolean separatorNeeded = false;
+ while (st.hasMoreTokens())
+ {
+ String id = st.nextToken().trim();
+
+ try
+ {
+ long l = Long.parseLong(id);
+ Bundle bundle = m_context.getBundle(l);
+ if (bundle != null)
+ {
+ if (separatorNeeded)
+ {
+ out.println("");
+ }
+ getImportedPackages(bundle, out, err);
+ separatorNeeded = true;
+ }
+ else
+ {
+ err.println("Bundle ID " + id + " is invalid.");
+ }
+ }
+ catch (NumberFormatException ex)
+ {
+ err.println("Unable to parse id '" + id + "'.");
+ }
+ catch (Exception ex)
+ {
+ err.println(ex.toString());
+ }
+ }
+ }
+ }
+
+ private void getImportedPackages(Bundle bundle, PrintStream out, PrintStream err)
+ {
+ // Get package admin service.
+ PackageAdmin pa = getPackageAdmin();
+ if (pa == null)
+ {
+ out.println("PackageAdmin service is unavailable.");
+ }
+ else
+ {
+ RequiredBundle[] rbs = pa.getRequiredBundles(null);
+ String title = bundle + " requires:";
+ out.println(title);
+ out.println(Util.getUnderlineString(title));
+ boolean found = false;
+ for (int rbIdx = 0; rbIdx < rbs.length; rbIdx++)
+ {
+ Bundle[] requirers = rbs[rbIdx].getRequiringBundles();
+ for (int reqIdx = 0; (requirers != null) && (reqIdx < requirers.length); reqIdx++)
+ {
+ if (requirers[reqIdx] == bundle)
+ {
+ out.println(rbs[reqIdx]);
+ found = true;
+ }
+ }
+ }
+ if (!found)
+ {
+ out.println("Nothing");
+ }
+ ungetPackageAdmin();
+ }
+ }
+
+ private PackageAdmin getPackageAdmin()
+ {
+ PackageAdmin pa = null;
+ m_ref = m_context.getServiceReference(
+ org.osgi.service.packageadmin.PackageAdmin.class.getName());
+ if (m_ref != null)
+ {
+ pa = (PackageAdmin) m_context.getService(m_ref);
+ }
+ return pa;
+ }
+
+ private void ungetPackageAdmin()
+ {
+ m_context.ungetService(m_ref);
+ }
+}
\ No newline at end of file