Initial pass at implementing FrameworkWiringImpl. More stress testing is likely
needed, but most of the code was simply stolen from the related PackageAdmin
implementation. (FELIX-2969)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1126616 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index a9d65f0..6a519f3 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -74,6 +74,7 @@
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.FrameworkWiring;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.startlevel.StartLevel;
@@ -85,6 +86,9 @@
// The extension manager to handle extension bundles
private final ExtensionManager m_extensionManager;
+ // Framework wiring object.
+ private final FrameworkWiringImpl m_fwkWiring;
+
// Logging related member variables.
private final Logger m_logger;
// Immutable config properties.
@@ -168,7 +172,7 @@
// Shutdown gate.
private volatile ThreadGate m_shutdownGate = null;
-
+
// Security Manager created by the framework
private SecurityManager m_securityManager = null;
@@ -384,6 +388,9 @@
// a runtime exception.
throw new RuntimeException(ex.getMessage());
}
+
+ // Create framework wiring object.
+ m_fwkWiring = new FrameworkWiringImpl(this);
}
Logger getLogger()
@@ -450,6 +457,16 @@
return this;
}
+ @Override
+ public <A> A adapt(Class<A> type)
+ {
+ if (type == FrameworkWiring.class)
+ {
+ return (A) m_fwkWiring;
+ }
+ return super.adapt(type);
+ }
+
public long getBundleId()
{
return 0;
@@ -550,10 +567,10 @@
if (Constants.FRAMEWORK_SECURITY_OSGI.equalsIgnoreCase(security) || (security.length() == 0))
{
// TODO: SECURITY - we only need our own security manager to convert the exceptions
- // because the 4.2.0 ct does expect them like this in one case.
+ // because the 4.2.0 ct does expect them like this in one case.
System.setSecurityManager(m_securityManager = new SecurityManager()
{
- public void checkPermission(Permission perm)
+ public void checkPermission(Permission perm)
{
try
{
@@ -570,11 +587,11 @@
}
else
{
- try
+ try
{
- System.setSecurityManager(m_securityManager =
+ System.setSecurityManager(m_securityManager =
(SecurityManager) Class.forName(security).newInstance());
- }
+ }
catch (Throwable t)
{
SecurityException se =
@@ -1595,7 +1612,9 @@
BundleImpl bundle, String path, String filePattern, boolean recurse)
{
// Try to resolve the bundle per the spec.
- resolveBundles(new Bundle[] { bundle });
+ List<Bundle> list = new ArrayList<Bundle>(1);
+ list.add(bundle);
+ resolveBundles(list);
// Get the entry enumeration from the revision content and
// create a wrapper enumeration to filter it.
@@ -2159,7 +2178,9 @@
{
try
{
- refreshPackages(new BundleImpl[] { bundle });
+ List<Bundle> list = new ArrayList<Bundle>(1);
+ list.add(bundle);
+ refreshPackages(list, null);
}
catch (Exception ex)
{
@@ -2499,7 +2520,9 @@
{
try
{
- refreshPackages(new BundleImpl[] { bundle });
+ List<Bundle> list = new ArrayList<Bundle>(1);
+ list.add(bundle);
+ refreshPackages(list, null);
}
catch (Exception ex)
{
@@ -3483,7 +3506,7 @@
return m_dependencies.getRequiringBundles(bundle);
}
- boolean resolveBundles(Bundle[] targets)
+ boolean resolveBundles(Collection<Bundle> targets)
{
// Acquire global lock.
boolean locked = acquireGlobalLock();
@@ -3502,7 +3525,7 @@
// specified bundles or all bundles if null.
if (targets == null)
{
- List list = new ArrayList();
+ targets = new ArrayList<Bundle>();
// Add all unresolved bundles to the list.
Iterator iter = m_installedBundles[LOCATION_MAP_IDX].values().iterator();
@@ -3511,30 +3534,27 @@
BundleImpl bundle = (BundleImpl) iter.next();
if (bundle.getState() == Bundle.INSTALLED)
{
- list.add(bundle);
+ targets.add(bundle);
}
}
-
- // Create an array.
- if (list.size() > 0)
- {
- targets = (Bundle[]) list.toArray(new BundleImpl[list.size()]);
- }
}
// Now resolve each target bundle.
boolean result = true;
// If there are targets, then resolve each one.
- for (int i = 0; (targets != null) && (i < targets.length); i++)
+ if (!targets.isEmpty())
{
- try
+ for (Bundle b : targets)
{
- resolveBundle((BundleImpl) targets[i]);
- }
- catch (BundleException ex)
- {
- result = false;
+ try
+ {
+ resolveBundle((BundleImpl) b);
+ }
+ catch (BundleException ex)
+ {
+ result = false;
+ }
}
}
@@ -3569,7 +3589,7 @@
}
}
- void refreshPackages(Bundle[] targets)
+ void refreshPackages(Collection<Bundle> targets, FrameworkListener[] listeners)
{
// Acquire global lock.
boolean locked = acquireGlobalLock();
@@ -3587,10 +3607,10 @@
// Determine set of bundles to refresh, which is all transitive
// dependencies of specified set or all transitive dependencies
// of all bundles if null is specified.
- Bundle[] newTargets = targets;
+ Collection<Bundle> newTargets = targets;
if (newTargets == null)
{
- List list = new ArrayList();
+ List<Bundle> list = new ArrayList<Bundle>();
// First add all uninstalled bundles.
for (int i = 0;
@@ -3611,31 +3631,27 @@
}
}
- // Create an array.
- if (list.size() > 0)
+ if (!list.isEmpty())
{
- newTargets = (Bundle[]) list.toArray(new Bundle[list.size()]);
+ newTargets = list;
}
}
// If there are targets, then find all dependencies for each one.
- BundleImpl[] bundles = null;
+ Set<Bundle> bundles = null;
if (newTargets != null)
{
// Create map of bundles that import the packages
// from the target bundles.
- Set<Bundle> set = new HashSet<Bundle>();
- for (int targetIdx = 0; targetIdx < newTargets.length; targetIdx++)
+ bundles = new HashSet<Bundle>();
+ for (Bundle target : newTargets)
{
// Add the current target bundle to the map of
// bundles to be refreshed.
- BundleImpl target = (BundleImpl) newTargets[targetIdx];
- set.add(target);
+ bundles.add(target);
// Add all importing bundles to map.
- populateDependentGraph(target, set);
+ populateDependentGraph((BundleImpl) target, bundles);
}
-
- bundles = (BundleImpl[]) set.toArray(new BundleImpl[set.size()]);
}
// Now refresh each bundle.
@@ -3648,62 +3664,61 @@
// We need to restart the framework if either an extension bundle is
// refreshed or the system bundle is refreshed and any extension bundle
// has been updated or uninstalled.
- for (int i = 0; (bundles != null) && !restart && (i < bundles.length); i++)
- {
- if (systemBundle == bundles[i])
- {
- Bundle[] allBundles = getBundles();
- for (int j = 0; !restart && j < allBundles.length; j++)
- {
- if (((BundleImpl) allBundles[j]).isExtension() &&
- (allBundles[j].getState() == Bundle.INSTALLED))
- {
- restart = true;
- }
- }
- }
- }
-
- // Remove any targeted bundles from the uninstalled bundles
- // array, since they will be removed from the system after
- // the refresh.
- // TODO: FRAMEWORK - Is this correct?
- for (int i = 0; (bundles != null) && (i < bundles.length); i++)
- {
- forgetUninstalledBundle(bundles[i]);
- }
- // If there are targets, then refresh each one.
if (bundles != null)
{
- // At this point the map contains every bundle that has been
- // updated and/or removed as well as all bundles that import
+ for (Bundle b : bundles)
+ {
+ if (systemBundle == b)
+ {
+ Bundle[] allBundles = getBundles();
+ for (int j = 0; !restart && j < allBundles.length; j++)
+ {
+ if (((BundleImpl) allBundles[j]).isExtension() &&
+ (allBundles[j].getState() == Bundle.INSTALLED))
+ {
+ restart = true;
+ break;
+ }
+ }
+ }
+
+ // Remove any targeted bundles from the uninstalled bundles
+ // array, since they will be removed from the system after
+ // the refresh.
+ // TODO: FRAMEWORK - Is this correct?
+ forgetUninstalledBundle((BundleImpl) b);
+ }
+
+ // Now we actually need to refresh the affected bundles.
+ // At this point the collection contains every bundle that has
+ // been updated and/or removed as well as all bundles that import
// packages from these bundles.
// Create refresh helpers for each bundle.
- RefreshHelper[] helpers = new RefreshHelper[bundles.length];
- for (int i = 0; i < bundles.length; i++)
+ List<RefreshHelper> helpers = new ArrayList<RefreshHelper>(bundles.size());
+ for (Bundle b : bundles)
{
- helpers[i] = new RefreshHelper(bundles[i]);
+ helpers.add(new RefreshHelper(b));
}
// Stop, purge or remove, and reinitialize all bundles first.
// TODO: FRAMEWORK - this will stop the system bundle if
// somebody called refresh 0. Is this what we want?
- for (int i = 0; i < helpers.length; i++)
+ for (RefreshHelper helper : helpers)
{
- if (helpers[i] != null)
+ if (helper != null)
{
- helpers[i].stop();
- helpers[i].refreshOrRemove();
+ helper.stop();
+ helper.refreshOrRemove();
}
}
// Then restart all bundles that were previously running.
- for (int i = 0; i < helpers.length; i++)
+ for (RefreshHelper helper : helpers)
{
- if (helpers[i] != null)
+ if (helper != null)
{
- helpers[i].restart();
+ helper.restart();
}
}
}
@@ -3727,8 +3742,69 @@
}
fireFrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, this, null);
+
+ if (listeners != null)
+ {
+ FrameworkEvent event = new FrameworkEvent(
+ FrameworkEvent.PACKAGES_REFRESHED, this, null);
+ for (FrameworkListener l : listeners)
+ {
+ try
+ {
+ l.frameworkEvent(event);
+ }
+ catch (Throwable th)
+ {
+ m_logger.log(Logger.LOG_ERROR,
+ "Framework listener delivery error.", th);
+ }
+ }
+ }
}
+ Collection<Bundle> getDependencyClosure(Collection<Bundle> targets)
+ {
+ // Acquire global lock.
+ boolean locked = acquireGlobalLock();
+ if (!locked)
+ {
+ // If the thread calling holds bundle locks, then we might not
+ // be able to get the global lock. However, in practice this
+ // should not happen since the calls to this method have either
+ // already acquired the global lock or it is PackageAdmin which
+ // doesn't hold bundle locks.
+ throw new IllegalStateException(
+ "Unable to acquire global lock for refresh.");
+ }
+
+ try
+ {
+ // If there are targets, then find all dependencies for each one.
+ Set<Bundle> bundles = Collections.EMPTY_SET;
+ if (targets != null)
+ {
+ // Create map of bundles that import the packages
+ // from the target bundles.
+ bundles = new HashSet<Bundle>();
+ for (Bundle target : targets)
+ {
+ // Add the current target bundle to the map of
+ // bundles to be refreshed.
+ bundles.add(target);
+ // Add all importing bundles to map.
+ populateDependentGraph((BundleImpl) target, bundles);
+ }
+ }
+ return bundles;
+ }
+ finally
+ {
+ // Always release the global lock.
+ releaseGlobalLock();
+ }
+ }
+
+ // Calls to this method must have the global lock.
private void populateDependentGraph(BundleImpl exporter, Set<Bundle> set)
{
// Get all dependent bundles of this bundle.
@@ -3750,6 +3826,47 @@
}
}
+ Collection<Bundle> getRemovalPendingBundles()
+ {
+ // Acquire global lock.
+ boolean locked = acquireGlobalLock();
+ if (!locked)
+ {
+ // If the thread calling holds bundle locks, then we might not
+ // be able to get the global lock. However, in practice this
+ // should not happen since the calls to this method have either
+ // already acquired the global lock or it is PackageAdmin which
+ // doesn't hold bundle locks.
+ throw new IllegalStateException(
+ "Unable to acquire global lock for refresh.");
+ }
+
+ try
+ {
+ List<Bundle> bundles = new ArrayList<Bundle>();
+ if (m_uninstalledBundles != null)
+ {
+ for (Bundle b : m_uninstalledBundles)
+ {
+ bundles.add(b);
+ }
+ }
+ for (Bundle b : getBundles())
+ {
+ if (((BundleImpl) b).isRemovalPending())
+ {
+ bundles.add(b);
+ }
+ }
+ return bundles;
+ }
+ finally
+ {
+ // Always release the global lock.
+ releaseGlobalLock();
+ }
+ }
+
//
// Miscellaneous private methods.
//
@@ -4473,7 +4590,7 @@
// Mark revision as resolved.
revision.resolve(entry.getValue());
-
+
// Update resolver state to remove substituted capabilities.
if (!Util.isFragment(revision))
{
@@ -4666,6 +4783,9 @@
// Should never happen.
}
+ // Stop framework wiring thread.
+ m_fwkWiring.stop();
+
// Shutdown event dispatching queue.
EventDispatcher.shutdown();
@@ -5181,17 +5301,17 @@
}
private volatile URLHandlersActivator m_urlHandlersActivator;
-
+
void setURLHandlersActivator(URLHandlersActivator urlHandlersActivator)
{
m_urlHandlersActivator = urlHandlersActivator;
}
-
+
Object getStreamHandlerService(String protocol)
{
return m_urlHandlersActivator.getStreamHandlerService(protocol);
}
-
+
Object getContentHandlerService(String mimeType)
{
return m_urlHandlersActivator.getContentHandlerService(mimeType);
diff --git a/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
new file mode 100644
index 0000000..3f8c8a0
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.felix.framework;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.osgi.framework.AdminPermission;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+class FrameworkWiringImpl implements FrameworkWiring, Runnable
+{
+ private final Felix m_felix;
+ private List<Collection<Bundle>> m_requests = null;
+ private List<FrameworkListener[]> m_requestListeners = null;
+ private Thread m_thread = null;
+
+ public FrameworkWiringImpl(Felix felix)
+ {
+ m_felix = felix;
+ }
+
+ /**
+ * Stops the FelixFrameworkWiring thread on system shutdown. Shutting down the
+ * thread explicitly is required in the embedded case, where Felix may be
+ * stopped without the Java VM being stopped. In this case the
+ * FelixFrameworkWiring thread must be stopped explicitly.
+ * <p>
+ * This method is called by the
+ * {@link PackageAdminActivator#stop(BundleContext)} method.
+ */
+ synchronized void stop()
+ {
+ if (m_thread != null)
+ {
+ // Null thread variable to signal to the thread that
+ // we want it to exit.
+ m_thread = null;
+
+ // Wake up the thread, if it is currently in the wait() state
+ // for more work.
+ notifyAll();
+ }
+ }
+
+ public Bundle getBundle()
+ {
+ return m_felix;
+ }
+
+ public void refreshBundles(Collection<Bundle> bundles, FrameworkListener... listeners)
+ {
+ Object sm = System.getSecurityManager();
+
+ if (sm != null)
+ {
+ ((SecurityManager) sm).checkPermission(
+ new AdminPermission(m_felix, AdminPermission.RESOLVE));
+ }
+ synchronized (this)
+ {
+ // Start a thread to perform asynchronous package refreshes.
+ if (m_thread == null)
+ {
+ m_thread = new Thread(this, "FelixFrameworkWiring");
+ m_thread.setDaemon(true);
+ m_thread.start();
+ }
+
+ // Save our request parameters and notify all.
+ if (m_requests == null)
+ {
+ List<Collection<Bundle>> requests = new ArrayList<Collection<Bundle>>();
+ requests.add(bundles);
+ m_requests = requests;
+ List<FrameworkListener[]> requestListeners =
+ new ArrayList<FrameworkListener[]>();
+ requestListeners.add(listeners);
+ m_requestListeners = requestListeners;
+ }
+ else
+ {
+ m_requests.add(bundles);
+ }
+ notifyAll();
+ }
+ }
+
+ public boolean resolveBundles(Collection<Bundle> bundles)
+ {
+ Object sm = System.getSecurityManager();
+
+ if (sm != null)
+ {
+ ((SecurityManager) sm).checkPermission(
+ new AdminPermission(m_felix, AdminPermission.RESOLVE));
+ }
+
+ return m_felix.resolveBundles(bundles);
+ }
+
+ public Collection<Bundle> getRemovalPendingBundles()
+ {
+ return m_felix.getRemovalPendingBundles();
+ }
+
+ public Collection<Bundle> getDependencyClosure(Collection<Bundle> targets)
+ {
+ return m_felix.getDependencyClosure(targets);
+ }
+
+ /**
+ * The OSGi specification states that package refreshes happen
+ * asynchronously; this is the run() method for the package
+ * refreshing thread.
+ **/
+ public void run()
+ {
+ // This thread loops forever, thus it should
+ // be a daemon thread.
+ while (true)
+ {
+ Collection<Bundle> bundles = null;
+ FrameworkListener[] listeners = null;
+ synchronized (this)
+ {
+ // Wait for a refresh request.
+ while (m_requests == null)
+ {
+ // Terminate the thread if requested to do so (see stop()).
+ if (m_thread == null)
+ {
+ return;
+ }
+
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException ex)
+ {
+ }
+ }
+
+ // Get the bundles parameter for the current refresh request.
+ bundles = m_requests.get(0);
+ listeners = m_requestListeners.get(0);
+ }
+
+ // Perform refresh.
+ // NOTE: We don't catch any exceptions here, because
+ // the invoked method shields us from exceptions by
+ // catching Throwables when its invokes callbacks.
+ m_felix.refreshPackages(bundles, listeners);
+
+ // Remove the first request since it is now completed.
+ synchronized (this)
+ {
+ m_requests.remove(0);
+ m_requestListeners.remove(0);
+ if (m_requests.isEmpty())
+ {
+ m_requests = null;
+ m_requestListeners = null;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
index 5e9175e..786c6b4 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -42,6 +42,5 @@
public void stop(BundleContext context) throws Exception
{
m_reg.unregister();
- m_packageAdmin.stop();
}
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
index 73ae668..ef1ca60 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -27,12 +27,13 @@
import org.osgi.framework.Version;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.FrameworkWiring;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.packageadmin.RequiredBundle;
-class PackageAdminImpl implements PackageAdmin, Runnable
+class PackageAdminImpl implements PackageAdmin
{
private static final Comparator COMPARATOR = new Comparator() {
public int compare(Object o1, Object o2)
@@ -44,48 +45,16 @@
};
private Felix m_felix = null;
- private Bundle[][] m_reqBundles = null;
- private Bundle m_systemBundle = null;
- private Thread m_thread = null;
public PackageAdminImpl(Felix felix)
{
m_felix = felix;
- m_systemBundle = m_felix.getBundle(0);
-
- // Start a thread to perform asynchronous package refreshes.
- m_thread = new Thread(this, "FelixPackageAdmin");
- m_thread.setDaemon(true);
- m_thread.start();
}
/**
- * Stops the FelixPackageAdmin thread on system shutdown. Shutting down the
- * thread explicitly is required in the embedded case, where Felix may be
- * stopped without the Java VM being stopped. In this case the
- * FelixPackageAdmin thread must be stopped explicitly.
- * <p>
- * This method is called by the
- * {@link PackageAdminActivator#stop(BundleContext)} method.
- */
- synchronized void stop()
- {
- if (m_thread != null)
- {
- // Null thread variable to signal to the thread that
- // we want it to exit.
- m_thread = null;
-
- // Wake up the thread, if it is currently in the wait() state
- // for more work.
- notifyAll();
- }
- }
-
- /**
* Returns the bundle associated with this class if the class was
* loaded from a bundle, otherwise returns null.
- *
+ *
* @param clazz the class for which to determine its associated bundle.
* @return the bundle associated with the specified class, otherwise null.
**/
@@ -99,7 +68,7 @@
* version is in the specified version range. If no version range is
* specified, then all bundles with the specified symbolic name are
* returned. The array is sorted in descending version order.
- *
+ *
* @param symbolicName the target symbolic name.
* @param versionRange the target version range.
* @return an array of matching bundles sorted in descending version order.
@@ -121,7 +90,7 @@
}
}
}
- if (list.size() == 0)
+ if (list.isEmpty())
{
return null;
}
@@ -279,102 +248,17 @@
public void refreshPackages(Bundle[] bundles)
throws SecurityException
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(m_systemBundle, AdminPermission.RESOLVE));
- }
- synchronized (this)
- {
- // Save our request parameters and notify all.
- if (m_reqBundles == null)
- {
- m_reqBundles = new Bundle[][] { bundles };
- }
- else
- {
- Bundle[][] newReqBundles = new Bundle[m_reqBundles.length + 1][];
- System.arraycopy(m_reqBundles, 0,
- newReqBundles, 0, m_reqBundles.length);
- newReqBundles[m_reqBundles.length] = bundles;
- m_reqBundles = newReqBundles;
- }
- notifyAll();
- }
+ List<Bundle> list = (bundles == null)
+ ? null
+ : Arrays.asList(bundles);
+ m_felix.adapt(FrameworkWiring.class).refreshBundles(list);
}
public boolean resolveBundles(Bundle[] bundles)
{
- Object sm = System.getSecurityManager();
-
- if (sm != null)
- {
- ((SecurityManager) sm).checkPermission(
- new AdminPermission(m_systemBundle, AdminPermission.RESOLVE));
- }
-
- return m_felix.resolveBundles(bundles);
- }
-
- /**
- * The OSGi specification states that package refreshes happen
- * asynchronously; this is the run() method for the package
- * refreshing thread.
- **/
- public void run()
- {
- // This thread loops forever, thus it should
- // be a daemon thread.
- while (true)
- {
- Bundle[] bundles = null;
- synchronized (this)
- {
- // Wait for a refresh request.
- while (m_reqBundles == null)
- {
- // Terminate the thread if requested to do so (see stop()).
- if (m_thread == null)
- {
- return;
- }
-
- try
- {
- wait();
- }
- catch (InterruptedException ex)
- {
- }
- }
-
- // Get the bundles parameter for the current refresh request.
- bundles = m_reqBundles[0];
- }
-
- // Perform refresh.
- // NOTE: We don't catch any exceptions here, because
- // the invoked method shields us from exceptions by
- // catching Throwables when its invokes callbacks.
- m_felix.refreshPackages(bundles);
-
- // Remove the first request since it is now completed.
- synchronized (this)
- {
- if (m_reqBundles.length == 1)
- {
- m_reqBundles = null;
- }
- else
- {
- Bundle[][] newReqBundles = new Bundle[m_reqBundles.length - 1][];
- System.arraycopy(m_reqBundles, 1,
- newReqBundles, 0, m_reqBundles.length - 1);
- m_reqBundles = newReqBundles;
- }
- }
- }
+ List<Bundle> list = (bundles == null)
+ ? null
+ : Arrays.asList(bundles);
+ return m_felix.adapt(FrameworkWiring.class).resolveBundles(list);
}
}
\ No newline at end of file