Class Hierarchy

When developing for the metadata aggregator framework — either within the Shibboleth project or externally to extend it — the classes you create will implement one or more of the Java interfaces defined by the framework, for example Stage or ItemMetadata. As long as you implement those interfaces faithfully, your new class will work with the framework. It's certainly possible to implement a new class "from scratch" by just saying class X implements Stage<T> but it can be a lot of work and this is almost never done within the framework itself. Instead, heavy use is made of a hierarchy of abstract classes each providing some useful functionality: you can extend one of these classes to greatly reduce the amount of code you need to write yourself.

Component Class Hierarchy

Many objects in the metadata aggregator are components as defined by the Shibboleth component model, which is to say they all implement the Component interface via one or more behavioural interfaces:

These interfaces are almost always implemented together (for example, Stage requires InitializableComponent, DestructableComponent and IdentifiedComponent) and shib-support supplies a number of abstract base classes to implement the associated functionality in a standard way. Two of these are of particular interest when working with the metadata aggregator.

AbstractInitializableComponent implements InitializableComponent and DestructableComponent.

  • Subclasses must not override the implementations of initialize() and destroy() (this will be enforced by making these methods final in a later release).

  • Instead, the base class implements empty protected doInitialize() and doDestroy() methods which subclasses may override.

  • Implementations of doInitialize() must call super.doInitialize() before other actions. Implementations of doDestroy() must call super.doDestroy() after other actions. This allows all classes in the class hierarchy to properly set up and tear down state.

  • When initialize() or destroy() are called for the first time on an instance, the instance's doInitialize() or doDestroy() methods are called. initialize() and destroy() are synchronized, so all doInitialize() and doDestroy() methods are executed under the instance's monitor as an atomic operation.

AbstractIdentifiableInitializableComponent extends AbstractInitializableComponent, adding implementations of IdentifiedComponent and IdentifiableComponent:

AbstractInitializableComponent and AbstractIdentifiableInitializableComponent provide the basis for almost all metadata aggregator components, depending on whether the component needs to have an id property. Both are @ThreadSafe so that thread-safe components can be built from them. They are not, however, normally used directly. Instead, the main abstract classes in the aggregator class hierarchy are derived from two intermediate classes (BaseInitializableComponent and BaseIdentifiableInitializableComponent) which add some helper methods to every component:

  • ifDestroyedThrowDestroyedComponentException()

  • ifNotInitializedThrowUninitializedComponentException()

  • ifInitializedThrowUnmodifiableComponentException()

  • throwSetterPreconditionExceptions() combines ifDestroyedThrowDestroyedComponentException() and ifInitializedThrowUnmodifiableComponentException(). This helper method can be used to check the preconditions for a setter method.

  • throwComponentStateExceptions() combines ifDestroyedThrowDestroyedComponentException() and ifNotInitializedThrowUninitializedComponentException(). This helper method can be used to check the preconditions for the main operational method in a class.

BaseInitializableComponent and BaseIdentifiableInitializableComponent are placed in an implementation package and should never be used outside the java-metadata-aggregator codebase. Instead, external classes should be based on one of the exposed abstract classes, such as AbstractStage and its subclasses, described below. This is because the functionality of BaseInitializableComponent and BaseIdentifiableInitializableComponent may be moved into the java-support classes in a future release.

Stage Class Hierarchy

The largest class hierarchy in the metadata aggregator is that for stages.

AbstractStage<T> extends BaseIdentifiableInitializableComponent implements Stage<T>