You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2008/01/18 11:03:37 UTC
svn commit: r613118 - in /incubator/sling/trunk/osgi/console-web: pom.xml
src/main/java/org/apache/sling/osgi/console/web/internal/AjaxBundleDetailsAction.java
Author: fmeschbe
Date: Fri Jan 18 02:03:37 2008
New Revision: 613118
URL: http://svn.apache.org/viewvc?rev=613118&view=rev
Log:
SLING-151 List imports and exports of unresolved (installed, that is) bundles
to provide some help in resolving why a bundle might not resolve. Specifically
each import is analzyed:
* If the import can be satisifed, print the potential provider
* If the import cannot be satisifed but is part of the bundle,
ignore the import (not actually correct, should look at
export list, but sounds enough)
* If an import is listed in the bootdelegation property and
cannot be resolved, both situations are marked.
Modified:
incubator/sling/trunk/osgi/console-web/pom.xml
incubator/sling/trunk/osgi/console-web/src/main/java/org/apache/sling/osgi/console/web/internal/AjaxBundleDetailsAction.java
Modified: incubator/sling/trunk/osgi/console-web/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/console-web/pom.xml?rev=613118&r1=613117&r2=613118&view=diff
==============================================================================
--- incubator/sling/trunk/osgi/console-web/pom.xml (original)
+++ incubator/sling/trunk/osgi/console-web/pom.xml Fri Jan 18 02:03:37 2008
@@ -70,10 +70,13 @@
<!-- Required by FileUpload and Util -->
org.apache.commons.io,
org.apache.commons.io.filefilter,
- org.apache.commons.io.output
+ org.apache.commons.io.output,
+
+ <!-- Import/Export-Package parsing -->
+ org.apache.felix.bundlerepository
</Private-Package>
<Import-Package>
- org.apache.felix.scr;resolution:=optional,*
+ org.apache.felix.*;resolution:=optional,*
</Import-Package>
</instructions>
</configuration>
@@ -129,5 +132,12 @@
</exclusion>
</exclusions>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.bundlerepository</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
</dependencies>
</project>
Modified: incubator/sling/trunk/osgi/console-web/src/main/java/org/apache/sling/osgi/console/web/internal/AjaxBundleDetailsAction.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/console-web/src/main/java/org/apache/sling/osgi/console/web/internal/AjaxBundleDetailsAction.java?rev=613118&r1=613117&r2=613118&view=diff
==============================================================================
--- incubator/sling/trunk/osgi/console-web/src/main/java/org/apache/sling/osgi/console/web/internal/AjaxBundleDetailsAction.java (original)
+++ incubator/sling/trunk/osgi/console-web/src/main/java/org/apache/sling/osgi/console/web/internal/AjaxBundleDetailsAction.java Fri Jan 18 02:03:37 2008
@@ -22,19 +22,27 @@
import java.util.Comparator;
import java.util.Date;
import java.util.Dictionary;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.StringTokenizer;
+import java.util.TreeMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.felix.bundlerepository.R4Attribute;
+import org.apache.felix.bundlerepository.R4Export;
+import org.apache.felix.bundlerepository.R4Import;
+import org.apache.felix.bundlerepository.R4Package;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentConstants;
import org.osgi.service.component.ComponentContext;
@@ -107,7 +115,11 @@
keyVal(props, "Start Level", getStartLevel(bundle));
- listImportExport(props, bundle);
+ if (bundle.getState() == Bundle.INSTALLED) {
+ listImportExportsUnresolved(props, bundle);
+ } else {
+ listImportExport(props, bundle);
+ }
listServices(props, bundle);
@@ -147,21 +159,7 @@
StringBuffer val = new StringBuffer();
for (ExportedPackage export : exports) {
-
- boolean bootDel = isBootDelegated(export.getName());
- if (bootDel) {
- val.append("<span style=\"color: red\">!! ");
- }
-
- val.append(export.getName());
- val.append(",version=");
- val.append(export.getVersion());
-
- if (bootDel) {
- val.append(" -- Overwritten by Boot Delegation</span>");
- }
-
- val.append("<br />");
+ printExport(val, export.getName(), export.getVersion());
}
keyVal(props, "Exported Packages", val.toString());
} else {
@@ -194,46 +192,92 @@
});
// and finally print out
for (ExportedPackage ep : packages) {
+ printImport(val, ep.getName(), ep.getVersion(), ep);
+ }
+ } else {
+ // add description if there are no imports
+ val.append("None");
+ }
- boolean bootDel = isBootDelegated(ep.getName());
- if (bootDel) {
- val.append("<span style=\"color: red\">!! ");
- }
+ keyVal(props, "Imported Packages", val.toString());
+ }
+ }
- val.append(ep.getName());
- val.append(",version=").append(ep.getVersion());
- val.append(" from ");
-
- if (ep.getExportingBundle().getSymbolicName() != null) {
- // list the bundle name if not null
- val.append(ep.getExportingBundle().getSymbolicName());
- val.append(" (").append(
- ep.getExportingBundle().getBundleId());
- val.append(")");
- } else if (ep.getExportingBundle().getLocation() != null) {
- // otherwise try the location
- val.append(ep.getExportingBundle().getLocation());
- val.append(" (").append(
- ep.getExportingBundle().getBundleId());
- val.append(")");
- } else {
- // fallback to just the bundle id
- // only append the bundle
- val.append(ep.getExportingBundle().getBundleId());
- }
+ private void listImportExportsUnresolved(JSONArray props, Bundle bundle) {
+ Dictionary<?, ?> dict = bundle.getHeaders();
- if (bootDel) {
- val.append(" -- Overwritten by Boot Delegation</span>");
+ String target = (String) dict.get(Constants.EXPORT_PACKAGE);
+ if (target != null) {
+ R4Package[] pkgs = R4Package.parseImportOrExportHeader(target);
+ if (pkgs != null && pkgs.length > 0) {
+ // do alphabetical sort
+ Arrays.sort(pkgs, new Comparator<R4Package>() {
+ public int compare(R4Package p1, R4Package p2) {
+ return p1.getName().compareTo(p2.getName());
}
+ });
+
+ StringBuffer val = new StringBuffer();
+ for (R4Package pkg : pkgs) {
+ R4Export export = new R4Export(pkg);
- val.append("<br />");
+ printExport(val, export.getName(), export.getVersion());
}
+ keyVal(props, "Exported Packages", val.toString());
} else {
- // add description if there are no imports
- val.append("None");
+ keyVal(props, "Exported Packages", "None");
}
+ }
- keyVal(props, "Imported Packages", val.toString());
+ target = (String) dict.get(Constants.IMPORT_PACKAGE);
+ if (target != null) {
+ R4Package[] pkgs = R4Package.parseImportOrExportHeader(target);
+ if (pkgs != null && pkgs.length > 0) {
+ Map<String, R4Import> imports = new TreeMap<String, R4Import>();
+ for (R4Package pkg : pkgs) {
+ imports.put(pkg.getName(), new R4Import(pkg));
+ }
+
+ // collect import packages first
+ final Map<String, ExportedPackage> candidates = new HashMap<String, ExportedPackage>();
+ ExportedPackage[] exports = packageAdmin.getExportedPackages((Bundle) null);
+ if (exports != null && exports.length > 0) {
+
+ for (int i = 0; i < exports.length; i++) {
+ final ExportedPackage ep = exports[i];
+
+ R4Import imp = imports.get(ep.getName());
+ if (imp != null && imp.isSatisfied(toR4Export(ep))) {
+ candidates.put(ep.getName(), ep);
+ }
+ }
+ }
+
+ // now sort
+ StringBuffer val = new StringBuffer();
+ if (imports.size() > 0) {
+ for (R4Import r4Import : imports.values()) {
+ ExportedPackage ep = candidates.get(r4Import.getName());
+
+ // if there is no matching export, check whether this
+ // bundle has the package, ignore the entry in this case
+ if (ep == null) {
+ String path = r4Import.getName().replace('.', '/');
+ if (bundle.getResource(path) != null) {
+ continue;
+ }
+ }
+
+ printImport(val, r4Import.getName(),
+ r4Import.getVersion(), ep);
+ }
+ } else {
+ // add description if there are no imports
+ val.append("None");
+ }
+
+ keyVal(props, "Imported Packages", val.toString());
+ }
}
}
@@ -297,6 +341,68 @@
}
}
+ private void printExport(StringBuffer val, String name, Version version) {
+ boolean bootDel = isBootDelegated(name);
+ if (bootDel) {
+ val.append("<span style=\"color: red\">!! ");
+ }
+
+ val.append(name);
+ val.append(",version=");
+ val.append(version);
+
+ if (bootDel) {
+ val.append(" -- Overwritten by Boot Delegation</span>");
+ }
+
+ val.append("<br />");
+
+ }
+
+ private void printImport(StringBuffer val, String name, Version version,
+ ExportedPackage export) {
+ boolean bootDel = isBootDelegated(name);
+ if (bootDel || export == null) {
+ val.append("<span style=\"color: red\">!! ");
+ }
+
+ val.append(name);
+ val.append(",version=").append(version);
+ val.append(" from ");
+
+ if (export != null) {
+ if (export.getExportingBundle().getSymbolicName() != null) {
+ // list the bundle name if not null
+ val.append(export.getExportingBundle().getSymbolicName());
+ val.append(" (").append(
+ export.getExportingBundle().getBundleId());
+ val.append(")");
+ } else if (export.getExportingBundle().getLocation() != null) {
+ // otherwise try the location
+ val.append(export.getExportingBundle().getLocation());
+ val.append(" (").append(
+ export.getExportingBundle().getBundleId());
+ val.append(")");
+ } else {
+ // fallback to just the bundle id
+ // only append the bundle
+ val.append(export.getExportingBundle().getBundleId());
+ }
+
+ if (bootDel) {
+ val.append(" -- Overwritten by Boot Delegation</span>");
+ }
+ } else {
+ val.append(" -- Cannot be resolved");
+ if (bootDel) {
+ val.append(" and overwritten by Boot Delegation");
+ }
+ val.append("</span>");
+ }
+
+ val.append("<br />");
+ }
+
// returns true if the package is listed in the bootdelegation property
private boolean isBootDelegated(String pkgName) {
@@ -327,6 +433,13 @@
}
return false;
+ }
+
+ private R4Export toR4Export(ExportedPackage export) {
+ R4Attribute version = new R4Attribute(Constants.VERSION_ATTRIBUTE,
+ export.getVersion().toString(), false);
+ return new R4Export(export.getName(), null,
+ new R4Attribute[] { version });
}
// ---------- SCR integration ----------------------------------------------