Class ComponentManager

java.lang.Object
com.atlassian.jira.component.pico.ComponentManager
All Implemented Interfaces:
Shutdown

@Internal @ParametersAreNonnullByDefault public class ComponentManager extends Object implements Shutdown
Manages Jira's ComponentContainer, which includes: It also provides lookup methods for obtaining components, such as getComponent(Class). Plugins developers should use ComponentAccessor for this, instead.

This class is a stateful singleton that lasts for the entire uptime of Jira, but the container it manages will come and go as Jira goes through different stages of its lifecycle.

  • Method Details

    • getInstance

      @Nonnull public static ComponentManager getInstance()
      Retuns a singleton instance of this class.
      Returns:
      a singleton instance of this class
    • createBootstrapContainer

      public void createBootstrapContainer()
      Creates the ComponentContainer that contains the minimal components required to bootstrap Jira. This is done before we know whether Jira has been set up or will otherwise start up properly.
      Throws:
      IllegalStateException - if a container already exists
    • extendBootstrapContainerForSetup

      public void extendBootstrapContainerForSetup()
      Extends the bootstrap container by adding the extra components needed for the admin to set up Jira.
      Throws:
      IllegalStateException - if there's no container, it's not initialised, or it's not in bootstrap mode
      See Also:
    • extendBootstrapContainerForDisplayingErrors

      public void extendBootstrapContainerForDisplayingErrors()
      Extends the bootstrap container by adding the extra components needed for displaying startup errors (or warnings) on the Johnson page. Does nothing if there's no container, or it's already been extended.
      Throws:
      IllegalStateException - if there's an unextended container, but it's either uninitialised or not in bootstrap mode
      See Also:
    • createFullContainer

      public void createFullContainer()
      Creates the ComponentContainer that contains the full set of Jira components.
      Throws:
      IllegalStateException - if a container already exists
    • earlyStartPluginSystem

      public void earlyStartPluginSystem()
      Early-starts the plugin system (including Plugins 1 components) and instantiates the components in the container. Lastly, transitions this manager to the ComponentContainerState.STARTED state and publishes a ComponentManagerStartedEvent.
    • lateStartPluginSystem

      public void lateStartPluginSystem()
      Start delayed plugins (if any).
      See Also:
      • SplitStartupPluginSystemLifecycle.lateStartup()
    • componentsAvailable

      public boolean componentsAvailable()
      Determines whether components have already been instantiated regardless of which container is in use.
      Returns:
      true iff components have already been instantiated by the container in play
    • stopPluginSystem

      public void stopPluginSystem()
      Publishes a ComponentManagerShutdownEvent and shuts down the plugin system.
    • discardContainer

      public void discardContainer()
      Gets rid of the ComponentContainer and resets the state to ComponentContainerState.NOT_STARTED.
    • shutdown

      public void shutdown()
      Stops the plugin system and discards the ComponentContainer.
      Specified by:
      shutdown in interface Shutdown
      See Also:
    • getState

      @Nonnull public ComponentContainerState getState()
      Returns the state of this instance.
      Returns:
      the current state.
    • getPluginSystemState

      public ComponentManager.PluginSystemState getPluginSystemState()
      Returns the state of the plugin system. This can be used to discover whether delayed plugins were started.
      Returns:
      the current state of the plugin system
    • getContainerLevel

      @Nonnull public Optional<ComponentContainer.ContainerLevel> getContainerLevel()
      Returns the ComponentContainer level.
      Returns:
      empty if there's no container
      See Also:
    • getComponentInstanceOfType

      @Nullable public <T> T getComponentInstanceOfType(Class<T> type)
      Retrieves and returns a component which is an instance of given class.

      In practise, this is the same as getComponent(Class) except it will try to find a unique component that implements/extends the given Class even if the Class is not an actual component key.

      Please note that this method only gets components from JIRA's core Pico Containter. That is, it retrieves core components and components declared in Plugins1 plugins, but not components declared in Plugins2 plugins. Plugins2 components can be retrieved via the getOSGiComponentInstanceOfType(Class) method, but only if they are public.

      NOTE to Jira devs: don't use this method for general purpose component retrieval. Use ComponentAccessor instead.

      Parameters:
      type - the class by which to find the component
      Returns:
      found component
      See Also:
    • getComponent

      @Nullable public <T> T getComponent(Class<T> componentClass)
      Retrieves and returns a component which is an instance of given class.

      In practise, this is the same as getComponentInstanceOfType(Class) except it will fail faster if the given Class is not a known component key (it also has a shorter and more meaningful name).

      Please note that this method only gets components from JIRA's core Pico Container. That is, it retrieves core components and components declared in Plugins1 plugins, but not components declared in Plugins2 plugins. Plugins2 components can be retrieved via the getOSGiComponentInstanceOfType(Class) method, but only if they are public.

      NOTE to Jira DEVS: Stop using this method for general purpose component retrieval; use ComponentAccessor please.

      Parameters:
      componentClass - class to find a component instance by
      Returns:
      found component, or null if not found
      See Also:
    • getOSGiComponentInstanceOfType

      @Nullable public <T> T getOSGiComponentInstanceOfType(Class<T> clazz)
      Retrieves and returns a public component from OSGi land via its class name. This method can be used to retrieve a component provided via a plugins2 OSGi bundle. Please note that components returned via this method should *NEVER* be cached (e.g. in a static field) as they may be refreshed at any time as a plugin is enabled/disabled or the componentManager is reinitialised (after an XML import).

      Plugin developers should prefer the API method ComponentAccessor.getOSGiComponentInstanceOfType(Class).

      It is important to note that this only works for public components. That is components with public="true" declared in their XML configuration. This means that they are available for other plugins to import.

      A use case for this is when for example for the dashboards plugin. In several areas in JIRA we may want to render gadgets via the GadgetViewFactory. Whilst the interface for this component is available in JIRA core, the implementation is provided by the dashboards OSGi bundle. This method will allow us to access it.

      NOTE to JIRA DEVS : Stop using this method for general purpose component retrieval. Use ComponentAccessor please.

      Parameters:
      clazz - class to find an OSGi component instance for
      Returns:
      found component. In case component is not found or osgi cache is not available returns null
      See Also:
    • getComponents

      public <T> List<T> getComponents(Class<T> type)
      Returns the components of the given type.
      Type Parameters:
      T - the component type
      Parameters:
      type - the component type
      Returns:
      see above
      Throws:
      IllegalStateException - if the container does not exist
      Since:
      7.7
    • getComponentsOfType

      public <T> List<T> getComponentsOfType(Class<T> type)
      Returns all the components inside Pico that are instances of the given class.
      Parameters:
      type - the class for which to search
      Returns:
      see above
    • getComponentsOfTypeMap

      public <T> Map<String,T> getComponentsOfTypeMap(Class<T> type)
      Returns all the components currently inside Pico which are instances of the given class, mapping them to their component key.
      Parameters:
      type - the type for which to search
      Returns:
      a map, mapping the component key, to the instances of the class registered in JIRA's pico container.
    • registerComponent

      public void registerComponent(@Nullable Class<?> interfaceClass, Class<?> componentClass)
      Registers a component of the given class, optionally using the given interface as the key. Does nothing if there is no container in play.
      Parameters:
      interfaceClass - the interface to use as the key
      componentClass - the component class
      Since:
      7.7
    • unregisterComponent

      public void unregisterComponent(@Nullable Class<?> interfaceClass, Class<?> componentClass)
      Unregisters a component of the given class, optionally using the given interface as the key.
      Parameters:
      interfaceClass - the interface to use as the key
      componentClass - the component class
      Since:
      7.7
    • createRequestScopedComponent

      public <T> T createRequestScopedComponent(Class<T> componentClass)
      Creates a request-scoped component of the given class.
      Type Parameters:
      T - the type of the component
      Parameters:
      componentClass - the class of component to instantiate
      Returns:
      the component
      Since:
      7.7 moved from PicoWebworkObjectCreator
    • loadComponent

      @Nullable public <T> T loadComponent(Class<T> componentClass, Collection<Object> dependencies)
      Instantiates a component from its class and dependent classes/instances.
      Type Parameters:
      T - the type of component
      Parameters:
      componentClass - the class of component to instantiate
      dependencies - the component's dependencies (classes and/or instances)
      Returns:
      the component, or null if the component class is the Void class
      Since:
      7.7 moved from JiraUtils
    • restart

      public void restart()
      Stops the plugin system, replaces any container with a new full container, and restarts the plugin system (early and late). This should only be done:
      • if you are importing,
      • if you are setting up Jira, or
      • during tests
      Since:
      7.7 was called globalRefresh() in now-deleted ManagerFactory class