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:
An InitializableComponent must be
initialize()
ed before it can be used.A DestructableComponent can be
destroy()
ed after use to reclaim resources.An IdentifiedComponent has an
id
property accessed through agetId()
method.An IdentifiableComponent is an
IdentifiedComponent
with asetId()
method.
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()
anddestroy()
(this will be enforced by making these methods final in a later release).Instead, the base class implements empty protected
doInitialize()
anddoDestroy()
methods which subclasses may override.Implementations of
doInitialize()
must callsuper.doInitialize()
before other actions. Implementations ofdoDestroy()
must callsuper.doDestroy()
after other actions. This allows all classes in the class hierarchy to properly set up and tear down state.When
initialize()
ordestroy()
are called for the first time on an instance, the instance'sdoInitialize()
ordoDestroy()
methods are called.initialize()
anddestroy()
are synchronized, so alldoInitialize()
anddoDestroy()
methods are executed under the instance's monitor as an atomic operation.
AbstractIdentifiableInitializableComponent extends AbstractInitializableComponent
, adding implementations of IdentifiedComponent
and IdentifiableComponent
:
Adds a settable
id
property (getId()
andsetId()
methods).The id property must be set before the component is initialized, or a ComponentInitializationException will be thrown.
The id property cannot be set after the component is initialized; attempts will cause a UnmodifiableComponentException to be thrown.
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()
combinesifDestroyedThrowDestroyedComponentException()
andifInitializedThrowUnmodifiableComponentException()
. This helper method can be used to check the preconditions for a setter method.throwComponentStateExceptions()
combinesifDestroyedThrowDestroyedComponentException()
andifNotInitializedThrowUninitializedComponentException()
. 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.