1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.datadictionary.util;
17
18 import java.beans.BeanInfo;
19 import java.beans.IntrospectionException;
20 import java.beans.Introspector;
21 import java.beans.PropertyDescriptor;
22 import java.lang.reflect.Field;
23 import java.lang.reflect.ParameterizedType;
24 import java.lang.reflect.Type;
25 import java.lang.reflect.TypeVariable;
26 import java.util.Date;
27 import java.util.LinkedHashSet;
28 import java.util.List;
29 import java.util.Set;
30
31 public class ComplexSubstructuresHelper {
32
33 public Set<String> getComplexStructures(String className) {
34 Set<String> complexStructures = new LinkedHashSet<String>();
35 loadComplexStructures(className, complexStructures);
36 return complexStructures;
37 }
38
39 private void loadComplexStructures(String className,
40 Set<String> complexStructures) {
41 if (!complexStructures.add(className)) {
42 return;
43 }
44 BeanInfo beanInfo;
45 Class<?> clazz;
46 try {
47 clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
48
49
50
51 } catch (ClassNotFoundException ex) {
52 System.out.println("ComplexSubstructuresHelper: Could not process because the class must be a freestanding object: " + className);
53 return;
54 }
55 try {
56 beanInfo = Introspector.getBeanInfo(clazz);
57 } catch (IntrospectionException ex) {
58 throw new RuntimeException(ex);
59 }
60 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
61 Class<?> subClass = pd.getPropertyType();
62 if (List.class.equals(subClass)) {
63
64 subClass = getActualClassFromList(clazz, pd.getName());
65 }
66 if (!Class.class.equals(subClass)
67 && !String.class.equals(subClass)
68 && !Integer.class.equals(subClass)
69 && !Long.class.equals(subClass)
70 && !Boolean.class.equals(subClass)
71 && !boolean.class.equals(subClass)
72 && !int.class.equals(subClass)
73 && !long.class.equals(subClass)
74 && !Double.class.equals(subClass)
75 && !Float.class.equals(subClass)
76 && !Date.class.equals(subClass)
77 && !Enum.class.isAssignableFrom(subClass)
78 && !Object.class.equals(subClass)) {
79 loadComplexStructures(subClass.getName(), complexStructures);
80 }
81 }
82 }
83
84 public static Class<?> getActualClassFromList(Class<?> originalClass, String fieldName) {
85 if (originalClass.isInterface()) {
86 throw new RuntimeException("Interface used in getter, use xxxInfo instead for field: " + originalClass.getName() + "." + fieldName);
87 }
88
89 Class<?> classToCheck = originalClass;
90 while (true) {
91 try {
92 Field field = classToCheck.getDeclaredField(fieldName);
93 Type type = field.getGenericType();
94 ParameterizedType pt = (ParameterizedType) type;
95 Type actualType = pt.getActualTypeArguments()[0];
96 return (Class<?>) actualType;
97 } catch (NoSuchFieldException ex) {
98 classToCheck = classToCheck.getSuperclass();
99 if (classToCheck == null) {
100 throw new RuntimeException("No such field: " + originalClass.getName() + "." + fieldName, ex);
101 }
102 if (classToCheck.equals(Object.class)) {
103 throw new RuntimeException("No such field: " + originalClass.getName() + "." + fieldName, ex);
104 }
105 } catch (SecurityException ex) {
106 throw new RuntimeException(originalClass.getName() + "." + fieldName, ex);
107 }
108 }
109 }
110 }