From 01e5e256f3c47ac16ac11ea5d56a91b11b0c9fa2 Mon Sep 17 00:00:00 2001 From: Fr Jeremy Krieg Date: Thu, 16 Dec 2021 17:56:50 +1030 Subject: [PATCH] [core] Made Central a service Part of #5004 Signed-off-by: Fr Jeremy Krieg --- .../org/bndtools/api/central/ICentral.java | 22 +++++ .../bndtools/api/central/package-info.java | 5 ++ .../src/bndtools/central/Auxiliary.java | 44 +++++----- .../src/bndtools/central/Central.java | 86 +++++++++---------- 4 files changed, 89 insertions(+), 68 deletions(-) create mode 100644 bndtools.api/src/org/bndtools/api/central/ICentral.java create mode 100644 bndtools.api/src/org/bndtools/api/central/package-info.java diff --git a/bndtools.api/src/org/bndtools/api/central/ICentral.java b/bndtools.api/src/org/bndtools/api/central/ICentral.java new file mode 100644 index 00000000000..8a3a3678a2b --- /dev/null +++ b/bndtools.api/src/org/bndtools/api/central/ICentral.java @@ -0,0 +1,22 @@ +package org.bndtools.api.central; + +import org.bndtools.api.ModelListener; +import org.eclipse.jdt.core.IJavaProject; +import org.osgi.annotation.versioning.ProviderType; + +import aQute.bnd.build.Project; + +@ProviderType +public interface ICentral { + + Project getModel(IJavaProject project); + + void changed(Project model); + + void addModelListener(ModelListener m); + + void removeModelListener(ModelListener m); + + void close(); + +} diff --git a/bndtools.api/src/org/bndtools/api/central/package-info.java b/bndtools.api/src/org/bndtools/api/central/package-info.java new file mode 100644 index 00000000000..fc9fa6f083f --- /dev/null +++ b/bndtools.api/src/org/bndtools/api/central/package-info.java @@ -0,0 +1,5 @@ + +@Version("1.0.0") +package org.bndtools.api.central; + +import org.osgi.annotation.versioning.Version; diff --git a/bndtools.core/src/bndtools/central/Auxiliary.java b/bndtools.core/src/bndtools/central/Auxiliary.java index 1f8edfba763..b90db50a1c3 100644 --- a/bndtools.core/src/bndtools/central/Auxiliary.java +++ b/bndtools.core/src/bndtools/central/Auxiliary.java @@ -1,7 +1,5 @@ package bndtools.central; -import java.io.Closeable; -import java.io.IOException; import java.util.Deque; import java.util.Iterator; import java.util.List; @@ -12,12 +10,17 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; -import org.osgi.framework.ServiceRegistration; +import org.osgi.framework.FrameworkUtil; import org.osgi.framework.hooks.weaving.WeavingHook; import org.osgi.framework.hooks.weaving.WovenClass; import org.osgi.framework.wiring.BundleWiring; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.ServiceScope; import org.osgi.util.tracker.BundleTracker; +import aQute.bnd.build.Workspace; import aQute.bnd.header.Attrs; import aQute.bnd.header.Parameters; import aQute.bnd.osgi.About; @@ -27,21 +30,20 @@ import aQute.bnd.version.VersionRange; /** - * This class extends the dynamic imports of bndlib with any exported package - * from OSGi that specifies a 'bnd-plugins' attribute. Its value is either true - * or a version range on the bnd version. + * This component extends the dynamic imports of bndlib with any exported + * package from OSGi that specifies a 'bnd-plugins' attribute. Its value is + * either true or a version range on the bnd version. */ -class Auxiliary implements Closeable, WeavingHook { - private final BundleContext context; - private final AtomicBoolean closed = new AtomicBoolean(false); - private final ServiceRegistration hook; - private final BundleTracker tracker; - private final Bundle bndlib; - private final Deque delta = new ConcurrentLinkedDeque<>(); - - Auxiliary(BundleContext context, Bundle bndlib) { - this.bndlib = bndlib; - this.context = context; +@Component(immediate = true, scope = ServiceScope.SINGLETON) +public class Auxiliary implements WeavingHook { + private AtomicBoolean closed = new AtomicBoolean(false); + private BundleTracker tracker; + private Bundle bndlib; + private Deque delta = new ConcurrentLinkedDeque<>(); + + @Activate + void activate(BundleContext context) { + bndlib = FrameworkUtil.getBundle(Workspace.class); this.tracker = new BundleTracker(context, Bundle.RESOLVED + Bundle.ACTIVE + Bundle.STARTING, null) { @Override public Bundle addingBundle(Bundle bundle, BundleEvent event) { @@ -54,7 +56,7 @@ public Bundle addingBundle(Bundle bundle, BundleEvent event) { }; this.tracker.open(); - this.hook = this.context.registerService(WeavingHook.class, this, null); + closed.set(false); } /* @@ -130,12 +132,10 @@ public void weave(WovenClass wovenClass) { } } - @Override - public void close() throws IOException { + @Deactivate + void deactivate() { if (closed.getAndSet(true) == false) { - hook.unregister(); tracker.close(); } } - } diff --git a/bndtools.core/src/bndtools/central/Central.java b/bndtools.core/src/bndtools/central/Central.java index 6eb2fdb6871..0164bfac108 100644 --- a/bndtools.core/src/bndtools/central/Central.java +++ b/bndtools.core/src/bndtools/central/Central.java @@ -21,8 +21,8 @@ import java.util.stream.Stream; import org.bndtools.api.BndtoolsConstants; -import org.bndtools.api.IStartupParticipant; import org.bndtools.api.ModelListener; +import org.bndtools.api.central.ICentral; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -42,10 +42,12 @@ import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.widgets.Display; -import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceRegistration; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.ServiceScope; import org.osgi.util.function.Consumer; import org.osgi.util.promise.Deferred; import org.osgi.util.promise.Promise; @@ -74,7 +76,8 @@ import bndtools.central.RepositoriesViewRefresher.RefreshModel; import bndtools.preferences.BndPreferences; -public class Central implements IStartupParticipant { +@Component(scope=ServiceScope.SINGLETON, immediate=true) +public class Central implements ICentral { private static final org.slf4j.Logger logger = LoggerFactory .getLogger(Central.class); @@ -89,78 +92,49 @@ public class Central implements IStartupParticipant { private static final Supplier eclipseWorkspaceRepository = Memoize .supplier(EclipseWorkspaceRepository::new); - private static Auxiliary auxiliary; - static final AtomicBoolean indexValid = new AtomicBoolean(false); - private final BundleContext bundleContext; private final Map javaProjectToModel = new HashMap<>(); private final List listeners = new CopyOnWriteArrayList<>(); private RepositoryListenerPluginTracker repoListenerTracker; - private final InternalPluginTracker internalPlugins; + private InternalPluginTracker internalPlugins; @SuppressWarnings("unused") private static WorkspaceRepositoryChangeDetector workspaceRepositoryChangeDetector; private static RepositoriesViewRefresher repositoriesViewRefresher = new RepositoriesViewRefresher(); - private static BundleContext context; private static ServiceRegistration workspaceService; + private static BundleContext context; - static { - try { - context = FrameworkUtil.getBundle(Central.class) - .getBundleContext(); - Bundle bndlib = FrameworkUtil.getBundle(Workspace.class); - auxiliary = new Auxiliary(context, bndlib); - - } catch (Exception e) { - // ignore - } - } - - /** - * WARNING: Do not instantiate this class. It must be public to allow - * instantiation by the Eclipse registry, but it is not intended for direct - * creation by clients. Instead call Central.getInstance(). - */ - @Deprecated - public Central() { - bundleContext = FrameworkUtil.getBundle(Central.class) - .getBundleContext(); - internalPlugins = new InternalPluginTracker(bundleContext); - - } - - @Override - public void start() { + @Activate + void activate(BundleContext bc) { + context = bc; instance = this; - - repoListenerTracker = new RepositoryListenerPluginTracker(bundleContext); + repoListenerTracker = new RepositoryListenerPluginTracker(bc); repoListenerTracker.open(); + internalPlugins = new InternalPluginTracker(bc); internalPlugins.open(); + // Trigger building of the Workspace object and registering it a service + + promiseFactory().submit(Central::getWorkspace); } - @Override - public void stop() { + @Deactivate + void deactivate() { repoListenerTracker.close(); ServiceRegistration service = workspaceService; if (service != null) { service.unregister(); } instance = null; + context = null; Workspace ws = workspace.peek(); if (ws != null) { ws.close(); } - if (auxiliary != null) - try { - auxiliary.close(); - } catch (Exception e) { - throw new RuntimeException(e); - } internalPlugins.close(); } @@ -168,6 +142,10 @@ public static Central getInstance() { return instance; } + /* (non-Javadoc) + * @see bndtools.central.Central#getModel(org.eclipse.jdt.core.IJavaProject) + */ + @Override public Project getModel(IJavaProject project) { try { Project model = javaProjectToModel.get(project); @@ -424,6 +402,10 @@ public static boolean isChangeDelta(IResourceDelta delta) { return true; } + /* (non-Javadoc) + * @see bndtools.central.Central#changed(aQute.bnd.build.Project) + */ + @Override public void changed(Project model) { model.setChanged(); for (ModelListener m : listeners) { @@ -435,12 +417,20 @@ public void changed(Project model) { } } + /* (non-Javadoc) + * @see bndtools.central.Central#addModelListener(org.bndtools.api.ModelListener) + */ + @Override public void addModelListener(ModelListener m) { if (!listeners.contains(m)) { listeners.add(m); } } + /* (non-Javadoc) + * @see bndtools.central.Central#removeModelListener(org.bndtools.api.ModelListener) + */ + @Override public void removeModelListener(ModelListener m) { listeners.remove(m); } @@ -616,6 +606,10 @@ public static void refresh(Project p) throws Exception { .refreshLocal(IResource.DEPTH_INFINITE, null); } + /* (non-Javadoc) + * @see bndtools.central.Central#close() + */ + @Override public void close() { repositoriesViewRefresher.close(); }