Method that checks for a class matching a predicate in hierarchy

This commit is contained in:
Emmanuel BENOîT 2015-09-16 17:15:50 +02:00
parent 48252c20b5
commit f3c535c967
2 changed files with 83 additions and 3 deletions

View file

@ -3,6 +3,7 @@ package info.ebenoit.ebul.reflection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.function.Predicate;
@ -16,7 +17,7 @@ public final class Classes
/**
* List all classes a class inherits from.
*
*
* @param cls
* the class to examine
* @return the list of ancestors, including the class itself
@ -35,7 +36,7 @@ public final class Classes
/**
* Find all types a class is compatible with: itself, its ancestors, and all implemented interfaces.
*
*
* @param cls
* the class to examine
* @return the set of compatible types
@ -54,8 +55,43 @@ public final class Classes
/**
* Internal method used by {@link #getAllTypes(Class)} to add all interfaces recursively.
* Checks for a class (or optionally an interface) matching a predicate in a class hierarchy.
*
* @param klass
* the class to start checking from
* @param test
* the predicate
* @param interfaces
* <code>true</code> if interfaces will be tested, <code>false</code> if the test is to be applied to
* actual classes only
* @return <code>true</code> if any class or interface matches the test, <code>false</code> if none of them do.
*/
public static boolean hasAncestorMatching( final Class< ? > klass , final Predicate< Class< ? > > test ,
final boolean interfaces )
{
if ( klass == null ) {
return false;
}
if ( test.test( klass ) ) {
return true;
}
if ( interfaces ) {
for ( final Class< ? > itf : klass.getInterfaces( ) ) {
if ( Classes.hasAncestorMatching( itf , test , true ) ) {
return true;
}
}
}
return Classes.hasAncestorMatching( klass.getSuperclass( ) , test , interfaces );
}
/**
* Internal method used by {@link #getAllTypes(Class)} to add all interfaces recursively.
*
* @param current
* the class or interface being examined
* @param found

View file

@ -98,4 +98,48 @@ public class TestClasses
Assert.assertEquals( expected , result );
}
/**
* Test: {@link Classes#hasAncestorMatching(Class, java.util.function.Predicate, boolean)} finds class itself in
* hierarchy
*/
@Test
public void testHasAncestorMatchingSelf( )
{
Assert.assertTrue( Classes.hasAncestorMatching( CTest4.class , c -> c == CTest4.class , false ) );
}
/**
* Test: {@link Classes#hasAncestorMatching(Class, java.util.function.Predicate, boolean)} finds top of class
* hierarchy
*/
@Test
public void testHasAncestorMatchingTopOfHierarchy( )
{
Assert.assertTrue( Classes.hasAncestorMatching( CTest4.class , c -> c == Object.class , false ) );
}
/**
* Test: {@link Classes#hasAncestorMatching(Class, java.util.function.Predicate, boolean)} doesn't look at
* interfaces if told not to
*/
@Test
public void testHasAncestorMatchingNoInterfaces( )
{
Assert.assertFalse( Classes.hasAncestorMatching( CTest5.class , c -> c == ITest1.class , false ) );
}
/**
* Test: {@link Classes#hasAncestorMatching(Class, java.util.function.Predicate, boolean)} looks at interfaces if
* told to
*/
@Test
public void testHasAncestorMatchingInterfaces( )
{
Assert.assertTrue( Classes.hasAncestorMatching( CTest5.class , c -> c == ITest1.class , true ) );
}
}