Index: shell/packages/src/main/java/org/apache/karaf/shell/packages/ExportsCommand.java =================================================================== --- shell/packages/src/main/java/org/apache/karaf/shell/packages/ExportsCommand.java (revision 967008) +++ shell/packages/src/main/java/org/apache/karaf/shell/packages/ExportsCommand.java (working copy) @@ -17,6 +17,7 @@ package org.apache.karaf.shell.packages; import java.io.PrintStream; +import java.util.ArrayList; import java.util.List; import org.apache.felix.gogo.commands.Argument; @@ -30,45 +31,112 @@ @Command(scope = "packages", name = "exports", description = "Display exported packages") public class ExportsCommand extends PackageCommandSupport { - @Option(name = "-i", aliases = { "--imports"}, description = "List bundles importing the specified packages") + @Option(name = "-i", aliases = {"--imports"}, description = "List bundles importing the specified packages") boolean imports; - + @Option(name = "-s", description = "Shows the symbolic name", required = false, multiValued = false) + boolean showSymbolic; + @Option(name = "-d", aliases = {"--details"}, description = "List bundles as a master detail table") + boolean details; @Argument(index = 0, name = "ids", description = "The IDs of bundles to check", required = false, multiValued = true) List ids; protected void doExecute(PackageAdmin admin) throws Exception { + String format = ""; + int index = 1; + List headers = new ArrayList(); + headers.add("ID"); + format += "%" + (index++) + "$6s"; + + if (showSymbolic) { + headers.add("Symbolic name"); + format += " %" + (index++) + "$-40s "; + } + + headers.add("Packages"); + format += " %" + (index++) + "$-40s"; + + if (imports) { + headers.add("Imported by"); + format += " %" + (index++) + "$-40s"; + } + format += "\n"; + System.out.format(format, headers.toArray()); + if (ids != null && !ids.isEmpty()) { for (long id : ids) { Bundle bundle = getBundleContext().getBundle(id); if (bundle != null) { - printExports(System.out, bundle, admin.getExportedPackages(bundle)); + printExports(System.out, format, bundle, admin.getExportedPackages(bundle)); } else { System.err.println("Bundle ID " + id + " is invalid."); } } + } else { + for (Bundle bundle : getBundleContext().getBundles()) { + printExports(System.out, format, bundle, admin.getExportedPackages((Bundle) bundle)); + } } - else { - printExports(System.out, null, admin.getExportedPackages((Bundle) null)); - } } - protected void printExports(PrintStream out, Bundle target, ExportedPackage[] exports) { + protected void printExports(PrintStream out, String format, Bundle target, ExportedPackage[] exports) { + List columns = new ArrayList(); + if ((exports != null) && (exports.length > 0)) { for (int i = 0; i < exports.length; i++) { + columns = new ArrayList(); Bundle bundle = exports[i].getExportingBundle(); - out.print(getBundleName(bundle)); - out.println(": " + exports[i]); + columns.add(String.valueOf(bundle.getBundleId())); + + if (showSymbolic) { + columns.add(bundle.getSymbolicName()); + } + + //Do not repeat ID, Symbolic names etc when bundle exports more that one package + if (i > 0) { + int size = columns.size(); + if (details) { + columns = new ArrayList(); + fillDetailRecord(columns, size); + } + } + + columns.add(exports[i].getName()); + if (imports) { Bundle[] bs = exports[i].getImportingBundles(); - if (bs != null) { - for (Bundle b : bs) { - out.println("\t" + getBundleName(b)); + if (bs != null && bs.length > 0) { + for (int j = 0; j < bs.length; j++) { + columns.add(getBundleName(bs[j])); + out.format(format, columns.toArray()); + //Do not repeat ID, Symbolic names etc when package is imported by more than one bundles + if (details) { + int size = columns.size(); + columns = new ArrayList(); + fillDetailRecord(columns, size - 1); + } else { + columns.remove(columns.size() - 1); + } } + } else { + columns.add(""); + out.format(format, columns.toArray()); } + } else { + out.format(format, columns.toArray()); } } } else { - out.println(getBundleName(target) + ": No active exported packages."); + columns.add(String.valueOf(target.getBundleId())); + + if (showSymbolic) { + columns.add(target.getSymbolicName()); + } + + columns.add("No active exported packages."); + if (imports) { + columns.add(""); + } + out.format(format, columns.toArray()); } } @@ -76,10 +144,20 @@ if (bundle != null) { String name = (String) bundle.getHeaders().get(Constants.BUNDLE_NAME); return (name == null) - ? "Bundle " + Long.toString(bundle.getBundleId()) - : name + " (" + Long.toString(bundle.getBundleId()) + ")"; + ? "Bundle " + Long.toString(bundle.getBundleId()) + : name + " (" + Long.toString(bundle.getBundleId()) + ")"; } return "[STALE BUNDLE]"; } + /** + * Method that creates an empty list of string that serves as detail record. + * @param colums + * @param size + */ + public void fillDetailRecord(List colums, int size) { + for (int i = 0; i < size; i++) { + colums.add(""); + } + } }