You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2012/08/21 17:45:23 UTC
svn commit: r1375615 - in /sling/trunk/installer/core/src:
main/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtil.java
test/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtilTest.java
Author: bdelacretaz
Date: Tue Aug 21 15:45:23 2012
New Revision: 1375615
URL: http://svn.apache.org/viewvc?rev=1375615&view=rev
Log:
SLING-2567 - reimplemented using PackageAdmin.getExportedPackages(...), thanks Felix for the pointers
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtil.java
sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtilTest.java
Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtil.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtil.java?rev=1375615&r1=1375614&r2=1375615&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtil.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtil.java Tue Aug 21 15:45:23 2012
@@ -18,13 +18,10 @@
*/
package org.apache.sling.installer.core.impl.util;
-import java.util.HashSet;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
-import org.apache.sling.commons.osgi.ManifestHeader;
import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.slf4j.Logger;
@@ -40,71 +37,56 @@ class RefreshDependenciesUtil {
this.pckAdmin = pa;
}
- private Set<String> getImportPackages(final Bundle bundle) {
- final Set<String> packages = new HashSet<String>();
- final String imports = (String)bundle.getHeaders().get(Constants.IMPORT_PACKAGE);
- if(imports != null) {
- final ManifestHeader header = ManifestHeader.parse(imports);
- for(final ManifestHeader.Entry entry : header.getEntries()) {
- packages.add(entry.getValue());
- }
- }
- return packages;
- }
-
/**
* Check whether a packages refresh of the supplied bundles would affect targetBundle
*/
- boolean isBundleAffected(Bundle targetBundle, final List<Bundle> bundles) {
- final Set<Long> checkedId = new HashSet<Long>();
- final boolean result = isBundleAffected(checkedId, targetBundle, bundles);
- log.debug("isBundleAffected({}, {}) -> {}", new Object[] { targetBundle, bundles, result});
- return result;
+ boolean isBundleAffected(Bundle target, final List<Bundle> bundles) {
+ log.debug("isBundleAffected({}, {})", target, bundles);
+
+ final List<Long> idChecked = new ArrayList<Long>();
+ for(Bundle b : bundles) {
+ if(dependsOn(idChecked, target, b)) {
+ log.debug("isBundleAffected({}) is true, dependency on bundle {}", target, b);
+ return true;
+ }
+ }
+
+ log.debug("isBundleAffected({}) is false, no dependencies on {}", target, bundles);
+ return false;
}
- private boolean isBundleAffected(Set<Long> checkedId, Bundle targetBundle, final List<Bundle> bundles) {
+ /** True if target depends on source via package imports */
+ private boolean dependsOn(List<Long> idChecked, Bundle target, Bundle source) {
- // Avoid cycles
- if(checkedId.contains(targetBundle.getBundleId())) {
+ if(idChecked.contains(source.getBundleId())) {
return false;
}
- checkedId.add(targetBundle.getBundleId());
- log.debug("Checking if {} is affected by {}", targetBundle, bundles);
+ idChecked.add(source.getBundleId());
- // ID of bundles that we check against
- final Set<Long> ids = new HashSet<Long>();
- for(final Bundle b : bundles) {
- ids.add(b.getBundleId());
+ final ExportedPackage [] eps = pckAdmin.getExportedPackages(source);
+ if(eps == null) {
+ return false;
}
- // Find all bundles from which we import packages, return true if one of them is in our bundles list,
- // and call this method recursively on them as well.
- // We don't care about possible duplicates in there, will be removed by the above cycle avoidance code.
- for(final String name : getImportPackages(targetBundle)) {
- final ExportedPackage[] pcks = this.pckAdmin.getExportedPackages(name);
- if ( pcks == null ) {
- log.debug("No bundles present that export {}", name);
- } else {
- log.debug("{} imports {}", targetBundle, name);
- for(final ExportedPackage pck : pcks) {
- final Bundle exportingBundle = pck.getExportingBundle();
- log.debug("Checking {} which exports {}", exportingBundle, pck.getName());
- if ( exportingBundle.getBundleId() == 0 || exportingBundle.getBundleId() == targetBundle.getBundleId() ) {
- log.debug("Exporting bundle {} is framework bundle or self, ignored", exportingBundle);
- continue;
- } else if ( ids.contains(exportingBundle.getBundleId()) ) {
- log.debug("Bundle {} affects {} due to package {}, returning true",
- new Object[] { exportingBundle, targetBundle, pck.getName() });
- return true;
- } else if(isBundleAffected(checkedId, exportingBundle, bundles)) {
- log.debug("{} recursively affects {}, returning true", exportingBundle, targetBundle);
- return true;
- }
- log.debug("{} does not affect {}", exportingBundle, targetBundle);
+ for(ExportedPackage ep : eps) {
+ final Bundle [] importers = ep.getImportingBundles();
+ if(importers == null) {
+ continue;
+ }
+ for(Bundle b : importers) {
+ if(b.getBundleId() == target.getBundleId()) {
+ log.debug("{} depends on {} via package {}",
+ new Object[] { target, source, ep.getName() });
+ return true;
+ }
+ if(dependsOn(idChecked, target, b)) {
+ log.debug("{} depends on {} which depends on {}, returning true",
+ new Object[] { target, b, source });
+ return true;
}
}
}
-
+
return false;
}
}
\ No newline at end of file
Modified: sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtilTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtilTest.java?rev=1375615&r1=1375614&r2=1375615&view=diff
==============================================================================
--- sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtilTest.java (original)
+++ sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/util/RefreshDependenciesUtilTest.java Tue Aug 21 15:45:23 2012
@@ -22,16 +22,15 @@ import static org.junit.Assert.assertFal
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.Before;
import org.junit.Test;
import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
@@ -44,65 +43,91 @@ public class RefreshDependenciesUtilTest
private Bundle C;
private Bundle D;
private Bundle E;
+ private Bundle F;
private PackageAdmin pa;
private RefreshDependenciesUtil rdu;
private long counter = 1;
+ private final Map<String, List<Bundle>> importingBundles = new HashMap<String, List<Bundle>>();
+
private Bundle setupBundle(String mockName, String importPackages, final String exportsPackages) {
final Bundle result = jmock.mock(Bundle.class, mockName);
- final Dictionary<Object, Object> headers = new Hashtable<Object, Object>();
- if(importPackages != null) {
- headers.put(Constants.IMPORT_PACKAGE, importPackages);
- }
-
jmock.checking(new Expectations() {{
allowing(result).getBundleId();
will(returnValue(counter++));
-
- allowing(result).getHeaders();
- will(returnValue(headers));
}});
+ if(importPackages != null) {
+ for(String pack : importPackages.split(";")) {
+ List<Bundle> list = importingBundles.get(pack);
+ if(list == null) {
+ list = new ArrayList<Bundle>();
+ importingBundles.put(pack, list);
+ }
+ list.add(result);
+ }
+ }
+
final List<ExportedPackage> eps = new ArrayList<ExportedPackage>();
-
if(exportsPackages != null) {
- final ExportedPackage ep = jmock.mock(ExportedPackage.class, "ExportedPackage" + mockName);
- eps.add(ep);
- jmock.checking(new Expectations() {{
- allowing(ep).getExportingBundle();
- will(returnValue(result));
- allowing(ep).getName();
- will(returnValue(exportsPackages));
- }});
+ for(final String pack : exportsPackages.split(";")) {
+ final ExportedPackage ep = jmock.mock(ExportedPackage.class, "ExportedPackage." + pack + "." + mockName);
+ eps.add(ep);
+ jmock.checking(new Expectations() {{
+ allowing(ep).getImportingBundles();
+ will(returnValue(getImportingBundles(pack)));
+ allowing(ep).getName();
+ will(returnValue(pack));
+ }});
+ }
}
jmock.checking(new Expectations() {{
- allowing(pa).getExportedPackages(exportsPackages);
+ allowing(pa).getExportedPackages(result);
will(returnValue(eps.toArray(new ExportedPackage[]{})));
}});
return result;
}
+ private Bundle [] getImportingBundles(String packageName) {
+ final List<Bundle> list = importingBundles.get(packageName);
+ if(list == null) {
+ return null;
+ } else {
+ return list.toArray(new Bundle[] {});
+ }
+ }
+
@Before
public void setup() {
jmock = new Mockery();
pa = jmock.mock(PackageAdmin.class);
rdu = new RefreshDependenciesUtil(pa);
- // Target depends on A directly and does not depend on B
- target = setupBundle("testTarget", "com.targetImportsOne;com.targetImportsTwo", null);
+ // Test bundle depends on A directly and does not depend on B
+ target = setupBundle("testBundle", "com.targetImportsOne;com.targetImportsTwo", null);
A = setupBundle("A", null, "com.targetImportsOne");
B = setupBundle("B", "some.import", "some.export");
- // Target depends on C which in turns depends on D
+ // Test bundle depends on C which in turns depends on D
C = setupBundle("C", "com.CimportsOne", "com.targetImportsTwo");
D = setupBundle("D", null, "com.CimportsOne");
E = setupBundle("E", null, null);
+
+ // F imports and exports the same packages
+ F = setupBundle("F", "foo", "foo");
}
@Test
+ public void testTargetDependsOnSelf() {
+ final List<Bundle> bundles = new ArrayList<Bundle>();
+ bundles.add(F);
+ assertTrue(rdu.isBundleAffected(F, bundles));
+ }
+
+ @Test
public void testTargetDependsOnBundleA() {
final List<Bundle> bundles = new ArrayList<Bundle>();
bundles.add(A);