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