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 import org.kuali.student.contract.model.impl.ServiceContractModelPescXsdLoader;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 public class ComplexSubstructuresHelper {
36
37 private static Logger log = LoggerFactory.getLogger(ComplexSubstructuresHelper.class);
38
39
40 public Set<String> getComplexStructures(String className) {
41 Set<String> complexStructures = new LinkedHashSet<String>();
42 loadComplexStructures(className, complexStructures);
43 return complexStructures;
44 }
45
46 private void loadComplexStructures(String className,
47 Set<String> complexStructures) {
48 if (!complexStructures.add(className)) {
49 return;
50 }
51 BeanInfo beanInfo;
52 Class<?> clazz;
53 try {
54 clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
55
56
57
58 } catch (ClassNotFoundException ex) {
59 log.warn("ComplexSubstructuresHelper: Could not process because the class must be a freestanding object: " + className);
60 return;
61 }
62 try {
63 beanInfo = Introspector.getBeanInfo(clazz);
64 } catch (IntrospectionException ex) {
65 throw new RuntimeException(ex);
66 }
67 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
68 Class<?> subClass = pd.getPropertyType();
69 if (List.class.equals(subClass)) {
70
71 subClass = getActualClassFromList(clazz, pd.getName());
72 }
73 if (!Class.class.equals(subClass)
74 && !String.class.equals(subClass)
75 && !Integer.class.equals(subClass)
76 && !Long.class.equals(subClass)
77 && !Boolean.class.equals(subClass)
78 && !boolean.class.equals(subClass)
79 && !int.class.equals(subClass)
80 && !long.class.equals(subClass)
81 && !Double.class.equals(subClass)
82 && !Float.class.equals(subClass)
83 && !Date.class.equals(subClass)
84 && !Enum.class.isAssignableFrom(subClass)
85 && !Object.class.equals(subClass)) {
86 loadComplexStructures(subClass.getName(), complexStructures);
87 }
88 }
89 }
90
91 public static Class<?> getActualClassFromList(Class<?> originalClass, String fieldName) {
92 if (originalClass.isInterface()) {
93 throw new RuntimeException("Interface used in getter, use xxxInfo instead for field: " + originalClass.getName() + "." + fieldName);
94 }
95
96 Class<?> classToCheck = originalClass;
97 while (true) {
98 try {
99 Field field = classToCheck.getDeclaredField(fieldName);
100 Type type = field.getGenericType();
101 ParameterizedType pt = (ParameterizedType) type;
102 Type actualType = pt.getActualTypeArguments()[0];
103 return (Class<?>) actualType;
104 } catch (NoSuchFieldException ex) {
105 classToCheck = classToCheck.getSuperclass();
106 if (classToCheck == null) {
107 throw new RuntimeException("No such field: " + originalClass.getName() + "." + fieldName, ex);
108 }
109 if (classToCheck.equals(Object.class)) {
110 throw new RuntimeException("No such field: " + originalClass.getName() + "." + fieldName, ex);
111 }
112 } catch (SecurityException ex) {
113 throw new RuntimeException(originalClass.getName() + "." + fieldName, ex);
114 }
115 }
116 }
117 }