summaryrefslogtreecommitdiffstats
path: root/jdisc_core/src/main/java/com/yahoo/jdisc/application/BundleInstaller.java
diff options
context:
space:
mode:
Diffstat (limited to 'jdisc_core/src/main/java/com/yahoo/jdisc/application/BundleInstaller.java')
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/application/BundleInstaller.java86
1 files changed, 86 insertions, 0 deletions
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/application/BundleInstaller.java b/jdisc_core/src/main/java/com/yahoo/jdisc/application/BundleInstaller.java
new file mode 100644
index 00000000000..273d29e8dfb
--- /dev/null
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/application/BundleInstaller.java
@@ -0,0 +1,86 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc.application;
+
+import com.google.inject.Inject;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * <p>This is a utility class to help with installing, starting, stopping and uninstalling OSGi Bundles. You can choose
+ * to inject an instance of this class, or it can be created explicitly by reference to a {@link OsgiFramework}.</p>
+ *
+ * <p>Please see commentary on {@link OsgiFramework#installBundle(String)} for a description of exception-safety issues
+ * to consider when installing bundles that use the {@link OsgiHeader#PREINSTALL_BUNDLE} manifest instruction.</p>
+ *
+ * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ */
+public final class BundleInstaller {
+
+ private final OsgiFramework osgiFramework;
+
+ @Inject
+ public BundleInstaller(OsgiFramework osgiFramework) {
+ this.osgiFramework = osgiFramework;
+ }
+
+ public List<Bundle> installAndStart(String... locations) throws BundleException {
+ return installAndStart(Arrays.asList(locations));
+ }
+
+ public List<Bundle> installAndStart(Iterable<String> locations) throws BundleException {
+ List<Bundle> bundles = new LinkedList<>();
+ try {
+ for (String location : locations) {
+ bundles.addAll(osgiFramework.installBundle(location));
+ }
+ } catch (BundleInstallationException e) {
+ bundles.addAll(e.installedBundles());
+ throw new BundleInstallationException(bundles, e);
+ } catch (Exception e) {
+ throw new BundleInstallationException(bundles, e);
+ }
+ try {
+ for (Bundle bundle : bundles) {
+ start(bundle);
+ }
+ } catch (Exception e) {
+ throw new BundleInstallationException(bundles, e);
+ }
+ return bundles;
+ }
+
+ public void stopAndUninstall(Bundle... bundles) throws BundleException {
+ stopAndUninstall(Arrays.asList(bundles));
+ }
+
+ public void stopAndUninstall(Iterable<Bundle> bundles) throws BundleException {
+ for (Bundle bundle : bundles) {
+ stop(bundle);
+ }
+ for (Bundle bundle : bundles) {
+ bundle.uninstall();
+ }
+ }
+
+ private void start(Bundle bundle) throws BundleException {
+ if (bundle.getState() == Bundle.ACTIVE) {
+ throw new BundleException("OSGi bundle " + bundle.getSymbolicName() + " already started.");
+ }
+ if (!OsgiHeader.asList(bundle, OsgiHeader.APPLICATION).isEmpty()) {
+ throw new BundleException("OSGi header '" + OsgiHeader.APPLICATION + "' not allowed for " +
+ "non-application bundle " + bundle.getSymbolicName() + ".");
+ }
+ osgiFramework.startBundles(Arrays.asList(bundle), false);
+ }
+
+ private void stop(Bundle bundle) throws BundleException {
+ if (bundle.getState() != Bundle.ACTIVE) {
+ throw new BundleException("OSGi bundle " + bundle.getSymbolicName() + " not started.");
+ }
+ bundle.stop();
+ }
+}