Class PluginExtensionRegistryImpl
- All Implemented Interfaces:
PluginExtensionRegistry
ApplicationContext (as this
@Component) and every plugin's curated parent context (PluginApiParentContext
registers the exact same object as a singleton there) - not two copies, one shared reference,
so a plugin-side registration is immediately visible to host-side queries.
Keyed internally by Bundle-SymbolicName, never the optional URL prefix, so one
plugin's entries can be removed atomically on teardown regardless of whether it ever declared
a prefix.
Mutations (register/unregister) are infrequent (plugin install/uninstall);
a single monitor guarding both mutation and read is simple and sufficiently cheap, and it also
sidesteps the ordering pitfall a ConcurrentHashMap-based structure would have (no
insertion-order guarantee), which registration-order correctness depends on.
Feeds two consumption styles: host code that pulls a snapshot on demand
(extensions(Class), e.g. PluginTaskExtensionResolver) and host code that wants
to be pushed add/remove events as they happen (addListener(java.lang.Class<? extends com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint>, com.xebialabs.xlrelease.osgi.spring.PluginExtensionRegistryImpl.ExtensionRegistryListener), e.g. an OSGi-service-backed
extension kind that maintains external derived state). Both styles are fed by every feeder that
calls register(java.lang.String, com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint)/unregister(java.lang.String) - a Spring plugin-context bean and an OSGi-service
extension arrive through the same two methods, so this class does not need to know which kind of
bundle contributed a given extension.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfacePush counterpart toextensions(Class): a host component that wants to maintain externally-visible derived state (e.g. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddListener(Class<? extends com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint> type, PluginExtensionRegistryImpl.ExtensionRegistryListener listener) Subscribeslistenerto add/remove events fortype, and immediately replays every currently-registered extension oftypeas a syntheticextensionAddedcall (outside the lock, like every other notification) - so a listener never has to race "subscribe" against "read the current snapshot" to build a consistent picture, regardless of the orderaddListener(java.lang.Class<? extends com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint>, com.xebialabs.xlrelease.osgi.spring.PluginExtensionRegistryImpl.ExtensionRegistryListener)and bundle installation happen to run in.<T extends com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint>
List<T> extensions(Class<T> type) voidregister(String bundleSymbolicName, com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint bean) Fansbeanout to everyHostExtensionPointsubtype it actually implements - a bean may implement more than one extension-point interface.voidunregister(String bundleSymbolicName) Removes every entry registered underbundleSymbolicName, atomically.voidunregister(String bundleSymbolicName, com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint bean) Removes justbeanfrombundleSymbolicName's entries, pruning now-empty type/bundle map entries.
-
Constructor Details
-
PluginExtensionRegistryImpl
public PluginExtensionRegistryImpl()
-
-
Method Details
-
register
public void register(String bundleSymbolicName, com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint bean) Fansbeanout to everyHostExtensionPointsubtype it actually implements - a bean may implement more than one extension-point interface. Called byPluginContextFactoryright after a successfulctx.refresh()for a Spring-plugin-context feeder, or by an OSGi-service feeder when a matching service appears. -
unregister
Removes every entry registered underbundleSymbolicName, atomically. Called byPluginTeardown's ordered teardown, which decides where in that sequence it runs. -
unregister
public void unregister(String bundleSymbolicName, com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint bean) Removes justbeanfrombundleSymbolicName's entries, pruning now-empty type/bundle map entries. Unlikeunregister(String), does not affect any other bean the same bundle may have registered. Used by feeders that observe removal of a single contribution (e.g. one OSGi service going away) rather than a whole bundle's teardown. -
addListener
public void addListener(Class<? extends com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint> type, PluginExtensionRegistryImpl.ExtensionRegistryListener listener) Subscribeslistenerto add/remove events fortype, and immediately replays every currently-registered extension oftypeas a syntheticextensionAddedcall (outside the lock, like every other notification) - so a listener never has to race "subscribe" against "read the current snapshot" to build a consistent picture, regardless of the orderaddListener(java.lang.Class<? extends com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint>, com.xebialabs.xlrelease.osgi.spring.PluginExtensionRegistryImpl.ExtensionRegistryListener)and bundle installation happen to run in. -
extensions
public <T extends com.xebialabs.xlrelease.osgi.api.spring.HostExtensionPoint> List<T> extensions(Class<T> type) - Specified by:
extensionsin interfacePluginExtensionRegistry- Returns:
- a freshly-built, independent list - never a live view - of every registered
implementation of
type, in registration order. No ordering/priority beyond registration order is supported in v1; this is a documented limitation, not an accidental behavior to discover later.
-