Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2011-08-08 19:59:53 +0000
committerThomas Watson2011-08-08 19:59:53 +0000
commitfe711b408d3523f680c4e356221369581057e6ce (patch)
tree124f2ba6848b21717ee17e593201d53d7712d8fc
parenta2cf4324f88e434de94e8904835dfb53fff6916b (diff)
downloadrt.equinox.framework-fe711b408d3523f680c4e356221369581057e6ce.tar.gz
rt.equinox.framework-fe711b408d3523f680c4e356221369581057e6ce.tar.xz
rt.equinox.framework-fe711b408d3523f680c4e356221369581057e6ce.zip
Bug 348967 - Handle new option "managed"v20110808-1537
for org.osgi.framework.bsnversion configuration property
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleInstallUpdateTests.java56
-rw-r--r--bundles/org.eclipse.osgi/.settings/.api_filters7
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java3
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java12
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java118
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/bundle/CollisionHook.java76
6 files changed, 228 insertions, 44 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleInstallUpdateTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleInstallUpdateTests.java
index cd21c1712..43b645e37 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleInstallUpdateTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/BundleInstallUpdateTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 IBM Corporation and others.
+ * Copyright (c) 2009, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,13 +11,16 @@
package org.eclipse.osgi.tests.bundles;
import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Collection;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.osgi.internal.baseadaptor.AdaptorUtil;
import org.eclipse.osgi.tests.OSGiTestsActivator;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
+import org.osgi.framework.*;
+import org.osgi.framework.hooks.bundle.CollisionHook;
public class BundleInstallUpdateTests extends AbstractBundleTests {
public static Test suite() {
@@ -195,4 +198,51 @@ public class BundleInstallUpdateTests extends AbstractBundleTests {
}
}
}
+
+ public void testCollisionHook() throws BundleException, MalformedURLException, IOException {
+ Bundle test1 = installer.installBundle("test");
+ installer.installBundle("test2");
+ try {
+ test1.update(new URL(installer.getBundleLocation("test2")).openStream());
+ fail("Expected to fail to update to another bsn/version that causes collision");
+ } catch (BundleException e) {
+ // expected;
+ }
+ Bundle junk = null;
+ try {
+ junk = OSGiTestsActivator.getContext().installBundle("junk", new URL(installer.getBundleLocation("test2")).openStream());
+ fail("Expected to fail to install duplication bsn/version that causes collision");
+ } catch (BundleException e) {
+ // expected;
+ } finally {
+ if (junk != null)
+ junk.uninstall();
+ junk = null;
+ }
+
+ CollisionHook hook = new CollisionHook() {
+ public void filterCollisions(int operationType, Bundle target, Collection collisionCandidates) {
+ collisionCandidates.clear();
+ }
+ };
+ ServiceRegistration reg = OSGiTestsActivator.getContext().registerService(CollisionHook.class, hook, null);
+ try {
+ try {
+ test1.update(new URL(installer.getBundleLocation("test2")).openStream());
+ } catch (BundleException e) {
+ fail("Expected to succeed in updating to a duplicate bsn/version", e);
+ }
+ try {
+ junk = OSGiTestsActivator.getContext().installBundle("junk", new URL(installer.getBundleLocation("test2")).openStream());
+ } catch (BundleException e) {
+ fail("Expected to succeed to install duplication bsn/version that causes collision", e);
+ } finally {
+ if (junk != null)
+ junk.uninstall();
+ junk = null;
+ }
+ } finally {
+ reg.unregister();
+ }
+ }
}
diff --git a/bundles/org.eclipse.osgi/.settings/.api_filters b/bundles/org.eclipse.osgi/.settings/.api_filters
index a95ba2ca5..57d8c9271 100644
--- a/bundles/org.eclipse.osgi/.settings/.api_filters
+++ b/bundles/org.eclipse.osgi/.settings/.api_filters
@@ -890,6 +890,13 @@
</message_arguments>
</filter>
</resource>
+<resource path="osgi/src/org/osgi/framework/hooks/bundle/CollisionHook.java" type="org.osgi.framework.hooks.bundle.CollisionHook">
+<filter comment="Ignore OSGi API" id="1110441988">
+<message_arguments>
+<message_argument value="org.osgi.framework.hooks.bundle.CollisionHook"/>
+</message_arguments>
+</filter>
+</resource>
<resource path="osgi/src/org/osgi/framework/hooks/bundle/EventHook.java" type="org.osgi.framework.hooks.bundle.EventHook">
<filter comment="Ingore OSGi API." id="1110441988">
<message_arguments>
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
index 36d52ab9a..8acd9a9a2 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
@@ -29,6 +29,7 @@ import org.eclipse.osgi.service.resolver.ResolverError;
import org.eclipse.osgi.signedcontent.*;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
+import org.osgi.framework.hooks.bundle.CollisionHook;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.framework.wiring.*;
@@ -660,7 +661,7 @@ public abstract class AbstractBundle implements Bundle, Comparable<Bundle>, Keye
try {
BundleData newBundleData = storage.begin();
// Must call framework createBundle to check execution environment.
- final AbstractBundle newBundle = framework.createAndVerifyBundle(newBundleData, false);
+ final AbstractBundle newBundle = framework.createAndVerifyBundle(CollisionHook.UPDATING, this, newBundleData, false);
boolean exporting;
int st = getState();
synchronized (bundles) {
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java
index b5dae7fd1..f10edf828 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -68,18 +68,22 @@ public final class BundleRepository {
return bundlesBySymbolicName.get(symbolicName);
}
- public synchronized AbstractBundle getBundle(String symbolicName, Version version) {
+ @SuppressWarnings("unchecked")
+ public synchronized List<AbstractBundle> getBundles(String symbolicName, Version version) {
AbstractBundle[] bundles = getBundles(symbolicName);
+ List<AbstractBundle> result = null;
if (bundles != null) {
if (bundles.length > 0) {
for (int i = 0; i < bundles.length; i++) {
if (bundles[i].getVersion().equals(version)) {
- return bundles[i];
+ if (result == null)
+ result = new ArrayList<AbstractBundle>();
+ result.add(bundles[i]);
}
}
}
}
- return null;
+ return result == null ? Collections.EMPTY_LIST : result;
}
public synchronized void add(AbstractBundle bundle) {
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java
index 297b457a4..050a1954a 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java
@@ -33,8 +33,7 @@ import org.eclipse.osgi.signedcontent.SignedContentFactory;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
-import org.osgi.framework.hooks.bundle.EventHook;
-import org.osgi.framework.hooks.bundle.FindHook;
+import org.osgi.framework.hooks.bundle.*;
import org.osgi.util.tracker.ServiceTracker;
/**
@@ -77,6 +76,10 @@ public class Framework implements EventPublisher, Runnable {
protected StartLevelManager startLevelManager;
/** The ServiceRegistry */
private ServiceRegistry serviceRegistry;
+ private final int BSN_VERSION;
+ private static final int BSN_VERSION_SINGLE = 1;
+ private static final int BSN_VERSION_MULTIPLE = 2;
+ private static final int BSN_VERSION_MANAGED = 3;
/*
* The following maps objects keep track of event listeners
@@ -99,6 +102,7 @@ public class Framework implements EventPublisher, Runnable {
protected static final int BATCHEVENT_END = Integer.MIN_VALUE;
static final String eventHookName = EventHook.class.getName();
static final String findHookName = FindHook.class.getName();
+ static final String collisionHookName = CollisionHook.class.getName();
/** EventManager for event delivery. */
protected EventManager eventManager;
/* Reservation object for install synchronization */
@@ -110,7 +114,6 @@ public class Framework implements EventPublisher, Runnable {
private boolean bootDelegateAll = false;
public final boolean contextBootDelegation = "true".equals(FrameworkProperties.getProperty("osgi.context.bootdelegation", "true")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
public final boolean compatibiltyBootDelegation = "true".equals(FrameworkProperties.getProperty(Constants.OSGI_COMPATIBILITY_BOOTDELEGATION, "true")); //$NON-NLS-1$ //$NON-NLS-2$
- private final boolean allowDuplicateBSNVersion = Constants.FRAMEWORK_BSNVERSION_MULTIPLE.equals(FrameworkProperties.getProperty(Constants.FRAMEWORK_BSNVERSION));
private final boolean allowRefreshDuplicateBSN = Boolean.TRUE.toString().equals(FrameworkProperties.getProperty(Constants.REFRESH_DUPLICATE_BSN, "true")); //$NON-NLS-1$
ClassLoaderDelegateHook[] delegateHooks;
private volatile boolean forcedRestart = false;
@@ -159,20 +162,19 @@ public class Framework implements EventPublisher, Runnable {
*
*/
public Framework(FrameworkAdaptor adaptor) {
- initialize(adaptor);
- }
-
- /**
- * Initialize the framework to an unlaunched state. This method is called
- * by the Framework constructor.
- *
- */
- protected void initialize(FrameworkAdaptor initAdaptor) {
if (Profile.PROFILE && Profile.STARTUP)
Profile.logEnter("Framework.initialze()", null); //$NON-NLS-1$
+ String bsnVersion = FrameworkProperties.getProperty(Constants.FRAMEWORK_BSNVERSION);
+ if (Constants.FRAMEWORK_BSNVERSION_SINGLE.equals(bsnVersion)) {
+ BSN_VERSION = BSN_VERSION_SINGLE;
+ } else if (Constants.FRAMEWORK_BSNVERSION_MULTIPLE.equals(bsnVersion)) {
+ BSN_VERSION = BSN_VERSION_MULTIPLE;
+ } else {
+ BSN_VERSION = BSN_VERSION_MANAGED;
+ }
long start = System.currentTimeMillis();
- this.adaptor = initAdaptor;
- delegateHooks = initAdaptor instanceof BaseAdaptor ? ((BaseAdaptor) initAdaptor).getHookRegistry().getClassLoaderDelegateHooks() : null;
+ this.adaptor = adaptor;
+ delegateHooks = adaptor instanceof BaseAdaptor ? ((BaseAdaptor) adaptor).getHookRegistry().getClassLoaderDelegateHooks() : null;
active = false;
installSecurityManager();
if (Debug.DEBUG_SECURITY) {
@@ -183,11 +185,11 @@ public class Framework implements EventPublisher, Runnable {
// initialize ContextFinder
initializeContextFinder();
/* initialize the adaptor */
- initAdaptor.initialize(this);
+ adaptor.initialize(this);
if (Profile.PROFILE && Profile.STARTUP)
Profile.logTime("Framework.initialze()", "adapter initialized"); //$NON-NLS-1$//$NON-NLS-2$
try {
- initAdaptor.initializeStorage();
+ adaptor.initializeStorage();
} catch (IOException e) /* fatal error */{
throw new RuntimeException(e.getMessage(), e);
}
@@ -197,12 +199,12 @@ public class Framework implements EventPublisher, Runnable {
* This must be done before calling any of the framework getProperty
* methods.
*/
- initializeProperties(initAdaptor.getProperties());
+ initializeProperties(adaptor.getProperties());
/* initialize admin objects */
packageAdmin = new PackageAdminImpl(this);
try {
// always create security admin even with security off
- securityAdmin = new SecurityAdmin(null, this, initAdaptor.getPermissionStorage());
+ securityAdmin = new SecurityAdmin(null, this, adaptor.getPermissionStorage());
} catch (IOException e) /* fatal error */{
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
@@ -227,13 +229,13 @@ public class Framework implements EventPublisher, Runnable {
if (Profile.PROFILE && Profile.STARTUP)
Profile.logTime("Framework.initialze()", "done createSystemBundle"); //$NON-NLS-1$ //$NON-NLS-2$
/* install URLStreamHandlerFactory */
- installURLStreamHandlerFactory(systemBundle.context, initAdaptor);
+ installURLStreamHandlerFactory(systemBundle.context, adaptor);
/* install ContentHandlerFactory for OSGi URLStreamHandler support */
- installContentHandlerFactory(systemBundle.context, initAdaptor);
+ installContentHandlerFactory(systemBundle.context, adaptor);
if (Profile.PROFILE && Profile.STARTUP)
Profile.logTime("Framework.initialze()", "done new URLStream/Content HandlerFactory"); //$NON-NLS-1$//$NON-NLS-2$
/* create bundle objects for all installed bundles. */
- BundleData[] bundleDatas = initAdaptor.getInstalledBundles();
+ BundleData[] bundleDatas = adaptor.getInstalledBundles();
bundles = new BundleRepository(bundleDatas == null ? 10 : bundleDatas.length + 1);
/* add the system bundle to the Bundle Repository */
bundles.add(systemBundle);
@@ -703,14 +705,20 @@ public class Framework implements EventPublisher, Runnable {
/**
* Create a new Bundle object.
- *
* @param bundledata the BundleData of the Bundle to create
*/
- AbstractBundle createAndVerifyBundle(BundleData bundledata, boolean setBundle) throws BundleException {
+ AbstractBundle createAndVerifyBundle(int operationType, Bundle target, BundleData bundledata, boolean setBundle) throws BundleException {
// Check for a bundle already installed with the same symbolic name and version.
- if (!allowDuplicateBSNVersion && bundledata.getSymbolicName() != null) {
- AbstractBundle installedBundle = getBundleBySymbolicName(bundledata.getSymbolicName(), bundledata.getVersion());
- if (installedBundle != null && installedBundle.getBundleId() != bundledata.getBundleID()) {
+ if (BSN_VERSION != BSN_VERSION_MULTIPLE && bundledata.getSymbolicName() != null) {
+ List<AbstractBundle> installedBundles = getBundleBySymbolicName(bundledata.getSymbolicName(), bundledata.getVersion());
+ if (operationType == CollisionHook.UPDATING) {
+ installedBundles.remove(target);
+ }
+ if (BSN_VERSION == BSN_VERSION_MANAGED && !installedBundles.isEmpty()) {
+ notifyCollisionHooks(operationType, target, installedBundles);
+ }
+ if (!installedBundles.isEmpty()) {
+ Bundle installedBundle = installedBundles.iterator().next();
String msg = NLS.bind(Msg.BUNDLE_INSTALL_SAME_UNIQUEID, new Object[] {installedBundle.getSymbolicName(), installedBundle.getVersion().toString(), installedBundle.getLocation()});
throw new DuplicateBundleException(msg, installedBundle);
}
@@ -825,7 +833,7 @@ public class Framework implements EventPublisher, Runnable {
* then the location is used to get the bundle content.
* @return The Bundle of the installed bundle.
*/
- AbstractBundle installBundle(final String location, final InputStream in, BundleContext origin) throws BundleException {
+ AbstractBundle installBundle(final String location, final InputStream in, final BundleContextImpl origin) throws BundleException {
if (Debug.DEBUG_GENERAL) {
Debug.println("install from inputstream: " + location + ", " + in); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -835,7 +843,7 @@ public class Framework implements EventPublisher, Runnable {
/* Map the InputStream or location to a URLConnection */
URLConnection source = in != null ? new BundleSource(in) : adaptor.mapLocationToURLConnection(location);
/* call the worker to install the bundle */
- return installWorkerPrivileged(location, source, callerContext);
+ return installWorkerPrivileged(location, source, callerContext, origin);
}
}, origin);
}
@@ -919,16 +927,20 @@ public class Framework implements EventPublisher, Runnable {
* The location identifier of the bundle to install.
* @param source
* The URLConnection from which the bundle will be read.
+ * @param callerContext
+ * The caller access control context
+ * @param origin
+ * The origin bundle context that is installing the the bundle
* @return The {@link AbstractBundle}of the installed bundle.
* @exception BundleException
* If the provided stream cannot be read.
*/
- protected AbstractBundle installWorkerPrivileged(String location, URLConnection source, AccessControlContext callerContext) throws BundleException {
+ protected AbstractBundle installWorkerPrivileged(String location, URLConnection source, AccessControlContext callerContext, BundleContextImpl origin) throws BundleException {
BundleOperation storage = adaptor.installBundle(location, source);
final AbstractBundle bundle;
try {
BundleData bundledata = storage.begin();
- bundle = createAndVerifyBundle(bundledata, true);
+ bundle = createAndVerifyBundle(CollisionHook.INSTALLING, origin.getBundle(), bundledata, true);
BundleWatcher bundleStats = adaptor.getBundleWatcher();
if (bundleStats != null)
@@ -1022,17 +1034,16 @@ public class Framework implements EventPublisher, Runnable {
}
/**
- * Retrieve the bundle that has the given symbolic name and version.
+ * Retrieve the bundles that has the given symbolic name and version.
*
* @param symbolicName
* The symbolic name of the bundle to retrieve
* @param version The version of the bundle to retrieve
- * @return A {@link AbstractBundle}object, or <code>null</code> if the
- * identifier doesn't match any installed bundle.
+ * @return A collection of {@link AbstractBundle} that match the symbolic name and version
*/
- public AbstractBundle getBundleBySymbolicName(String symbolicName, Version version) {
+ public List<AbstractBundle> getBundleBySymbolicName(String symbolicName, Version version) {
synchronized (bundles) {
- return bundles.getBundle(symbolicName, version);
+ return bundles.getBundles(symbolicName, version);
}
}
@@ -1113,6 +1124,41 @@ public class Framework implements EventPublisher, Runnable {
});
}
+ private void notifyCollisionHooks(final int operationType, final Bundle target, List<AbstractBundle> collisionCandidates) {
+ final Collection<Bundle> shrinkable = new ShrinkableCollection<Bundle>(collisionCandidates);
+ if (System.getSecurityManager() == null) {
+ notifyCollisionHooksPriviledged(operationType, target, shrinkable);
+ } else {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ notifyCollisionHooksPriviledged(operationType, target, shrinkable);
+ return null;
+ }
+ });
+ }
+ }
+
+ void notifyCollisionHooksPriviledged(final int operationType, final Bundle target, final Collection<Bundle> collisionCandidates) {
+ if (Debug.DEBUG_HOOKS) {
+ Debug.println("notifyCollisionHooks(" + operationType + ", " + target + ", " + collisionCandidates + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+ getServiceRegistry().notifyHooksPrivileged(new HookContext() {
+ public void call(Object hook, ServiceRegistration<?> hookRegistration) throws Exception {
+ if (hook instanceof CollisionHook) {
+ ((CollisionHook) hook).filterCollisions(operationType, target, collisionCandidates);
+ }
+ }
+
+ public String getHookClassName() {
+ return collisionHookName;
+ }
+
+ public String getHookMethodName() {
+ return "filterCollisions"; //$NON-NLS-1$
+ }
+ });
+ }
+
/**
* Resume a bundle.
*
@@ -1209,7 +1255,7 @@ public class Framework implements EventPublisher, Runnable {
* @param symbolicName
* The symbolic name for the bundle
* @return Bundle object for bundle with the specified Unique or null if no
- * bundle is installed with the specified location.
+ * bundle is installed with the specified symbolicName.
*/
protected AbstractBundle[] getBundleBySymbolicName(String symbolicName) {
synchronized (bundles) {
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/bundle/CollisionHook.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/bundle/CollisionHook.java
new file mode 100644
index 000000000..94dabb724
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/bundle/CollisionHook.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.framework.hooks.bundle;
+
+import java.util.Collection;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * OSGi Framework Bundle Collision Hook Service.
+ *
+ * <p>
+ * Bundles registering this service will be called during framework bundle
+ * install and update operations to determine if an install or update
+ * operation will result in a bundle symbolic name and version collision.
+ *
+ * @ThreadSafe
+ * @version $Id: 64a98074fa8331b0cd21989f9c8583b99b2370cf $
+ */
+public interface CollisionHook {
+
+ /**
+ * Specifies a bundle install operation is being performed.
+ */
+ public static final int INSTALLING = 0x01;
+ /**
+ * Specifies a bundle update operation is being performed.
+ */
+ public static final int UPDATING = 0x02;
+
+ /**
+ * Filter bundle collisions hook method. This method is called during the
+ * install or update operation. The operation type will be
+ * {@link #INSTALLING installing} or
+ * {@link #UPDATING updating}. Depending on the operation
+ * type the target bundle and the collision candidate collection are the following:
+ * <ul>
+ * <li> {@link #INSTALLING installing} - The target is the bundle associated with the
+ * {@link BundleContext} used to call one of the
+ * {@link BundleContext#installBundle(String) install}
+ * methods. The collision candidate collection contains the existing bundles
+ * installed which have the same symbolic name and version as the bundle being installed.
+ * <li> {@link #UPDATING updating} - The target is the bundle used to call one of the
+ * {@link Bundle#update() update} methods. The collision candidate collection
+ * contains the existing bundles installed which have the same symbolic name and version
+ * as the content the target bundle is being updated to.
+ * </ul>
+ * This method can filter the list of collision candidates by removing
+ * potential collisions. Removing a collision candidate will allow the
+ * specified operation to succeed as if the collision candidate is not installed.
+ *
+ * @param operationType the operation type. Must be the value of
+ * {@link #INSTALLING installing} or {@link #UPDATING updating}.
+ * @param target the target bundle used to determine what collision candidates to filter.
+ * @param collisionCandidates a collection of collision candidates.
+ * The collection supports all the optional {@code Collection}
+ * operations except {@code add} and {@code addAll}. Attempting
+ * to add to the collection will result in an
+ * {@code UnsupportedOperationException}. The collection is not
+ * synchronized.
+ */
+ void filterCollisions(int operationType, Bundle target, Collection<Bundle> collisionCandidates);
+}

Back to the top