| 1 |  |   | 
  | 2 |  |   | 
  | 3 |  |   | 
  | 4 |  |  package org.kuali.student.lum.program.service.impl; | 
  | 5 |  |   | 
  | 6 |  |  import static org.apache.commons.collections.CollectionUtils.isEmpty; | 
  | 7 |  |  import static org.apache.commons.lang.StringUtils.isEmpty; | 
  | 8 |  |   | 
  | 9 |  |  import java.util.HashMap; | 
  | 10 |  |  import java.util.List; | 
  | 11 |  |  import java.util.Map; | 
  | 12 |  |   | 
  | 13 |  |  import org.apache.log4j.Logger; | 
  | 14 |  |  import org.kuali.student.common.assembly.BOAssembler; | 
  | 15 |  |  import org.kuali.student.common.assembly.BaseDTOAssemblyNode; | 
  | 16 |  |  import org.kuali.student.common.assembly.BaseDTOAssemblyNode.NodeOperation; | 
  | 17 |  |  import org.kuali.student.common.assembly.data.AssemblyException; | 
  | 18 |  |  import org.kuali.student.common.dto.DtoConstants; | 
  | 19 |  |  import org.kuali.student.common.exceptions.DoesNotExistException; | 
  | 20 |  |  import org.kuali.student.common.util.UUIDHelper; | 
  | 21 |  |  import org.kuali.student.core.statement.dto.RefStatementRelationInfo; | 
  | 22 |  |  import org.kuali.student.core.statement.dto.StatementTreeViewInfo; | 
  | 23 |  |  import org.kuali.student.core.statement.service.StatementService; | 
  | 24 |  |  import org.kuali.student.core.statement.service.assembler.StatementTreeViewAssembler; | 
  | 25 |  |  import org.kuali.student.lum.course.service.assembler.LoAssembler; | 
  | 26 |  |  import org.kuali.student.lum.lo.service.LearningObjectiveService; | 
  | 27 |  |  import org.kuali.student.lum.lu.dto.CluCluRelationInfo; | 
  | 28 |  |  import org.kuali.student.lum.lu.dto.CluIdentifierInfo; | 
  | 29 |  |  import org.kuali.student.lum.lu.dto.CluInfo; | 
  | 30 |  |  import org.kuali.student.lum.lu.service.LuService; | 
  | 31 |  |  import org.kuali.student.lum.program.dto.ProgramRequirementInfo; | 
  | 32 |  |  import org.kuali.student.lum.program.service.assembler.ProgramAssemblerConstants; | 
  | 33 |  |  import org.kuali.student.lum.program.service.assembler.ProgramAssemblerUtils; | 
  | 34 |  |  import org.kuali.student.lum.service.assembler.CluAssemblerUtils; | 
  | 35 |  |   | 
  | 36 |  |   | 
  | 37 |  |   | 
  | 38 |  |   | 
  | 39 |  |   | 
  | 40 |  |   | 
  | 41 | 8 |  public class ProgramRequirementAssembler implements BOAssembler<ProgramRequirementInfo, CluInfo> { | 
  | 42 | 1 |      final static Logger LOG = Logger.getLogger(ProgramRequirementAssembler.class); | 
  | 43 |  |   | 
  | 44 |  |          private StatementService statementService; | 
  | 45 |  |          private StatementTreeViewAssembler statementTreeViewAssembler; | 
  | 46 |  |          private LearningObjectiveService loService; | 
  | 47 |  |          private LuService luService; | 
  | 48 |  |          private LoAssembler loAssembler; | 
  | 49 |  |          private CluAssemblerUtils cluAssemblerUtils; | 
  | 50 |  |      private ProgramAssemblerUtils programAssemblerUtils; | 
  | 51 |  |   | 
  | 52 |  |   | 
  | 53 |  |          @Override | 
  | 54 |  |          public ProgramRequirementInfo assemble(CluInfo clu, | 
  | 55 |  |                          ProgramRequirementInfo progReqInfo, boolean shallowBuild) | 
  | 56 |  |                          throws AssemblyException { | 
  | 57 | 12 |                  ProgramRequirementInfo progReq = (progReqInfo != null ? progReqInfo : new ProgramRequirementInfo()); | 
  | 58 |  |   | 
  | 59 | 12 |                  if (clu.getOfficialIdentifier() != null) { | 
  | 60 | 12 |                          progReq.setShortTitle(clu.getOfficialIdentifier().getShortName()); | 
  | 61 | 12 |                          progReq.setLongTitle(clu.getOfficialIdentifier().getLongName()); | 
  | 62 |  |                  } | 
  | 63 | 12 |                  progReq.setDescr(clu.getDescr()); | 
  | 64 |  |   | 
  | 65 |  |                   | 
  | 66 | 12 |                  assembleCredits(clu, progReq); | 
  | 67 |  |   | 
  | 68 | 12 |                  if (progReq.getStatement() == null) { | 
  | 69 |  |                          try { | 
  | 70 | 5 |                                  List<RefStatementRelationInfo> relations = statementService.getRefStatementRelationsByRef(ProgramAssemblerConstants.PROGRAM_REQUIREMENT, clu.getId()); | 
  | 71 |  |   | 
  | 72 |  |   | 
  | 73 | 5 |                                  StatementTreeViewInfo statementTree = new StatementTreeViewInfo(); | 
  | 74 | 5 |                                  if (relations != null) { | 
  | 75 | 5 |                                          statementTreeViewAssembler.assemble(statementService.getStatementTreeView(relations.get(0).getStatementId()), statementTree, shallowBuild); | 
  | 76 |  |                                  } | 
  | 77 | 5 |                                  progReq.setStatement(statementTree); | 
  | 78 | 0 |                          } catch (AssemblyException e) { | 
  | 79 | 0 |                                  throw e; | 
  | 80 | 0 |                          } catch (Exception e) { | 
  | 81 | 0 |                                  throw new AssemblyException(e); | 
  | 82 | 5 |                          } | 
  | 83 |  |                  } | 
  | 84 |  |   | 
  | 85 | 12 |                  if (isEmpty(progReq.getLearningObjectives())) { | 
  | 86 | 5 |                          progReq.setLearningObjectives(cluAssemblerUtils.assembleLos(clu.getId(), shallowBuild)); | 
  | 87 |  |                  } | 
  | 88 |  |   | 
  | 89 | 12 |                  progReq.setMetaInfo(clu.getMetaInfo()); | 
  | 90 | 12 |                  progReq.setType(clu.getType()); | 
  | 91 | 12 |                  progReq.setAttributes(clu.getAttributes()); | 
  | 92 | 12 |                  progReq.setId(clu.getId()); | 
  | 93 |  |   | 
  | 94 | 12 |                  return progReq; | 
  | 95 |  |          } | 
  | 96 |  |   | 
  | 97 |  |          @Override | 
  | 98 |  |          public BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo> disassemble( | 
  | 99 |  |                          ProgramRequirementInfo progReq, NodeOperation operation) | 
  | 100 |  |                          throws AssemblyException { | 
  | 101 |  |   | 
  | 102 | 9 |                  if (progReq == null) { | 
  | 103 |  |                           | 
  | 104 |  |                           | 
  | 105 | 0 |                      LOG.error("ProgramRequirementInfo to disassemble is null!"); | 
  | 106 | 0 |                          throw new AssemblyException("ProgramRequirementInfo can not be null"); | 
  | 107 |  |                  } | 
  | 108 |  |   | 
  | 109 | 9 |                  BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo> result = new BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo>(null); | 
  | 110 |  |                   | 
  | 111 |  |                   | 
  | 112 | 9 |          StatementTreeViewInfo statement = progReq.getStatement(); | 
  | 113 | 9 |          statement.setId(UUIDHelper.genStringUUID(statement.getId())); | 
  | 114 |  |          BaseDTOAssemblyNode<StatementTreeViewInfo, StatementTreeViewInfo> statementTree; | 
  | 115 |  |                  try { | 
  | 116 | 9 |                          statementTree = statementTreeViewAssembler.disassemble(statement, operation); | 
  | 117 | 0 |                  } catch (AssemblyException e) { | 
  | 118 | 0 |                          throw e; | 
  | 119 | 0 |                  } catch (Exception e) { | 
  | 120 | 0 |                          throw new AssemblyException(e); | 
  | 121 | 9 |                  } | 
  | 122 | 9 |          result.getChildNodes().add(statementTree); | 
  | 123 |  |   | 
  | 124 |  |                  CluInfo clu; | 
  | 125 |  |                  try { | 
  | 126 | 9 |                          clu = (NodeOperation.UPDATE == operation) ?  luService.getClu(progReq.getId()) : new CluInfo(); | 
  | 127 | 0 |          } catch (Exception e) { | 
  | 128 | 0 |                          throw new AssemblyException("Error getting existing learning unit during program requirement update", e); | 
  | 129 | 9 |          } | 
  | 130 |  |   | 
  | 131 | 9 |          if (operation.equals(NodeOperation.DELETE)) { | 
  | 132 |  |              try { | 
  | 133 | 2 |                                  final List<CluCluRelationInfo> relations = luService.getCluCluRelationsByClu(progReq.getId()); | 
  | 134 | 2 |                      final BaseDTOAssemblyNode<ProgramRequirementInfo, CluCluRelationInfo> cluRelation = new BaseDTOAssemblyNode<ProgramRequirementInfo, CluCluRelationInfo>(null); | 
  | 135 | 2 |                      if (relations.size() > 1) { | 
  | 136 | 0 |                              throw new AssemblyException("Unable to dissamble ProgramRequirement, more than one CluCluRelation found"); | 
  | 137 | 2 |                      } else if (relations.size() == 1) { | 
  | 138 | 1 |                              cluRelation.setNodeData(relations.get(0)); | 
  | 139 | 1 |                              cluRelation.setOperation(operation); | 
  | 140 | 1 |                              result.getChildNodes().add(cluRelation); | 
  | 141 |  |                      } | 
  | 142 | 0 |                          } catch (Exception e) { | 
  | 143 | 0 |                                  throw new AssemblyException(e); | 
  | 144 | 2 |                          } | 
  | 145 |  |          } | 
  | 146 |  |   | 
  | 147 | 9 |          BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo> cluResult = new BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo>(this); | 
  | 148 |  |   | 
  | 149 | 9 |          cluResult.setNodeData(clu); | 
  | 150 | 9 |          cluResult.setBusinessDTORef(progReq); | 
  | 151 | 9 |          cluResult.setOperation(operation); | 
  | 152 | 9 |          result.getChildNodes().add(cluResult); | 
  | 153 |  |   | 
  | 154 | 9 |          programAssemblerUtils.disassembleBasics(clu, progReq); | 
  | 155 |  |   | 
  | 156 |  |                   | 
  | 157 | 9 |          disassembleCredits(clu, progReq); | 
  | 158 |  |   | 
  | 159 | 9 |          progReq.setId(clu.getId()); | 
  | 160 | 9 |          CluIdentifierInfo official = null != clu.getOfficialIdentifier() ? clu.getOfficialIdentifier() : new CluIdentifierInfo(); | 
  | 161 | 9 |          official.setLongName(progReq.getLongTitle()); | 
  | 162 | 9 |          official.setShortName(progReq.getShortTitle()); | 
  | 163 |  |           | 
  | 164 |  |           | 
  | 165 |  |           | 
  | 166 | 9 |          official.setState(progReq.getState()); | 
  | 167 |  |           | 
  | 168 |  |           | 
  | 169 | 9 |          official.setType(ProgramAssemblerConstants.OFFICIAL); | 
  | 170 | 9 |          clu.setOfficialIdentifier(official); | 
  | 171 |  |   | 
  | 172 | 9 |          clu.setDescr(progReq.getDescr()); | 
  | 173 | 9 |          if (progReq.getLearningObjectives() != null) { | 
  | 174 | 9 |              disassembleLearningObjectives(progReq, operation, result); | 
  | 175 |  |          } | 
  | 176 |  |   | 
  | 177 |  |          RefStatementRelationInfo relation; | 
  | 178 | 9 |          if (operation == NodeOperation.CREATE) { | 
  | 179 | 6 |              relation = new RefStatementRelationInfo(); | 
  | 180 | 6 |              relation.setId(UUIDHelper.genStringUUID(null)); | 
  | 181 |  |          } else { | 
  | 182 |  |                  try { | 
  | 183 | 3 |                          relation = statementService.getRefStatementRelationsByRef(ProgramAssemblerConstants.PROGRAM_REQUIREMENT, clu.getId()).get(0); | 
  | 184 | 0 |                          } catch (Exception e) { | 
  | 185 | 0 |                                  throw new AssemblyException("Unable to find RefStatementRelation", e); | 
  | 186 | 3 |                          } | 
  | 187 |  |          } | 
  | 188 |  |           | 
  | 189 | 9 |          relation.setType(ProgramAssemblerConstants.PROGRAM_REFERENCE_TYPE); | 
  | 190 | 9 |          relation.setRefObjectId(clu.getId()); | 
  | 191 | 9 |          relation.setRefObjectTypeKey(ProgramAssemblerConstants.PROGRAM_REQUIREMENT); | 
  | 192 | 9 |          relation.setStatementId(statement.getId()); | 
  | 193 |  |           | 
  | 194 |  |           | 
  | 195 | 9 |          relation.setState(DtoConstants.STATE_ACTIVE); | 
  | 196 |  |   | 
  | 197 | 9 |          BaseDTOAssemblyNode<ProgramRequirementInfo, RefStatementRelationInfo> relationNode = new BaseDTOAssemblyNode<ProgramRequirementInfo, RefStatementRelationInfo>(null); | 
  | 198 | 9 |          relationNode.setNodeData(relation); | 
  | 199 | 9 |          relationNode.setOperation(operation); | 
  | 200 |  |   | 
  | 201 | 9 |          result.getChildNodes().add(relationNode); | 
  | 202 | 9 |          result.setBusinessDTORef(progReq); | 
  | 203 | 9 |          result.setOperation(operation); | 
  | 204 | 9 |                  return result; | 
  | 205 |  |          } | 
  | 206 |  |   | 
  | 207 |  |          private void disassembleLearningObjectives(ProgramRequirementInfo progReq, | 
  | 208 |  |                          NodeOperation operation, | 
  | 209 |  |                          BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo> result) throws AssemblyException { | 
  | 210 |  |          try { | 
  | 211 | 9 |              List<BaseDTOAssemblyNode<?, ?>> loResults = cluAssemblerUtils.disassembleLos(progReq.getId(), progReq.getState(),  progReq.getLearningObjectives(), operation); | 
  | 212 | 9 |              if (loResults != null) { | 
  | 213 | 9 |                  result.getChildNodes().addAll(loResults); | 
  | 214 |  |              } | 
  | 215 | 0 |          } catch (DoesNotExistException e) { | 
  | 216 | 0 |          } catch (Exception e) { | 
  | 217 | 0 |              throw new AssemblyException("Error while disassembling los", e); | 
  | 218 | 9 |          } | 
  | 219 | 9 |          } | 
  | 220 |  |   | 
  | 221 |  |          private void disassembleCredits(CluInfo clu, ProgramRequirementInfo progReq){ | 
  | 222 | 9 |                  Map<String,String> attributes = null != clu.getAttributes() ? clu.getAttributes() : new HashMap<String,String>(); | 
  | 223 |  |   | 
  | 224 | 9 |                  if(progReq.getMinCredits() != null){ | 
  | 225 | 1 |                          attributes.put(ProgramAssemblerConstants.MIN_CREDITS, Integer.toString(progReq.getMinCredits())); | 
  | 226 |  |                  }else{ | 
  | 227 | 8 |                          attributes.put(ProgramAssemblerConstants.MIN_CREDITS, null); | 
  | 228 |  |                  } | 
  | 229 | 9 |                  if(progReq.getMaxCredits() != null) { | 
  | 230 | 1 |                          attributes.put(ProgramAssemblerConstants.MAX_CREDITS, Integer.toString(progReq.getMaxCredits())); | 
  | 231 |  |                  }else{ | 
  | 232 | 8 |                          attributes.put(ProgramAssemblerConstants.MAX_CREDITS, null); | 
  | 233 |  |                  } | 
  | 234 |  |                           | 
  | 235 | 9 |                  clu.setAttributes(attributes); | 
  | 236 | 9 |          } | 
  | 237 |  |   | 
  | 238 |  |          private void assembleCredits(CluInfo clu, ProgramRequirementInfo progReq){ | 
  | 239 | 12 |                  Map<String,String> attributes = clu.getAttributes(); | 
  | 240 | 12 |                  if(attributes != null){ | 
  | 241 | 12 |                          String minCredits = attributes.get(ProgramAssemblerConstants.MIN_CREDITS); | 
  | 242 | 12 |                          String maxCredits = attributes.get(ProgramAssemblerConstants.MAX_CREDITS); | 
  | 243 | 12 |                          progReq.setMinCredits(isEmpty(minCredits)?null:Integer.parseInt(minCredits)); | 
  | 244 | 12 |                          progReq.setMaxCredits(isEmpty(maxCredits)?null:Integer.parseInt(maxCredits)); | 
  | 245 |  |                  } | 
  | 246 | 12 |          } | 
  | 247 |  |   | 
  | 248 |  |          public StatementTreeViewAssembler getStatementTreeViewAssembler() { | 
  | 249 | 0 |                  return statementTreeViewAssembler; | 
  | 250 |  |          } | 
  | 251 |  |   | 
  | 252 |  |          public void setStatementTreeViewAssembler( | 
  | 253 |  |                          StatementTreeViewAssembler statementTreeViewAssembler) { | 
  | 254 | 1 |                  this.statementTreeViewAssembler = statementTreeViewAssembler; | 
  | 255 | 1 |          } | 
  | 256 |  |   | 
  | 257 |  |          public StatementService getStatementService() { | 
  | 258 | 0 |                  return statementService; | 
  | 259 |  |          } | 
  | 260 |  |   | 
  | 261 |  |          public void setStatementService(StatementService statementService) { | 
  | 262 | 1 |                  this.statementService = statementService; | 
  | 263 | 1 |          } | 
  | 264 |  |   | 
  | 265 |  |          public LearningObjectiveService getLoService() { | 
  | 266 | 0 |                  return loService; | 
  | 267 |  |          } | 
  | 268 |  |   | 
  | 269 |  |          public void setLoService(LearningObjectiveService loService) { | 
  | 270 | 1 |                  this.loService = loService; | 
  | 271 | 1 |          } | 
  | 272 |  |   | 
  | 273 |  |          public LuService getLuService() { | 
  | 274 | 0 |                  return luService; | 
  | 275 |  |          } | 
  | 276 |  |   | 
  | 277 |  |          public void setLuService(LuService luService) { | 
  | 278 | 1 |                  this.luService = luService; | 
  | 279 | 1 |          } | 
  | 280 |  |   | 
  | 281 |  |          public LoAssembler getLoAssembler() { | 
  | 282 | 0 |                  return loAssembler; | 
  | 283 |  |          } | 
  | 284 |  |   | 
  | 285 |  |          public void setLoAssembler(LoAssembler loAssembler) { | 
  | 286 | 1 |                  this.loAssembler = loAssembler; | 
  | 287 | 1 |          } | 
  | 288 |  |   | 
  | 289 |  |          public CluAssemblerUtils getCluAssemblerUtils() { | 
  | 290 | 0 |                  return cluAssemblerUtils; | 
  | 291 |  |          } | 
  | 292 |  |   | 
  | 293 |  |          public void setCluAssemblerUtils(CluAssemblerUtils cluAssemblerUtils) { | 
  | 294 | 1 |                  this.cluAssemblerUtils = cluAssemblerUtils; | 
  | 295 | 1 |          } | 
  | 296 |  |   | 
  | 297 |  |          public ProgramAssemblerUtils getProgramAssemblerUtils() { | 
  | 298 | 0 |                  return programAssemblerUtils; | 
  | 299 |  |          } | 
  | 300 |  |   | 
  | 301 |  |          public void setProgramAssemblerUtils(ProgramAssemblerUtils programAssemblerUtils) { | 
  | 302 | 1 |                  this.programAssemblerUtils = programAssemblerUtils; | 
  | 303 | 1 |          } | 
  | 304 |  |           | 
  | 305 |  |  } |