Fix SubclassClassifier so it recognizes multiple parents

Prior to this fix interfaces with multiple parents were not
recognized.
This commit is contained in:
Dave Syer
2020-04-08 11:34:01 +01:00
parent b279131e40
commit 39cf01dc19
2 changed files with 47 additions and 4 deletions

View File

@@ -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<T, C> implements Classifier<T, C> {
/**
* 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<Class<? extends T>, C> typeMap, C defaultValue) {
super();
@@ -115,7 +119,7 @@ public class SubclassClassifier<T, C> implements Classifier<T, C> {
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<T, C> implements Classifier<T, C> {
return this.classified;
}
private static Set<Class<?>> getAllInterfacesForClass(Class<?> cls) {
Set<Class<?>> set = new HashSet<Class<?>>();
getAllInterfacesForClass(cls, set);
return set;
}
private static void getAllInterfacesForClass(Class<?> cls, Set<Class<?>> set) {
set.addAll(ClassUtils.getAllInterfacesForClassAsSet(cls));
for (Class<?> ifc : cls.getInterfaces()) {
getAllInterfacesForClass(ifc, set);
}
}
}

View File

@@ -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<Object, String> classifier = new SubclassClassifier<Object, String>();
classifier.setTypeMap(
Collections.<Class<?>, String>singletonMap(Supplier.class, "foo"));
assertEquals("foo", classifier.classify(new Spam()));
}
@Test
public void testClassifyInterfaceOfParent() {
SubclassClassifier<Object, String> classifier = new SubclassClassifier<Object, String>();
@@ -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<String>, Callable<String> {
}
}