Annotations-related helpers
This commit is contained in:
parent
ea9563c324
commit
d633aac37d
1 changed files with 200 additions and 0 deletions
200
src/main/java/info/ebenoit/ebul/reflection/Annotations.java
Normal file
200
src/main/java/info/ebenoit/ebul/reflection/Annotations.java
Normal file
|
@ -0,0 +1,200 @@
|
|||
package info.ebenoit.ebul.reflection;
|
||||
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helpers to deal with annotated methods, fields or classes.
|
||||
*
|
||||
* @author <a href="mailto:ebenoit@ebenoit.info">E. Benoît</a>
|
||||
*/
|
||||
public final class Annotations
|
||||
{
|
||||
|
||||
/**
|
||||
* Finds all declared methods that have a specific annotation in a given class
|
||||
*
|
||||
* @param target
|
||||
* the class to examine
|
||||
* @param annotation
|
||||
* the annotation that must be present
|
||||
* @return the list of methods that have the specified annotation
|
||||
*/
|
||||
public static final ArrayList< Method > findAnnotatedMethods( final Class< ? > target ,
|
||||
final Class< ? extends Annotation > annotation )
|
||||
{
|
||||
final ArrayList< Method > methods = new ArrayList< >( );
|
||||
Annotations.findAnnotatedMethods( methods , target , annotation );
|
||||
return methods;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds all declared methods that have a specific annotation in a given class and adds them to an existing
|
||||
* {@link Collection}.
|
||||
*
|
||||
* @param output
|
||||
* the collection to which methods will be added
|
||||
* @param target
|
||||
* the class to examine
|
||||
* @param annotation
|
||||
* the annotation that must be present
|
||||
* @return the output collection
|
||||
*/
|
||||
public static final Collection< Method > findAnnotatedMethods( final Collection< Method > output ,
|
||||
final Class< ? > target , final Class< ? extends Annotation > annotation )
|
||||
{
|
||||
for ( final Method m : target.getDeclaredMethods( ) ) {
|
||||
if ( m.isAnnotationPresent( annotation ) ) {
|
||||
output.add( m );
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds all declared fields that have a specific annotation in a given class
|
||||
*
|
||||
* @param target
|
||||
* the class to examine
|
||||
* @param annotation
|
||||
* the annotation that must be present
|
||||
* @return the list of fields that have the specified annotation
|
||||
*/
|
||||
public static final ArrayList< Field > findAnnotatedFields( final Class< ? > target ,
|
||||
final Class< ? extends Annotation > annotation )
|
||||
{
|
||||
final ArrayList< Field > fields = new ArrayList< >( );
|
||||
Annotations.findAnnotatedFields( fields , target , annotation );
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds all declared fields that have a specific annotation in a given class and adds them to an existing
|
||||
* {@link Collection}.
|
||||
*
|
||||
* @param output
|
||||
* the output collection
|
||||
* @param target
|
||||
* the class to examine
|
||||
* @param annotation
|
||||
* the annotation that must be present
|
||||
* @return the output collection
|
||||
*/
|
||||
public static final Collection< Field > findAnnotatedFields( final Collection< Field > output ,
|
||||
final Class< ? > target , final Class< ? extends Annotation > annotation )
|
||||
{
|
||||
for ( final Field f : target.getDeclaredFields( ) ) {
|
||||
if ( f.isAnnotationPresent( annotation ) ) {
|
||||
output.add( f );
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies a function to declared methods with a specific annotation
|
||||
*
|
||||
* @param target
|
||||
* the class to examine
|
||||
* @param annotation
|
||||
* the annotation that must be present
|
||||
* @param function
|
||||
* the function to apply to the methods
|
||||
*/
|
||||
public static final void applyToAnnotatedMethods( final Class< ? > target ,
|
||||
final Class< ? extends Annotation > annotation , final Consumer< Method > function )
|
||||
{
|
||||
for ( final Method m : target.getDeclaredMethods( ) ) {
|
||||
if ( m.isAnnotationPresent( annotation ) ) {
|
||||
function.accept( m );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies a function to declared fields with a specific annotation
|
||||
*
|
||||
* @param target
|
||||
* the class to examine
|
||||
* @param annotation
|
||||
* the annotation that must be present
|
||||
* @param function
|
||||
* the function to apply to the fields
|
||||
*/
|
||||
public static final void applyToAnnotatedFields( final Class< ? > target ,
|
||||
final Class< ? extends Annotation > annotation , final Consumer< Field > function )
|
||||
{
|
||||
for ( final Field f : target.getDeclaredFields( ) ) {
|
||||
if ( f.isAnnotationPresent( annotation ) ) {
|
||||
function.accept( f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds the closest class in a hierarchy that has the specified annotation.
|
||||
* <p>
|
||||
* For example, assuming class A extends B which extends C which extends D, both B and C having the annotation, this
|
||||
* method will return B if called on A or B.
|
||||
*
|
||||
* @param klass
|
||||
* the class to examine
|
||||
* @param annotation
|
||||
* the annotation to look for
|
||||
* @return the closest class with the specified annotation in the hierarchy, or <code>null</code> if the annotation
|
||||
* is not present.
|
||||
*/
|
||||
public static final < T > Class< ? super T > findClosestClass( final Class< T > klass ,
|
||||
final Class< ? extends Annotation > annotation )
|
||||
{
|
||||
Class< ? super T > current = klass;
|
||||
while ( current != null ) {
|
||||
if ( current.isAnnotationPresent( annotation ) ) {
|
||||
return current;
|
||||
}
|
||||
current = current.getSuperclass( );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds the farthest class in a hierarchy that has the specified annotation.
|
||||
* <p>
|
||||
* For example, assuming class A extends B which extends C which extends D, both B and C having the annotation, this
|
||||
* method will return C if called on A or B.
|
||||
*
|
||||
* @param klass
|
||||
* the class to examine
|
||||
* @param annotation
|
||||
* the annotation to look for
|
||||
* @return the farthest class with the specified annotation in the hierarchy, or <code>null</code> if the annotation
|
||||
* is not present.
|
||||
*/
|
||||
public static final < T > Class< ? super T > findFarthestClass( final Class< T > klass ,
|
||||
final Class< ? extends Annotation > annotation )
|
||||
{
|
||||
Class< ? super T > found = null , current = klass;
|
||||
while ( current != null ) {
|
||||
if ( current.isAnnotationPresent( annotation ) ) {
|
||||
found = current;
|
||||
}
|
||||
current = current.getSuperclass( );
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue