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