1
16 package org.springframework.data.querydsl;
17
18 import java.lang.reflect.Field;
19 import java.lang.reflect.Modifier;
20 import java.util.Optional;
21
22 import org.springframework.util.Assert;
23 import org.springframework.util.ClassUtils;
24 import org.springframework.util.ReflectionUtils;
25
26 import com.querydsl.core.types.EntityPath;
27
28
35 public class SimpleEntityPathResolver implements EntityPathResolver {
36
37 private static final String NO_CLASS_FOUND_TEMPLATE = "Did not find a query class %s for domain class %s!";
38 private static final String NO_FIELD_FOUND_TEMPLATE = "Did not find a static field of the same type in %s!";
39
40 public static final SimpleEntityPathResolver INSTANCE = new SimpleEntityPathResolver("");
41
42 private final String querySuffix;
43
44
49 public SimpleEntityPathResolver(String querySuffix) {
50
51 Assert.notNull(querySuffix, "Query suffix must not be null!");
52
53 this.querySuffix = querySuffix;
54 }
55
56
64 @SuppressWarnings("unchecked")
65 public <T> EntityPath<T> createPath(Class<T> domainClass) {
66
67 String pathClassName = getQueryClassName(domainClass);
68
69 try {
70
71 Class<?> pathClass = ClassUtils.forName(pathClassName, domainClass.getClassLoader());
72
73 return getStaticFieldOfType(pathClass)
74 .map(it -> (EntityPath<T>) ReflectionUtils.getField(it, null))
75 .orElseThrow(() -> new IllegalStateException(String.format(NO_FIELD_FOUND_TEMPLATE, pathClass)));
76
77 } catch (ClassNotFoundException e) {
78 throw new IllegalArgumentException(String.format(NO_CLASS_FOUND_TEMPLATE, pathClassName, domainClass.getName()),
79 e);
80 }
81 }
82
83
89 private Optional<Field> getStaticFieldOfType(Class<?> type) {
90
91 for (Field field : type.getDeclaredFields()) {
92
93 boolean isStatic = Modifier.isStatic(field.getModifiers());
94 boolean hasSameType = type.equals(field.getType());
95
96 if (isStatic && hasSameType) {
97 return Optional.of(field);
98 }
99 }
100
101 Class<?> superclass = type.getSuperclass();
102 return Object.class.equals(superclass) ? Optional.empty() : getStaticFieldOfType(superclass);
103 }
104
105
111 private String getQueryClassName(Class<?> domainClass) {
112
113 String simpleClassName = ClassUtils.getShortName(domainClass);
114 String packageName = domainClass.getPackage().getName();
115
116 return String.format("%s%s.Q%s%s", packageName, querySuffix, getClassBase(simpleClassName),
117 domainClass.getSimpleName());
118 }
119
120
126 private String getClassBase(String shortName) {
127
128 String[] parts = shortName.split("\\.");
129
130 return parts.length < 2 ? "" : parts[0] + "_";
131 }
132 }
133