Clover Coverage Report - KS R2 POC 0.0.1-SNAPSHOT (Aggregated)
Coverage timestamp: Mon May 23 2011 04:02:06 EDT
../../../../../img/srcFileCovDistChart0.png 0% of files have more coverage
206   398   72   10.84
80   338   0.35   9.5
19     3.79  
2    
 
  DictionaryCreator       Line # 38 178 0% 58 251 0% 0.0
  DictionaryCreator.PropertyDescriptorComparator       Line # 154 28 0% 14 54 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.io.File;
23    import java.io.FileNotFoundException;
24    import java.io.FileOutputStream;
25    import java.io.IOException;
26    import java.io.OutputStream;
27    import java.util.ArrayList;
28    import java.util.Arrays;
29    import java.util.Collections;
30    import java.util.Comparator;
31    import java.util.HashSet;
32    import java.util.List;
33    import java.util.Set;
34    import org.kuali.rice.kns.datadictionary.DataObjectEntry;
35   
36    import org.kuali.rice.kns.datadictionary.validation.DataType;
37   
 
38    public class DictionaryCreator {
39   
 
40  0 toggle private static String initLower(String str) {
41  0 if (str == null) {
42  0 return null;
43    }
44  0 if (str.length() == 0) {
45  0 return str;
46    }
47  0 if (str.length() == 1) {
48  0 return str.toLowerCase();
49    }
50  0 return str.substring(0, 1).toLowerCase() + str.substring(1);
51    }
52   
 
53  0 toggle public void execute(Class<?> clazz, String outputFileName) {
54    // Create base dictionary object structure for DTOs that map to entities
55  0 File file = new File(outputFileName);
56  0 OutputStream os;
57  0 try {
58  0 os = new FileOutputStream(file);
59    } catch (FileNotFoundException ex) {
60  0 throw new IllegalArgumentException(ex);
61    }
62  0 StringBuffer s = new StringBuffer();
63  0 addSpringHeaderOpen(s);
64   
65  0 System.out.println(clazz.getName());
66  0 addObjectStructure(clazz, s, new HashSet<Class<?>>());
67   
68  0 addSpringHeaderClose(s);
69  0 try {
70  0 os.write(s.toString().getBytes());
71  0 os.close();
72    } catch (IOException ex) {
73  0 throw new IllegalArgumentException(ex);
74    }
75    }
76   
 
77  0 toggle private void addObjectStructure(Class<?> clazz, StringBuffer s,
78    Set<Class<?>> processed) {
79    //Don't process if processed
80  0 if (processed.contains(clazz)) {
81  0 return;
82    }
83  0 processed.add(clazz);
84   
85  0 BeanInfo beanInfo;
86  0 try {
87  0 beanInfo = Introspector.getBeanInfo(clazz);
88    } catch (IntrospectionException ex) {
89  0 throw new IllegalArgumentException(ex);
90    }
91   
92   
93    //Step 1, create the abstract structure
94  0 s.append("\n\n<!-- " + clazz.getSimpleName() + "-->");
95  0 s.append("\n<bean id=\"" + initLower(clazz.getSimpleName())
96    + "-parent\" abstract=\"true\" parent=\"" + initLower(DataObjectEntry.class.getSimpleName())
97    + "\">");
98  0 addProperty("name", initLower(clazz.getSimpleName()), s);
99  0 addProperty("objectClass", clazz.getName(), s);
100  0 addProperty("objectLabel", "", s);
101  0 addProperty("objectDescription", "", s);
102  0 String titleAttribute = calcTitleAttribute(clazz, beanInfo);
103  0 if (titleAttribute != null) {
104  0 addProperty("titleAttribute", titleAttribute, s);
105    }
106  0 s.append("\n<property name=\"primaryKeys\">");
107  0 List<String> pks = calcPrimaryKeys(clazz, beanInfo);
108  0 if (pks != null && !pks.isEmpty()) {
109  0 s.append("\n<list>");
110  0 for (String pk : pks) {
111  0 addValue(pk, s);
112    }
113  0 s.append("\n</list>");
114    }
115  0 s.append("\n</property>");
116  0 s.append("\n<property name=\"attributes\">");
117  0 s.append("\n<list>");
118   
119  0 for (PropertyDescriptor pd : getFilteredSortedProperties(beanInfo)) {
120  0 String fieldName = initLower(clazz.getSimpleName() + "." + initLower(pd.getName()));
121  0 s.append("\n<ref bean=\"" + fieldName + "\"/>");
122    }
123  0 s.append("\n</list>");
124  0 s.append("\n</property>");
125  0 s.append("\n</bean>");
126   
127    //Create the instance
128  0 s.append("\n<bean id=\"" + initLower(clazz.getSimpleName()) + "\" parent=\""
129    + initLower(clazz.getSimpleName()) + "-parent\"/>");
130   
131    //Step 2, loop through attributes
132  0 Set<Class<?>> dependantStructures = new HashSet<Class<?>>();
133  0 for (PropertyDescriptor pd : getFilteredSortedProperties(beanInfo)) {
134  0 dependantStructures.addAll(addAttributeDefinition(clazz, pd, s, processed));
135    }
136    //Step 3, process all dependant object structures
137  0 for (Class<?> dependantClass : dependantStructures) {
138  0 addObjectStructure(dependantClass, s, processed);
139    }
140    }
141   
 
142  0 toggle private List<PropertyDescriptor> getFilteredSortedProperties(BeanInfo beanInfo) {
143  0 List<PropertyDescriptor> list = new ArrayList(beanInfo.getPropertyDescriptors().length);
144  0 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
145  0 if (pd.getPropertyType().equals(Class.class)) {
146  0 continue;
147    }
148  0 list.add(pd);
149    }
150  0 Collections.sort(list, new PropertyDescriptorComparator());
151  0 return list;
152    }
153   
 
154    private static class PropertyDescriptorComparator implements Comparator<PropertyDescriptor> {
155   
 
156  0 toggle @Override
157    public int compare(PropertyDescriptor o1, PropertyDescriptor o2) {
158  0 return calcRank(o1).compareTo(calcRank(o2));
159    }
160   
 
161  0 toggle private String calcRank(PropertyDescriptor pd) {
162   
163  0 String name = pd.getName();
164  0 String lowerName = pd.getName().toLowerCase();
165  0 if (lowerName.equals("id")) {
166  0 return "00" + name;
167    }
168  0 if (lowerName.equals("key")) {
169  0 return "00" + name;
170    }
171  0 if (lowerName.equals("typekey")) {
172  0 return "01" + name;
173    }
174  0 if (lowerName.equals("statekey")) {
175  0 return "02" + name;
176    }
177  0 if (lowerName.equals("name")) {
178  0 return "03" + name;
179    }
180  0 if (lowerName.equals("descr")) {
181  0 return "04" + name;
182    }
183  0 if (lowerName.equals("effectivedate")) {
184  0 return "10" + name;
185    }
186  0 if (lowerName.equals("expirationdate")) {
187  0 return "11" + name;
188    }
189  0 if (lowerName.equals("attributes")) {
190  0 return "80" + name;
191    }
192  0 if (lowerName.equals("metainfo")) {
193  0 return "90" + name;
194    }
195  0 if (lowerName.equals("startdate")) {
196  0 return "48" + name;
197    }
198  0 if (lowerName.equals ("enddate")) {
199  0 return "49" + name;
200    }
201  0 return "50" + name;
202    }
203    }
204   
 
205  0 toggle private String calcTitleAttribute(Class<?> clazz, BeanInfo beanInfo) {
206  0 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
207  0 if (pd.getName().equalsIgnoreCase("name")) {
208  0 return initLower(pd.getName());
209    }
210    }
211  0 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
212  0 if (pd.getName().equalsIgnoreCase("title")) {
213  0 return initLower(pd.getName());
214    }
215    }
216  0 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
217  0 if (pd.getName().toLowerCase().endsWith("name")) {
218  0 return initLower(pd.getName());
219    }
220    }
221  0 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
222  0 if (pd.getName().toLowerCase().endsWith("title")) {
223  0 return initLower(pd.getName());
224    }
225    }
226  0 return null;
227    }
228   
 
229  0 toggle private List<String> calcPrimaryKeys(Class<?> clazz, BeanInfo beanInfo) {
230  0 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
231  0 if (pd.getName().equalsIgnoreCase("id")) {
232  0 return Arrays.asList(initLower(pd.getName()));
233    }
234    }
235  0 for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
236  0 if (pd.getName().equalsIgnoreCase("key")) {
237  0 return Arrays.asList(initLower(pd.getName()));
238    }
239    }
240  0 return null;
241    }
242   
 
243  0 toggle private Set<Class<?>> addAttributeDefinition(Class<?> clazz, PropertyDescriptor pd,
244    StringBuffer s, Set<Class<?>> processed) {
245  0 Set<Class<?>> dependantStructures = new HashSet<Class<?>>();
246   
247    //Create the abstract field
248  0 String name = clazz.getSimpleName().substring(0, 1).toLowerCase() + clazz.getSimpleName().substring(
249    1) + "." + pd.getName();
250  0 Class<?> actualClass = Bean2DictionaryConverter.calcActualClass(clazz, pd);
251  0 DataType dt = calcDataType(clazz, pd);
252  0 String parentField = calcBaseKualiType(actualClass, pd, dt);
253   
254  0 s.append("\n\n<bean id=\"" + name
255    + "-parent\" abstract=\"true\" parent=\"" + parentField + "\">");
256  0 addProperty("name", initLower(pd.getName()), s);
257  0 if (isList(pd)) {
258  0 addProperty("maxOccurs", "" + DictionaryConstants.UNBOUNDED, s);
259    }
260  0 s.append("\n</bean>");
261   
262    //Create the instance
263  0 s.append("\n<bean id=\"" + name + "\" parent=\"" + name
264    + "-parent\"/>");
265  0 return dependantStructures;
266    }
267   
 
268  0 toggle private DataType calcDataType(Class<?> clazz, PropertyDescriptor pd) {
269  0 Class<?> actualClass = Bean2DictionaryConverter.calcActualClass(clazz, pd);
270  0 DataType dataType = Bean2DictionaryConverter.calcDataType(actualClass);
271  0 return dataType;
272    }
273   
 
274  0 toggle private boolean isList(PropertyDescriptor pd) {
275  0 if (pd.getPropertyType().equals(List.class)) {
276  0 return true;
277    }
278  0 return false;
279    }
280   
 
281  0 toggle private boolean isComplex(Class<?> clazz, PropertyDescriptor pd) {
282  0 return isComplex(calcDataType(clazz, pd));
283    }
284   
 
285  0 toggle private boolean isComplex(DataType dt) {
286  0 if (dt.equals(DataType.COMPLEX)) {
287  0 return true;
288    }
289  0 return false;
290    }
291   
 
292  0 toggle private String calcBaseKualiType(Class<?> clazz, PropertyDescriptor pd, DataType dt) {
293   
294  0 String name = pd.getName();
295  0 String lowerName = pd.getName().toLowerCase();
296  0 if (lowerName.equals("id")) {
297  0 return "baseKualiId";
298    }
299  0 if (lowerName.equals("key")) {
300  0 return "baseKualiKey";
301    }
302  0 if (lowerName.equals("typeKey")) {
303  0 return "baseKualiTypeKey";
304    }
305  0 if (lowerName.equals("stateKey")) {
306  0 return "baseKualiStateKey";
307    }
308  0 if (lowerName.equals("effectivedate")) {
309  0 return "baseKualiEffectiveDate";
310    }
311  0 if (lowerName.equals("expirationdate")) {
312  0 return "baseKualiExpirationDate";
313    }
314  0 if (lowerName.endsWith("orgid")) {
315  0 return "baseKualiOrgId";
316    }
317  0 if (lowerName.endsWith("personid")) {
318  0 return "baseKualiPersonId";
319    }
320  0 if (lowerName.endsWith("principalid")) {
321  0 return "baseKualiPrincipalId";
322    }
323  0 if (lowerName.endsWith("cluid")) {
324  0 return "baseKualiCluId";
325    }
326  0 if (lowerName.endsWith("luiid")) {
327  0 return "baseKualiCluId";
328    }
329  0 if (lowerName.endsWith("code")) {
330  0 return "baseKualiCode";
331    }
332  0 switch (dt) {
333  0 case STRING:
334  0 return "baseKualiString";
335  0 case DATE:
336  0 return "baseKualiDateTime";
337  0 case TRUNCATED_DATE:
338  0 return "baseKualiDate";
339  0 case BOOLEAN:
340  0 return "baseKualiBoolean";
341  0 case INTEGER:
342  0 case LONG:
343  0 return "baseKualiInteger";
344  0 case FLOAT:
345  0 case DOUBLE:
346  0 return "baseKualiCurrency";
347  0 case COMPLEX:
348  0 return "baseKualiComplex";
349  0 default:
350  0 return "baseKualiString";
351    }
352    }
353   
 
354  0 toggle private void addValue(String value, StringBuffer s) {
355  0 s.append("\n<value>" + value + "</value>");
356    }
357   
 
358  0 toggle private void addProperty(String propertyName, String propertyValue,
359    StringBuffer s) {
360  0 s.append("\n<property name=\"" + propertyName + "\" value=\"" + propertyValue
361    + "\"/>");
362    }
363   
 
364  0 toggle private static void addPropertyRef(String propertyName, String propertyValue,
365    StringBuffer s) {
366  0 s.append("\n<property name=\"" + propertyName + "\" ref=\"" + propertyValue
367    + "\"/>");
368    }
369   
 
370  0 toggle private void addSpringHeaderClose(StringBuffer s) {
371  0 s.append("\n</beans>").append("\n");
372    }
373   
 
374  0 toggle private void addSpringHeaderOpen(StringBuffer s) {
375  0 s.append("<!--").append("\n");
376  0 s.append(" Copyright 2011 The Kuali Foundation").append("\n");
377  0 s.append("").append("\n");
378  0 s.append(" Licensed under the Educational Community License, Version 2.0 (the \"License\");").append("\n");
379  0 s.append(" you may not use this file except in compliance with the License.").append("\n");
380  0 s.append(" You may obtain a copy of the License at").append("\n");
381  0 s.append("").append("\n");
382  0 s.append(" http://www.opensource.org/licenses/ecl2.php").append("\n");
383  0 s.append("").append("\n");
384  0 s.append(" Unless required by applicable law or agreed to in writing, software").append("\n");
385  0 s.append(" distributed under the License is distributed on an \"AS IS\" BASIS,").append("\n");
386  0 s.append(" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.").append("\n");
387  0 s.append(" See the License for the specific language governing permissions and").append("\n");
388  0 s.append(" limitations under the License.").append("\n");
389  0 s.append("-->").append("\n");
390  0 s.append("<beans xmlns=\"http://www.springframework.org/schema/beans\"").append("\n");
391  0 s.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"").append("\n");
392  0 s.append("xsi:schemaLocation=\"").append("\n");
393  0 s.append("http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd").append("\n");
394  0 s.append("\">").append("\n");
395  0 s.append("\n<import resource=\"classpath:ks-base-dictionary.xml\"/>");
396    }
397    }
398