Interface AttributeLoaderProvider

All Known Implementing Classes:
SimpleAttributeProvider

@PublicSpi public interface AttributeLoaderProvider

Attributes extension point - you can add new attributes and attribute implementations to the system by implementing this interface and declaring the implementation in atlassian-plugin.xml.

The declaration is pretty simple - you only need to refer to the class: <structure-attribute-loader-provider key="my-loader" class="com.acme.myapp.MyAttributeLoaderProvider"/>

The class will be instantiated as a singleton component, so you can inject all the required services through the constructor parameters.

An implementation of the provider would typically check the passed attribute spec to understand if it can offer a loader for that ID and parameters.

The provider will return null if it cannot offer a loader for the given spec.

Analyzing value format and conversions

Note that the ValueFormat of the created loader must not necessarily correspond to the value format provided in the attribute spec. The provider should offer the best matching loader. The system will then convert the loaded values, if such conversion is possible.

This means that typically loader providers do not analyze the value format. Instead, they would use AttributeSpec.as(ValueFormat) method on the provided attribute spec to cast it to the format they support.

However, when a provider can offer different loaders for different value formats, they would analyze the requested format and offer the best match.

Loader caching

Most attribute loader providers would emit the same attribute loader for the same attribute spec. To speed up attribute loading, the system will cache the attribute loaders per each used attribute spec.

The provider may indicate that the loader should not be cached by calling AttributeProviderContext.mustNotCacheLoader(). This is needed when the provided loader may be different each time.

Using context values

A provider may use the current user or other context values from AttributeContext, but that will automatically make the loader non-cacheable, and also will implicitly introduce the corresponding context dependency to that loader.

Order

You can define the relative order of a provider by using "order" attribute in atlassian-plugin.xml: <structure-attribute-loader-provider key="my-loader" class="com.acme.myapp.MyAttributeLoaderProvider" order="-10"/>

Doing so will affect the order in which attribute loaders for the same attribute spec are called. The loaders created by a provider with a lower order number will be called first. The default order value for all providers is 0.

This means that you can introduce a loader for a specific attribute with a low order value, and that would let it override existing loaders and return a value first.

Concurrency and state

Attribute loader provider may be called concurrently, for the same or different attribute specs. The provider should be a stateless, thread-safe component and not keep any state between the calls.

If the attribute implementation does need to keep state between the loadings, consider introducing a separate component responsible for maintaining that state.

See Also:
  • Method Details

    • createAttributeLoader

      @Nullable AttributeLoader<?> createAttributeLoader(@NotNull AttributeSpec<?> attributeSpec, @NotNull AttributeProviderContext context) throws StructureProviderException
      Creates an attribute loader for the given attribute spec.
      Parameters:
      attributeSpec - attribute spec
      context - creation context
      Returns:
      a loader that can load values for the given spec, or a spec with a different value format; null if this provider cannot offer a loader
      Throws:
      StructureProviderException - if there was a problem creating a loader (the provider will continue being called)