You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2010/09/15 11:36:55 UTC

svn commit: r997239 - in /karaf/trunk/shell/osgi: pom.xml src/main/java/org/apache/karaf/shell/osgi/Headers.java

Author: gnodet
Date: Wed Sep 15 09:36:54 2010
New Revision: 997239

URL: http://svn.apache.org/viewvc?rev=997239&view=rev
Log:
KARAF-196: use felix header parsing library, remote the use of the green color which doesn't provide any information

Modified:
    karaf/trunk/shell/osgi/pom.xml
    karaf/trunk/shell/osgi/src/main/java/org/apache/karaf/shell/osgi/Headers.java

Modified: karaf/trunk/shell/osgi/pom.xml
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/osgi/pom.xml?rev=997239&r1=997238&r2=997239&view=diff
==============================================================================
--- karaf/trunk/shell/osgi/pom.xml (original)
+++ karaf/trunk/shell/osgi/pom.xml Wed Sep 15 09:36:54 2010
@@ -94,7 +94,11 @@
                         <DynamicImport-Package>
                             org.springframework.*
                         </DynamicImport-Package>
-                        <Private-Package>org.apache.felix.utils.version,!*</Private-Package>
+                        <Private-Package>
+                            org.apache.felix.utils.version,
+                            org.apache.felix.utils.manifest,
+                            !*
+                        </Private-Package>
                         <_versionpolicy>${bnd.version.policy}</_versionpolicy>
                     </instructions>
                 </configuration>

Modified: karaf/trunk/shell/osgi/src/main/java/org/apache/karaf/shell/osgi/Headers.java
URL: http://svn.apache.org/viewvc/karaf/trunk/shell/osgi/src/main/java/org/apache/karaf/shell/osgi/Headers.java?rev=997239&r1=997238&r2=997239&view=diff
==============================================================================
--- karaf/trunk/shell/osgi/src/main/java/org/apache/karaf/shell/osgi/Headers.java (original)
+++ karaf/trunk/shell/osgi/src/main/java/org/apache/karaf/shell/osgi/Headers.java Wed Sep 15 09:36:54 2010
@@ -16,8 +16,23 @@
  */
 package org.apache.karaf.shell.osgi;
 
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import jline.Terminal;
 import org.apache.felix.gogo.commands.Argument;
 import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+import org.apache.felix.utils.manifest.Attribute;
+import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Directive;
+import org.apache.felix.utils.manifest.Parser;
 import org.apache.felix.utils.version.VersionRange;
 import org.apache.karaf.shell.console.OsgiCommandSupport;
 import org.fusesource.jansi.Ansi;
@@ -26,23 +41,21 @@ import org.osgi.framework.ServiceReferen
 import org.osgi.service.packageadmin.ExportedPackage;
 import org.osgi.service.packageadmin.PackageAdmin;
 
-import java.util.*;
-
 @Command(scope = "osgi", name = "headers", description = "Displays OSGi headers of a given bundle")
 public class Headers extends OsgiCommandSupport {
 
     protected final static String BUNDLE_PREFIX = "Bundle-";
     protected final static String PACKAGE_SUFFFIX = "-Package";
     protected final static String SERVICE_SUFFIX = "-Service";
-    protected final static String USES_ATTRIB = "uses:=";
-    protected final static String VERSION_ATTRIB = "version=";
-    protected final static String RESOLUTION_ATTRIB = "resolution:=";
     protected final static String IMPORT_PACKAGES_ATTRIB = "Import-Package";
     protected final static String REQUIRE_BUNDLE_ATTRIB = "Require-Bundle";
 
     private ServiceReference ref;
     private PackageAdmin admin;
 
+    @Option(name = "--indent", description = "Indentation method")
+    int indent = -1;
+
     @Argument(index = 0, name = "ids", description = "A list of bundle IDs separated by whitespaces", required = false, multiValued = true)
     List<Long> ids;
 
@@ -87,11 +100,21 @@ public class Headers extends OsgiCommand
         String title = Util.getBundleName(bundle);
         System.out.println("\n" + title);
         System.out.println(Util.getUnderlineString(title));
-        System.out.println(generateFormattedOutput(bundle));
+        if (indent == 0) {
+            Dictionary dict = bundle.getHeaders();
+            Enumeration keys = dict.keys();
+            while (keys.hasMoreElements()) {
+                Object k = keys.nextElement();
+                Object v = dict.get(k);
+                System.out.println(k + " = " + Util.getValueString(v));
+            }
+        } else {
+            System.out.println(generateFormattedOutput(bundle));
+        }
     }
 
     protected String generateFormattedOutput(Bundle bundle) {
-        StringBuffer output = new StringBuffer();
+        StringBuilder output = new StringBuilder();
         Map<String, Object> otherAttribs = new HashMap<String, Object>();
         Map<String, Object> bundleAttribs = new HashMap<String, Object>();
         Map<String, Object> serviceAttribs = new HashMap<String, Object>();
@@ -152,20 +175,45 @@ public class Headers extends OsgiCommand
         it = serviceAttribs.entrySet().iterator();
         while (it.hasNext()) {
             Map.Entry<String, Object> e = it.next();
-            output.append(String.format("%s = %s\n", e.getKey(), Util.getValueString(e.getValue())));
+            output.append(e.getKey());
+            output.append(" = \n");
+            formatHeader(Util.getValueString(e.getValue()), null, output, indent);
+            output.append("\n");
         }
         if (serviceAttribs.size() > 0) {
             output.append('\n');
         }
 
+        Map<String, ClauseFormatter> formatters = new HashMap<String, ClauseFormatter>();
+        formatters.put(REQUIRE_BUNDLE_ATTRIB, new ClauseFormatter() {
+            public void pre(Clause clause, StringBuilder output) {
+                boolean isSatisfied = checkBundle(clause.getName(), clause.getAttribute("version"));
+                Ansi.ansi(output).fg(isSatisfied ? Ansi.Color.DEFAULT : Ansi.Color.RED).a("");
+            }
+            public void post(Clause clause, StringBuilder output) {
+                Ansi.ansi(output).reset().a("");
+            }
+        });
+        formatters.put(IMPORT_PACKAGES_ATTRIB, new ClauseFormatter() {
+            public void pre(Clause clause, StringBuilder output) {
+                boolean isSatisfied = checkPackage(clause.getName(), clause.getAttribute("version"));
+                boolean isOptional = "optional".equals(clause.getDirective("resolution"));
+                Ansi.ansi(output).fg(isSatisfied ? Ansi.Color.DEFAULT : Ansi.Color.RED)
+                                 .a(isSatisfied || isOptional ? Ansi.Attribute.INTENSITY_BOLD_OFF : Ansi.Attribute.INTENSITY_BOLD)
+                                 .a("");
+            }
+            public void post(Clause clause, StringBuilder output) {
+                Ansi.ansi(output).reset().a("");
+            }
+        });
+
         it = packagesAttribs.entrySet().iterator();
         while (it.hasNext()) {
             Map.Entry<String, Object> e = it.next();
-            if (e.getKey().equals(REQUIRE_BUNDLE_ATTRIB)) {
-                output.append(String.format("%s = %s\n", e.getKey(), getFormattedBundles(Util.getValueString(e.getValue()))));
-            } else {
-                output.append(String.format("%s = \n%s\n", e.getKey(), getFormattedPackages(Util.getValueString(e.getValue()), e.getKey().trim().equals(IMPORT_PACKAGES_ATTRIB))));
-            }
+            output.append(e.getKey());
+            output.append(" = \n");
+            formatHeader(Util.getValueString(e.getValue()), formatters.get(e.getKey()), output, indent);
+            output.append("\n");
         }
         if (packagesAttribs.size() > 0) {
             output.append('\n');
@@ -174,388 +222,123 @@ public class Headers extends OsgiCommand
         return output.toString();
     }
 
-    protected String getFormattedPackages(String packagesString, boolean colorize) {
-        StringBuffer output = new StringBuffer();
-
-        List<PackageDefinition> packages = splitPackages(packagesString, colorize);
-        boolean first = true;
-        for (PackageDefinition def : packages) {
-            if (first) {
-                first = false;
-            } else {
-                output.append(",\n");
-            }
-            output.append(def.toString());
-        }
-        return output.toString();
+    protected interface ClauseFormatter {
+        void pre(Clause clause, StringBuilder output);
+        void post(Clause clause, StringBuilder output);
     }
 
-    protected String getFormattedBundles(String bundlesString) {
-        StringBuffer output = new StringBuffer();
+    protected void formatHeader(String header, ClauseFormatter formatter, StringBuilder builder, int indent) {
+        Clause[] clauses = Parser.parseHeader(header);
+        formatClauses(clauses, formatter, builder, indent);
+    }
 
-        List<BundleDefinition> bundles = splitBundles(bundlesString);
+    protected void formatClauses(Clause[] clauses, ClauseFormatter formatter, StringBuilder builder, int indent) {
         boolean first = true;
-        for (BundleDefinition def : bundles) {
+        for (Clause clause : clauses) {
             if (first) {
                 first = false;
             } else {
-                output.append(",\n");
+                builder.append(",\n");
             }
-            output.append(def.toString());
+            formatClause(clause, formatter, builder, indent);
         }
-        return output.toString();
     }
 
-    protected List<PackageDefinition> splitPackages(String packagesString, boolean colorize) {
-        boolean inQuotes = false;
-        List<PackageDefinition> parts = new ArrayList<PackageDefinition>();
-        StringBuffer statement = new StringBuffer();
-        for (int index = 0; index < packagesString.length(); index++) {
-            char c = packagesString.charAt(index);
-
-            if (c == '"') {
-                // quote switcher
-                inQuotes = !inQuotes;
-            }
-
-            if (c == ',' && !inQuotes) {
-                // package statement ends here
-                parts.add(new PackageDefinition(statement.toString(), colorize));
-                statement.setLength(0);
-            } else {
-                statement.append(c);
-            }
+    protected void formatClause(Clause clause, ClauseFormatter formatter, StringBuilder builder, int indent) {
+        builder.append("\t");
+        if (formatter != null) {
+            formatter.pre(clause, builder);
+        }
+        formatClause(clause, builder, indent);
+        if (formatter != null) {
+            formatter.post(clause, builder);
         }
-
-        if (statement.length() > 0) {
-            parts.add(new PackageDefinition(statement.toString(), colorize));
-        }
-
-        return parts;
     }
 
-    protected List<BundleDefinition> splitBundles(String bundlesString) {
-        boolean inQuotes = false;
-        List<BundleDefinition> parts = new ArrayList<BundleDefinition>();
-        StringBuffer statement = new StringBuffer();
-        for (int index = 0; index < bundlesString.length(); index++) {
-            char c = bundlesString.charAt(index);
-
-            if (c == '"') {
-                // quote switcher
-                inQuotes = !inQuotes;
-            }
+    protected int getTermWidth() {
+        Terminal term = (Terminal) session.get(".jline.terminal");
+        return term != null ? term.getTerminalWidth() : 80;
 
-            if (c == ',' && !inQuotes) {
-                // package statement ends here
-                parts.add(new BundleDefinition(statement.toString()));
-                statement.setLength(0);
-            } else {
-                statement.append(c);
-            }
-        }
-
-        if (statement.length() > 0) {
-            parts.add(new BundleDefinition(statement.toString()));
-        }
-
-        return parts;
     }
 
-    class PackageDefinition {
-        private String packageStr;
-        private String nameStr;
-        private String usesStr;
-        private String versionStr;
-        private String resolutionStr;
-        private List<String> usesItems;
-        private List<String> parameters;
-        private boolean colorize;
-
-        public PackageDefinition(String packageString, boolean colorize) {
-            this.packageStr = packageString;
-            this.colorize = colorize;
-            this.usesItems = new LinkedList<String>();
-            this.parameters = new LinkedList<String>();
-            parse();
-        }
-
-        private void parse() {
-            boolean inQuotes = false;
-            StringBuffer statement = new StringBuffer();
-            boolean first = true;
-            for (int index = 0; index < packageStr.length(); index++) {
-                char c = packageStr.charAt(index);
-
-                if (c == '"') {
-                    // quote switcher
-                    inQuotes = !inQuotes;
-                }
-
-                if (c == ';' && !inQuotes) {
-                    // part finished
-                    apply(statement.toString(), first);
-                    first = false;
-                    statement.setLength(0);
-                } else {
-                    statement.append(c);
-                }
-            }
-
-            if (statement.length() > 0) {
-                apply(statement.toString(), first);
-            }
-        }
-
-        private void apply(String part, boolean first) {
-            if (part.startsWith(USES_ATTRIB)) {
-                // uses definition
-                this.usesStr = part;
-                StringTokenizer usesTok = new StringTokenizer(this.usesStr.substring(this.usesStr.indexOf(USES_ATTRIB) + USES_ATTRIB.length()).replaceAll("\"", ""), ",");
-                while (usesTok.hasMoreTokens()) {
-                    this.usesItems.add(usesTok.nextToken());
+    protected void formatClause(Clause clause, StringBuilder builder, int indent) {
+        if (indent < 0) {
+            if (clause.toString().length() < getTermWidth() - 8) { // -8 for tabs
+                indent = 1;
+            } else {
+                indent = 3;
+            }
+        }
+        String name = clause.getName();
+        Directive[] directives = clause.getDirectives();
+        Attribute[] attributes = clause.getAttributes();
+        Arrays.sort(directives, new Comparator<Directive>() {
+            public int compare(Directive o1, Directive o2) {
+                return o1.getName().compareTo(o2.getName());
+            }
+        });
+        Arrays.sort(attributes, new Comparator<Attribute>() {
+            public int compare(Attribute o1, Attribute o2) {
+                return o1.getName().compareTo(o2.getName());
+            }
+        });
+        builder.append(name);
+        for (int i = 0; directives != null && i < directives.length; i++) {
+            builder.append(";");
+            if (indent > 1) {
+                builder.append("\n\t\t");
+            }
+            builder.append(directives[i].getName()).append(":=");
+            String v = directives[i].getValue();
+            if (v.contains(",")) {
+                if (indent > 2 && v.length() > 20) {
+                    v = v.replace(",", ",\n\t\t\t");
+                }
+                builder.append("\"").append(v).append("\"");
+            } else {
+                builder.append(v);
+            }
+        }
+        for (int i = 0; attributes != null && i < attributes.length; i++) {
+            builder.append(";");
+            if (indent > 1) {
+                builder.append("\n\t\t");
+            }
+            builder.append(attributes[i].getName()).append("=");
+            String v = attributes[i].getValue();
+            if (v.contains(",")) {
+                if (indent > 2 && v.length() > 20) {
+                    v = v.replace(",", ",\n\t\t\t");
                 }
-            } else if (part.startsWith(VERSION_ATTRIB)) {
-                // version definition
-                this.versionStr = part;
-            } else if (part.startsWith(RESOLUTION_ATTRIB)) {
-                // resolution definition
-                this.resolutionStr = part;
+                builder.append("\"").append(v).append("\"");
             } else {
-                if (first) {
-                    // must be package name
-                    this.nameStr = part;
-                } else {
-                    parameters.add(part);
-                }
+                builder.append(v);
             }
         }
+    }
 
-        public String getName() {
-            return this.nameStr;
-        }
-
-        public String getResolution() {
-            return this.resolutionStr;
-        }
-
-        public String getVersion() {
-            return this.versionStr;
-        }
-
-        public List<String> getUsesItems() {
-            return this.usesItems;
-        }
-
-        public String toString() {
-            StringBuffer output = new StringBuffer();
-
-            // output should look like this...
-            // <package>;
-            // uses:=<package>,
-            // <anotherPackage>,
-            // <etc>;
-            // <parameters>;
-            // version="<version>",
-            // resolution:="<resolution>",
-            // <blank line>
-            output.append(String.format("\t%s", this.getName()));
-
-            // we do a line feed if there are uses defined
-            if (this.usesItems.size() > 0) {
-                output.append(String.format(";\n\t%s \"", USES_ATTRIB));
-                boolean first = true;
-                for (String usesItem : this.usesItems) {
-                    if (first) {
-                        first = false;
-                    } else {
-                        output.append(",\n\t\t");
-                    }
-                    output.append(usesItem);
-                }
-                output.append("\"");
-
-                for (String param : this.parameters) {
-                    if (first) {
-                        first = false;
-                    } else {
-                        output.append(";\n\t");
-                    }
-                    output.append(String.format("%s", param));
-                }
-
-                if (this.getVersion() != null) {
-                    output.append(String.format(";\n\t%s", this.getVersion()));
-                }
-                if (this.getResolution() != null) {
-                    output.append(String.format(";\n\t%s", this.getResolution()));
-                }
-            } else {
-                // if there are no uses defined we put all on a single line
-                boolean first = true;
-                for (String param : this.parameters) {
-                    if (first) {
-                        first = false;
-                    } else {
-                        output.append(",\n\t\t");
-                    }
-                    output.append(String.format(";%s", param));
-                }
-
-                if (this.getVersion() != null) {
-                    output.append(String.format(";%s", this.getVersion()));
-                }
-                if (this.getResolution() != null) {
-                    output.append(String.format(";%s", this.getResolution()));
-                }
-            }
-
-            String retVal;
-
-            if (colorize) {
-                boolean isSatisfied = checkPackage(getName(), getVersion());
-                if (isSatisfied) {
-                    // color it green
-                    retVal = Ansi.ansi().fg(Ansi.Color.GREEN).a(output.toString()).reset().toString();
-                } else {
-                    // color it red
-                    retVal = Ansi.ansi().fg(Ansi.Color.RED).a(output.toString()).reset().toString();
-                }
-            } else {
-                retVal = output.toString();
-            }
 
-            return retVal;
+   private boolean checkBundle(String bundleName, String version) {
+        if (admin != null) {
+            Bundle[] bundles = admin.getBundles(bundleName, version);
+            return bundles != null && bundles.length > 0;
         }
+        return false;
+    }
 
-        private boolean checkPackage(String packageName, String versionInfo) {
-            boolean satisfied = false;
-            String version = versionInfo == null ? null : versionInfo.substring(versionInfo.indexOf('"') + 1, versionInfo.lastIndexOf('"'));
-            VersionRange range = version == null ? null : VersionRange.parseVersionRange(version);
-
-            if (admin != null) {
-                ExportedPackage[] packages = admin.getExportedPackages(packageName);
-                if (version == null) {
-                    satisfied = packages != null && packages.length > 0;
-                } else {
-                    if (packages != null) {
-                        for (ExportedPackage export : packages) {
-                            if (range.contains(export.getVersion())) {
-                                satisfied = true;
-                                break;
-                            }
-                        }
+    private boolean checkPackage(String packageName, String version) {
+        VersionRange range = VersionRange.parseVersionRange(version);
+        if (admin != null) {
+            ExportedPackage[] packages = admin.getExportedPackages(packageName);
+            if (packages != null) {
+                for (ExportedPackage export : packages) {
+                    if (range.contains(export.getVersion())) {
+                        return true;
                     }
                 }
             }
-
-            return satisfied;
         }
+        return false;
     }
 
-    class BundleDefinition {
-        private String bundleStr;
-        private String nameStr;
-        private String versionStr;
-        private String resolutionStr;
-
-        public BundleDefinition(String bundleString) {
-            this.bundleStr = bundleString;
-            parse();
-        }
-
-        private void parse() {
-            boolean inQuotes = false;
-            StringBuffer statement = new StringBuffer();
-            for (int index = 0; index < this.bundleStr.length(); index++) {
-                char c = this.bundleStr.charAt(index);
-
-                if (c == '"') {
-                    // quote switcher
-                    inQuotes = !inQuotes;
-                }
-
-                if (c == ';' && !inQuotes) {
-                    // part finished
-                    apply(statement.toString());
-                    statement.setLength(0);
-                } else {
-                    statement.append(c);
-                }
-            }
-
-            if (statement.length() > 0) {
-                apply(statement.toString());
-            }
-        }
-
-        private void apply(String part) {
-            if (part.startsWith(VERSION_ATTRIB)) {
-                // version definition
-                this.versionStr = part;
-            } else if (part.startsWith(RESOLUTION_ATTRIB)) {
-                // resolution definition
-                this.resolutionStr = part;
-            } else {
-                // must be bundle name
-                this.nameStr = part;
-            }
-        }
-
-        public String getName() {
-            return this.nameStr;
-        }
-
-        public String getResolution() {
-            return this.resolutionStr;
-        }
-
-        public String getVersion() {
-            return this.versionStr;
-        }
-
-        public String toString() {
-            StringBuffer output = new StringBuffer();
-
-            // output should look like this...
-            // <bundle>;
-            // version="<version>",
-            // resolution:="<resolution>",
-            // <blank line>
-            output.append(String.format("\t%s", this.getName()));
-
-            // if there are no uses defined we put all on a single line
-            if (this.getVersion() != null) {
-                output.append(String.format(";%s", this.getVersion()));
-            }
-            if (this.getResolution() != null) {
-                output.append(String.format(";%s", this.getResolution()));
-            }
-
-            String retVal;
-
-            boolean isSatisfied = checkBundle(getName(), getVersion());
-            if (isSatisfied) {
-                // color it green
-                retVal = Ansi.ansi().fg(Ansi.Color.GREEN).a(output.toString()).reset().toString();
-            } else {
-                // color it red
-                retVal = Ansi.ansi().fg(Ansi.Color.RED).a(output.toString()).reset().toString();
-            }
-
-            return retVal;
-        }
-
-        private boolean checkBundle(String bundleName, String versionInfo) {
-            boolean satisfied = false;
-            String version = versionInfo == null ? null : versionInfo.substring(versionInfo.indexOf('"') + 1, versionInfo.lastIndexOf('"'));
-
-            if (admin != null) {
-                Bundle[] bundles = admin.getBundles(bundleName, version);
-                satisfied = bundles != null && bundles.length > 0;
-            }
-
-            return satisfied;
-        }
-    }
 }