Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.e4.core.di.extensions/src/org/eclipse/e4/core/di/internal/extensions/BundleContextObjectSupplier.java')
-rw-r--r--bundles/org.eclipse.e4.core.di.extensions/src/org/eclipse/e4/core/di/internal/extensions/BundleContextObjectSupplier.java84
1 files changed, 84 insertions, 0 deletions
diff --git a/bundles/org.eclipse.e4.core.di.extensions/src/org/eclipse/e4/core/di/internal/extensions/BundleContextObjectSupplier.java b/bundles/org.eclipse.e4.core.di.extensions/src/org/eclipse/e4/core/di/internal/extensions/BundleContextObjectSupplier.java
new file mode 100644
index 000000000..f2547e422
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.di.extensions/src/org/eclipse/e4/core/di/internal/extensions/BundleContextObjectSupplier.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Markus Alexander Kuppe 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 http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.core.di.internal.extensions;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.e4.core.di.InjectionException;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier;
+import org.eclipse.e4.core.di.suppliers.IObjectDescriptor;
+import org.eclipse.e4.core.di.suppliers.IRequestor;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.SynchronousBundleListener;
+
+public class BundleContextObjectSupplier extends ExtendedObjectSupplier {
+
+ /**
+ * A Map of Requestor to BundleListener. Each Requestor will only ever request its own bundle and thus there is a 1:1 relationship between R and BL.
+ */
+ private final Map<IRequestor, BundleListener> requestor2listener = new HashMap<IRequestor, BundleListener>();
+
+ private final BundleContext localBundleContext = FrameworkUtil.getBundle(BundleContextObjectSupplier.class).getBundleContext();
+
+ @Override
+ public Object get(IObjectDescriptor descriptor, IRequestor requestor, boolean track, boolean group) {
+ final Class<?> requestingObjectClass = requestor.getRequestingObjectClass();
+ final Bundle bundle = FrameworkUtil.getBundle(requestingObjectClass);
+
+ // Cannot use BundleListener as a BL can only be registered with a BC (which might be null)
+ if (track) {
+ if (!requestor2listener.containsKey(requestor)) {
+ track(bundle, requestor);
+ }
+ } else {
+ untrack(requestor);
+ }
+
+ final BundleContext bundleContext = bundle.getBundleContext();
+ if (bundleContext != null) {
+ return bundleContext;
+ } else if (descriptor.getQualifier(Optional.class) != null) {
+ // Do not have a bundle context but requestor has marked the parameter/field optional
+ return null;
+ }
+ throw new InjectionException("Unable to inject BundleContext: " + bundle.getSymbolicName() + " bundle is not active or starting/stopping"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private void untrack(final IRequestor requestor) {
+ synchronized (requestor2listener) {
+ BundleListener l = requestor2listener.remove(requestor);
+ localBundleContext.removeBundleListener(l);
+ }
+ }
+
+ private void track(final Bundle bundle, final IRequestor requestor) {
+ // A _synchronous_ BundleListener asserts that the BC is un-injected,
+ // _before_ it becomes invalid (state-wise).
+ BundleListener listener = new SynchronousBundleListener() {
+ public void bundleChanged(BundleEvent event) {
+ if (event.getBundle().equals(bundle)) {
+ if (requestor.isValid()) {
+ requestor.resolveArguments(false);
+ requestor.execute();
+ }
+ }
+ }
+ };
+ synchronized (requestor2listener) {
+ localBundleContext.addBundleListener(listener);
+ requestor2listener.put(requestor, listener);
+ }
+ }
+}

Back to the top