NewComponentInfo - Fixed default constructor access
This commit is contained in:
parent
93e8c9a90e
commit
095ecca3dc
1 changed files with 47 additions and 1 deletions
|
@ -1,6 +1,7 @@
|
|||
package info.ebenoit.ebul.cmp;
|
||||
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
@ -12,6 +13,7 @@ import java.util.HashSet;
|
|||
import info.ebenoit.ebul.func.ThrowingBiConsumer;
|
||||
import info.ebenoit.ebul.func.ThrowingConsumer;
|
||||
import info.ebenoit.ebul.func.ThrowingSupplier;
|
||||
import info.ebenoit.ebul.reflection.MemberFinder;
|
||||
|
||||
|
||||
|
||||
|
@ -23,16 +25,34 @@ import info.ebenoit.ebul.func.ThrowingSupplier;
|
|||
*/
|
||||
public final class NewComponentInfo< T >
|
||||
{
|
||||
/** Member finder that looks for the default constructor */
|
||||
private static final MemberFinder< Constructor< ? > > CONSTRUCTOR_FINDER;
|
||||
|
||||
|
||||
static {
|
||||
CONSTRUCTOR_FINDER = new MemberFinder< >( ( final Class< ? > c ) -> c.getDeclaredConstructors( ) , false );
|
||||
NewComponentInfo.CONSTRUCTOR_FINDER
|
||||
.setMemberFilter( ( final Constructor< ? > c ) -> c.getParameterCount( ) == 0 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new component information record based on a component's annotated class.
|
||||
*
|
||||
* @param klass
|
||||
* the class to extract the information from
|
||||
* @return the generated information record
|
||||
* @throws ComponentDefinitionException
|
||||
* if the class cannot be used as a component
|
||||
*/
|
||||
public static < T > NewComponentInfo< T > fromClass( final Class< T > klass )
|
||||
throws ComponentDefinitionException
|
||||
{
|
||||
final NewComponentInfo< T > info = new NewComponentInfo< >( ( ) -> klass.newInstance( ) );
|
||||
final Constructor< ? > constructor = NewComponentInfo.getDefaultConstructor( klass );
|
||||
constructor.setAccessible( true );
|
||||
final NewComponentInfo< T > info = new NewComponentInfo< T >( ( ) -> {
|
||||
return klass.cast( constructor.newInstance( ) );
|
||||
} );
|
||||
|
||||
// Sets the new component's name
|
||||
final Component aComp = klass.getAnnotation( Component.class );
|
||||
|
@ -68,6 +88,32 @@ public final class NewComponentInfo< T >
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds the default constructor for the specified class
|
||||
*
|
||||
* @param klass
|
||||
* the class
|
||||
* @return the default constructor (even if it is private)
|
||||
* @throws ComponentDefinitionException
|
||||
* if there is no default constructor
|
||||
*/
|
||||
private static < T > Constructor< ? > getDefaultConstructor( final Class< T > klass )
|
||||
throws ComponentDefinitionException
|
||||
{
|
||||
final ArrayList< Constructor< ? > > constructors = new ArrayList< >( );
|
||||
NewComponentInfo.CONSTRUCTOR_FINDER.find( constructors , klass );
|
||||
if ( constructors.isEmpty( ) ) {
|
||||
throw new ComponentDefinitionException( "could not find default constructor in " + klass );
|
||||
}
|
||||
|
||||
final Constructor< ? > constructor = constructors.get( 0 );
|
||||
if ( constructor.getDeclaringClass( ) != klass ) {
|
||||
throw new ComponentDefinitionException( "could not find default constructor in " + klass );
|
||||
}
|
||||
return constructor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds annotations from the members of a component's class and of its ancestors
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue