Component registry - clean-up
This commit is contained in:
parent
7ccae60ba9
commit
dc6668e6dc
1 changed files with 91 additions and 91 deletions
|
@ -28,7 +28,7 @@ public class ComponentRegistry
|
|||
private boolean added;
|
||||
|
||||
|
||||
private TempBuildRec( NewComponentInfo< ? > info )
|
||||
private TempBuildRec( final NewComponentInfo< ? > info )
|
||||
{
|
||||
this.info = info;
|
||||
this.state = new ComponentState( ComponentRegistry.this , info );
|
||||
|
@ -43,12 +43,12 @@ public class ComponentRegistry
|
|||
private final HashSet< Field > setFields;
|
||||
|
||||
|
||||
private SingletonClass( Class< ? > klass )
|
||||
private SingletonClass( final Class< ? > klass )
|
||||
{
|
||||
this.missingFields = new HashSet< >( );
|
||||
this.setFields = new HashSet< >( );
|
||||
|
||||
for ( Field fld : klass.getFields( ) ) {
|
||||
for ( final Field fld : klass.getFields( ) ) {
|
||||
if ( !fld.isAnnotationPresent( ComponentSingleton.class ) ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public class ComponentRegistry
|
|||
throw new ComponentManagementException( "singleton field " + fld.getName( ) + " in class "
|
||||
+ klass.getCanonicalName( ) + " is final" );
|
||||
}
|
||||
missingFields.add( fld );
|
||||
this.missingFields.add( fld );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,18 +80,18 @@ public class ComponentRegistry
|
|||
private boolean active;
|
||||
|
||||
|
||||
public void addSingletonClass( Class< ? > klass )
|
||||
public void addSingletonClass( final Class< ? > klass )
|
||||
throws ComponentManagementException , AmbiguousComponentException
|
||||
{
|
||||
if ( !this.singletonClasses.containsKey( klass ) ) {
|
||||
SingletonClass info = new SingletonClass( klass );
|
||||
final SingletonClass info = new SingletonClass( klass );
|
||||
this.fillSingletonFields( info );
|
||||
this.singletonClasses.put( klass , info );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void removeSingletonClass( Class< ? > klass )
|
||||
public void removeSingletonClass( final Class< ? > klass )
|
||||
{
|
||||
this.singletonClasses.remove( klass );
|
||||
}
|
||||
|
@ -99,32 +99,32 @@ public class ComponentRegistry
|
|||
|
||||
public boolean hasFailed( )
|
||||
{
|
||||
return failed;
|
||||
return this.failed;
|
||||
}
|
||||
|
||||
|
||||
public boolean isInitialised( )
|
||||
{
|
||||
return initialised;
|
||||
return this.initialised;
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive( )
|
||||
{
|
||||
return active;
|
||||
return this.active;
|
||||
}
|
||||
|
||||
|
||||
public ComponentState getState( String name )
|
||||
public ComponentState getState( final String name )
|
||||
{
|
||||
return this.byName.get( name );
|
||||
}
|
||||
|
||||
|
||||
public ComponentState getState( Class< ? > type )
|
||||
public ComponentState getState( final Class< ? > type )
|
||||
throws AmbiguousComponentException
|
||||
{
|
||||
ArrayList< ComponentState > l = this.byType.get( type );
|
||||
final ArrayList< ComponentState > l = this.byType.get( type );
|
||||
if ( l == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -135,10 +135,10 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
|
||||
public List< ComponentState > getStates( Class< ? > type )
|
||||
public List< ComponentState > getStates( final Class< ? > type )
|
||||
throws AmbiguousComponentException
|
||||
{
|
||||
ArrayList< ComponentState > l = this.byType.get( type );
|
||||
final ArrayList< ComponentState > l = this.byType.get( type );
|
||||
if ( l == null ) {
|
||||
return Collections.emptyList( );
|
||||
}
|
||||
|
@ -146,11 +146,11 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
|
||||
public void getStates( Class< ? > type , Collection< ComponentState > states )
|
||||
public void getStates( final Class< ? > type , final Collection< ComponentState > states )
|
||||
{
|
||||
ArrayList< ComponentState > l = this.byType.get( type );
|
||||
final ArrayList< ComponentState > l = this.byType.get( type );
|
||||
if ( l != null ) {
|
||||
int nFound = l.size( );
|
||||
final int nFound = l.size( );
|
||||
for ( int i = 0 ; i < nFound ; i++ ) {
|
||||
states.add( l.get( i ) );
|
||||
}
|
||||
|
@ -160,27 +160,27 @@ public class ComponentRegistry
|
|||
|
||||
public List< ComponentState > getAllStates( )
|
||||
{
|
||||
return Collections.unmodifiableList( components );
|
||||
return Collections.unmodifiableList( this.components );
|
||||
}
|
||||
|
||||
|
||||
public void getAllStates( Collection< ComponentState > result )
|
||||
public void getAllStates( final Collection< ComponentState > result )
|
||||
{
|
||||
result.addAll( result );
|
||||
}
|
||||
|
||||
|
||||
public Object get( String name )
|
||||
public Object get( final String name )
|
||||
{
|
||||
ComponentState cs = this.byName.get( name );
|
||||
final ComponentState cs = this.byName.get( name );
|
||||
return cs == null ? null : cs.getComponent( );
|
||||
}
|
||||
|
||||
|
||||
public < T > T get( Class< T > type )
|
||||
public < T > T get( final Class< T > type )
|
||||
throws AmbiguousComponentException
|
||||
{
|
||||
ArrayList< ComponentState > l = this.byType.get( type );
|
||||
final ArrayList< ComponentState > l = this.byType.get( type );
|
||||
if ( l == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -191,15 +191,15 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
|
||||
public < T > List< T > getAll( Class< T > type )
|
||||
public < T > List< T > getAll( final Class< T > type )
|
||||
{
|
||||
ArrayList< ComponentState > l = this.byType.get( type );
|
||||
final ArrayList< ComponentState > l = this.byType.get( type );
|
||||
if ( l == null ) {
|
||||
return Collections.emptyList( );
|
||||
}
|
||||
|
||||
int nFound = l.size( );
|
||||
ArrayList< T > result = new ArrayList< >( nFound );
|
||||
final int nFound = l.size( );
|
||||
final ArrayList< T > result = new ArrayList< >( nFound );
|
||||
for ( int i = 0 ; i < nFound ; i++ ) {
|
||||
result.add( type.cast( l.get( i ).getComponent( ) ) );
|
||||
}
|
||||
|
@ -207,11 +207,11 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
|
||||
public < T > void getAll( Class< T > type , Collection< T > result )
|
||||
public < T > void getAll( final Class< T > type , final Collection< T > result )
|
||||
{
|
||||
ArrayList< ComponentState > l = this.byType.get( type );
|
||||
final ArrayList< ComponentState > l = this.byType.get( type );
|
||||
if ( l != null ) {
|
||||
int nFound = l.size( );
|
||||
final int nFound = l.size( );
|
||||
for ( int i = 0 ; i < nFound ; i++ ) {
|
||||
result.add( type.cast( l.get( i ).getComponent( ) ) );
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
|
||||
public ComponentRegistry register( Collection< NewComponentInfo< ? > > components )
|
||||
public ComponentRegistry register( final Collection< NewComponentInfo< ? > > components )
|
||||
throws ComponentCreationException , DuplicateComponentException , RecursiveDependenciesException ,
|
||||
DependencyInjectionException , AmbiguousComponentException , ComponentInitialisationException ,
|
||||
ComponentStartupException
|
||||
|
@ -229,23 +229,23 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
// Create "raw" state records for the new components
|
||||
int nAdd = components.size( );
|
||||
final int nAdd = components.size( );
|
||||
int nLeft = nAdd;
|
||||
ArrayList< TempBuildRec > adding = new ArrayList< >( nAdd );
|
||||
for ( NewComponentInfo< ? > nci : components ) {
|
||||
final ArrayList< TempBuildRec > adding = new ArrayList< >( nAdd );
|
||||
for ( final NewComponentInfo< ? > nci : components ) {
|
||||
adding.add( new TempBuildRec( nci ) );
|
||||
}
|
||||
|
||||
// Create the registry's new state
|
||||
ArrayList< ComponentState > nComponents = new ArrayList< >( this.components );
|
||||
HashMap< String , ComponentState > byName = new HashMap< >( this.byName );
|
||||
HashMap< Class< ? > , ArrayList< ComponentState > > byType = new HashMap< >( this.byType );
|
||||
final ArrayList< ComponentState > nComponents = new ArrayList< >( this.components );
|
||||
final HashMap< String , ComponentState > byName = new HashMap< >( this.byName );
|
||||
final HashMap< Class< ? > , ArrayList< ComponentState > > byType = new HashMap< >( this.byType );
|
||||
|
||||
// Add all new components whose dependencies are satisfied. Stop when there are no new components left. If there
|
||||
// are components left in the input list but no component can be added, it means there are some circular
|
||||
// dependencies.
|
||||
while ( nLeft > 0 ) {
|
||||
int found = resolveNewDependencies( adding , nComponents , byName , byType );
|
||||
final int found = ComponentRegistry.resolveNewDependencies( adding , nComponents , byName , byType );
|
||||
if ( found == 0 ) {
|
||||
throw new RecursiveDependenciesException( adding.stream( ) //
|
||||
.filter( r -> !r.added ) //
|
||||
|
@ -257,27 +257,27 @@ public class ComponentRegistry
|
|||
|
||||
// Set up driver components
|
||||
for ( int i = 0 ; i < nAdd ; i++ ) {
|
||||
TempBuildRec c = adding.get( i );
|
||||
String df = c.info.getDriverFor( );
|
||||
final TempBuildRec c = adding.get( i );
|
||||
final String df = c.info.getDriverFor( );
|
||||
if ( df != null ) {
|
||||
c.state.setDriverFor( byName.get( df ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Inject and track dependencies
|
||||
injectDependencies( adding );
|
||||
ComponentRegistry.injectDependencies( adding );
|
||||
|
||||
// Replace registry contents
|
||||
int nOld = this.components.size( );
|
||||
final int nOld = this.components.size( );
|
||||
this.components = nComponents;
|
||||
this.byName = byName;
|
||||
this.byType = byType;
|
||||
|
||||
// Update singleton classes
|
||||
for ( SingletonClass sc : this.singletonClasses.values( ) ) {
|
||||
for ( final SingletonClass sc : this.singletonClasses.values( ) ) {
|
||||
try {
|
||||
this.fillSingletonFields( sc );
|
||||
} catch ( ComponentManagementException e ) {
|
||||
} catch ( final ComponentManagementException e ) {
|
||||
this.failed = true;
|
||||
throw e;
|
||||
}
|
||||
|
@ -286,14 +286,14 @@ public class ComponentRegistry
|
|||
// Initialise all new components if the registry has been initialised
|
||||
if ( this.initialised ) {
|
||||
for ( int i = nOld ; i < nOld + nAdd ; i++ ) {
|
||||
initComponent( i );
|
||||
this.initComponent( i );
|
||||
}
|
||||
}
|
||||
|
||||
// Activate autostart components
|
||||
if ( this.active ) {
|
||||
for ( int i = 0 ; i < nOld + nAdd ; i++ ) {
|
||||
autostartComponent( i );
|
||||
this.autostartComponent( i );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,9 +311,9 @@ public class ComponentRegistry
|
|||
return;
|
||||
}
|
||||
|
||||
int nComponents = this.components.size( );
|
||||
final int nComponents = this.components.size( );
|
||||
for ( int i = 0 ; i < nComponents ; i++ ) {
|
||||
initComponent( i );
|
||||
this.initComponent( i );
|
||||
}
|
||||
|
||||
this.initialised = true;
|
||||
|
@ -332,7 +332,7 @@ public class ComponentRegistry
|
|||
|
||||
this.stop( );
|
||||
for ( int i = this.components.size( ) - 1 ; i >= 0 ; i-- ) {
|
||||
destroyComponent( i );
|
||||
this.destroyComponent( i );
|
||||
}
|
||||
this.initialised = false;
|
||||
}
|
||||
|
@ -351,9 +351,9 @@ public class ComponentRegistry
|
|||
return;
|
||||
}
|
||||
|
||||
int nComponents = this.components.size( );
|
||||
final int nComponents = this.components.size( );
|
||||
for ( int i = 0 ; i < nComponents ; i++ ) {
|
||||
autostartComponent( i );
|
||||
this.autostartComponent( i );
|
||||
}
|
||||
this.initialised = true;
|
||||
}
|
||||
|
@ -370,18 +370,18 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
for ( int i = this.components.size( ) - 1 ; i >= 0 ; i-- ) {
|
||||
stopComponent( i );
|
||||
this.stopComponent( i );
|
||||
}
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
|
||||
private void fillSingletonFields( SingletonClass info )
|
||||
private void fillSingletonFields( final SingletonClass info )
|
||||
throws ComponentManagementException , AmbiguousComponentException
|
||||
{
|
||||
HashMap< Field , Object > matches = new HashMap< >( );
|
||||
for ( Field fld : info.missingFields ) {
|
||||
ComponentSingleton cs = fld.getAnnotation( ComponentSingleton.class );
|
||||
final HashMap< Field , Object > matches = new HashMap< >( );
|
||||
for ( final Field fld : info.missingFields ) {
|
||||
final ComponentSingleton cs = fld.getAnnotation( ComponentSingleton.class );
|
||||
ComponentState target;
|
||||
if ( "".equals( cs.value( ) ) ) {
|
||||
target = this.getState( fld.getType( ) );
|
||||
|
@ -397,10 +397,10 @@ public class ComponentRegistry
|
|||
return;
|
||||
}
|
||||
|
||||
for ( Map.Entry< Field , Object > entry : matches.entrySet( ) ) {
|
||||
for ( final Map.Entry< Field , Object > entry : matches.entrySet( ) ) {
|
||||
try {
|
||||
entry.getKey( ).set( null , entry.getValue( ) );
|
||||
} catch ( IllegalAccessException e ) {
|
||||
} catch ( final IllegalAccessException e ) {
|
||||
throw new ComponentManagementException( "internal error while setting singleton" , e );
|
||||
}
|
||||
}
|
||||
|
@ -409,30 +409,30 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
|
||||
private static int resolveNewDependencies( ArrayList< TempBuildRec > adding ,
|
||||
ArrayList< ComponentState > nComponents , HashMap< String , ComponentState > byName ,
|
||||
HashMap< Class< ? > , ArrayList< ComponentState > > byType )
|
||||
private static int resolveNewDependencies( final ArrayList< TempBuildRec > adding ,
|
||||
final ArrayList< ComponentState > nComponents , final HashMap< String , ComponentState > byName ,
|
||||
final HashMap< Class< ? > , ArrayList< ComponentState > > byType )
|
||||
throws AmbiguousComponentException , DuplicateComponentException
|
||||
{
|
||||
int size = adding.size( );
|
||||
final int size = adding.size( );
|
||||
int found = 0;
|
||||
|
||||
for ( int i = 0 ; i < size ; i++ ) {
|
||||
TempBuildRec rec = adding.get( i );
|
||||
if ( rec.added || !checkDependencies( byName , byType , rec ) ) {
|
||||
final TempBuildRec rec = adding.get( i );
|
||||
if ( rec.added || !ComponentRegistry.checkDependencies( byName , byType , rec ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the component
|
||||
found++;
|
||||
nComponents.add( rec.state );
|
||||
String name = rec.state.getName( );
|
||||
final String name = rec.state.getName( );
|
||||
if ( name != null ) {
|
||||
if ( byName.put( name , rec.state ) != null ) {
|
||||
throw new DuplicateComponentException( name );
|
||||
}
|
||||
}
|
||||
for ( Class< ? > cls : Classes.getAllTypes( rec.state.getComponent( ).getClass( ) ) ) {
|
||||
for ( final Class< ? > cls : Classes.getAllTypes( rec.state.getComponent( ).getClass( ) ) ) {
|
||||
if ( cls == Object.class ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -450,12 +450,12 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
|
||||
private static boolean checkDependencies( HashMap< String , ComponentState > byName ,
|
||||
HashMap< Class< ? > , ArrayList< ComponentState > > byType , TempBuildRec rec )
|
||||
private static boolean checkDependencies( final HashMap< String , ComponentState > byName ,
|
||||
final HashMap< Class< ? > , ArrayList< ComponentState > > byType , final TempBuildRec rec )
|
||||
throws AmbiguousComponentException
|
||||
{
|
||||
boolean depsOk = true;
|
||||
for ( DependencyInfo dep : rec.info.getDependencies( ) ) {
|
||||
for ( final DependencyInfo dep : rec.info.getDependencies( ) ) {
|
||||
if ( rec.deps.containsKey( dep ) ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -465,7 +465,7 @@ public class ComponentRegistry
|
|||
cs = byName.get( dep.getTargetName( ) );
|
||||
continue;
|
||||
} else {
|
||||
ArrayList< ComponentState > lt = byType.get( dep.getTargetClass( ) );
|
||||
final ArrayList< ComponentState > lt = byType.get( dep.getTargetClass( ) );
|
||||
if ( lt == null ) {
|
||||
cs = null;
|
||||
} else if ( lt.size( ) == 1 ) {
|
||||
|
@ -485,24 +485,24 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
|
||||
private static void injectDependencies( ArrayList< TempBuildRec > adding )
|
||||
private static void injectDependencies( final ArrayList< TempBuildRec > adding )
|
||||
throws DependencyInjectionException
|
||||
{
|
||||
int size = adding.size( );
|
||||
final int size = adding.size( );
|
||||
|
||||
for ( int i = 0 ; i < size ; i++ ) {
|
||||
TempBuildRec rec = adding.get( i );
|
||||
Object cmp = rec.state.getComponent( );
|
||||
for ( Map.Entry< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > di : rec.info
|
||||
final TempBuildRec rec = adding.get( i );
|
||||
final Object cmp = rec.state.getComponent( );
|
||||
for ( final Map.Entry< DependencyInfo , ArrayList< ThrowingBiConsumer< Object , Object > > > di : rec.info
|
||||
.getInjectors( ).entrySet( ) ) {
|
||||
ComponentState toInject = rec.deps.get( di.getKey( ) );
|
||||
final ComponentState toInject = rec.deps.get( di.getKey( ) );
|
||||
assert toInject != null;
|
||||
for ( ThrowingBiConsumer< Object , Object > action : di.getValue( ) ) {
|
||||
for ( final ThrowingBiConsumer< Object , Object > action : di.getValue( ) ) {
|
||||
try {
|
||||
action.accept( cmp , toInject.getComponent( ) );
|
||||
} catch ( FunctionException e ) {
|
||||
} catch ( final FunctionException e ) {
|
||||
throw new DependencyInjectionException( rec.state , toInject , e.getCause( ) );
|
||||
} catch ( RuntimeException e ) {
|
||||
} catch ( final RuntimeException e ) {
|
||||
throw new DependencyInjectionException( rec.state , toInject , e );
|
||||
}
|
||||
}
|
||||
|
@ -510,59 +510,59 @@ public class ComponentRegistry
|
|||
}
|
||||
|
||||
for ( int i = 0 ; i < size ; i++ ) {
|
||||
TempBuildRec rec = adding.get( i );
|
||||
for ( ComponentState dep : rec.deps.values( ) ) {
|
||||
final TempBuildRec rec = adding.get( i );
|
||||
for ( final ComponentState dep : rec.deps.values( ) ) {
|
||||
rec.state.addDependency( dep );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void initComponent( int index )
|
||||
private void initComponent( final int index )
|
||||
throws ComponentInitialisationException
|
||||
{
|
||||
try {
|
||||
this.components.get( index ).init( );
|
||||
} catch ( RuntimeException e ) {
|
||||
} catch ( final RuntimeException e ) {
|
||||
this.failed = true;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void autostartComponent( int index )
|
||||
private void autostartComponent( final int index )
|
||||
throws ComponentStartupException
|
||||
{
|
||||
try {
|
||||
ComponentState cmp = this.components.get( index );
|
||||
final ComponentState cmp = this.components.get( index );
|
||||
if ( cmp.hasAutostart( ) ) {
|
||||
cmp.start( );
|
||||
}
|
||||
} catch ( RuntimeException e ) {
|
||||
} catch ( final RuntimeException e ) {
|
||||
this.failed = true;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void stopComponent( int index )
|
||||
private void stopComponent( final int index )
|
||||
throws ComponentDestructionException
|
||||
{
|
||||
try {
|
||||
this.components.get( index ).stop( );
|
||||
} catch ( RuntimeException e ) {
|
||||
} catch ( final RuntimeException e ) {
|
||||
this.failed = true;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void destroyComponent( int index )
|
||||
private void destroyComponent( final int index )
|
||||
throws ComponentDestructionException
|
||||
{
|
||||
try {
|
||||
this.components.get( index ).destroy( );
|
||||
} catch ( RuntimeException e ) {
|
||||
} catch ( final RuntimeException e ) {
|
||||
this.failed = true;
|
||||
throw e;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue