Clover Coverage Report - KS Contract Documentation Generator 0.0.1-SNAPSHOT
Coverage timestamp: Wed Dec 31 1969 19:00:00 EST
../../../../../img/srcFileCovDistChart0.png 0% of files have more coverage
111   245   50   11.1
62   175   0.45   10
10     5  
1    
 
  Bean2DictionaryConverter       Line # 33 111 0% 50 183 0% 0.0
 
No Tests
 
1    /*
2    * Copyright 2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 1.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl1.php
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
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.Method;
23    import java.util.Date;
24    import java.util.List;
25    import java.util.Stack;
26    import org.kuali.rice.core.api.uif.DataType;
27    import org.kuali.rice.krad.datadictionary.AttributeDefinition;
28    import org.kuali.rice.krad.datadictionary.CollectionDefinition;
29    import org.kuali.rice.krad.datadictionary.ComplexAttributeDefinition;
30    import org.kuali.rice.krad.datadictionary.DataDictionaryDefinitionBase;
31    import org.kuali.rice.krad.datadictionary.DataObjectEntry;
32   
 
33    public class Bean2DictionaryConverter {
34   
35    private Class<?> clazz;
36    private Stack<DataDictionaryDefinitionBase> parentFields;
37    private Stack<Class<?>> parentClasses;
38   
 
39  0 toggle public Bean2DictionaryConverter(Class<?> clazz, Stack<DataDictionaryDefinitionBase> parentFields, Stack<Class<?>> parentClasses) {
40  0 this.clazz = clazz;
41  0 this.parentFields = parentFields;
42  0 this.parentClasses = parentClasses;
43    }
44   
 
45  0 toggle public DataObjectEntry convert() {
46  0 DataObjectEntry ode = new DataObjectEntry();
47  0 ode.setDataObjectClass(clazz);
48  0 addFields("", ode);
49  0 return ode;
50    }
51   
 
52  0 toggle public void addFields(String debuggingContext, DataObjectEntry ode) {
53  0 BeanInfo beanInfo;
54  0 try {
55  0 beanInfo = Introspector.getBeanInfo(clazz);
56    } catch (IntrospectionException ex) {
57  0 throw new RuntimeException(ex);
58    }
59  0 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
60  0 if (Class.class.equals(pd.getPropertyType())) {
61  0 continue;
62    }
63  0 if ("_futureElements".equals(pd.getName())) {
64  0 continue;
65    }
66  0 if ("attributes".equals(pd.getName())) {
67  0 continue;
68    }
69  0 String name = calcName(pd.getName());
70  0 Class<?> actualClass = calcActualClass(clazz, pd);
71  0 DataType dt = calcDataType(debuggingContext + "." + clazz.getSimpleName() + "." + name, actualClass);
72  0 DataDictionaryDefinitionBase dddef = calcDataDictionaryDefinition(pd, dt);
73  0 if (dddef instanceof AttributeDefinition) {
74  0 AttributeDefinition ad = (AttributeDefinition) dddef;
75  0 ode.getAttributes().add(ad);
76  0 } else if (dddef instanceof ComplexAttributeDefinition) {
77  0 ComplexAttributeDefinition cad = (ComplexAttributeDefinition) dddef;
78  0 ode.getComplexAttributes().add(cad);
79  0 if (!parentClasses.contains(clazz)) {
80  0 parentFields.push(dddef);
81  0 parentClasses.push(clazz);
82  0 Bean2DictionaryConverter subConverter = new Bean2DictionaryConverter(actualClass, parentFields, parentClasses);
83  0 subConverter.addFields(debuggingContext + "." + clazz.getSimpleName() + name, ode);
84  0 parentFields.pop();
85  0 parentClasses.pop();
86    }
87  0 } else if (dddef instanceof CollectionDefinition) {
88  0 CollectionDefinition cd = (CollectionDefinition) dddef;
89  0 ode.getCollections().add(cd);
90    // TODO: handle collections of primitives
91    // DataType == null means it is a complex
92    // TODO: add back in this logic once they fix the jira about collectoin definition not working right
93    // if (dt == null) {
94    // if (!parentClasses.contains(clazz)) {
95    // parentFields.push(dddef);
96    // parentClasses.push(clazz);
97    // Bean2DictionaryConverter subConverter = new Bean2DictionaryConverter(actualClass, parentFields, parentClasses);
98    // subConverter.addFields(debuggingContext + "." + clazz.getSimpleName() + name, ode);
99    // parentFields.pop();
100    // parentClasses.pop();
101    // }
102    // }
103    }
104  0 if (dddef instanceof ComplexAttributeDefinition || dddef instanceof CollectionDefinition) {
105    }
106    }
107    }
108   
 
109  0 toggle private DataDictionaryDefinitionBase calcDataDictionaryDefinition(PropertyDescriptor pd, DataType dataType) {
110  0 Class<?> pt = pd.getPropertyType();
111  0 if (List.class.equals(pt)) {
112  0 if (dataType != null) {
113  0 System.out.println("WARNING: Can't handle lists of primitives just yet: " + calcName(pd.getName()));
114    }
115  0 CollectionDefinition cd = new CollectionDefinition();
116  0 cd.setName(calcName(pd.getName()));
117    // cd.setDataObjectClass(pt);
118  0 return cd;
119    }
120  0 if (dataType != null) {
121  0 AttributeDefinition ad = new AttributeDefinition();
122  0 ad.setName(calcName(pd.getName()));
123  0 ad.setDataType(dataType);
124  0 return ad;
125    }
126  0 ComplexAttributeDefinition cad = new ComplexAttributeDefinition();
127  0 cad.setName(calcName(pd.getName()));
128    // cad.setDataObjectEntry(pt);
129  0 return cad;
130    }
131   
 
132  0 toggle private String calcName(String leafName) {
133  0 StringBuilder bldr = new StringBuilder();
134  0 if (!parentFields.isEmpty()) {
135  0 DataDictionaryDefinitionBase parent = parentFields.peek();
136  0 if (parent instanceof ComplexAttributeDefinition) {
137  0 ComplexAttributeDefinition cad = (ComplexAttributeDefinition) parent;
138  0 bldr.append(cad.getName());
139  0 bldr.append(".");
140  0 } else if (parent instanceof CollectionDefinition) {
141  0 CollectionDefinition cad = (CollectionDefinition) parent;
142  0 bldr.append(cad.getName());
143  0 bldr.append(".");
144    }
145    }
146  0 bldr.append(initLower(leafName));
147  0 return bldr.toString();
148    }
149   
 
150  0 toggle private String initLower(String name) {
151  0 return name.substring(0, 1).toLowerCase() + name.substring(1);
152    }
153   
 
154  0 toggle public static Class<?> calcActualClass(Class<?> clazz, PropertyDescriptor pd) {
155  0 Class<?> pt = null;
156    // there is a bug in the BeanInfo impl see workaround below
157    // pd.getPropertyType gets the interface not the info object
158    // for example:
159    // info has...
160    // @Override
161    // ExpenditureInfo getExpenditure ();
162    //
163    // and interface has
164    // Expenditure getExpenditure ();
165    // then pd.getPropertyType () returns Expenditure not ExpenditureInfo
166    // so...
167    // we use the work around if it gets an interface
168  0 pt = pd.getPropertyType();
169  0 if (pt.isInterface()) {
170  0 if (pd.getReadMethod() == null) {
171  0 throw new NullPointerException (clazz.getName() + "." + pd.getName() + " has no read method");
172    }
173  0 pt = workAround(clazz, pd.getReadMethod().getName());
174    }
175   
176  0 if (List.class.equals(pt)) {
177  0 pt = ComplexSubstructuresHelper.getActualClassFromList(clazz, pd.getName());
178    }
179  0 return pt;
180    }
181   
 
182  0 toggle private static Class<?> workAround(Class<?> currentTargetClass, String methodName) {
183  0 Method method = findMethodImplFirst(currentTargetClass, methodName);
184  0 return method.getReturnType();
185    }
186   
187    /**
188    * Got this code from:
189    * http://raulraja.com/2009/09/12/java-beans-introspector-odd-behavio/
190    *
191    * workaround for introspector odd behavior with javabeans that implement interfaces with comaptible return types
192    * but instrospection is unable to find the right accessors
193    *
194    * @param currentTargetClass the class being evaluated
195    * @param methodName the method name we are looking for
196    * @param argTypes the arg types for the method name
197    * @return a method if found
198    */
 
199  0 toggle private static Method findMethodImplFirst(Class<?> currentTargetClass, String methodName, Class<?>... argTypes) {
200  0 Method method = null;
201  0 if (currentTargetClass != null && methodName != null) {
202  0 try {
203  0 method = currentTargetClass.getMethod(methodName, argTypes);
204    } catch (Throwable t) {
205    // nothing we can do but continue
206    }
207    //Is the method in one of our parent classes
208  0 if (method == null) {
209  0 Class<?> superclass = currentTargetClass.getSuperclass();
210  0 if (!superclass.equals(Object.class)) {
211  0 method = findMethodImplFirst(superclass, methodName, argTypes);
212    }
213    }
214    }
215  0 return method;
216    }
217   
 
218  0 toggle public static DataType calcDataType(String context, Class<?> pt) {
219  0 if (int.class.equals(pt) || Integer.class.equals(pt)) {
220  0 return DataType.INTEGER;
221  0 } else if (long.class.equals(pt) || Long.class.equals(pt)) {
222  0 return DataType.LONG;
223  0 } else if (double.class.equals(pt) || Double.class.equals(pt)) {
224  0 return DataType.DOUBLE;
225  0 } else if (float.class.equals(pt) || Float.class.equals(pt)) {
226  0 return DataType.FLOAT;
227  0 } else if (boolean.class.equals(pt) || Boolean.class.equals(pt)) {
228  0 return DataType.BOOLEAN;
229  0 } else if (Date.class.equals(pt)) {
230  0 return DataType.DATE;
231  0 } else if (String.class.equals(pt)) {
232  0 return DataType.STRING;
233  0 } else if (List.class.equals(pt)) {
234  0 throw new RuntimeException("Found list can't have a list of lists, List<List<?>> in " + context);
235  0 } else if (Enum.class.isAssignableFrom(pt)) {
236  0 return DataType.STRING;
237  0 } else if (Object.class.equals(pt)) {
238  0 return DataType.STRING;
239  0 } else if (pt.getName().startsWith("org.kuali.student.")) {
240  0 return null;
241    } else {
242  0 throw new RuntimeException("Found unknown/unhandled type of object in bean " + pt.getName() + " in " + context);
243    }
244    }
245    }