Skip to content

Commit dc854ef

Browse files
authored
Merge pull request #239 from domaframework/issue-238
Resolve an external domain class by traversing class hierarchy
2 parents 8c6495e + 1327b8d commit dc854ef

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

src/main/java/org/seasar/doma/internal/util/ClassUtil.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Arrays;
2424
import java.util.Collections;
2525
import java.util.List;
26+
import java.util.function.Function;
2627

2728
import org.seasar.doma.internal.WrapException;
2829

@@ -152,4 +153,30 @@ public static Class<?> toBoxedPrimitiveTypeIfPossible(Class<?> clazz) {
152153
}
153154
return clazz;
154155
}
156+
157+
public static <R> R traverse(Class<?> clazz, Function<Class<?>, R> f) {
158+
assertNotNull(clazz);
159+
{
160+
R result = f.apply(clazz);
161+
if (result != null) {
162+
return result;
163+
}
164+
}
165+
for (Class<?> c : clazz.getInterfaces()) {
166+
R result = traverse(c, f);
167+
if (result != null) {
168+
return result;
169+
}
170+
}
171+
Class<?> superclass = clazz.getSuperclass();
172+
if (superclass == null) {
173+
return null;
174+
}
175+
R result = traverse(superclass, f);
176+
if (result != null) {
177+
return result;
178+
}
179+
return null;
180+
}
181+
155182
}

src/main/java/org/seasar/doma/jdbc/domain/DomainTypeFactory.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,21 @@ public static <BASIC, DOMAIN> DomainType<BASIC, DOMAIN> getExternalDomainType(
151151
if (classHelper == null) {
152152
throw new DomaNullPointerException("classHelper");
153153
}
154-
String domainTypeClassName = Constants.EXTERNAL_DOMAIN_METATYPE_ROOT_PACKAGE
155-
+ "." + Conventions.toFullMetaName(domainClass.getName());
154+
Class<?> clazz = ClassUtil.traverse(domainClass, c -> {
155+
String domainTypeClassName = Constants.EXTERNAL_DOMAIN_METATYPE_ROOT_PACKAGE
156+
+ "." + Conventions.toFullMetaName(c.getName());
157+
try {
158+
return classHelper.forName(domainTypeClassName);
159+
} catch (WrapException e) {
160+
return null;
161+
} catch (Exception e) {
162+
return null;
163+
}
164+
});
165+
if (clazz == null) {
166+
return null;
167+
}
156168
try {
157-
Class<DOMAIN> clazz = classHelper.forName(domainTypeClassName);
158169
Method method = ClassUtil.getMethod(clazz, "getSingletonInternal");
159170
return MethodUtil.invoke(method, null);
160171
} catch (WrapException e) {

src/test/java/org/seasar/doma/internal/util/ClassUtilTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.lang.reflect.Constructor;
1919
import java.lang.reflect.Field;
20+
import java.util.ArrayList;
2021
import java.util.List;
2122

2223
import junit.framework.TestCase;
@@ -70,4 +71,39 @@ public void testGetEnclosingNames_nestedClass() {
7071
assertEquals("Ddd", names.get(1));
7172
}
7273

74+
public void testTraverse() throws Exception {
75+
List<Class<?>> list = new ArrayList<>();
76+
ClassUtil.traverse(Ccc.class, c -> {
77+
list.add(c);
78+
return null;
79+
});
80+
assertEquals(8, list.size());
81+
assertEquals(Ccc.class, list.get(0));
82+
assertEquals(ICcc.class, list.get(1));
83+
assertEquals(Bbb.class, list.get(2));
84+
assertEquals(IBbb.class, list.get(3));
85+
assertEquals(IAaa.class, list.get(4));
86+
assertEquals(Aaa.class, list.get(5));
87+
assertEquals(IAaa.class, list.get(6));
88+
assertEquals(Object.class, list.get(7));
89+
}
90+
91+
private interface IAaa {
92+
}
93+
94+
private interface IBbb extends IAaa {
95+
}
96+
97+
private interface ICcc {
98+
}
99+
100+
private static class Aaa implements IAaa {
101+
}
102+
103+
private static class Bbb extends Aaa implements IBbb {
104+
}
105+
106+
private static class Ccc extends Bbb implements ICcc {
107+
}
108+
73109
}

0 commit comments

Comments
 (0)