View Javadoc

1   package org.kuali.student.r1.common.dictionary.service.impl;
2   
3   import org.kuali.student.r1.common.dictionary.dto.FieldDefinition;
4   import org.kuali.student.r1.common.dto.Idable;
5   import org.kuali.student.r2.common.dto.MetaInfo;
6   
7   import java.beans.BeanInfo;
8   import java.beans.IntrospectionException;
9   import java.beans.Introspector;
10  import java.beans.PropertyDescriptor;
11  import java.io.File;
12  import java.io.FileNotFoundException;
13  import java.io.FileOutputStream;
14  import java.io.IOException;
15  import java.io.OutputStream;
16  import java.lang.reflect.ParameterizedType;
17  import java.util.Date;
18  import java.util.HashSet;
19  import java.util.List;
20  import java.util.Set;
21  
22  @Deprecated
23  public class DictionaryCreator
24  {
25  
26   private static final String OBJECT_STRUCTURE_CLASS =
27                               "objectStructureDefinition";
28   private static final String FIELD_DEFINITION_CLASS =
29                               FieldDefinition.class.getSimpleName ();
30   private static final String ATTRIBUTES = "attributes";
31   private static final String NAME = "name";
32   private static final String HAS_META_DATA = "hasMetaData";
33   private static final String DATA_OBJECT_STRUCTURE = "dataObjectStructure";
34   private static final String BASE_INTEGER_REPEATING = "baseIntegerRepeating";
35   private static final String BASE_LONG_REPEATING = "baseLongRepeating";
36   private static final String BASE_DOUBLE_REPEATING = "baseDoubleRepeating";
37   private static final String BASE_FLOAT_REPEATING = "baseFloatRepeating";
38   private static final String BASE_BOOLEAN_REPEATING = "baseBooleanRepeating";
39   private static final String BASE_DATE_REPEATING = "baseDateRepeating";
40   private static final String BASE_STRING_REPEATING = "baseStringRepeating";
41   private static final String BASE_COMPLEX_REPEATING = "baseComplexRepeating";
42   private static final String BASE_INTEGER = "baseInteger";
43   private static final String BASE_LONG = "baseLong";
44   private static final String BASE_DOUBLE = "baseDouble";
45   private static final String BASE_FLOAT = "baseFloat";
46   private static final String BASE_BOOLEAN = "baseBoolean";
47   private static final String BASE_DATE = "baseDate";
48   private static final String BASE_STRING = "baseString";
49   private static final String BASE_COMPLEX = "baseComplex";
50   private static final String BASE_KUALI_ID = "baseKualiId";
51   private static final String BASE_KUALI_ORG_ID = "baseKualiOrgId";
52   private static final String BASE_KUALI_CLU_ID = "baseKualiCluId";
53   private static final String BASE_KUALI_PERSON_ID = "baseKualiPersonId";
54   private static final String BASE_KUALI_TYPE = "baseKualiType";
55   private static final String BASE_KUALI_STATE = "baseKualiState";
56   private static final String BASE_KUALI_EFFECTIVE_DATE =
57                               "baseKualiEffectiveDate";
58   private static final String BASE_KUALI_EXPIRATION_DATE =
59                               "baseKualiExpirationDate";
60  
61   
62   public void execute (Class<?> clazz, String outputFileName)
63   {
64    // Create base dictionary object structure for DTOs that map to entities
65    File file = new File (outputFileName);
66    OutputStream os;
67    try
68    {
69     os = new FileOutputStream (file);
70    }
71    catch (FileNotFoundException ex)
72    {
73     throw new IllegalArgumentException (ex);
74    }
75    StringBuilder s = new StringBuilder ();
76    addSpringHeaderOpen (s);
77  
78  //Debuggin System.out.println (clazz.getName ());
79    addObjectStructure (clazz, s, new HashSet<Class<?>> ());
80  
81    addSpringHeaderClose (s);
82    try
83    {
84     os.write (s.toString ().getBytes ());
85    }
86    catch (IOException ex)
87    {
88     throw new IllegalArgumentException (ex);
89    }
90   }
91  
92   private void addObjectStructure (Class<?> clazz, StringBuilder s,
93                                    Set<Class<?>> processed)
94   {
95    //Don't process if processed
96    if (processed.contains (clazz))
97    {
98     return;
99    }
100   processed.add (clazz);
101 
102   //Step 1, create the abstract structure
103   s.append ("\n\n<!-- " + clazz.getSimpleName () + "-->");
104   s.append ("\n<bean id=\"" + clazz.getName ()
105             + "-parent\" abstract=\"true\" parent=\"" + OBJECT_STRUCTURE_CLASS
106             + "\">");
107   addProperty (NAME, clazz.getName (), s);
108   s.append ("\n<property name=\"" + ATTRIBUTES + "\">");
109   s.append ("\n<list>");
110   BeanInfo beanInfo;
111   try
112   {
113    beanInfo = Introspector.getBeanInfo (clazz);
114   }
115   catch (IntrospectionException ex)
116   {
117    throw new IllegalArgumentException (ex);
118   }
119   boolean hasMetaData = false;
120   for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors ())
121   {
122    if ( ! MetaInfo.class.equals (pd.getPropertyType ()) &&  ! Class.class.equals (
123      pd.getPropertyType ()) &&  ! ATTRIBUTES.equals (pd.getName ()))
124    {
125     String fieldName = clazz.getSimpleName ().substring (0, 1).toLowerCase () + clazz.getSimpleName ().substring (
126       1) + "." + pd.getName ();
127     s.append ("\n<ref bean=\"" + fieldName + "\"/>");
128    }
129    else
130    {
131     hasMetaData = true;
132    }
133   }
134   s.append ("\n</list>");
135   s.append ("\n</property>");
136 
137   addProperty (HAS_META_DATA, String.valueOf (hasMetaData), s);
138   s.append ("\n</bean>");
139 
140   //Create the instance
141   s.append ("\n<bean id=\"" + clazz.getName () + "\" parent=\""
142             + clazz.getName () + "-parent\"/>");
143   //Step 2, loop through attributes
144   Set<Class<?>> dependantStructures = new HashSet<Class<?>> ();
145   for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors ())
146   {
147    if ( ! MetaInfo.class.equals (pd.getPropertyType ()) &&  ! Class.class.equals (
148      pd.getPropertyType ()) &&  ! ATTRIBUTES.equals (pd.getName ()))
149    {
150     dependantStructures.addAll (addField (clazz, pd, s, processed));
151    }
152   }
153   //Step 3, process all dependant object structures
154   for (Class<?> dependantClass : dependantStructures)
155   {
156    addObjectStructure (dependantClass, s, processed);
157   }
158 
159  }
160 
161  private Set<Class<?>> addField (Class<?> clazz, PropertyDescriptor pd,
162                                  StringBuilder s, Set<Class<?>> processed)
163  {
164   Set<Class<?>> dependantStructures = new HashSet<Class<?>> ();
165 
166   //Create the abstract field
167   String fieldName = clazz.getSimpleName ().substring (0, 1).toLowerCase () + clazz.getSimpleName ().substring (
168     1) + "." + pd.getName ();
169   Class<?> pt = pd.getPropertyType ();
170   String parentField = FIELD_DEFINITION_CLASS;
171   boolean isComplex = false;
172   if (clazz.isAssignableFrom (Idable.class) && "id".equals (pd.getName ()))
173   {
174    parentField = BASE_KUALI_ID;
175   }
176   else if (pd.getName ().endsWith ("orgId"))
177   {
178    parentField = BASE_KUALI_ORG_ID;
179   }
180   else if (pd.getName ().endsWith ("personId"))
181   {
182    parentField = BASE_KUALI_PERSON_ID;
183   }
184   else if (pd.getName ().endsWith ("cluId"))
185   {
186    parentField = BASE_KUALI_CLU_ID;
187   }
188   else if (List.class.equals (pt))
189   {
190    try
191    {
192     pt =
193     (Class<?>) ((ParameterizedType) clazz.getDeclaredField (pd.getName ()).getGenericType ()).getActualTypeArguments ()[0];
194    }
195    catch (NoSuchFieldException ex)
196    {
197     throw new IllegalArgumentException (ex);
198    }
199    catch (SecurityException ex)
200    {
201     throw new IllegalArgumentException (ex);
202    }
203    if (int.class.equals (pt) || Integer.class.equals (pt))
204    {
205     parentField = BASE_INTEGER_REPEATING;
206    }
207    else if (long.class.equals (pt) || Long.class.equals (pt))
208    {
209     parentField = BASE_LONG_REPEATING;
210    }
211    else if (double.class.equals (pt) || Double.class.equals (pt))
212    {
213     parentField = BASE_DOUBLE_REPEATING;
214    }
215    else if (float.class.equals (pt) || Float.class.equals (pt))
216    {
217     parentField = BASE_FLOAT_REPEATING;
218    }
219    else if (boolean.class.equals (pt) || Boolean.class.equals (pt))
220    {
221     parentField = BASE_BOOLEAN_REPEATING;
222    }
223    else if (Date.class.equals (pt))
224    {
225     parentField = BASE_DATE_REPEATING;
226    }
227    else if (String.class.equals (pt))
228    {
229     parentField = BASE_STRING_REPEATING;
230    }
231    else if (List.class.equals (pt))
232    {
233     throw new RuntimeException ("Can't have a list of lists, List<List<?>> for property: "
234                                 + fieldName);
235    }
236    else
237    {
238     parentField = BASE_COMPLEX_REPEATING;
239     isComplex = true;
240     dependantStructures.add (pt);
241    }
242   }
243   else
244   {
245    if (int.class.equals (pt) || Integer.class.equals (pt))
246    {
247     parentField = BASE_INTEGER;
248    }
249    else if (long.class.equals (pt) || Long.class.equals (pt))
250    {
251     parentField = BASE_LONG;
252    }
253    else if (double.class.equals (pt) || Double.class.equals (pt))
254    {
255     parentField = BASE_DOUBLE;
256    }
257    else if (float.class.equals (pt) || Float.class.equals (pt))
258    {
259     parentField = BASE_FLOAT;
260    }
261    else if (boolean.class.equals (pt) || Boolean.class.equals (pt))
262    {
263     parentField = BASE_BOOLEAN;
264    }
265    else if (Date.class.equals (pt))
266    {
267     parentField = BASE_DATE;
268    }
269    else if (String.class.equals (pt))
270    {
271     parentField = BASE_STRING;
272    }
273    else
274    {
275     parentField = BASE_COMPLEX;
276     isComplex = true;
277     dependantStructures.add (pt);
278    }
279   }
280 
281 
282   s.append ("\n\n<bean id=\"" + fieldName
283             + "-parent\" abstract=\"true\" parent=\"" + parentField + "\">");
284   addProperty (NAME, pd.getName (), s);
285   if (isComplex)
286   {
287    addPropertyRef (DATA_OBJECT_STRUCTURE, pt.getName (), s);
288   }
289 
290   s.append ("\n</bean>");
291 
292   //Create the instance
293   s.append ("\n<bean id=\"" + fieldName + "\" parent=\"" + fieldName
294             + "-parent\"/>");
295 
296   return dependantStructures;
297  }
298 
299  private void addProperty (String propertyName, String propertyValue,
300                            StringBuilder s)
301  {
302   s.append ("\n<property name=\"" + propertyName + "\" value=\"" + propertyValue
303             + "\"/>");
304  }
305 
306  private static void addPropertyRef (String propertyName, String propertyValue,
307                                      StringBuilder s)
308  {
309   s.append ("\n<property name=\"" + propertyName + "\" ref=\"" + propertyValue
310             + "\"/>");
311  }
312 
313  private void addSpringHeaderClose (StringBuilder s)
314  {
315   s.append ("\n</beans>");
316  }
317 
318  public void addSpringHeaderOpen (StringBuilder s)
319  {
320   s.append ("<beans xmlns=\"http://www.springframework.org/schema/beans\""
321             + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
322             + "xsi:schemaLocation=\""
323             + "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
324             + "\">");
325   s.append ("\n<import resource=\"classpath:ks-base-dictionary-context.xml\"/>");
326  }
327 }