diff --git a/common/source/java/ch/systemsx/cisd/common/utilities/ClassUtils.java b/common/source/java/ch/systemsx/cisd/common/utilities/ClassUtils.java index b5e5a156797e22fe8f9b037bf62a043c4ee42905..6fa03646ecc0c87fab5b07fe5f34fcacdb63830a 100644 --- a/common/source/java/ch/systemsx/cisd/common/utilities/ClassUtils.java +++ b/common/source/java/ch/systemsx/cisd/common/utilities/ClassUtils.java @@ -21,6 +21,9 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Set; import org.apache.commons.lang.StringUtils; @@ -37,6 +40,33 @@ public final class ClassUtils { // Can not be instantiated. } + + /** + * Gathers all classes and interfaces the specified object can be casted to. + */ + public static Collection<Class<?>> gatherAllCastableClassesAndInterfacesFor(Object object) + { + assert object != null; + + Set<Class<?>> classes = new LinkedHashSet<Class<?>>(); + gather(classes, object.getClass()); + return classes; + } + + private static void gather(Set<Class<?>> classes, Class<?> clazz) + { + classes.add(clazz); + Class<?> superclass = clazz.getSuperclass(); + if (superclass != null) + { + gather(classes, superclass); + } + Class<?>[] interfaces = clazz.getInterfaces(); + for (Class<?> interfaze : interfaces) + { + gather(classes, interfaze); + } + } /** * Returns the currently called <code>Method</code>. diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ClassUtilsTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ClassUtilsTest.java index c53fafd749af5720d599885f6fbc9bfc4dab844d..11c40f20b9f7b9306758cc60129aa43be34b229b 100644 --- a/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ClassUtilsTest.java +++ b/common/sourceTest/java/ch/systemsx/cisd/common/utilities/ClassUtilsTest.java @@ -26,6 +26,8 @@ import static org.testng.AssertJUnit.fail; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Properties; @@ -38,6 +40,29 @@ import org.testng.annotations.Test; */ public final class ClassUtilsTest { + private static interface IA {} + private static interface IExtendingIA extends IA {} + private static interface IB {} + private static class A {} + private static class ExtendingA extends A implements IExtendingIA {} + private static class ExtendingExtendingA extends ExtendingA implements IB, IA {} + + @Test + public void testGatherAllCastableClassesAndInterfacesFor() + { + ExtendingExtendingA object = new ExtendingExtendingA(); + Collection<Class<?>> classes = ClassUtils.gatherAllCastableClassesAndInterfacesFor(object); + Iterator<Class<?>> iterator = classes.iterator(); + assertSame(ExtendingExtendingA.class, iterator.next()); + assertSame(ExtendingA.class, iterator.next()); + assertSame(A.class, iterator.next()); + assertSame(Object.class, iterator.next()); + assertSame(IExtendingIA.class, iterator.next()); + assertSame(IA.class, iterator.next()); + assertSame(IB.class, iterator.next()); + + assertEquals(false, iterator.hasNext()); + } /** * Test method for {@link ch.systemsx.cisd.common.utilities.ClassUtils#getCurrentMethod()}.