Package net.shibboleth.shared.spring.service

# Class AbstractServiceableComponent<T>

java.lang.Object
net.shibboleth.shared.component.AbstractInitializableComponent
net.shibboleth.shared.component.AbstractIdentifiedInitializableComponent
net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent
net.shibboleth.shared.spring.service.AbstractServiceableComponent<T>

Type Parameters:
  `T` - The type of service.

All Implemented Interfaces:
  `AutoCloseable`, `Component`, `DestructableComponent`, `IdentifiableComponent`, `IdentifiedComponent`, `InitializableComponent`, `ServiceableComponent<T>`, `Aware`, `ApplicationContextAware`

Direct Known Subclasses:
  `ApplicationContextServiceableComponent`, `ReloadingAccessControlService`, `ServiceableAccessControlService`, `SpringServiceableComponent`

public abstract class AbstractServiceableComponent<T> extends AbstractIdentifiableInitializableComponent implements ServiceableComponent<T>, ApplicationContextAware
Implementation of `ServiceableComponent` that does most of the work required. It leverages the spring environment to allow easy cleanup.

## Field Summary

Fields
Modifier and Type
Field
Description
`private ApplicationContext`
`applicationContext`
The context used to load this bean.
`private final org.slf4j.Logger`
`log`
Class logger.
`private final ReentrantReadWriteLock`
`serviceLock`
Lock for this service.

## Constructor Summary

Constructors
Constructor
Description
`AbstractServiceableComponent()`
Constructor.

## Method Summary

Modifier and Type
Method
Description
`void`
`close()`
Note that this is explicitly declared to not throw an `IOException`
`protected void`
`doDestroy()`
Performs component specific destruction logic.
`protected void`
`doInitialize()`
This method checks to ensure that the component ID is not null.
`ApplicationContext`
`getApplicationContext()`
Get the context used to load this bean.
`abstract T`
`getComponent()`
Extract the component that does the actual work.
`void`
`pinComponent()`
Grab the service lock shared.
`void`
`setApplicationContext(ApplicationContext context)`
`void`
`unloadComponent()`
Grab the service lock ex (which means no-one else is active) and then call Spring to tear everything down.
`void`
`unpinComponent()`
Drop the shared lock.

### Methods inherited from class net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent

`setId`

### Methods inherited from class net.shibboleth.shared.component.AbstractIdentifiedInitializableComponent

`ensureId, getId, ifDestroyedThrowDestroyedComponentException, ifInitializedThrowUnmodifiabledComponentException, ifNotInitializedThrowUninitializedComponentException`

### Methods inherited from class net.shibboleth.shared.component.AbstractInitializableComponent

`checkComponentActive, checkSetterPreconditions, destroy, initialize, isDestroyed, isInitialized`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface net.shibboleth.shared.component.IdentifiedComponent

`getId`

## Field Details

### log

@Nonnull private final org.slf4j.Logger log
Class logger.

### applicationContext

@Nullable private ApplicationContext applicationContext
The context used to load this bean.

### serviceLock

@Nonnull private final ReentrantReadWriteLock serviceLock
Lock for this service. We make it unfair since we will control access and there will only ever be contention during unload.

## Constructor Details

### AbstractServiceableComponent

public AbstractServiceableComponent()
Constructor.

## Method Details

### setApplicationContext

public void setApplicationContext(@Nullable ApplicationContext context)

Specified by:
  `setApplicationContext` in interface `ApplicationContextAware`

### getApplicationContext

@Nullable public ApplicationContext getApplicationContext()
Get the context used to load this bean.

Returns:
  the context.

### getComponent

@Nonnull public abstract T getComponent()
Extract the component that does the actual work. Callers MUST have the ServiceableComponent pinned at this stage.

Specified by:
  `getComponent` in interface `ServiceableComponent<T>`
Returns:
  the component.

### pinComponent

public void pinComponent()
Grab the service lock shared. This will block unloads until `unpinComponent()` is called.

### unpinComponent

public void unpinComponent()
Drop the shared lock.

### close

public void close()
Note that this is explicitly declared to not throw an `IOException`

Specified by:
  `close` in interface `AutoCloseable`
Specified by:
  `close` in interface `ServiceableComponent<T>`

### unloadComponent

public void unloadComponent()
Grab the service lock ex (which means no-one else is active) and then call Spring to tear everything down. The fact that we have the service lock ex means that this method does not need to be add a 'synchronize' because we are doing it explicitly. Further we are careful with the operation order so there are no races in this code and and no user of the underlying component can be active as we are tearing down.

### doInitialize

protected void doInitialize() throws ComponentInitializationException
This method checks to ensure that the component ID is not null. Performs the initialization of the component. This method is executed within the lock on the object being initialized. The default implementation of this method is a no-op.

Overrides:
  `doInitialize` in class `AbstractIdentifiedInitializableComponent`
Throws:
  `ComponentInitializationException` - thrown if there is a problem initializing the component

### doDestroy

protected void doDestroy()
Performs component specific destruction logic. This method is executed within the lock on the object being destroyed. The default implementation of this method is a no-op.. Force unload; this will usually be a no-op since the component should have been explicitly unloaded, but we do the unload here so that error cases also clean up.

Overrides:
  `doDestroy` in class `AbstractInitializableComponent`