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;
|
package info.ebenoit.ebul.cmp;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
@ -12,6 +13,7 @@ import java.util.HashSet;
|
||||||
import info.ebenoit.ebul.func.ThrowingBiConsumer;
|
import info.ebenoit.ebul.func.ThrowingBiConsumer;
|
||||||
import info.ebenoit.ebul.func.ThrowingConsumer;
|
import info.ebenoit.ebul.func.ThrowingConsumer;
|
||||||
import info.ebenoit.ebul.func.ThrowingSupplier;
|
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 >
|
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.
|
* Creates a new component information record based on a component's annotated class.
|
||||||
*
|
*
|
||||||
* @param klass
|
* @param klass
|
||||||
* the class to extract the information from
|
* the class to extract the information from
|
||||||
* @return the generated information record
|
* @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 )
|
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
|
// Sets the new component's name
|
||||||
final Component aComp = klass.getAnnotation( Component.class );
|
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
|
* Finds annotations from the members of a component's class and of its ancestors
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue