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;
- }
- }
}