View Javadoc

1   package org.kuali.student.r2.common.assembler;
2   
3   import org.kuali.student.r2.common.dto.AttributeInfo;
4   import org.kuali.student.r2.common.entity.AttributeOwner;
5   import org.kuali.student.r2.common.entity.BaseAttributeEntity;
6   import org.kuali.student.r2.common.infc.Attribute;
7   import org.kuali.student.r2.common.infc.HasAttributes;
8   import org.kuali.student.r2.common.util.date.DateFormatters;
9   
10  import java.text.ParseException;
11  import java.util.ArrayList;
12  import java.util.Date;
13  import java.util.HashMap;
14  import java.util.HashSet;
15  import java.util.List;
16  import java.util.Map;
17  import java.util.Set;
18  
19  /**
20   * Utility class containing utility methods to aide in DTO & Entity transformations
21   */
22  public class TransformUtility {
23  
24  
25      /**
26       *
27       * This merges DTO attributes into Entity attributes and returns the orphaned attributes to delete
28       *
29       * @param attributeClass The attribute entity class for the attributes on the entity owner
30       * @param dto The dto to copy attributes from
31       * @param owner The owner entity of the attributes.
32       *
33       * @return The orphaned attributes to delete.
34       */
35      public static <A extends BaseAttributeEntity<O>, O extends AttributeOwner<A>> List<Object>
36      mergeToEntityAttributes(Class<A> attributeClass, HasAttributes dto, O owner) {
37  
38  
39          // Existing Attributes
40          Map<String, A> existingAttributes = new HashMap<String, A>();
41          Map<String, Attribute> dtoAttributes = new HashMap<String, Attribute>();
42  
43          // Find all the old attributes and add to existing attributes map
44          if(owner.getAttributes()!=null){
45              for (A attribute : owner.getAttributes()) {
46                  existingAttributes.put(attribute.getKey(), attribute);
47              }
48          }
49  
50          for (Attribute attribute : dto.getAttributes()) {
51              dtoAttributes.put(attribute.getKey(), attribute);
52          }
53  
54          //Clear out the attributes
55          Set<A> attributes = new HashSet<A>();
56  
57          //Update anything that exists, or create a new attribute if it doesn't
58          for (Map.Entry<String, Attribute> entry : dtoAttributes.entrySet()) {
59              Attribute attributeInfo = entry.getValue();
60              A attribute;
61              if (existingAttributes.containsKey(attributeInfo.getKey())) {
62                  attribute = existingAttributes.remove(attributeInfo.getKey());
63              }else{
64                  try{
65                      attribute = attributeClass.newInstance();
66                  }catch(Exception e){
67                      throw new RuntimeException("Error copying attributes.",e);
68                  }
69  
70                  attribute.setOwner(owner);
71                  attribute.setKey(attributeInfo.getKey());
72              }
73              attribute.setValue(attributeInfo.getValue());
74              attributes.add(attribute);
75          }
76          owner.setAttributes(attributes);
77  
78          //Remove the orphaned attributes
79          List<Object> orphansToDelete = new ArrayList<Object>();
80          orphansToDelete.addAll(existingAttributes.values());
81  
82          return orphansToDelete;
83      }
84  
85  
86      /**
87       * Converts attributes from an entity to list of AttributeInfo objects for a DTO
88       *
89       * @param owner The entity containing the attributes
90       * @return list of attributeInfo object
91       */
92      public static <A extends BaseAttributeEntity<O>, O extends AttributeOwner<A>> List<AttributeInfo> toAttributeInfoList(AttributeOwner<A> owner){
93          List<AttributeInfo> attributes = new ArrayList<AttributeInfo>();
94          if (null != owner.getAttributes()){
95              for (A attr : owner.getAttributes()) {
96                  AttributeInfo attrInfo = attr.toDto();
97                  attributes.add(attrInfo);
98              }
99          }
100 
101         return attributes;
102     }
103     // ======================================================================================================
104     // Pick a format that is human readable.  Year-month-day is kinda neutral way to represent a date
105     // so that it isn't the US month-day-year, nor other places day-month-year.  The advantage of using this over
106     // a more agnostic UTC representation (i.e., milliseconds since Jan 1, 1970) is that
107     // Used in the two methods below for KSDateFormatter
108     public static final String DYNAMIC_ATTRIBUTE_DATE_FORMAT = "yyyy MMM d HH:mm:ss zzz";
109 
110     /**
111      * dateTime refers to a date where hours/minutes/seconds are important in addition to the month day year
112      * This is used to convert to and from a dynamic attribute which requires a string format.
113      * @param date A date object to convert
114      * @return The string version to save it as a dynamic attribute
115      */
116     public static String dateTimeToDynamicAttributeString(Date date) {
117         if (date == null) {
118             return null;
119         }
120 
121         String formattedDate = DateFormatters.DYNAMIC_ATTRIBUTE_DATE_FORMATTER.format(date);
122         return formattedDate;
123     }
124 
125     /**
126      * Takes a dynamic attribute representing
127      * @param formattedDateStr
128      * @return
129      * @throws ParseException
130      */
131     public static Date dynamicAttributeStringToDateTime(String formattedDateStr) throws ParseException {
132         if (formattedDateStr == null) {
133             return null;
134         }
135 
136         Date date = DateFormatters.DYNAMIC_ATTRIBUTE_DATE_FORMATTER.parse(formattedDateStr);
137         return date;
138     }
139     // ------------------------ For Dynamic Attributes ---------------------------------
140     private static Map<Class, DynAttrConverter<? extends Object>> dynAttrConverterMap =
141             new HashMap<Class, DynAttrConverter<? extends Object>>();
142 
143     private static DynAttrConverter<Date> dateDynAttrConverter = null;
144     private static DynAttrConverter<Date> _getDateDynamicAttributeConverter() {
145         if (dateDynAttrConverter == null) {
146             dateDynAttrConverter = new DynAttrConverter<Date>() {
147                 @Override
148                 public String convertNativeValueToString(Date date) {
149                     return dateTimeToDynamicAttributeString(date);
150                 }
151 
152                 @Override
153                 public Date convertStringValueToNative(String formattedDateStr) {
154                     try {
155                         return dynamicAttributeStringToDateTime(formattedDateStr);
156                     } catch (Exception e) {
157                         e.printStackTrace();
158                         return null;
159                     }
160                 }
161             };
162         }
163         return dateDynAttrConverter;
164     }
165 
166     private static DynAttrConverter<Integer> intDynAttrConverter = null;
167     private static DynAttrConverter<Integer> _getIntegerDynamicAttributeConverter() {
168         if (intDynAttrConverter == null) {
169             intDynAttrConverter = new DynAttrConverter<Integer>() {
170                 @Override
171                 public String convertNativeValueToString(Integer val) {
172                     if (val == null) {
173                         return null;
174                     }
175 
176                     return val.toString();
177                 }
178 
179                 @Override
180                 public Integer convertStringValueToNative(String intStr) {
181                     if (intStr == null) {
182                         return null;
183                     }
184                     try {
185                         Integer intVal = Integer.parseInt(intStr);
186                         return intVal;
187                     } catch (Exception e) {
188                         return null;
189                     }
190                 }
191             };
192         }
193         return intDynAttrConverter;
194     }
195     static {
196         dynAttrConverterMap.put(Date.class, _getDateDynamicAttributeConverter());
197         dynAttrConverterMap.put(Integer.class, _getIntegerDynamicAttributeConverter());
198     }
199 
200     public static DynAttrConverter<? extends Object> getConverterByClass(Class clazz) {
201         return dynAttrConverterMap.get(clazz);
202     }
203 }
204