1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.r2.lum.course.service.assembler;
17
18
19
20 import org.apache.log4j.Logger;
21 import org.kuali.student.common.util.UUIDHelper;
22 import org.kuali.student.r1.common.assembly.BOAssembler;
23 import org.kuali.student.r1.common.assembly.BaseDTOAssemblyNode;
24 import org.kuali.student.r1.common.assembly.BaseDTOAssemblyNode.NodeOperation;
25 import org.kuali.student.r2.common.assembler.AssemblyException;
26 import org.kuali.student.r2.common.dto.AttributeInfo;
27 import org.kuali.student.r2.common.dto.ContextInfo;
28 import org.kuali.student.r2.common.dto.DtoConstants;
29 import org.kuali.student.r2.common.dto.RichTextInfo;
30 import org.kuali.student.r2.common.exceptions.DoesNotExistException;
31 import org.kuali.student.r2.common.exceptions.InvalidParameterException;
32 import org.kuali.student.r2.common.exceptions.MissingParameterException;
33 import org.kuali.student.r2.common.exceptions.OperationFailedException;
34 import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
35 import org.kuali.student.r2.core.atp.dto.AtpInfo;
36 import org.kuali.student.r2.core.atp.service.AtpService;
37 import org.kuali.student.r2.lum.clu.dto.AdminOrgInfo;
38 import org.kuali.student.r2.lum.clu.dto.CluAccountingInfo;
39 import org.kuali.student.r2.lum.clu.dto.CluCluRelationInfo;
40 import org.kuali.student.r2.lum.clu.dto.CluFeeInfo;
41 import org.kuali.student.r2.lum.clu.dto.CluFeeRecordInfo;
42 import org.kuali.student.r2.lum.clu.dto.CluIdentifierInfo;
43 import org.kuali.student.r2.lum.clu.dto.CluInfo;
44 import org.kuali.student.r2.lum.clu.dto.CluLoRelationInfo;
45 import org.kuali.student.r2.lum.clu.dto.CluResultInfo;
46 import org.kuali.student.r2.lum.clu.dto.LuCodeInfo;
47 import org.kuali.student.r2.lum.clu.dto.ResultOptionInfo;
48 import org.kuali.student.r2.lum.clu.service.CluService;
49 import org.kuali.student.r2.lum.course.dto.CourseCrossListingInfo;
50 import org.kuali.student.r2.lum.course.dto.CourseExpenditureInfo;
51 import org.kuali.student.r2.lum.course.dto.CourseFeeInfo;
52 import org.kuali.student.r2.lum.course.dto.CourseInfo;
53 import org.kuali.student.r2.lum.course.dto.CourseJointInfo;
54 import org.kuali.student.r2.lum.course.dto.CourseRevenueInfo;
55 import org.kuali.student.r2.lum.course.dto.CourseVariationInfo;
56 import org.kuali.student.r2.lum.course.dto.FormatInfo;
57 import org.kuali.student.r2.lum.course.dto.LoDisplayInfo;
58 import org.kuali.student.r2.lum.lo.dto.LoInfo;
59 import org.kuali.student.r2.lum.lo.service.LearningObjectiveService;
60 import org.kuali.student.r2.lum.lrc.dto.ResultValueInfo;
61 import org.kuali.student.r2.lum.lrc.dto.ResultValueRangeInfo;
62 import org.kuali.student.r2.lum.lrc.dto.ResultValuesGroupInfo;
63 import org.kuali.student.r2.lum.lrc.service.LRCService;
64 import org.kuali.student.r2.lum.service.assembler.CluAssemblerUtils;
65 import org.kuali.student.r2.lum.util.constants.LrcServiceConstants;
66 import org.springframework.util.StringUtils;
67
68 import java.util.ArrayList;
69 import java.util.Collections;
70 import java.util.Comparator;
71 import java.util.Date;
72 import java.util.HashMap;
73 import java.util.HashSet;
74 import java.util.Iterator;
75 import java.util.List;
76 import java.util.Map;
77 import java.util.Map.Entry;
78 import java.util.Set;
79
80
81
82
83
84
85
86
87
88 public class CourseAssembler implements BOAssembler<CourseInfo, CluInfo> {
89
90 final static Logger LOG = Logger.getLogger(CourseAssembler.class);
91 private CluService cluService;
92 private FormatAssembler formatAssembler;
93 private CourseJointAssembler courseJointAssembler;
94 private LoAssembler loAssembler;
95 private LearningObjectiveService loService;
96 private CluAssemblerUtils cluAssemblerUtils;
97 private LRCService lrcService;
98 private AtpService atpService;
99 private float defaultCreditIncrement = 1.0f;
100
101 @Override
102 public CourseInfo assemble(CluInfo clu, CourseInfo courseInfo,
103 boolean shallowBuild,ContextInfo contextInfo) throws AssemblyException {
104
105 CourseInfo course = (null != courseInfo) ? courseInfo
106 : new CourseInfo();
107
108
109
110 course.setAttributes(clu.getAttributes());
111 course.setCampusLocations(clu.getCampusLocations());
112 course.setCode(clu.getOfficialIdentifier().getCode());
113 course.setCourseNumberSuffix(clu.getOfficialIdentifier()
114 .getSuffixCode());
115 course.setLevel(clu.getOfficialIdentifier().getLevel());
116 course.setOutOfClassHours(clu.getIntensity());
117 course.setInstructors(clu.getInstructors());
118 course.setStartTerm(clu.getExpectedFirstAtp());
119 course.setEndTerm(clu.getLastAtp());
120 course.setCourseTitle(clu.getOfficialIdentifier().getLongName());
121
122
123 List<CourseCrossListingInfo> crossListings = assembleCrossListings(clu.getAlternateIdentifiers());
124 course.setCrossListings(crossListings);
125
126
127 List<CourseVariationInfo> variations = assembleVariations(clu.getAlternateIdentifiers());
128 course.setVariations(variations);
129
130
131 if (course.getUnitsDeployment() == null) {
132 course.setUnitsDeployment(new ArrayList<String>());
133 }
134 if (course.getUnitsContentOwner() == null) {
135 course.setUnitsContentOwner(new ArrayList<String>());
136 }
137 List<String> courseAdminOrgs = new ArrayList<String>();
138 List<String> courseSubjectOrgs = new ArrayList<String>();
139 for(AdminOrgInfo adminOrg: clu.getAdminOrgs()){
140 if (adminOrg.getTypeKey().equals(CourseAssemblerConstants.ADMIN_ORG)) {
141 courseAdminOrgs.add(adminOrg.getOrgId());
142 }
143 if (adminOrg.getTypeKey().equals(CourseAssemblerConstants.SUBJECT_ORG)) {
144 courseSubjectOrgs.add(adminOrg.getOrgId());
145 }
146 }
147 course.setUnitsDeployment(courseAdminOrgs);
148 course.setUnitsContentOwner(courseSubjectOrgs);
149 course.setDescr(clu.getDescr());
150 course.setDuration(clu.getStdDuration());
151 course.setEffectiveDate(clu.getEffectiveDate());
152 course.setExpirationDate(clu.getExpirationDate());
153
154
155
156 List<CourseFeeInfo> fees = new ArrayList<CourseFeeInfo>();
157 List<CourseRevenueInfo> revenues = new ArrayList<CourseRevenueInfo>();
158 if(clu.getFeeInfo() != null){
159 course.setFeeJustification(clu.getFeeInfo().getDescr());
160
161
162 for(CluFeeRecordInfo cluFeeRecord: clu.getFeeInfo().getCluFeeRecords()){
163 String feeType = cluFeeRecord.getFeeType();
164 if(CourseAssemblerConstants.COURSE_FINANCIALS_REVENUE_TYPE.equals(feeType)){
165 CourseRevenueInfo courseRevenue = new CourseRevenueInfo();
166 courseRevenue.setFeeType(feeType);
167 courseRevenue.setAffiliatedOrgs(cluFeeRecord.getAffiliatedOrgs());
168 courseRevenue.setAttributes(cluFeeRecord.getAttributes());
169 courseRevenue.setId(cluFeeRecord.getId());
170 courseRevenue.setMeta(cluFeeRecord.getMeta());
171 revenues.add(courseRevenue);
172 }else{
173 CourseFeeInfo courseFee = new CourseFeeInfo();
174 courseFee.setFeeType(feeType);
175 courseFee.setRateType(cluFeeRecord.getRateType());
176 courseFee.setDescr(cluFeeRecord.getDescr());
177 courseFee.setMeta(cluFeeRecord.getMeta());
178 courseFee.setId(cluFeeRecord.getId());
179 courseFee.setFeeAmounts(cluFeeRecord.getFeeAmounts());
180 courseFee.setAttributes(cluFeeRecord.getAttributes());
181 fees.add(courseFee);
182 }
183 }
184 }
185 course.setFees(fees);
186 course.setRevenues(revenues);
187
188 if(course.getExpenditure() == null || clu.getAccountingInfo() == null){
189 course.setExpenditure(new CourseExpenditureInfo());
190 }
191 if(clu.getAccountingInfo() != null){
192 course.getExpenditure().setAffiliatedOrgs(clu.getAccountingInfo().getAffiliatedOrgs());
193 }
194
195 course.setId(clu.getId());
196 course.setTypeKey(clu.getTypeKey());
197 course.setTermsOffered(clu.getOfferedAtpTypes());
198 course.setPrimaryInstructor(clu.getPrimaryInstructor());
199 course.setInstructors(clu.getInstructors());
200 course.setStateKey(clu.getStateKey());
201 course.setSubjectArea(clu.getOfficialIdentifier().getDivision());
202 course.setTranscriptTitle(clu.getOfficialIdentifier().getShortName());
203 course.setMeta(clu.getMeta());
204 course.setVersion(clu.getVersion());
205
206
207
208 course.setSpecialTopicsCourse(false);
209 for(LuCodeInfo luCode : clu.getLuCodes()){
210 if(CourseAssemblerConstants.COURSE_CODE_SPECIAL_TOPICS.equals(luCode.getType())){
211 course.setSpecialTopicsCourse(Boolean.parseBoolean(luCode.getValue()));
212 break;
213 }
214 }
215
216 course.setPilotCourse(false);
217 for(LuCodeInfo luCode : clu.getLuCodes()){
218 if(CourseAssemblerConstants.COURSE_CODE_PILOT_COURSE.equals(luCode.getType())){
219 course.setPilotCourse(Boolean.parseBoolean(luCode.getValue()));
220 break;
221 }
222 }
223
224
225 if (!shallowBuild) {
226 try {
227
228
229 List<CluCluRelationInfo> cluClus = cluService.getCluCluRelationsByClu(clu.getId(),contextInfo);
230
231 for (CluCluRelationInfo cluRel : cluClus) {
232 if (cluRel.getTypeKey().equals(CourseAssemblerConstants.JOINT_RELATION_TYPE)) {
233 CourseJointInfo jointInfo = null;
234 if(cluRel.getCluId().equals(clu.getId())){
235 jointInfo = courseJointAssembler.assemble(cluRel, cluRel.getRelatedCluId(), null, false, contextInfo);
236 }else{
237 jointInfo = courseJointAssembler.assemble(cluRel, cluRel.getCluId(), null, false, contextInfo);
238 }
239 if (jointInfo != null){
240 course.getJoints().add(jointInfo);
241 }
242 }
243 }
244 } catch (DoesNotExistException e) {
245 } catch (Exception e) {
246 throw new AssemblyException("Error getting course joints", e);
247 }
248
249 try {
250
251
252 List<CluInfo> formats = cluService.getRelatedClusByCluAndRelationType(course
253 .getId(),
254 CourseAssemblerConstants.COURSE_FORMAT_RELATION_TYPE , new ContextInfo());
255
256 for (CluInfo format : formats) {
257 FormatInfo formatInfo = formatAssembler.assemble(format,
258 null, false,contextInfo);
259 course.getFormats().add(formatInfo);
260 }
261
262 } catch (DoesNotExistException e) {
263 } catch (Exception e) {
264 throw new AssemblyException("Error getting related formats", e);
265 }
266
267 try{
268
269 List<CluResultInfo> cluResults = cluService.getCluResultByClu(course.getId(),contextInfo);
270
271 List<ResultValuesGroupInfo> creditOptions = assembleCreditOptions(cluResults, contextInfo);
272
273 course.setCreditOptions(creditOptions);
274
275 List<String> gradingOptions = assembleGradingOptions(cluResults);
276
277 course.setGradingOptions(gradingOptions);
278 } catch (DoesNotExistException e){
279 } catch (Exception e) {
280 throw new AssemblyException("Error getting course results", e);
281 }
282
283
284
285
286 }
287
288
289 boolean isAudit = course.getGradingOptions().remove(CourseAssemblerConstants.COURSE_RESULT_COMP_GRADE_AUDIT);
290
291 return course;
292 }
293
294 @Override
295 public BaseDTOAssemblyNode<CourseInfo, CluInfo> disassemble(
296 CourseInfo course, NodeOperation operation,ContextInfo contextInfo)
297 throws AssemblyException, PermissionDeniedException {
298
299 if (course == null) {
300
301
302 LOG.error("Course to disassemble is null!");
303 throw new AssemblyException("Course can not be null");
304 }
305
306 BaseDTOAssemblyNode<CourseInfo, CluInfo> result = new BaseDTOAssemblyNode<CourseInfo, CluInfo>(
307 this);
308
309 CluInfo clu;
310 try {
311 clu = (NodeOperation.UPDATE == operation) ? cluService.getClu(course.getId(),contextInfo) : new CluInfo();
312 } catch (Exception e) {
313 throw new AssemblyException("Error getting existing learning unit during course update", e);
314 }
315
316
317
318 clu.setId(UUIDHelper.genStringUUID(course.getId()));
319 if (null == course.getId()) {
320 course.setId(clu.getId());
321 }
322 clu.setTypeKey(CourseAssemblerConstants.COURSE_TYPE);
323 clu.setStateKey(course.getStateKey());
324 clu.setIsEnrollable(false);
325
326 CluIdentifierInfo identifier = new CluIdentifierInfo();
327 identifier.setTypeKey(CourseAssemblerConstants.COURSE_OFFICIAL_IDENT_TYPE);
328 identifier.setStateKey(course.getStateKey());
329 identifier.setLongName(course.getCourseTitle());
330 identifier.setShortName(course.getTranscriptTitle());
331 identifier.setSuffixCode(course.getCourseNumberSuffix());
332 identifier.setDivision(course.getSubjectArea());
333 identifier.setCode(course.getCode());
334
335
336 if(StringUtils.hasText(course.getLevel())) {
337 identifier.setLevel(course.getLevel());
338 } else if(course.getCourseNumberSuffix()!=null&&course.getCourseNumberSuffix().length()>=3){
339 identifier.setLevel(course.getCourseNumberSuffix().substring(0, 1)+"00");
340 }
341
342 clu.setOfficialIdentifier(identifier);
343
344 clu.setAdminOrgs(new ArrayList<AdminOrgInfo>());
345
346
347
348
349
350 for(Iterator<CluIdentifierInfo> iter = clu.getAlternateIdentifiers().iterator();iter.hasNext();){
351 CluIdentifierInfo cluIdentifier = iter.next();
352 if(CourseAssemblerConstants.COURSE_VARIATION_IDENT_TYPE.equals(cluIdentifier.getTypeKey()) ||
353 CourseAssemblerConstants.COURSE_CROSSLISTING_IDENT_TYPE.equals(cluIdentifier.getTypeKey()) ){
354 iter.remove();
355 }
356 }
357
358 for(CourseVariationInfo variation:course.getVariations()){
359 CluIdentifierInfo cluIdentifier = new CluIdentifierInfo();
360 cluIdentifier.setId(variation.getId());
361 cluIdentifier.setTypeKey(CourseAssemblerConstants.COURSE_VARIATION_IDENT_TYPE);
362 cluIdentifier.setCode(identifier.getCode());
363 cluIdentifier.setSuffixCode(course.getCourseNumberSuffix());
364 cluIdentifier.setDivision(course.getSubjectArea());
365 cluIdentifier.setVariation(variation.getVariationCode());
366 cluIdentifier.setLongName(variation.getVariationTitle());
367 cluIdentifier.setStateKey(course.getStateKey());
368 clu.getAlternateIdentifiers().add(cluIdentifier);
369 }
370
371 for(CourseCrossListingInfo crossListing:course.getCrossListings()){
372 CluIdentifierInfo cluIdentifier = new CluIdentifierInfo();
373 cluIdentifier.setId(crossListing.getId());
374 cluIdentifier.setTypeKey(CourseAssemblerConstants.COURSE_CROSSLISTING_IDENT_TYPE);
375 cluIdentifier.setSuffixCode(crossListing.getCourseNumberSuffix());
376 cluIdentifier.setDivision(crossListing.getSubjectArea());
377 cluIdentifier.setStateKey(course.getStateKey());
378 cluIdentifier.setOrgId(crossListing.getSubjectOrgId());
379 cluIdentifier.setAttributes(crossListing.getAttributes());
380 cluIdentifier.setCode(crossListing.getCode());
381 clu.getAlternateIdentifiers().add(cluIdentifier);
382 }
383
384 List<AdminOrgInfo> adminOrgInfos = new ArrayList<AdminOrgInfo>();
385 for(String org:course.getUnitsDeployment()){
386 AdminOrgInfo adminOrg = new AdminOrgInfo();
387 adminOrg.setTypeKey(CourseAssemblerConstants.ADMIN_ORG);
388 adminOrg.setOrgId(org);
389 adminOrgInfos.add(adminOrg);
390 }
391 clu.getAdminOrgs().addAll(adminOrgInfos);
392
393 List<AdminOrgInfo> subjectOrgs = new ArrayList<AdminOrgInfo>();
394 for (String subOrg : course.getUnitsContentOwner()) {
395 AdminOrgInfo subjectOrg = new AdminOrgInfo();
396 subjectOrg.setTypeKey(CourseAssemblerConstants.SUBJECT_ORG);
397 subjectOrg.setOrgId(subOrg);
398 subjectOrgs.add(subjectOrg);
399 }
400 clu.getAdminOrgs().addAll(subjectOrgs);
401
402
403 clu.setAttributes(course.getAttributes());
404 clu.setCampusLocations(course.getCampusLocations());
405 clu.setDescr(course.getDescr());
406 clu.setStdDuration(course.getDuration());
407
408
409 if(course.getStartTerm() != null){
410 try {
411 AtpInfo startAtp = atpService.getAtp(course.getStartTerm(), contextInfo);
412 course.setEffectiveDate(startAtp.getStartDate());
413 } catch (Exception e) {
414 throw new AssemblyException("Error getting start term Atp.",e);
415 }
416 }
417 if(course.getEndTerm() != null){
418 try {
419 AtpInfo endAtp = atpService.getAtp(course.getEndTerm(), contextInfo);
420 course.setExpirationDate(endAtp.getEndDate());
421 } catch (Exception e) {
422 throw new AssemblyException("Error getting end term Atp.",e);
423 }
424 }
425
426 clu.setEffectiveDate(course.getEffectiveDate());
427 clu.setExpirationDate(course.getExpirationDate());
428
429 clu.setOfferedAtpTypes(course.getTermsOffered());
430 clu.setPrimaryInstructor(course.getPrimaryInstructor());
431
432 clu.setIntensity(course.getOutOfClassHours());
433 clu.setInstructors(course.getInstructors());
434
435 clu.setExpectedFirstAtp(course.getStartTerm());
436 clu.setLastAtp(course.getEndTerm());
437
438 clu.setMeta(course.getMeta());
439 clu.setVersion(course.getVersion());
440
441
442 result.setNodeData(clu);
443 result.setOperation(operation);
444 result.setBusinessDTORef(course);
445
446
447 List<BaseDTOAssemblyNode<?, ?>> formatResults;
448 try {
449 formatResults = disassembleFormats(clu.getId(), course, operation,contextInfo);
450 result.getChildNodes().addAll(formatResults);
451
452 } catch (DoesNotExistException e) {
453 } catch (Exception e) {
454 throw new AssemblyException("Error while disassembling format", e);
455 }
456
457
458
459 List<BaseDTOAssemblyNode<?, ?>> courseJointResults = disassembleJoints(clu.getId(), course, operation,contextInfo);
460 result.getChildNodes().addAll(courseJointResults);
461
462
463
464 for (AttributeInfo attr : course.getAttributes()) {
465 if (attr.getKey() != null){
466 if (attr.getKey().equals(CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_AUDIT)
467 && "true".equals(attr.getValue()) ){
468 if(!course.getGradingOptions().contains(CourseAssemblerConstants.COURSE_RESULT_COMP_GRADE_AUDIT)){
469 course.getGradingOptions().add(CourseAssemblerConstants.COURSE_RESULT_COMP_GRADE_AUDIT);
470 }
471 break;
472 }
473 }
474 }
475
476
477 for (AttributeInfo attr : course.getAttributes()){
478 if (attr.getKey() != null){
479 if (attr.getKey().equals(CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_PASSFAIL)
480 && "true".equals(attr.getValue()) ){
481 if(!course.getGradingOptions().contains(CourseAssemblerConstants.COURSE_RESULT_COMP_GRADE_PASSFAIL)){
482 course.getGradingOptions().add(CourseAssemblerConstants.COURSE_RESULT_COMP_GRADE_PASSFAIL);
483 }
484 break;
485 }
486 }
487 }
488
489
490 List<CluResultInfo> cluResultList;
491 try {
492 cluResultList = cluService.getCluResultByClu(clu.getId(),contextInfo);
493 } catch (DoesNotExistException e) {
494 cluResultList = Collections.emptyList();
495 } catch (Exception e) {
496 throw new AssemblyException("Error getting cluResults", e);
497 }
498
499 List<BaseDTOAssemblyNode<?, ?>> creditOutcomes = disassembleCreditOutcomes(course, clu, cluResultList, operation, contextInfo);
500 result.getChildNodes().addAll(creditOutcomes);
501 BaseDTOAssemblyNode<?, ?> gradingOptions = disassembleGradingOptions(clu.getId(), course.getStateKey(), course.getGradingOptions(), cluResultList, operation);
502 result.getChildNodes().add(gradingOptions);
503
504
505 try {
506 List<BaseDTOAssemblyNode<?, ?>> loResults;
507 loResults = disassembleLos(clu.getId(), course, operation,contextInfo);
508 result.getChildNodes().addAll(loResults);
509 } catch (Exception e) {
510 throw new AssemblyException("Error while disassembling los", e);
511 }
512
513
514 boolean alreadyHadSpecialTopicsCode = false;
515 for(Iterator<LuCodeInfo> luCodeIterator = clu.getLuCodes().iterator();luCodeIterator.hasNext();){
516 LuCodeInfo luCode = luCodeIterator.next();
517 if(CourseAssemblerConstants.COURSE_CODE_SPECIAL_TOPICS.equals(luCode.getType())){
518 alreadyHadSpecialTopicsCode = true;
519 if(!course.isSpecialTopicsCourse()){
520 luCodeIterator.remove();
521 }
522 break;
523 }
524 }
525 if(!alreadyHadSpecialTopicsCode && course.isSpecialTopicsCourse()){
526 LuCodeInfo luCode = new LuCodeInfo();
527 luCode.setType(CourseAssemblerConstants.COURSE_CODE_SPECIAL_TOPICS);
528 luCode.setValue("true");
529 clu.getLuCodes().add(luCode);
530 }
531
532
533 boolean alreadyHadPilotCourseCode = false;
534 for(Iterator<LuCodeInfo> luCodeIterator = clu.getLuCodes().iterator();luCodeIterator.hasNext();){
535 LuCodeInfo luCode = luCodeIterator.next();
536 if(CourseAssemblerConstants.COURSE_CODE_PILOT_COURSE.equals(luCode.getType())){
537 alreadyHadPilotCourseCode = true;
538 if(!course.isPilotCourse()){
539 luCodeIterator.remove();
540 }
541 break;
542 }
543 }
544 if(!alreadyHadPilotCourseCode && course.isPilotCourse()){
545 LuCodeInfo luCode = new LuCodeInfo();
546 luCode.setType(CourseAssemblerConstants.COURSE_CODE_PILOT_COURSE);
547 luCode.setValue("true");
548 clu.getLuCodes().add(luCode);
549 }
550
551
552 if(clu.getFeeInfo() == null){
553 clu.setFeeInfo(new CluFeeInfo());
554 }
555 clu.getFeeInfo().setDescr(course.getFeeJustification());
556 clu.getFeeInfo().getCluFeeRecords().clear();
557 for(CourseRevenueInfo courseRevenue:course.getRevenues()){
558 CluFeeRecordInfo cluFeeRecord = new CluFeeRecordInfo();
559 cluFeeRecord.setFeeType(CourseAssemblerConstants.COURSE_FINANCIALS_REVENUE_TYPE);
560 cluFeeRecord.setRateType(CourseAssemblerConstants.COURSE_FINANCIALS_REVENUE_TYPE);
561
562 cluFeeRecord.setAttributes(courseRevenue.getAttributes());
563 cluFeeRecord.setAffiliatedOrgs(courseRevenue.getAffiliatedOrgs());
564 cluFeeRecord.setId(courseRevenue.getId());
565 cluFeeRecord.setMeta(courseRevenue.getMeta());
566 clu.getFeeInfo().getCluFeeRecords().add(cluFeeRecord);
567 }
568 for(CourseFeeInfo courseFee : course.getFees()){
569 CluFeeRecordInfo cluFeeRecord = new CluFeeRecordInfo();
570 cluFeeRecord.setFeeType(courseFee.getFeeType());
571 cluFeeRecord.setRateType(courseFee.getRateType());
572 cluFeeRecord.setDescr(courseFee.getDescr());
573 cluFeeRecord.setMeta(courseFee.getMeta());
574 cluFeeRecord.setId(courseFee.getId());
575 cluFeeRecord.setFeeAmounts(courseFee.getFeeAmounts());
576
577 cluFeeRecord.setAttributes(courseFee.getAttributes());
578 clu.getFeeInfo().getCluFeeRecords().add(cluFeeRecord);
579 }
580 if(clu.getAccountingInfo() == null || course.getExpenditure()== null){
581 clu.setAccountingInfo( new CluAccountingInfo());
582 }
583 if(course.getExpenditure() != null){
584 clu.getAccountingInfo().setAffiliatedOrgs(course.getExpenditure().getAffiliatedOrgs());
585
586 clu.getAccountingInfo().setAttributes(course.getExpenditure().getAttributes());
587 }
588
589 return result;
590 }
591
592
593
594
595
596
597
598
599 private boolean _checkIfSimpleFloat(String str) {
600 String DIGITS = "0123456789";
601 String DIGITS_AND_DOT = DIGITS + ".";
602 boolean foundDot = false;
603 int numDigits = 0;
604 for (int i = 0; i < str.length(); i++) {
605 String ch = str.substring(i, i + 1);
606 if (DIGITS_AND_DOT.indexOf(ch) < 0) {
607 return false;
608 }
609 if (".".equals(ch)) {
610 if (!foundDot) {
611 foundDot = true;
612 } else {
613
614 return false;
615 }
616 }
617 if (DIGITS.indexOf(ch) >= 0) {
618 numDigits++;
619 }
620 }
621
622 return numDigits > 0;
623 }
624
625
626
627
628
629
630 private List<String> _computeResultValues(List<String> resultValueKeys, ContextInfo contextInfo) throws InvalidParameterException, MissingParameterException, DoesNotExistException, PermissionDeniedException, OperationFailedException {
631 List<String> values = new ArrayList<String>();
632 if(resultValueKeys!=null && !resultValueKeys.isEmpty()){
633 String firstKey = resultValueKeys.get(0);
634
635
636 if (_checkIfSimpleFloat(firstKey)) {
637
638 return resultValueKeys;
639 }
640
641 for (String key: resultValueKeys) {
642 ResultValueInfo rv = lrcService.getResultValue(key, contextInfo);
643 String value = rv.getValue();
644 values.add(value);
645 }
646 }
647 return values;
648 }
649
650 private List<BaseDTOAssemblyNode<?, ?>> disassembleCreditOutcomes(CourseInfo course, CluInfo clu, List<CluResultInfo> currentCluResults, NodeOperation operation, ContextInfo contextInfo) throws AssemblyException, NumberFormatException {
651
652 List<BaseDTOAssemblyNode<?, ?>> results = new ArrayList<BaseDTOAssemblyNode<?, ?>>();
653
654 String courseResultType = CourseAssemblerConstants.COURSE_RESULT_TYPE_CREDITS;
655
656
657 if(NodeOperation.DELETE!=operation){
658
659 Set<String> resultValueGroupIds = new HashSet<String>();
660
661 try{
662 try {
663 resultValueGroupIds.addAll(lrcService.getResultValuesGroupKeysByType(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_FIXED, contextInfo));
664 } catch (DoesNotExistException e) {}
665 try {
666 resultValueGroupIds.addAll(lrcService.getResultValuesGroupKeysByType(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_MULTIPLE, contextInfo));
667 } catch (DoesNotExistException e) {}
668 try {
669 resultValueGroupIds.addAll(lrcService.getResultValuesGroupKeysByType(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_VARIABLE, contextInfo));
670 } catch (DoesNotExistException e) {}
671
672
673 for(ResultValuesGroupInfo creditOption:course.getCreditOptions()){
674
675 String id = null;
676 String type = null;
677 List<String> resultValues = null;
678 ResultValueRangeInfo resultValueRange = null;
679
680 if(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_FIXED.equals(creditOption.getTypeKey())){
681 float fixedCreditValue = Float.parseFloat(creditOption.getResultValueRange().getMinValue());
682 id = CourseAssemblerConstants.COURSE_RESULT_COMP_CREDIT_PREFIX + fixedCreditValue;
683 type = CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_FIXED;
684 resultValues = new ArrayList<String>();
685 resultValues.add(String.valueOf(fixedCreditValue));
686 resultValueRange = new ResultValueRangeInfo();
687 resultValueRange.setMinValue(String.valueOf(fixedCreditValue));
688 resultValueRange.setMaxValue(String.valueOf(fixedCreditValue));
689 } else if (CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_MULTIPLE.equals(creditOption.getTypeKey())){
690 List<String> resultVals = _computeResultValues(creditOption.getResultValueKeys(), contextInfo);
691 Collections.sort(resultVals, new Comparator<String>() {
692 public int compare(String o1, String o2) {
693 return Float.compare(Float.parseFloat(o1),Float.parseFloat(o2));
694 }
695 });
696
697 StringBuilder sb = new StringBuilder(CourseAssemblerConstants.COURSE_RESULT_COMP_CREDIT_PREFIX);
698 for (Iterator<String> iter = resultVals.iterator();
699 iter.hasNext();){
700 String str = iter.next();
701 sb.append(str);
702 if(iter.hasNext()){
703 sb.append(",");
704 }
705 }
706 id = sb.toString();
707 type = CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_MULTIPLE;
708 resultValues = new ArrayList<String>();
709 resultValues.addAll(resultVals);
710 }else if(CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_VARIABLE.equals(creditOption.getTypeKey())){
711
712
713
714
715
716 float minCredits = Float.parseFloat(creditOption.getResultValueRange().getMinValue());
717 float maxCredits = Float.parseFloat(creditOption.getResultValueRange().getMaxValue());
718 String creditValueIncr = creditOption.getResultValueRange().getIncrement();
719 float increment = (null != creditValueIncr && creditValueIncr.length() > 0 ) ? Float.parseFloat(creditValueIncr) : defaultCreditIncrement ;
720
721 id = CourseAssemblerConstants.COURSE_RESULT_COMP_CREDIT_PREFIX + String.valueOf(minCredits) + "-" + String.valueOf(maxCredits);
722
723 if (creditValueIncr!=null && !"1".equals(creditValueIncr) && !"1.0".equals(creditValueIncr)) {
724 id += (" by " + creditValueIncr);
725 }
726
727 type = CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_VARIABLE;
728 resultValues = new ArrayList<String>();
729 for(float i = minCredits; i <= maxCredits; i+=increment){
730 resultValues.add(String.valueOf(i));
731 }
732 resultValueRange = new ResultValueRangeInfo();
733 resultValueRange.setMinValue(String.valueOf(minCredits));
734 resultValueRange.setMaxValue(String.valueOf(maxCredits));
735 resultValueRange.setIncrement(String.valueOf(increment));
736 }else{
737 resultValues = Collections.emptyList();
738 }
739
740
741 creditOption.setKey(id);
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756 if(id != null && !resultValueGroupIds.contains(id)){
757
758
759 ResultValuesGroupInfo resultValueGroup = new ResultValuesGroupInfo();
760 resultValueGroup.setKey(id);
761 resultValueGroup.setTypeKey(type);
762 if (DtoConstants.STATE_DRAFT.equals(course.getStateKey())){
763 resultValueGroup.setStateKey(LrcServiceConstants.RESULT_GROUPS_STATE_DRAFT);
764 } else if (DtoConstants.STATE_APPROVED.equals(course.getStateKey())) {
765 resultValueGroup.setStateKey(LrcServiceConstants.RESULT_GROUPS_STATE_APPROVED);
766 } else {
767 resultValueGroup.setStateKey(LrcServiceConstants.RESULT_GROUPS_STATE_RETIRED);
768 }
769 resultValueGroup.setResultScaleKey(LrcServiceConstants.RESULT_SCALE_KEY_CREDIT_DEGREE);
770 resultValueGroup.setResultValueKeys(resultValues);
771 resultValueGroup.setResultValueRange(resultValueRange);
772 BaseDTOAssemblyNode<ResultValuesGroupInfo, ResultValuesGroupInfo> node = new BaseDTOAssemblyNode<ResultValuesGroupInfo, ResultValuesGroupInfo>(null);
773 node.setOperation(NodeOperation.CREATE);
774 node.setNodeData(resultValueGroup);
775 node.setBusinessDTORef(creditOption);
776 results.add(node);
777
778 resultValueGroupIds.add(id);
779 }
780 }
781 }catch (NumberFormatException e){
782 throw new AssemblyException("Invalid Arguments for credit outcome values",e);
783 }catch (Exception e){
784 throw new AssemblyException("Error Assembling", e);
785 }
786 }
787
788
789
790
791 Map<String, List<CluResultInfo>> currentResults = new HashMap<String, List<CluResultInfo>>();
792
793
794 if (!NodeOperation.CREATE.equals(operation)) {
795 for (CluResultInfo currentResult : currentCluResults) {
796 if (courseResultType.equals(currentResult.getTypeKey())) {
797
798 if(currentResult.getResultOptions().size()==1){
799
800 String resultComponentId = currentResult.getResultOptions().get(0).getResultComponentId();
801 if(!currentResults.containsKey(resultComponentId)){
802 currentResults.put(resultComponentId, new ArrayList<CluResultInfo>());
803 }
804 currentResults.get(resultComponentId).add(currentResult);
805 }else{
806 LOG.warn("Credit Results should have exactly one result option each");
807 }
808 }
809 }
810 }
811
812
813 for(ResultValuesGroupInfo creditOption : course.getCreditOptions()){
814 if (NodeOperation.CREATE == operation
815 || (NodeOperation.UPDATE == operation && !currentResults.containsKey(creditOption.getKey()) )) {
816
817 ResultOptionInfo resultOption = new ResultOptionInfo();
818 resultOption.setStateKey(course.getStateKey());
819 resultOption.setResultComponentId(creditOption.getKey());
820
821 CluResultInfo cluResult = new CluResultInfo();
822 cluResult.setCluId(clu.getId());
823 cluResult.setStateKey(course.getStateKey());
824 cluResult.setTypeKey(courseResultType);
825
826 cluResult.getResultOptions().add(resultOption);
827
828 BaseDTOAssemblyNode<ResultValuesGroupInfo, CluResultInfo> cluResultNode = new BaseDTOAssemblyNode<ResultValuesGroupInfo, CluResultInfo>(null);
829 cluResultNode.setNodeData(cluResult);
830 cluResultNode.setOperation(NodeOperation.CREATE);
831
832 results.add(cluResultNode);
833 } else if (NodeOperation.UPDATE == operation
834 && currentResults.containsKey(creditOption.getKey())) {
835
836 List<CluResultInfo> cluResults = currentResults.get(creditOption.getKey());
837 cluResults.remove(cluResults.size()-1);
838 if(cluResults.isEmpty()){
839 currentResults.remove(creditOption.getKey());
840 }
841 }
842 }
843
844
845 for(Entry<String,List<CluResultInfo>> entry:currentResults.entrySet()){
846 for(CluResultInfo cluResult:entry.getValue()){
847 BaseDTOAssemblyNode<ResultValuesGroupInfo, CluResultInfo> cluResultNode = new BaseDTOAssemblyNode<ResultValuesGroupInfo, CluResultInfo>(null);
848 cluResultNode.setNodeData(cluResult);
849 cluResultNode.setOperation(NodeOperation.DELETE);
850 results.add(cluResultNode);
851 }
852 }
853
854 return results;
855 }
856
857 private List<String> assembleGradingOptions(List<CluResultInfo> cluResults){
858
859 String courseResultType = CourseAssemblerConstants.COURSE_RESULT_TYPE_GRADE;
860
861 List<String> results = new ArrayList<String>();
862
863 for(CluResultInfo cluResult:cluResults){
864 if(courseResultType.equals(cluResult.getTypeKey())){
865
866 for(ResultOptionInfo resultOption: cluResult.getResultOptions()){
867 results.add(resultOption.getResultComponentId());
868 }
869 break;
870 }
871 }
872 return results;
873 }
874
875 private List<ResultValuesGroupInfo> assembleCreditOptions(
876 List<CluResultInfo> cluResults, ContextInfo contextInfo) throws AssemblyException {
877 String courseResultType = CourseAssemblerConstants.COURSE_RESULT_TYPE_CREDITS;
878 List<ResultValuesGroupInfo> results = new ArrayList<ResultValuesGroupInfo>();
879
880 for(CluResultInfo cluResult:cluResults){
881 if(courseResultType.equals(cluResult.getTypeKey())){
882
883 for(ResultOptionInfo resultOption: cluResult.getResultOptions()){
884 try {
885 if(resultOption.getResultComponentId()!=null){
886 ResultValuesGroupInfo resultValuesGroup = lrcService.getResultValuesGroup(resultOption.getResultComponentId(), contextInfo);
887 results.add(resultValuesGroup);
888 }
889 } catch (DoesNotExistException e) {
890 LOG.warn("Course Credit option:"+resultOption.getId()+" refers to non-existant ResultValuesGroupInfo "+ resultOption.getResultComponentId());
891 } catch (Exception e) {
892 throw new AssemblyException("Error getting ResultValuesGroupInfo",e);
893 }
894 }
895 }
896 }
897 return results;
898 }
899
900
901 private List<BaseDTOAssemblyNode<?, ?>> disassembleLos(String cluId, CourseInfo course, NodeOperation operation,ContextInfo contextInfo) throws AssemblyException {
902
903 List<BaseDTOAssemblyNode<?, ?>> results = new ArrayList<BaseDTOAssemblyNode<?, ?>>();
904
905
906
907 Map<String, CluLoRelationInfo> currentCluLoRelations = new HashMap<String, CluLoRelationInfo>();
908 try {
909 List<CluLoRelationInfo> cluLoRelations = cluService.getCluLoRelationsByClu(cluId,contextInfo);
910 for(CluLoRelationInfo cluLoRelation:cluLoRelations){
911 if(CourseAssemblerConstants.COURSE_LO_COURSE_SPECIFIC_RELATION.equals(cluLoRelation.getTypeKey())){
912 currentCluLoRelations.put(cluLoRelation.getLoId(), cluLoRelation);
913 }
914 }
915 } catch (DoesNotExistException e) {
916 } catch (Exception e) {
917 throw new AssemblyException("Error finding related Los");
918 }
919
920
921 for(LoDisplayInfo loDisplay : course.getCourseSpecificLOs()){
922
923
924 if (NodeOperation.CREATE == operation
925 || (NodeOperation.UPDATE == operation && !currentCluLoRelations.containsKey(loDisplay.getLoInfo().getId()))) {
926
927
928
929 loDisplay.getLoInfo().setId(null);
930 loDisplay.getLoInfo().setStateKey(course.getStateKey());
931 BaseDTOAssemblyNode<LoDisplayInfo, LoInfo> loNode = loAssembler
932 .disassemble(loDisplay, NodeOperation.CREATE,contextInfo);
933 results.add(loNode);
934
935
936 CluLoRelationInfo relation = new CluLoRelationInfo();
937 relation.setCluId(cluId);
938 relation.setLoId(loNode.getNodeData().getId());
939 relation
940 .setTypeKey(CourseAssemblerConstants.COURSE_LO_COURSE_SPECIFIC_RELATION);
941 relation.setStateKey(course.getStateKey());
942
943 BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo> relationNode = new BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo>(
944 null);
945 relationNode.setNodeData(relation);
946 relationNode.setOperation(NodeOperation.CREATE);
947
948 results.add(relationNode);
949 } else if (NodeOperation.UPDATE == operation
950 && currentCluLoRelations.containsKey(loDisplay.getLoInfo().getId())) {
951 loDisplay.getLoInfo().setStateKey(course.getStateKey());
952
953 BaseDTOAssemblyNode<LoDisplayInfo, LoInfo> loNode = loAssembler
954 .disassemble(loDisplay, NodeOperation.UPDATE,contextInfo);
955 results.add(loNode);
956
957
958
959 currentCluLoRelations.remove(loDisplay.getLoInfo().getId());
960 } else if (NodeOperation.DELETE == operation
961 && currentCluLoRelations.containsKey(loDisplay.getLoInfo().getId())) {
962
963
964 CluLoRelationInfo relationToDelete = currentCluLoRelations.get(loDisplay.getLoInfo().getId());
965 BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo> relationToDeleteNode = new BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo>(
966 null);
967 relationToDeleteNode.setNodeData(relationToDelete);
968 relationToDeleteNode.setOperation(NodeOperation.DELETE);
969 results.add(relationToDeleteNode);
970
971 BaseDTOAssemblyNode<LoDisplayInfo, LoInfo> loNode = loAssembler
972 .disassemble(loDisplay, NodeOperation.DELETE,contextInfo);
973 results.add(loNode);
974
975
976
977 currentCluLoRelations.remove(loDisplay.getLoInfo().getId());
978 }
979 }
980
981
982
983 for (Entry<String, CluLoRelationInfo> entry : currentCluLoRelations.entrySet()) {
984
985
986 CluLoRelationInfo relationToDelete = entry.getValue();
987 BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo> relationToDeleteNode = new BaseDTOAssemblyNode<LoDisplayInfo, CluLoRelationInfo>(
988 null);
989 relationToDeleteNode.setNodeData(relationToDelete);
990 relationToDeleteNode.setOperation(NodeOperation.DELETE);
991 results.add(relationToDeleteNode);
992
993 try{
994 LoInfo loToDelete = loService.getLo(entry.getKey(),contextInfo);
995
996 LoDisplayInfo loDisplayToDelete = loAssembler.assemble(loToDelete, null, false,contextInfo);
997 BaseDTOAssemblyNode<LoDisplayInfo, LoInfo> loNode = loAssembler
998 .disassemble(loDisplayToDelete, NodeOperation.DELETE,contextInfo);
999 results.add(loNode);
1000 } catch (DoesNotExistException e){
1001 LOG.warn("Trying to delete non exsistant LO:"+entry.getKey());
1002 } catch (Exception e) {
1003 throw new AssemblyException("Error disassembling LOs",e);
1004 }
1005 }
1006
1007 return results;
1008 }
1009
1010 private BaseDTOAssemblyNode<?, ?> disassembleGradingOptions(String cluId,
1011 String courseState, List<String> options, List<CluResultInfo> currentCluResults, NodeOperation operation) throws AssemblyException {
1012 BaseDTOAssemblyNode<List<String>, CluResultInfo> cluResultNode = new BaseDTOAssemblyNode<List<String>, CluResultInfo>(null);
1013
1014 String courseResultType=CourseAssemblerConstants.COURSE_RESULT_TYPE_GRADE;
1015 String resultsDescription="Grading options";
1016 String resultDescription="Grading option";
1017
1018
1019 Map<String, ResultOptionInfo> currentResults = new HashMap<String, ResultOptionInfo>();
1020
1021 CluResultInfo cluResult = null;
1022
1023
1024 if (!NodeOperation.CREATE.equals(operation)) {
1025 for (CluResultInfo currentResult : currentCluResults) {
1026 if (courseResultType.equals(currentResult.getTypeKey())) {
1027 cluResult = currentResult;
1028 if(NodeOperation.DELETE.equals(operation)){
1029
1030 cluResultNode.setOperation(NodeOperation.DELETE);
1031 }else{
1032
1033 cluResultNode.setOperation(NodeOperation.UPDATE);
1034 for(ResultOptionInfo resultOption:currentResult.getResultOptions()){
1035 currentResults.put(resultOption.getResultComponentId(), resultOption);
1036 }
1037 }
1038 break;
1039 }
1040 }
1041 }
1042
1043
1044 if(!NodeOperation.DELETE.equals(operation)){
1045 if(cluResult == null){
1046
1047 cluResult = new CluResultInfo();
1048 cluResult.setCluId(cluId);
1049 cluResult.setStateKey(courseState);
1050 cluResult.setTypeKey(courseResultType);
1051 RichTextInfo desc = new RichTextInfo();
1052 desc.setPlain(resultsDescription);
1053 cluResult.setDescr(desc);
1054 cluResult.setEffectiveDate(new Date());
1055 cluResultNode.setOperation(NodeOperation.CREATE);
1056 }
1057
1058 cluResult.setResultOptions(new ArrayList<ResultOptionInfo>());
1059
1060
1061 for (String optionType : options) {
1062 if(currentResults.containsKey(optionType)){
1063
1064 ResultOptionInfo resultOptionInfo = currentResults.get(optionType);
1065 cluResult.getResultOptions().add(resultOptionInfo);
1066 }else{
1067
1068 ResultOptionInfo resultOptionInfo = new ResultOptionInfo();
1069 RichTextInfo desc = new RichTextInfo();
1070 desc.setPlain(resultDescription);
1071 resultOptionInfo.setDescr(desc);
1072 resultOptionInfo.setResultComponentId(optionType);
1073 resultOptionInfo.setStateKey(courseState);
1074
1075 cluResult.getResultOptions().add(resultOptionInfo);
1076 }
1077 }
1078 }
1079
1080 cluResultNode.setNodeData(cluResult);
1081 return cluResultNode;
1082 }
1083
1084
1085
1086 private List<BaseDTOAssemblyNode<?, ?>> disassembleFormats(String nodeId,
1087 CourseInfo course, NodeOperation operation,ContextInfo contextInfo)
1088 throws AssemblyException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
1089
1090 List<BaseDTOAssemblyNode<?, ?>> results = new ArrayList<BaseDTOAssemblyNode<?, ?>>();
1091
1092
1093
1094 Map<String, String> currentformatIds = new HashMap<String, String>();
1095
1096 if (!NodeOperation.CREATE.equals(operation)) {
1097 try {
1098 List<CluCluRelationInfo> formatRelationships = cluService
1099 .getCluCluRelationsByClu(course.getId(),contextInfo);
1100
1101 formatRelationships = (null == formatRelationships) ? new ArrayList<CluCluRelationInfo>() : formatRelationships;
1102
1103 for (CluCluRelationInfo formatRelation : formatRelationships) {
1104 if (CourseAssemblerConstants.COURSE_FORMAT_RELATION_TYPE
1105 .equals(formatRelation.getTypeKey())) {
1106 currentformatIds.put(formatRelation.getRelatedCluId(),
1107 formatRelation.getId());
1108 }
1109 }
1110 } catch (DoesNotExistException e) {
1111 } catch (InvalidParameterException e) {
1112 throw new AssemblyException("Error getting related formats", e);
1113 } catch (MissingParameterException e) {
1114 throw new AssemblyException("Error getting related formats", e);
1115 } catch (OperationFailedException e) {
1116 throw new AssemblyException("Error getting related formats", e);
1117 }
1118 }
1119
1120
1121 for (FormatInfo format : course.getFormats()) {
1122
1123
1124 if (NodeOperation.CREATE == operation
1125 || (NodeOperation.UPDATE == operation && !currentformatIds.containsKey(format.getId()) )) {
1126
1127
1128 format.setStateKey(course.getStateKey());
1129 BaseDTOAssemblyNode<FormatInfo, CluInfo> formatNode = formatAssembler
1130 .disassemble(format, NodeOperation.CREATE,contextInfo);
1131 results.add(formatNode);
1132
1133
1134
1135 CluCluRelationInfo relation = new CluCluRelationInfo();
1136 relation.setCluId(nodeId);
1137 relation.setRelatedCluId(formatNode.getNodeData().getId());
1138
1139
1140
1141
1142 relation
1143 .setTypeKey(CourseAssemblerConstants.COURSE_FORMAT_RELATION_TYPE);
1144 relation.setStateKey(course.getStateKey());
1145
1146 BaseDTOAssemblyNode<CourseInfo, CluCluRelationInfo> relationNode = new BaseDTOAssemblyNode<CourseInfo, CluCluRelationInfo>(
1147 null);
1148 relationNode.setNodeData(relation);
1149 relationNode.setOperation(NodeOperation.CREATE);
1150
1151 results.add(relationNode);
1152 } else if (NodeOperation.UPDATE == operation
1153 && currentformatIds.containsKey(format.getId())) {
1154
1155
1156 format.setStateKey(course.getStateKey());
1157 BaseDTOAssemblyNode<FormatInfo, CluInfo> formatNode = formatAssembler
1158 .disassemble(format, NodeOperation.UPDATE,contextInfo);
1159 results.add(formatNode);
1160
1161
1162
1163 currentformatIds.remove(format.getId());
1164 } else if (NodeOperation.DELETE == operation
1165 && currentformatIds.containsKey(format.getId())) {
1166
1167 CluCluRelationInfo relationToDelete = new CluCluRelationInfo();
1168 relationToDelete.setId( currentformatIds.get(format.getId()) );
1169 BaseDTOAssemblyNode<CourseInfo, CluCluRelationInfo> relationToDeleteNode = new BaseDTOAssemblyNode<CourseInfo, CluCluRelationInfo>(
1170 null);
1171 relationToDeleteNode.setNodeData(relationToDelete);
1172 relationToDeleteNode.setOperation(NodeOperation.DELETE);
1173 results.add(relationToDeleteNode);
1174
1175 BaseDTOAssemblyNode<FormatInfo, CluInfo> formatNode = formatAssembler
1176 .disassemble(format, NodeOperation.DELETE,contextInfo);
1177 results.add(formatNode);
1178
1179
1180
1181 currentformatIds.remove(format.getId());
1182 }
1183 }
1184
1185
1186
1187 for (Entry<String, String> entry : currentformatIds.entrySet()) {
1188
1189
1190 CluCluRelationInfo relationToDelete = new CluCluRelationInfo();
1191 relationToDelete.setId( entry.getValue() );
1192 BaseDTOAssemblyNode<CourseInfo, CluCluRelationInfo> relationToDeleteNode = new BaseDTOAssemblyNode<CourseInfo, CluCluRelationInfo>(
1193 null);
1194 relationToDeleteNode.setNodeData(relationToDelete);
1195 relationToDeleteNode.setOperation(NodeOperation.DELETE);
1196 results.add(relationToDeleteNode);
1197
1198 CluInfo formatCluToDelete = cluService.getClu(entry.getKey() , new ContextInfo());
1199 FormatInfo formatToDelete = formatAssembler.assemble(formatCluToDelete, null, false,contextInfo);
1200 BaseDTOAssemblyNode<FormatInfo, CluInfo> formatNode = formatAssembler
1201 .disassemble(formatToDelete, NodeOperation.DELETE,contextInfo);
1202 results.add(formatNode);
1203 }
1204
1205 return results;
1206 }
1207
1208 private List<CourseVariationInfo> assembleVariations(List<CluIdentifierInfo> cluIdents) {
1209 List<CourseVariationInfo> variations = new ArrayList<CourseVariationInfo>();
1210 if (cluIdents != null) {
1211 for (CluIdentifierInfo cluIdent : cluIdents) {
1212 if (cluIdent.getTypeKey() != null &&
1213 cluIdent.getTypeKey().equals(CourseAssemblerConstants.COURSE_VARIATION_IDENT_TYPE)) {
1214 CourseVariationInfo variation = new CourseVariationInfo();
1215 variation.setId(cluIdent.getId());
1216 variation.setTypeKey(cluIdent.getTypeKey());
1217 variation.setCourseNumberSuffix(cluIdent.getSuffixCode());
1218 variation.setSubjectArea(cluIdent.getDivision());
1219 variation.setVariationCode(cluIdent.getVariation());
1220 variation.setVariationTitle(cluIdent.getLongName());
1221 variations.add(variation);
1222 }
1223 }
1224 }
1225 return variations;
1226 }
1227
1228 private List<CourseCrossListingInfo> assembleCrossListings(List<CluIdentifierInfo> cluIdents)
1229 throws AssemblyException {
1230 List<CourseCrossListingInfo> crossListings = new ArrayList<CourseCrossListingInfo>();
1231 if (cluIdents != null) {
1232 for (CluIdentifierInfo cluIdent : cluIdents) {
1233 if (cluIdent.getTypeKey() != null &&
1234 cluIdent.getTypeKey().equals(CourseAssemblerConstants.COURSE_CROSSLISTING_IDENT_TYPE)) {
1235 CourseCrossListingInfo crosslisting = new CourseCrossListingInfo();
1236
1237 boolean found = false;
1238 for (AttributeInfo attr : cluIdent.getAttributes()){
1239 if (attr.getKey().equals("courseId")){
1240 found = true;
1241 try {
1242 CluInfo cluInfo = cluService.getClu(attr.getValue(), new ContextInfo());
1243 crosslisting.setId(cluIdent.getId());
1244 crosslisting.setCode(cluInfo.getOfficialIdentifier().getCode());
1245 crosslisting.setAttributes(cluIdent.getAttributes());
1246 crosslisting.setTypeKey(cluInfo.getTypeKey());
1247 crosslisting.setCourseNumberSuffix(cluInfo.getOfficialIdentifier().getSuffixCode());
1248 crosslisting.setSubjectArea(cluInfo.getOfficialIdentifier().getDivision());
1249 crosslisting.setSubjectOrgId(cluIdent.getOrgId());
1250 } catch (Exception e) {
1251 throw new AssemblyException("Error getting related clus", e);
1252 }
1253 }
1254 }
1255 if (!found) {
1256 crosslisting.setId(cluIdent.getId());
1257 crosslisting.setCode(cluIdent.getCode());
1258 crosslisting.setAttributes(cluIdent.getAttributes());
1259 crosslisting.setTypeKey(cluIdent.getTypeKey());
1260 crosslisting.setCourseNumberSuffix(cluIdent.getSuffixCode());
1261 crosslisting.setSubjectArea(cluIdent.getDivision());
1262 crosslisting.setSubjectOrgId(cluIdent.getOrgId());
1263 }
1264
1265 crossListings.add(crosslisting);
1266 }
1267 }
1268 }
1269 return crossListings;
1270 }
1271
1272
1273
1274 private List<BaseDTOAssemblyNode<?, ?>> disassembleJoints(String nodeId,
1275 CourseInfo course, NodeOperation operation,ContextInfo contextInfo)
1276 throws AssemblyException, PermissionDeniedException {
1277
1278 List<BaseDTOAssemblyNode<?, ?>> results = new ArrayList<BaseDTOAssemblyNode<?, ?>>();
1279
1280
1281
1282 Map<String, CluCluRelationInfo> currentJointIds = new HashMap<String, CluCluRelationInfo>();
1283
1284 if (!NodeOperation.CREATE.equals(operation)) {
1285 try {
1286 List<CluCluRelationInfo> jointRelationships = cluService.getCluCluRelationsByClu(course.getId(),contextInfo);
1287 for (CluCluRelationInfo jointRelation : jointRelationships) {
1288 if (CourseAssemblerConstants.JOINT_RELATION_TYPE.equals(jointRelation.getTypeKey())) {
1289 if(jointRelation.getCluId().equals(course.getId())) {
1290 cluService.getClu(jointRelation.getRelatedCluId(), contextInfo);
1291 currentJointIds.put(jointRelation.getId(),jointRelation);
1292 } else {
1293 cluService.getClu(jointRelation.getCluId(), contextInfo);
1294 currentJointIds.put(jointRelation.getId(),jointRelation);
1295 }
1296 }
1297 }
1298 } catch (DoesNotExistException e) {
1299 } catch (InvalidParameterException e) {
1300 throw new AssemblyException("Error getting related formats", e);
1301 } catch (MissingParameterException e) {
1302 throw new AssemblyException("Error getting related formats", e);
1303 } catch (OperationFailedException e) {
1304 throw new AssemblyException("Error getting related formats", e);
1305 }
1306 }
1307
1308
1309 for (CourseJointInfo joint : course.getJoints()) {
1310
1311 if (NodeOperation.UPDATE.equals(operation) && joint.getRelationId() != null
1312 && currentJointIds.containsKey(joint.getRelationId())) {
1313
1314
1315 CluCluRelationInfo relation = currentJointIds.remove(joint.getRelationId());
1316 relation.setRelatedCluId(joint.getCourseId());
1317 relation.setStateKey(course.getStateKey());
1318 BaseDTOAssemblyNode<CourseJointInfo, CluCluRelationInfo> jointNode = new BaseDTOAssemblyNode<CourseJointInfo, CluCluRelationInfo>(courseJointAssembler);
1319 jointNode.setBusinessDTORef(joint);
1320 jointNode.setNodeData(relation);
1321 jointNode.setOperation(NodeOperation.UPDATE);
1322 results.add(jointNode);
1323 } else if (!NodeOperation.DELETE.equals(operation)) {
1324
1325 BaseDTOAssemblyNode<CourseJointInfo, CluCluRelationInfo> jointNode = courseJointAssembler
1326 .disassemble(joint, NodeOperation.CREATE,contextInfo);
1327 jointNode.getNodeData().setCluId(nodeId);
1328 jointNode.getNodeData().setStateKey(course.getStateKey());
1329 results.add(jointNode);
1330 }
1331 }
1332
1333
1334
1335 for (String id : currentJointIds.keySet()) {
1336
1337
1338 CluCluRelationInfo relationToDelete = new CluCluRelationInfo();
1339 relationToDelete.setId(id);
1340 BaseDTOAssemblyNode<CourseJointInfo, CluCluRelationInfo> relationToDeleteNode = new BaseDTOAssemblyNode<CourseJointInfo, CluCluRelationInfo>(
1341 courseJointAssembler);
1342 relationToDeleteNode.setNodeData(relationToDelete);
1343 relationToDeleteNode.setOperation(NodeOperation.DELETE);
1344 results.add(relationToDeleteNode);
1345 }
1346
1347 return results;
1348 }
1349
1350 public void setCluService(CluService cluService) {
1351 this.cluService = cluService;
1352 }
1353
1354 public void setFormatAssembler(FormatAssembler formatAssembler) {
1355 this.formatAssembler = formatAssembler;
1356 }
1357
1358 public void setCourseJointAssembler(
1359 CourseJointAssembler courseJointAssembler) {
1360 this.courseJointAssembler = courseJointAssembler;
1361 }
1362
1363 public void setLoAssembler(LoAssembler loAssembler) {
1364 this.loAssembler = loAssembler;
1365 }
1366
1367 public void setLoService(LearningObjectiveService loService) {
1368 this.loService = loService;
1369 }
1370
1371 public void setCluAssemblerUtils(CluAssemblerUtils cluAssemblerUtils) {
1372 this.cluAssemblerUtils = cluAssemblerUtils;
1373 }
1374
1375 public void setLrcService(LRCService lrcService) {
1376 this.lrcService = lrcService;
1377 }
1378
1379 public void setAtpService(AtpService atpService) {
1380 this.atpService = atpService;
1381 }
1382
1383 public void setDefaultCreditIncrement(float defaultCreditIncrement) {
1384 this.defaultCreditIncrement = defaultCreditIncrement;
1385 }
1386 }