From 39cf01dc1933c9054086cc693d44a4d8eae8fddc Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 8 Apr 2020 11:34:01 +0100 Subject: [PATCH] Fix SubclassClassifier so it recognizes multiple parents Prior to this fix interfaces with multiple parents were not recognized. --- .../classify/SubclassClassifier.java | 20 ++++++++++-- .../classify/SubclassClassifierTests.java | 31 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/springframework/classify/SubclassClassifier.java b/src/main/java/org/springframework/classify/SubclassClassifier.java index 900b98d..3894352 100644 --- a/src/main/java/org/springframework/classify/SubclassClassifier.java +++ b/src/main/java/org/springframework/classify/SubclassClassifier.java @@ -16,10 +16,14 @@ package org.springframework.classify; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import org.springframework.util.ClassUtils; + /** * A {@link Classifier} for a parameterised object type based on a map. Classifies objects * according to their inheritance relation with the supplied type map. If the object to be @@ -58,7 +62,7 @@ public class SubclassClassifier implements Classifier { /** * Create a {@link SubclassClassifier} with supplied default value. * @param defaultValue the default value - * @param typeMap the map of types + * @param typeMap the map of types */ public SubclassClassifier(Map, C> typeMap, C defaultValue) { super(); @@ -115,7 +119,7 @@ public class SubclassClassifier implements Classifier { if (value == null) { for (Class cls = exceptionClass; !cls.equals(Object.class) && value == null; cls = cls.getSuperclass()) { - for (Class ifc : cls.getInterfaces()) { + for (Class ifc : getAllInterfacesForClass(cls)) { value = this.classified.get(ifc); if (value != null) { break; @@ -148,4 +152,16 @@ public class SubclassClassifier implements Classifier { return this.classified; } + private static Set> getAllInterfacesForClass(Class cls) { + Set> set = new HashSet>(); + getAllInterfacesForClass(cls, set); + return set; + } + + private static void getAllInterfacesForClass(Class cls, Set> set) { + set.addAll(ClassUtils.getAllInterfacesForClassAsSet(cls)); + for (Class ifc : cls.getInterfaces()) { + getAllInterfacesForClass(ifc, set); + } + } } diff --git a/src/test/java/org/springframework/classify/SubclassClassifierTests.java b/src/test/java/org/springframework/classify/SubclassClassifierTests.java index 88efea9..5dcee41 100644 --- a/src/test/java/org/springframework/classify/SubclassClassifierTests.java +++ b/src/test/java/org/springframework/classify/SubclassClassifierTests.java @@ -16,13 +16,14 @@ package org.springframework.classify; +import static org.junit.Assert.assertEquals; + import java.util.Collections; +import java.util.concurrent.Callable; import java.util.function.Supplier; import org.junit.Test; -import static org.junit.Assert.assertEquals; - public class SubclassClassifierTests { @Test @@ -33,6 +34,14 @@ public class SubclassClassifierTests { assertEquals("foo", classifier.classify(new Foo())); } + @Test + public void testClassifyMultipleInterface() { + SubclassClassifier classifier = new SubclassClassifier(); + classifier.setTypeMap( + Collections., String>singletonMap(Supplier.class, "foo")); + assertEquals("foo", classifier.classify(new Spam())); + } + @Test public void testClassifyInterfaceOfParent() { SubclassClassifier classifier = new SubclassClassifier(); @@ -54,4 +63,22 @@ public class SubclassClassifierTests { } + public class Spam implements Mixer { + + @Override + public String get() { + return "foo"; + } + + @Override + public String call() throws Exception { + return "bar"; + } + + } + + public static interface Mixer extends Supplier, Callable { + + } + }