View Javadoc

1   /*
2    * To change this template, choose Tools | Templates
3    * and open the template in the editor.
4    */
5   package org.kuali.student.r2.lum.lrc.service.impl;
6   
7   import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
8   import org.kuali.student.r2.common.dto.ContextInfo;
9   import org.kuali.student.r2.common.dto.RichTextInfo;
10  import org.kuali.student.r2.common.exceptions.*;
11  import org.kuali.student.r2.lum.lrc.dto.ResultValueInfo;
12  import org.kuali.student.r2.lum.lrc.dto.ResultValueRangeInfo;
13  import org.kuali.student.r2.lum.lrc.dto.ResultValuesGroupInfo;
14  import org.kuali.student.r2.lum.lrc.service.LRCService;
15  import org.kuali.student.r2.lum.lrc.service.LrcServiceBusinessLogic;
16  import org.kuali.student.r2.lum.util.constants.LrcServiceConstants;
17  
18  import javax.xml.namespace.QName;
19  import java.util.ArrayList;
20  import java.util.Date;
21  import java.util.List;
22  
23  /**
24   *
25   * @author nwright
26   */
27  public class LrcServiceBusinessLogicImpl implements LrcServiceBusinessLogic {
28  
29      private LRCService lrcService;
30  
31      public LRCService getLrcService() {
32          if(lrcService == null){
33              lrcService = GlobalResourceLoader.getService(new QName(LrcServiceConstants.NAMESPACE,
34                      LrcServiceConstants.SERVICE_NAME_LOCAL_PART));
35          }
36          return lrcService;
37      }
38  
39      public void setLrcService(LRCService lrcService) {
40          this.lrcService = lrcService;
41      }
42  
43      /** 
44       * Calculate the result values group key for the fixed credit value
45       * @param creditValue
46       * @param scaleKey
47       * @return
48       * @throws InvalidParameterException 
49       */
50      protected String calcFixedCreditRvgKey(String creditValue,
51              String scaleKey,
52              ContextInfo contextInfo)
53              throws InvalidParameterException {
54  
55          if (scaleKey.equals(LrcServiceConstants.RESULT_SCALE_KEY_CREDIT_DEGREE)) {
56              return LrcServiceConstants.RESULT_GROUP_KEY_KUALI_CREDITTYPE_CREDIT_BASE + creditValue;
57          }
58          if (scaleKey.equals(LrcServiceConstants.RESULT_SCALE_KEY_CREDIT_REMEDIAL)) {
59              return LrcServiceConstants.RESULT_GROUP_KEY_CREDIT_REMEDIAL_FIXED_BASE + creditValue;
60          }
61          throw new InvalidParameterException("unknown/unhandled credit type scale key " + scaleKey);
62      }
63  
64      /** 
65       * Calculate the result values group key for the range credit value
66       * @param value
67       * @param scaleKey
68       * @return
69       * @throws InvalidParameterException 
70       */
71      protected String calcFixedCreditRvgName(String value,
72              String scaleKey,
73              ContextInfo contextInfo)
74              throws InvalidParameterException {
75          StringBuilder sb = new StringBuilder();
76          sb.append("Credits");
77          sb.append(value);
78          return sb.toString();
79      }
80  
81      /**
82       * Calculate the fixed credit value key to use that matches the specified value
83       * @param creditValue
84       * @param scaleKey
85       * @return
86       * @throws InvalidParameterException 
87       */
88      protected String calcCreditValueKey(String creditValue,
89              String scaleKey,
90              ContextInfo contextInfo)
91              throws InvalidParameterException {
92  
93          if (scaleKey.equals(LrcServiceConstants.RESULT_SCALE_KEY_CREDIT_DEGREE)) {
94              return "kuali.result.value.credit.degree." + creditValue;
95          }
96          if (scaleKey.equals(LrcServiceConstants.RESULT_SCALE_KEY_CREDIT_REMEDIAL)) {
97              return "kuali.result.value.credit.remedial." + creditValue;
98          }
99          throw new InvalidParameterException("unknown/unhandled credit type scale key " + scaleKey);
100     }
101 
102     @Override
103     public ResultValuesGroupInfo getCreateFixedCreditResultValuesGroup(String creditValue,
104             String scaleKey,
105             ContextInfo contextInfo)
106             throws InvalidParameterException,
107             MissingParameterException,
108             OperationFailedException,
109             PermissionDeniedException {
110         String rvgKey = calcFixedCreditRvgKey(creditValue, scaleKey, contextInfo);
111         String valueKey = this.calcCreditValueKey(creditValue, scaleKey, contextInfo);
112         try {
113             ResultValuesGroupInfo rvg = getLrcService().getResultValuesGroup(rvgKey, contextInfo);
114             if (!rvg.getTypeKey().equals(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_FIXED)) {
115                 throw new OperationFailedException("Calculated key does not point to a FIXED RVG: " + rvgKey);
116             }
117             if (!rvg.getResultScaleKey().equals(scaleKey)) {
118                 throw new OperationFailedException("Calculated key does not point to an RVG of the expected scale key: " + rvgKey);
119             }
120             if (rvg.getResultValueKeys().size() != 1) {
121                 throw new OperationFailedException("Calculated key does not point to an RVG with a single value: " + rvgKey);
122             }
123             if (!rvg.getResultValueKeys().get(0).equals(valueKey)) {
124                 throw new OperationFailedException("Calculated key does not point to an RVG with the expected value key : " +
125                         rvgKey);
126             }
127             return rvg;
128         } catch (DoesNotExistException ex) {
129             // ok then create
130         }
131 //      find/create value
132         ResultValueInfo value = null;
133         try {
134             value = getLrcService().getResultValue(valueKey, contextInfo);
135         } catch (DoesNotExistException ex) {
136             value = new ResultValueInfo();
137             value.setKey(valueKey);
138             value.setTypeKey(LrcServiceConstants.RESULT_VALUE_TYPE_KEY_VALUE);
139             value.setStateKey(LrcServiceConstants.RESULT_VALUE_STATE_APPROVED);
140             value.setName(creditValue);
141             value.setValue(creditValue);
142             value.setNumericValue(creditValue);
143             value.setResultScaleKey(scaleKey);
144             value.setEffectiveDate(new Date());
145             try {
146                 value = lrcService.createResultValue(value.getResultScaleKey(), value.getTypeKey(), value, contextInfo);
147             } catch (AlreadyExistsException ex1) {
148                 throw new OperationFailedException("unexpected", ex);
149             } catch (DataValidationErrorException ex1) {
150                 throw new OperationFailedException("unexpected", ex);
151             } catch (DoesNotExistException ex1) {
152                 throw new OperationFailedException("unexpected", ex);
153             }
154         }
155 
156         // not found so create it 
157         ResultValuesGroupInfo rvg = new ResultValuesGroupInfo();
158         rvg.setKey(rvgKey);
159         rvg.setTypeKey(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_FIXED);
160         rvg.setStateKey(LrcServiceConstants.RESULT_GROUPS_STATE_APPROVED);
161         rvg.setName("Fixed Credit Value " + creditValue);
162         rvg.setEffectiveDate(new Date());
163         rvg.setResultScaleKey(scaleKey);
164         rvg.getResultValueKeys().add(valueKey);
165         try {
166             rvg = getLrcService().createResultValuesGroup(rvg.getResultScaleKey(), rvg.getTypeKey(), rvg, contextInfo);
167         } catch (AlreadyExistsException ex) {
168             throw new OperationFailedException("unexpected", ex);
169         } catch (DataValidationErrorException ex) {
170             throw new OperationFailedException("unexpected", ex);
171         }
172         return rvg;
173     }
174 
175     /** 
176      * Calculate the result values group key for the range credit value
177      * @param creditValueMin
178      * @param creditValueMax
179      * @param creditValueIncrement
180      * @param scaleKey
181      * @param contextInfo
182      * @return
183      * @throws InvalidParameterException 
184      */
185     protected String calcRangeCreditRvgKey(String creditValueMin,
186             String creditValueMax,
187             String creditValueIncrement,
188             String scaleKey,
189             ContextInfo contextInfo)
190             throws InvalidParameterException {
191 
192         if (scaleKey.equals(LrcServiceConstants.RESULT_SCALE_KEY_CREDIT_DEGREE)) {
193             StringBuilder sb = new StringBuilder();
194             sb.append(LrcServiceConstants.RESULT_GROUP_KEY_KUALI_CREDITTYPE_CREDIT_BASE);
195             sb.append(creditValueMin).append("-").append(creditValueMax);
196             if (!creditValueIncrement.equals("1")) {
197                 sb.append(".by.").append(creditValueIncrement);
198             }
199             return sb.toString();
200         }
201         if (scaleKey.equals(LrcServiceConstants.RESULT_SCALE_KEY_CREDIT_REMEDIAL)) {
202             StringBuilder sb = new StringBuilder();
203             //TODO this needs to be a constant and the DB needs to match these values.
204             sb.append("kuali.result.group.credit.remedial.range.").append(creditValueMin).append("-").append(creditValueMax);
205             if (creditValueIncrement.equals("1")) {
206                 sb.append(".by.").append(creditValueIncrement);
207             }
208             return sb.toString();
209         }
210         throw new InvalidParameterException("unknown/unhandled credit type scale key " + scaleKey);
211     }
212 
213     /** 
214      * Calculate the result values group key for the range credit value
215      * @param creditValueMin
216      * @param creditValueMax
217      * @param creditValueIncrement
218      * @param scaleKey
219      * @param contextInfo
220      * @return
221      * @throws InvalidParameterException 
222      */
223     protected String calcRangeCreditRvgName(String creditValueMin,
224             String creditValueMax,
225             String creditValueIncrement,
226             String scaleKey,
227             ContextInfo contextInfo)
228             throws InvalidParameterException {
229 
230         StringBuilder sb = new StringBuilder();
231         sb.append(creditValueMin).append(" - ").append(creditValueMax);
232         if (!creditValueIncrement.equals("1")) {
233             sb.append(" by ").append(creditValueIncrement);
234         }
235         return sb.toString();
236     }
237 
238     @Override
239     public ResultValuesGroupInfo getCreateRangeCreditResultValuesGroup(String creditValueMin,
240             String creditValueMax,
241             String creditValueIncrement,
242             String scaleKey,
243             ContextInfo contextInfo)
244             throws InvalidParameterException,
245             MissingParameterException,
246             OperationFailedException,
247             PermissionDeniedException {
248         String rvgKey = calcRangeCreditRvgKey(creditValueMin, creditValueMax, creditValueIncrement, scaleKey, contextInfo);
249         try {
250             ResultValuesGroupInfo rvg = getLrcService().getResultValuesGroup(rvgKey, contextInfo);
251             if (!rvg.getTypeKey().equals(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_RANGE)) {
252                 throw new OperationFailedException("Calculated key does not point to a RANGE RVG: " + rvgKey);
253             }
254             if (!rvg.getResultScaleKey().equals(scaleKey)) {
255                 throw new OperationFailedException("Calculated key does not point to an RVG of the expected scale key: " + rvgKey);
256             }
257             if (rvg.getResultValueRange() == null) {
258                 throw new OperationFailedException("Calculated key does not point to an RVG with a range: " + rvgKey);
259             }
260             if (!stringNumberEquals(rvg.getResultValueRange().getMinValue(),creditValueMin)) {
261                 throw new OperationFailedException("Calculated key does not point to an RVG with a range with the same min value: " +
262                         rvgKey);
263             }
264             if (!stringNumberEquals(rvg.getResultValueRange().getMaxValue(), creditValueMax)) {
265                 throw new OperationFailedException("Calculated key does not point to an RVG with a range with the same max value: " +
266                         rvgKey);
267             }
268             if (!stringNumberEquals(rvg.getResultValueRange().getIncrement(),creditValueIncrement)) {
269                 throw new OperationFailedException("Calculated key does not point to an RVG with a range with the same increment value: " +
270                         rvgKey);
271             }
272             return rvg;
273         } catch (DoesNotExistException ex) {
274             // ok then create
275         }
276 
277         // not found so create it 
278         ResultValuesGroupInfo rvg = new ResultValuesGroupInfo();
279         rvg.setKey(rvgKey);
280         rvg.setTypeKey(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_RANGE);
281         rvg.setStateKey(LrcServiceConstants.RESULT_GROUPS_STATE_APPROVED);
282         rvg.setName(this.calcRangeCreditRvgName(creditValueMin, creditValueMax, creditValueIncrement, scaleKey, contextInfo));
283         rvg.setEffectiveDate(new Date());
284         rvg.setResultScaleKey(scaleKey);
285         ResultValueRangeInfo range = new ResultValueRangeInfo();
286         range.setMinValue(creditValueMin);
287         range.setMaxValue(creditValueMax);
288         range.setIncrement(creditValueIncrement);
289         rvg.setResultValueRange(range);
290         try {
291             rvg = getLrcService().createResultValuesGroup(rvg.getResultScaleKey(), rvg.getTypeKey(), rvg, contextInfo);
292         } catch (AlreadyExistsException ex) {
293             throw new OperationFailedException("unexpected", ex);
294         } catch (DataValidationErrorException ex) {
295             throw new OperationFailedException("unexpected", ex);
296         }
297         return rvg;
298     }
299 
300     /**
301      * This method converts the two input strings into floats and returns true if they're equal, false otherwise.
302      *
303      * This is needed because  getCreateRangeCreditResultValuesGroup was throwing errors saying strings
304      * 1.0 != 1.
305      *
306      * @param value1
307      * @param value2
308      * @return
309      */
310     protected static boolean stringNumberEquals(String value1, String value2){
311         Float f1 = new Float(value1);
312         Float f2 = new Float(value2);
313         return f1.equals(f2);
314     }
315 
316     /** 
317      * Calculate the result values group key for the range credit value
318      * @param values
319      * @param scaleKey
320      * @param contextInfo
321      * @return
322      * @throws InvalidParameterException 
323      */
324     protected String calcMultipleCreditRvgKey(List<String> values,
325             String scaleKey,
326             ContextInfo contextInfo)
327             throws InvalidParameterException {
328 
329         if (scaleKey.equals(LrcServiceConstants.RESULT_SCALE_KEY_CREDIT_DEGREE)) {
330             StringBuilder sb = new StringBuilder();
331 
332             // so the base string has a "." at the end... remove it
333             String baseType = LrcServiceConstants.RESULT_GROUP_KEY_KUALI_CREDITTYPE_CREDIT_BASE.substring(0,
334                                 LrcServiceConstants.RESULT_GROUP_KEY_KUALI_CREDITTYPE_CREDIT_BASE.length() - 1);
335 
336             sb.append(baseType);
337 
338             for (String value : values) {
339                 sb.append(".");
340                 sb.append(value);
341             }
342             return sb.toString();
343         }
344         if (scaleKey.equals(LrcServiceConstants.RESULT_SCALE_KEY_CREDIT_REMEDIAL)) {
345             StringBuilder sb = new StringBuilder();
346             sb.append("kuali.result.group.credit.remedial.multiple");
347             for (String value : values) {
348                 sb.append(".");
349                 sb.append(value);
350             }
351             return sb.toString();
352         }
353         throw new InvalidParameterException("unknown/unhandled credit type scale key " + scaleKey);
354     }
355 
356     /** 
357      * Calculate the result values group key for the range credit value
358      * @param values
359      * @param scaleKey
360      * @param contextInfo
361      * @return
362      * @throws InvalidParameterException 
363      */
364     protected String calcMultipleCreditRvgName(List<String> values,
365             String scaleKey,
366             ContextInfo contextInfo)
367             throws InvalidParameterException {
368         StringBuilder sb = new StringBuilder();
369         sb.append("Mulitple credits ");
370         String comma = "";
371         for (String value : values) {
372             sb.append(comma);
373             sb.append(value);
374             comma = ", ";
375         }
376         return sb.toString();
377     }
378 
379     /**
380      * Calculate the multiple credit value keys to use that matches the specified value
381      * @param creditValues
382      * @param scaleKey
383      * @return
384      * @throws InvalidParameterException 
385      */
386     protected List<String> calcMultipleCreditValueKey(List<String> creditValues,
387             String scaleKey,
388             ContextInfo contextInfo)
389             throws InvalidParameterException {
390         List<String> list = new ArrayList<String>();
391         for (String value : creditValues) {
392             list.add(this.calcCreditValueKey(value, scaleKey, contextInfo));
393         }
394         return list;
395     }
396 
397     @Override
398     public ResultValuesGroupInfo getCreateMultipleCreditResultValuesGroup(List<String> creditValues,
399             String scaleKey,
400             ContextInfo contextInfo)
401             throws InvalidParameterException,
402             MissingParameterException,
403             OperationFailedException,
404             PermissionDeniedException {
405         String rvgKey = calcMultipleCreditRvgKey(creditValues, scaleKey, contextInfo);
406         List<String> valueKeys = this.calcMultipleCreditValueKey(creditValues, scaleKey, contextInfo);
407         try {
408             ResultValuesGroupInfo rvg = getLrcService().getResultValuesGroup(rvgKey, contextInfo);
409             if (!rvg.getTypeKey().equals(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_MULTIPLE)) {
410                 throw new OperationFailedException("Calculated key does not point to a MULTIPLE RVG: " + rvgKey);
411             }
412             if (!rvg.getResultScaleKey().equals(scaleKey)) {
413                 throw new OperationFailedException("Calculated key does not point to an RVG of the expected scale key: " + rvgKey);
414             }
415             if (rvg.getResultValueKeys().size() != valueKeys.size()) {
416                 throw new OperationFailedException("Calculated key does not point to an RVG with the expected number of credit values: " +
417                         rvgKey);
418             }
419             for (String valueKey : valueKeys) {
420                 if (!rvg.getResultValueKeys().contains(valueKey)) {
421                     throw new OperationFailedException("Calculated key does not point to an RVG with the expected value key : " +
422                             rvgKey + " " + valueKey);
423                 }
424             }
425             return rvg;
426         } catch (DoesNotExistException ex) {
427             // ok then create
428         }
429 //      find/create values first
430         int i = 0;
431         for (String valueKey : valueKeys) {
432             String creditValue = creditValues.get(i);
433             i++;
434             ResultValueInfo value = null;
435             try {
436                 value = getLrcService().getResultValue(valueKey, contextInfo);
437             } catch (DoesNotExistException ex) {
438                 value = new ResultValueInfo();
439                 value.setKey(valueKey);
440                 value.setTypeKey(LrcServiceConstants.RESULT_VALUE_TYPE_KEY_VALUE);
441                 value.setStateKey(LrcServiceConstants.RESULT_VALUE_STATE_APPROVED);
442                 value.setName(creditValue);
443                 value.setValue(creditValue);
444                 value.setNumericValue(creditValue);
445                 value.setResultScaleKey(scaleKey);
446                 value.setEffectiveDate(new Date());
447                 try {
448                     value = getLrcService().createResultValue(value.getResultScaleKey(), value.getTypeKey(), value, contextInfo);
449                 } catch (AlreadyExistsException ex1) {
450                     throw new OperationFailedException("unexpected", ex);
451                 } catch (DataValidationErrorException ex1) {
452                     throw new OperationFailedException("unexpected", ex);
453                 } catch (DoesNotExistException ex1) {
454                     throw new OperationFailedException("unexpected", ex);
455                 }
456             }
457         }
458 
459         // not found so create it 
460         ResultValuesGroupInfo rvg = new ResultValuesGroupInfo();
461         rvg.setKey(rvgKey);
462         rvg.setTypeKey(LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_MULTIPLE);
463         rvg.setStateKey(LrcServiceConstants.RESULT_GROUPS_STATE_APPROVED);
464         rvg.setName(calcMultipleCreditRvgName(creditValues, scaleKey, contextInfo));
465         rvg.setEffectiveDate(new Date());
466         rvg.setResultScaleKey(scaleKey);
467         rvg.getResultValueKeys().addAll(valueKeys);
468         try {
469             rvg = getLrcService().createResultValuesGroup(rvg.getResultScaleKey(), rvg.getTypeKey(), rvg, contextInfo);
470         } catch (AlreadyExistsException ex) {
471             throw new OperationFailedException("unexpected", ex);
472         } catch (DataValidationErrorException ex) {
473             throw new OperationFailedException("unexpected", ex);
474         }
475         return rvg;
476     }
477 
478     /**
479      * Calculate key to use for the result value
480      * @param resultValue the value of the result
481      * @param scaleKey key used for getting the proper scale.
482      * @param contextInfo context
483      * @return the calculated value
484      */
485     protected String calcResultValueKey(String resultValue,
486             String scaleKey,
487             ContextInfo contextInfo) {
488         StringBuilder sb = new StringBuilder();
489         sb.append(scaleKey.replace(".scale.", ".value."));
490         sb.append(".");
491         if(resultValue.contains(sb.toString())){
492             return resultValue;
493         }
494         sb.append(resultValue);
495         return sb.toString();
496     }
497 
498     /**
499      * Calculate key to use for the result value
500      * @param resultValueKey the value key
501      * @param scaleKey key used for getting the proper scale.
502      * @param contextInfo context
503      * @return the calculated value
504      */
505     private String calcResultValueFromKeyAndScale(String resultValueKey,
506                                         String scaleKey,
507                                         ContextInfo contextInfo) {
508         StringBuilder sb = new StringBuilder();
509         sb.append(scaleKey.replace(".scale.", ".value."));
510         sb.append(".");
511         return resultValueKey.replace(sb.toString(), "");
512     }
513 
514     @Override
515     public ResultValueInfo getCreateResultValueForScale(String resultValue,
516             String scaleKey,
517             ContextInfo contextInfo)
518             throws InvalidParameterException,
519             MissingParameterException,
520             OperationFailedException,
521             PermissionDeniedException {
522         String resultValueKey = this.calcResultValueKey(resultValue, scaleKey, contextInfo);
523         if(resultValue.equals(resultValueKey)){
524             resultValue = calcResultValueFromKeyAndScale(resultValue, scaleKey, contextInfo);
525         }
526         try {
527             ResultValueInfo info = this.getLrcService().getResultValue(resultValueKey, contextInfo);
528             return info;
529         } catch (DoesNotExistException ex) {
530             // ok so we create it
531         }
532         // create the value
533         ResultValueInfo value = new ResultValueInfo();
534         value.setKey(resultValueKey);
535         value.setTypeKey(LrcServiceConstants.RESULT_VALUE_TYPE_KEY_VALUE);
536         value.setStateKey(LrcServiceConstants.RESULT_VALUE_STATE_APPROVED);
537         value.setDescr(new RichTextInfo(resultValue,resultValue));
538         value.setName(resultValue);
539         value.setValue(resultValue);
540         try {
541             Float.parseFloat(resultValue);
542             value.setNumericValue(resultValue);
543         } catch (NumberFormatException ex) {
544             // ok not a floating point number
545         }
546         value.setResultScaleKey(scaleKey);
547         value.setEffectiveDate(new Date());
548         try {
549             value = getLrcService().createResultValue(value.getResultScaleKey(), value.getTypeKey(), value, contextInfo);
550         } catch (AlreadyExistsException ex) {
551             throw new OperationFailedException("unexpected", ex);
552         } catch (DataValidationErrorException ex) {
553             throw new OperationFailedException("unexpected", ex);
554         } catch (DoesNotExistException ex) {
555             throw new OperationFailedException("unexpected", ex);
556         }
557         return value;
558     }
559 }