Clover Coverage Report - Kuali Student 1.2-M4-SNAPSHOT (Aggregated)
Coverage timestamp: Wed Jul 20 2011 11:14:35 EDT
../../../../../../../img/srcFileCovDistChart7.png 32% of files have more coverage
425   1,550   190   4.17
90   1,091   0.45   102
102     1.86  
1    
 
  ProgramServiceImpl       Line # 75 425 0% 190 238 61.4% 0.6142626
 
  (30)
 
1    package org.kuali.student.lum.program.service.impl;
2   
3    import java.util.ArrayList;
4    import java.util.Date;
5    import java.util.Iterator;
6    import java.util.List;
7   
8    import org.apache.log4j.Logger;
9    import org.kuali.student.common.assembly.BaseDTOAssemblyNode;
10    import org.kuali.student.common.assembly.BaseDTOAssemblyNode.NodeOperation;
11    import org.kuali.student.common.assembly.BusinessServiceMethodInvoker;
12    import org.kuali.student.common.assembly.data.AssemblyException;
13    import org.kuali.student.common.dictionary.dto.DataType;
14    import org.kuali.student.common.dictionary.dto.ObjectStructureDefinition;
15    import org.kuali.student.common.dictionary.service.DictionaryService;
16    import org.kuali.student.common.dto.DtoConstants;
17    import org.kuali.student.common.dto.StatusInfo;
18    import org.kuali.student.common.exceptions.AlreadyExistsException;
19    import org.kuali.student.common.exceptions.CircularReferenceException;
20    import org.kuali.student.common.exceptions.CircularRelationshipException;
21    import org.kuali.student.common.exceptions.DataValidationErrorException;
22    import org.kuali.student.common.exceptions.DependentObjectsExistException;
23    import org.kuali.student.common.exceptions.DoesNotExistException;
24    import org.kuali.student.common.exceptions.IllegalVersionSequencingException;
25    import org.kuali.student.common.exceptions.InvalidParameterException;
26    import org.kuali.student.common.exceptions.MissingParameterException;
27    import org.kuali.student.common.exceptions.OperationFailedException;
28    import org.kuali.student.common.exceptions.PermissionDeniedException;
29    import org.kuali.student.common.exceptions.UnsupportedActionException;
30    import org.kuali.student.common.exceptions.VersionMismatchException;
31    import org.kuali.student.common.search.dto.SearchCriteriaTypeInfo;
32    import org.kuali.student.common.search.dto.SearchRequest;
33    import org.kuali.student.common.search.dto.SearchResult;
34    import org.kuali.student.common.search.dto.SearchResultTypeInfo;
35    import org.kuali.student.common.search.dto.SearchTypeInfo;
36    import org.kuali.student.common.search.service.SearchManager;
37    import org.kuali.student.common.validation.dto.ValidationResultInfo;
38    import org.kuali.student.common.validator.ServerDateParser;
39    import org.kuali.student.common.validator.Validator;
40    import org.kuali.student.common.validator.ValidatorFactory;
41    import org.kuali.student.common.validator.ValidatorUtils;
42    import org.kuali.student.common.versionmanagement.dto.VersionDisplayInfo;
43    import org.kuali.student.core.atp.dto.AtpInfo;
44    import org.kuali.student.core.atp.service.AtpService;
45    import org.kuali.student.core.document.dto.RefDocRelationInfo;
46    import org.kuali.student.core.document.service.DocumentService;
47    import org.kuali.student.core.statement.dto.ReqCompFieldInfo;
48    import org.kuali.student.core.statement.dto.ReqComponentInfo;
49    import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
50    import org.kuali.student.lum.course.dto.LoDisplayInfo;
51    import org.kuali.student.lum.course.service.impl.CourseServiceUtils;
52    import org.kuali.student.lum.lu.dto.CluCluRelationInfo;
53    import org.kuali.student.lum.lu.dto.CluInfo;
54    import org.kuali.student.lum.lu.dto.CluSetInfo;
55    import org.kuali.student.lum.lu.dto.LuTypeInfo;
56    import org.kuali.student.lum.lu.service.LuService;
57    import org.kuali.student.lum.lu.service.LuServiceConstants;
58    import org.kuali.student.lum.program.dto.CoreProgramInfo;
59    import org.kuali.student.lum.program.dto.CredentialProgramInfo;
60    import org.kuali.student.lum.program.dto.HonorsProgramInfo;
61    import org.kuali.student.lum.program.dto.MajorDisciplineInfo;
62    import org.kuali.student.lum.program.dto.MinorDisciplineInfo;
63    import org.kuali.student.lum.program.dto.ProgramRequirementInfo;
64    import org.kuali.student.lum.program.dto.ProgramVariationInfo;
65    import org.kuali.student.lum.program.service.ProgramService;
66    import org.kuali.student.lum.program.service.ProgramServiceConstants;
67    import org.kuali.student.lum.program.service.assembler.CoreProgramAssembler;
68    import org.kuali.student.lum.program.service.assembler.CredentialProgramAssembler;
69    import org.kuali.student.lum.program.service.assembler.MajorDisciplineAssembler;
70    import org.kuali.student.lum.program.service.assembler.ProgramAssemblerConstants;
71    import org.kuali.student.lum.statement.typekey.ReqComponentFieldTypes;
72    import org.springframework.transaction.annotation.Transactional;
73   
74    @Transactional(readOnly=true,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 
75    public class ProgramServiceImpl implements ProgramService {
76    final static Logger LOG = Logger.getLogger(ProgramServiceImpl.class);
77   
78    private LuService luService;
79    private ValidatorFactory validatorFactory;
80    private BusinessServiceMethodInvoker programServiceMethodInvoker;
81    private DictionaryService dictionaryService;
82    private SearchManager searchManager;
83    private MajorDisciplineAssembler majorDisciplineAssembler;
84    private ProgramRequirementAssembler programRequirementAssembler;
85    private CredentialProgramAssembler credentialProgramAssembler;
86    private CoreProgramAssembler coreProgramAssembler;
87    // private StatementService statementService;
88    private AtpService atpService;
89    private DocumentService documentService;
90   
91   
 
92  1 toggle @Override
93    @Transactional(readOnly=false)
94    public CredentialProgramInfo createCredentialProgram(
95    CredentialProgramInfo credentialProgramInfo)
96    throws AlreadyExistsException, DataValidationErrorException,
97    InvalidParameterException, MissingParameterException,
98    OperationFailedException, PermissionDeniedException {
99   
100  1 checkForMissingParameter(credentialProgramInfo, "CredentialProgramInfo");
101   
102    // Validate
103  1 List<ValidationResultInfo> validationResults = validateCredentialProgram("OBJECT", credentialProgramInfo);
104  1 if (ValidatorUtils.hasErrors(validationResults)) {
105  0 throw new DataValidationErrorException("Validation error!", validationResults);
106    }
107   
108  1 try {
109  1 return processCredentialProgramInfo(credentialProgramInfo, NodeOperation.CREATE);
110    } catch (AssemblyException e) {
111  0 LOG.error("Error disassembling Credential Program", e);
112  0 throw new OperationFailedException("Error disassembling Credential Program");
113    }
114    }
115   
 
116  1 toggle @Override
117    @Transactional(readOnly=false)
118    public HonorsProgramInfo createHonorsProgram(
119    HonorsProgramInfo honorsProgramInfo) throws AlreadyExistsException,
120    DataValidationErrorException, InvalidParameterException,
121    MissingParameterException, OperationFailedException,
122    PermissionDeniedException {
123    // TODO Auto-generated method stub
124  1 return null;
125    }
126   
 
127  7 toggle @Override
128    @Transactional(readOnly=false)
129    public ProgramRequirementInfo createProgramRequirement(
130    ProgramRequirementInfo programRequirementInfo)
131    throws AlreadyExistsException, DataValidationErrorException,
132    InvalidParameterException, MissingParameterException,
133    OperationFailedException, PermissionDeniedException {
134  7 checkForMissingParameter(programRequirementInfo, "programRequirementInfo");
135   
136    // Validate
137  6 List<ValidationResultInfo> validationResults = validateProgramRequirement("OBJECT", programRequirementInfo);
138  6 if (ValidatorUtils.hasErrors(validationResults)) {
139  0 throw new DataValidationErrorException("Validation error!", validationResults);
140    }
141   
142  6 try {
143  6 return processProgramRequirement(programRequirementInfo, NodeOperation.CREATE);
144    } catch (AssemblyException e) {
145  0 LOG.error("Error disassembling Program Requirement", e);
146  0 throw new OperationFailedException("Error disassembling Program Requirement", e);
147    }
148    }
149   
 
150  3 toggle @Override
151    @Transactional(readOnly=false)
152    public MajorDisciplineInfo createMajorDiscipline(
153    MajorDisciplineInfo majorDisciplineInfo)
154    throws AlreadyExistsException, DataValidationErrorException,
155    InvalidParameterException, MissingParameterException,
156    OperationFailedException, PermissionDeniedException {
157   
158  3 checkForMissingParameter(majorDisciplineInfo, "MajorDisciplineInfo");
159   
160    // Validate
161  3 List<ValidationResultInfo> validationResults = validateMajorDiscipline("OBJECT", majorDisciplineInfo);
162  3 if (ValidatorUtils.hasErrors(validationResults)) {
163  0 throw new DataValidationErrorException("Validation error!", validationResults);
164    }
165   
166  3 try {
167  3 return processMajorDisciplineInfo(majorDisciplineInfo, NodeOperation.CREATE);
168    } catch (AssemblyException e) {
169  0 LOG.error("Error creating Major Discipline", e);
170  0 throw new OperationFailedException("Error creating Major Discipline");
171    }
172    }
173   
 
174  2 toggle @Override
175    @Transactional(readOnly=false)
176    public MajorDisciplineInfo createNewMajorDisciplineVersion(
177    String majorDisciplineVerIndId, String versionComment)
178    throws DoesNotExistException, InvalidParameterException,
179    MissingParameterException, OperationFailedException,
180    PermissionDeniedException, VersionMismatchException, DataValidationErrorException {
181    //step one, get the original
182  2 VersionDisplayInfo currentVersion = luService.getCurrentVersion(LuServiceConstants.CLU_NAMESPACE_URI, majorDisciplineVerIndId);
183  2 MajorDisciplineInfo originalMajorDiscipline = getMajorDiscipline(currentVersion.getId());
184   
185    //Version the Clu
186  2 CluInfo newVersionClu = luService.createNewCluVersion(majorDisciplineVerIndId, versionComment);
187   
188  2 try {
189  2 BaseDTOAssemblyNode<MajorDisciplineInfo, CluInfo> results;
190   
191    //Integrate changes into the original. (should this just be just the id?)
192  2 majorDisciplineAssembler.assemble(newVersionClu, originalMajorDiscipline, true);
193   
194    //Clear Ids from the original so it will make a copy and do other processing
195  2 processCopy(originalMajorDiscipline, currentVersion.getId());
196   
197    // Since we are creating a new version, update the requirements and statement
198    // tree and set the state to Draft
199  2 List<String> programRequirementIds = originalMajorDiscipline.getProgramRequirements();
200  2 updateRequirementsState(programRequirementIds, DtoConstants.STATE_DRAFT);
201   
202    //Disassemble the new major discipline
203  2 results = majorDisciplineAssembler.disassemble(originalMajorDiscipline, NodeOperation.UPDATE);
204   
205    // Use the results to make the appropriate service calls here
206  2 programServiceMethodInvoker.invokeServiceCalls(results);
207   
208  2 return results.getBusinessDTORef();
209    } catch(AssemblyException e) {
210  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
211    } catch (AlreadyExistsException e) {
212  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
213    } catch (DependentObjectsExistException e) {
214  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
215    } catch (CircularRelationshipException e) {
216  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
217    } catch (UnsupportedActionException e) {
218  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
219    } catch (CircularReferenceException e) {
220  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
221    }
222    }
223   
224    /**
225    * This method will update the requirement state.
226    * <p>
227    * Note that it uses StatementUtil to update the statement tree.
228    *
229    * @param majorDisciplineInfo
230    * @param newState
231    * @throws Exception
232    */
 
233  2 toggle private void updateRequirementsState(List<String> programRequirementIds, String newState) throws DoesNotExistException,
234    InvalidParameterException, MissingParameterException,
235    OperationFailedException, PermissionDeniedException, VersionMismatchException, DataValidationErrorException {
236   
237    /*
238    * WARNING: This is an exact copy of the method from ProgramStateChangeServiceImpl.
239    * We had to copy it because we cannot reference classes in the
240    * org.kuali.student.lum.program.server
241    *
242    * TODO: find a place to put a shared StatementUtil
243    */
244   
245  2 for (String programRequirementId : programRequirementIds) {
246   
247    // Get program requirement from the program service
248  0 ProgramRequirementInfo programRequirementInfo = getProgramRequirement(programRequirementId, null, null);
249   
250    // Look in the requirement for the statement tree
251  0 StatementTreeViewInfo statementTree = programRequirementInfo.getStatement();
252   
253    // And recursively update the entire tree with the new state
254  0 updateStatementTreeViewInfoState(newState, statementTree);
255   
256    // Update the state of the requirement object
257  0 programRequirementInfo.setState(newState);
258   
259    // The write the requirement back to the program service
260  0 updateProgramRequirement(programRequirementInfo);
261   
262    }
263    }
264   
265    /**
266    * This method will recursively set the state of all statements in the tree.
267    * <p>
268    * WARNING: you must call the statement service in order to update statements.
269    * <p>
270    *
271    * @param state is the state we should set all statements in the tree to
272    * @param statementTreeViewInfo the tree of statements
273    * @throws Exception
274    */
 
275  0 toggle private static void updateStatementTreeViewInfoState(String state, StatementTreeViewInfo statementTreeViewInfo) {
276    /*
277    * WARNING: This is a copy of the method from StatementUtil. We had to copy it because
278    * we cannot reference the common.server package from this class.
279    *
280    * TODO: find a place to put a shared StatementUtil
281    */
282   
283    // Set the state on the statement tree itself
284  0 statementTreeViewInfo.setState(state);
285   
286    // Get all the requirements components for this statement
287  0 List<ReqComponentInfo> reqComponents = statementTreeViewInfo.getReqComponents();
288   
289    // Loop over requirements and set the state for each requirement
290  0 for(Iterator<ReqComponentInfo> it = reqComponents.iterator(); it.hasNext();)
291  0 it.next().setState(state);
292   
293    // Loop over each statement and set the state for each statement (recursively calling this method)
294  0 for(Iterator<StatementTreeViewInfo> itr = statementTreeViewInfo.getStatements().iterator(); itr.hasNext();)
295  0 updateStatementTreeViewInfoState(state, (StatementTreeViewInfo)itr.next());
296    }
297   
298    /**
299    * Recurses through the statement tree and clears out ids so the tree can be copied.
300    * Also creates copies of clusets since they are single use
301    *
302    * @param statementTreeView
303    * @throws OperationFailedException
304    * @see CourseServiceUtils (This is duplicate code because of the weird dependencies cause by program being in its own module)
305    */
 
306  0 toggle private void clearStatementTreeViewIdsRecursively(StatementTreeViewInfo statementTreeView) throws OperationFailedException{
307  0 if(statementTreeView!=null){
308  0 statementTreeView.setId(null);
309  0 for(ReqComponentInfo reqComp:statementTreeView.getReqComponents()){
310  0 reqComp.setId(null);
311  0 for(ReqCompFieldInfo field:reqComp.getReqCompFields()){
312  0 field.setId(null);
313    //copy any clusets that are adhoc'd and set the field value to the new cluset
314  0 if(ReqComponentFieldTypes.COURSE_CLUSET_KEY.getId().equals(field.getType())||
315    ReqComponentFieldTypes.PROGRAM_CLUSET_KEY.getId().equals(field.getType())||
316    ReqComponentFieldTypes.CLUSET_KEY.getId().equals(field.getType())){
317  0 try {
318  0 CluSetInfo cluSet = luService.getCluSetInfo(field.getValue());
319  0 cluSet.setId(null);
320    //Clear clu ids if membership info exists, they will be re-added based on membership info
321  0 if (cluSet.getMembershipQuery() != null){
322  0 cluSet.getCluIds().clear();
323  0 cluSet.getCluSetIds().clear();
324    }
325  0 cluSet = luService.createCluSet(cluSet.getType(), cluSet);
326  0 field.setValue(cluSet.getId());
327    } catch (Exception e) {
328  0 throw new OperationFailedException("Error copying clusets.", e);
329    }
330    }
331   
332    }
333    }
334    //Recurse through the children
335  0 for(StatementTreeViewInfo child: statementTreeView.getStatements()){
336  0 clearStatementTreeViewIdsRecursively(child);
337    }
338    }
339    }
340   
341    /**
342    * Clears out any ids so that a subsequent call to create will copy complex structures.
343    * Also updates VersionInfo on variations to match VersionInfo on parent.
344    *
345    * @param majorDiscipline
346    * @throws PermissionDeniedException
347    * @throws OperationFailedException
348    * @throws MissingParameterException
349    * @throws InvalidParameterException
350    * @throws DoesNotExistException
351    * @throws DataValidationErrorException
352    * @throws AlreadyExistsException
353    * @throws VersionMismatchException
354    * @throws CircularRelationshipException
355    */
 
356  2 toggle private void processCopy(MajorDisciplineInfo majorDiscipline,String originalId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, AlreadyExistsException, DataValidationErrorException, VersionMismatchException, CircularRelationshipException {
357    //Clear Los
358  2 for(LoDisplayInfo lo:majorDiscipline.getLearningObjectives()){
359  4 resetLoRecursively(lo);
360    }
361    //Clear OrgCoreProgram
362  2 if(majorDiscipline.getOrgCoreProgram()!=null){
363  0 majorDiscipline.getOrgCoreProgram().setId(null);
364   
365  0 if(majorDiscipline.getOrgCoreProgram().getLearningObjectives()!=null){
366  0 for(LoDisplayInfo lo:majorDiscipline.getOrgCoreProgram().getLearningObjectives()){
367  0 resetLoRecursively(lo);
368    }
369    }
370    }
371    //Clear Variations
372  2 for(ProgramVariationInfo variation:majorDiscipline.getVariations()){
373    //Create new variation version
374  4 String variationVersionIndId = variation.getVersionInfo().getVersionIndId();
375  4 CluInfo newVariationClu = luService.createNewCluVersion(variationVersionIndId, "Variation version for MajorDiscipline version " + majorDiscipline.getVersionInfo().getSequenceNumber());
376   
377    //Create relation b/w new major discipline and new variation
378  4 CluCluRelationInfo relation = new CluCluRelationInfo();
379  4 relation.setCluId(majorDiscipline.getId());
380  4 relation.setRelatedCluId(newVariationClu.getId());
381  4 relation.setType(ProgramAssemblerConstants.HAS_PROGRAM_VARIATION);
382   
383    // Relations can only be ACTIVE or Suspended
384    // We will set to ACTIVE for now
385  4 relation.setState(DtoConstants.STATE_ACTIVE);
386  4 luService.createCluCluRelation(relation.getCluId(), relation.getRelatedCluId(), relation.getType(), relation);
387   
388    //Set variation id & versionInfo to new variation clu
389  4 variation.setId(newVariationClu.getId());
390  4 variation.setMetaInfo(newVariationClu.getMetaInfo());
391   
392    //Set state to parent program's state
393  4 variation.setState(majorDiscipline.getState());
394    //Clear Los
395  4 for(LoDisplayInfo lo:variation.getLearningObjectives()){
396  8 resetLoRecursively(lo);
397    }
398    //Copy Requirements for variation
399  4 copyProgramRequirements(variation.getProgramRequirements(),majorDiscipline.getState());
400    }
401   
402    //Copy requirements for majorDiscipline
403  2 copyProgramRequirements(majorDiscipline.getProgramRequirements(),majorDiscipline.getState());
404   
405    //Copy documents(create new relations to the new version)
406  2 List<RefDocRelationInfo> docRelations = documentService.getRefDocRelationsByRef("kuali.org.RefObjectType.ProposalInfo", originalId);
407  2 if(docRelations!=null){
408  0 for(RefDocRelationInfo docRelation:docRelations){
409  0 docRelation.setId(null);
410  0 docRelation.setRefObjectId(majorDiscipline.getId());
411  0 documentService.createRefDocRelation("kuali.org.RefObjectType.ProposalInfo", majorDiscipline.getId(), docRelation.getDocumentId(), docRelation.getType(), docRelation);
412    }
413    }
414    }
415   
 
416  0 toggle private void processCopy(CredentialProgramInfo originaCredentialProgram,
417    String originalId) throws OperationFailedException, AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, PermissionDeniedException, DoesNotExistException {
418    //Clear Los
419  0 if (originaCredentialProgram.getLearningObjectives() != null){
420  0 for(LoDisplayInfo lo:originaCredentialProgram.getLearningObjectives()){
421  0 resetLoRecursively(lo);
422    }
423    }
424   
425    //Copy requirements for majorDiscipline
426  0 copyProgramRequirements(originaCredentialProgram.getProgramRequirements(),originaCredentialProgram.getState());
427   
428    //Copy documents(create new relations to the new version)
429  0 List<RefDocRelationInfo> docRelations = documentService.getRefDocRelationsByRef("kuali.org.RefObjectType.ProposalInfo", originalId);
430  0 if(docRelations!=null){
431  0 for(RefDocRelationInfo docRelation:docRelations){
432  0 docRelation.setId(null);
433  0 docRelation.setRefObjectId(originaCredentialProgram.getId());
434  0 documentService.createRefDocRelation("kuali.org.RefObjectType.ProposalInfo", originaCredentialProgram.getId(), docRelation.getDocumentId(), docRelation.getType(), docRelation);
435    }
436    }
437    }
438   
 
439  2 toggle private void processCopy(CoreProgramInfo originalCoreProgram, String originalId) throws OperationFailedException, AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, PermissionDeniedException, DoesNotExistException {
440    //Clear Los
441  2 for(LoDisplayInfo lo:originalCoreProgram.getLearningObjectives()){
442  4 resetLoRecursively(lo);
443    }
444    //Copy requirements for majorDiscipline
445  2 copyProgramRequirements(originalCoreProgram.getProgramRequirements(),originalCoreProgram.getState());
446   
447    //Copy documents(create new relations to the new version)
448  2 List<RefDocRelationInfo> docRelations = documentService.getRefDocRelationsByRef("kuali.org.RefObjectType.ProposalInfo", originalId);
449  2 if(docRelations!=null){
450  0 for(RefDocRelationInfo docRelation:docRelations){
451  0 docRelation.setId(null);
452  0 docRelation.setRefObjectId(originalCoreProgram.getId());
453  0 documentService.createRefDocRelation("kuali.org.RefObjectType.ProposalInfo", originalCoreProgram.getId(), docRelation.getDocumentId(), docRelation.getType(), docRelation);
454    }
455    }
456    }
457   
458    /**
459    * Copy requirements (these exist external to the program save process and are referenced by id)
460    * @param originalProgramRequirementIds
461    * @param state
462    * @throws OperationFailedException
463    * @throws AlreadyExistsException
464    * @throws DataValidationErrorException
465    * @throws InvalidParameterException
466    * @throws MissingParameterException
467    * @throws PermissionDeniedException
468    * @throws DoesNotExistException
469    */
 
470  8 toggle private void copyProgramRequirements(List<String> originalProgramRequirementIds,String state) throws OperationFailedException, AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, PermissionDeniedException, DoesNotExistException{
471    //Pull out the current requirement ids to be replaced by the ids of the new copies
472  8 List<String> programRequirementIds = new ArrayList<String>(originalProgramRequirementIds);
473  8 originalProgramRequirementIds.clear();
474   
475  8 for(String programRequirementId:programRequirementIds){
476    //Grab the original
477  0 ProgramRequirementInfo programRequirementInfo = getProgramRequirement(programRequirementId, null, null);
478    //Clear the id
479  0 programRequirementInfo.setId(null);
480   
481  0 programRequirementInfo.setState(state);
482    //Clear statement tree ids
483  0 clearStatementTreeViewIdsRecursively(programRequirementInfo.getStatement());
484    //Clear learning objectives
485  0 for(LoDisplayInfo lo:programRequirementInfo.getLearningObjectives()){
486  0 resetLoRecursively(lo);
487    }
488    //Create the new copy
489  0 ProgramRequirementInfo createdProgramRequirement = createProgramRequirement(programRequirementInfo);
490    //add the copy's id back to the majorDiscipline's list of requirements
491  0 originalProgramRequirementIds.add(createdProgramRequirement.getId());
492    }
493    }
494   
495    /**
496    * Recursively clears out the ids in a Lo and in its child Los
497    * @param lo
498    */
 
499  112 toggle private void resetLoRecursively(LoDisplayInfo lo){
500  112 lo.getLoInfo().setId(null);
501  112 for(LoDisplayInfo nestedLo:lo.getLoDisplayInfoList()){
502  96 resetLoRecursively(nestedLo);
503    }
504    }
505   
 
506  1 toggle @Override
507    @Transactional(readOnly=false)
508    public StatusInfo setCurrentMajorDisciplineVersion(
509    String majorDisciplineId, Date currentVersionStart)
510    throws DoesNotExistException, InvalidParameterException,
511    MissingParameterException, IllegalVersionSequencingException,
512    OperationFailedException, PermissionDeniedException {
513  1 StatusInfo status = luService.setCurrentCluVersion(majorDisciplineId, currentVersionStart);
514   
515    //Update the variations to be current as well
516  1 List<ProgramVariationInfo> variationList = getVariationsByMajorDisciplineId(majorDisciplineId);
517  1 for (ProgramVariationInfo variationInfo:variationList){
518  2 String variationId = variationInfo.getId();
519    //If null set to current (non-null value means version is first and is already current)
520  2 if (variationInfo.getVersionInfo().getCurrentVersionStart() == null){
521  2 luService.setCurrentCluVersion(variationId, currentVersionStart);
522    }
523    }
524   
525  1 return status;
526    }
527   
 
528  1 toggle @Override
529    @Transactional(readOnly=false)
530    public MinorDisciplineInfo createMinorDiscipline(
531    MinorDisciplineInfo minorDisciplineInfo)
532    throws AlreadyExistsException, DataValidationErrorException,
533    InvalidParameterException, MissingParameterException,
534    OperationFailedException, PermissionDeniedException {
535    // TODO Auto-generated method stub
536  1 return null;
537    }
538   
 
539  1 toggle @Override
540    @Transactional(readOnly=false)
541    public StatusInfo deleteCredentialProgram(String credentialProgramId)
542    throws DoesNotExistException, InvalidParameterException,
543    MissingParameterException, OperationFailedException,
544    PermissionDeniedException {
545   
546    // try {
547    // CredentialProgramInfo credentialProgram = getCredentialProgram(credentialProgramId);
548    //
549    // processCredentialProgramInfo(credentialProgram, NodeOperation.DELETE);
550    //
551    // return getStatus();
552    //
553    // } catch (AssemblyException e) {
554    // LOG.error("Error disassembling CredentialProgram", e);
555    // throw new OperationFailedException("Error disassembling CredentialProgram");
556    // }
557  1 throw new OperationFailedException("Deletion of CredentialProgram is not supported.");
558    }
559   
 
560  1 toggle @Override
561    @Transactional(readOnly=false)
562    public StatusInfo deleteHonorsProgram(String honorsProgramId)
563    throws DoesNotExistException, InvalidParameterException,
564    MissingParameterException, OperationFailedException,
565    PermissionDeniedException {
566    // TODO Auto-generated method stub
567  1 return null;
568    }
569   
 
570  0 toggle @Override
571    @Transactional(readOnly=false)
572    public StatusInfo deleteMajorDiscipline(String majorDisciplineId)
573    throws DoesNotExistException, InvalidParameterException,
574    MissingParameterException, OperationFailedException,
575    PermissionDeniedException {
576   
577  0 try {
578  0 MajorDisciplineInfo majorDiscipline = getMajorDiscipline(majorDisciplineId);
579   
580  0 processMajorDisciplineInfo(majorDiscipline, NodeOperation.DELETE);
581   
582  0 return getStatus();
583   
584    } catch (AssemblyException e) {
585  0 LOG.error("Error disassembling MajorDiscipline", e);
586  0 throw new OperationFailedException("Error disassembling MajorDiscipline");
587    }
588    }
589   
 
590  1 toggle @Override
591    @Transactional(readOnly=false)
592    public StatusInfo deleteMinorDiscipline(String minorDisciplineId)
593    throws DoesNotExistException, InvalidParameterException,
594    MissingParameterException, OperationFailedException,
595    PermissionDeniedException {
596    // TODO Auto-generated method stub
597  1 return null;
598    }
599   
 
600  2 toggle @Override
601    @Transactional(readOnly=false)
602    public StatusInfo deleteProgramRequirement(String programRequirementId)
603    throws DoesNotExistException, InvalidParameterException,
604    MissingParameterException, OperationFailedException,
605    PermissionDeniedException {
606  2 checkForMissingParameter(programRequirementId, "programRequirementId");
607  2 try {
608  2 ProgramRequirementInfo programRequirement = getProgramRequirement(programRequirementId, null, null);
609   
610  2 processProgramRequirement(programRequirement, NodeOperation.DELETE);
611   
612  2 return getStatus();
613   
614    } catch (AssemblyException e) {
615  0 LOG.error("Error disassembling MajorDiscipline", e);
616  0 throw new OperationFailedException("Error disassembling ProgramRequirement", e);
617    }
618   
619    }
620   
 
621  4 toggle @Override
622    public CredentialProgramInfo getCredentialProgram(String credentialProgramId)
623    throws DoesNotExistException, InvalidParameterException,
624    MissingParameterException, OperationFailedException,
625    PermissionDeniedException {
626   
627  4 CredentialProgramInfo credentialProgramInfo = null;
628   
629  4 try {
630  4 CluInfo clu = luService.getClu(credentialProgramId);
631   
632  4 if ( ! ProgramAssemblerConstants.CREDENTIAL_PROGRAM_TYPES.contains(clu.getType()) ) {
633  0 throw new DoesNotExistException("Specified CLU is not a Credential Program");
634    }
635   
636  4 credentialProgramInfo = credentialProgramAssembler.assemble(clu, null, false);
637    } catch (AssemblyException e) {
638  0 LOG.error("Error assembling CredentialProgram", e);
639  0 throw new OperationFailedException("Error assembling CredentialProgram");
640    }
641  4 return credentialProgramInfo;
642   
643    // comment out the above, and uncomment below to get auto-generated data
644    // (and vice-versa)
645    // try {
646    // return new CredentialProgramDataGenerator(ProgramAssemblerConstants.BACCALAUREATE_PROGRAM).getCPTestData();
647    // } catch (Exception e) {
648    // return null;
649    // }
650    }
651   
 
652  1 toggle @Override
653    public LuTypeInfo getCredentialProgramType(String credentialProgramTypeKey)
654    throws DoesNotExistException, InvalidParameterException,
655    MissingParameterException, OperationFailedException {
656    // TODO Auto-generated method stub
657  1 return null;
658    }
659   
 
660  1 toggle @Override
661    public List<LuTypeInfo> getCredentialProgramTypes()
662    throws OperationFailedException {
663    // TODO Auto-generated method stub
664  1 return null;
665    }
666   
 
667  1 toggle @Override
668    public List<String> getHonorsByCredentialProgramType(String programType)
669    throws DoesNotExistException, InvalidParameterException,
670    MissingParameterException, OperationFailedException {
671    // TODO Auto-generated method stub
672  1 return null;
673    }
674   
 
675  1 toggle @Override
676    public HonorsProgramInfo getHonorsProgram(String honorsProgramId)
677    throws DoesNotExistException, InvalidParameterException,
678    MissingParameterException, OperationFailedException,
679    PermissionDeniedException {
680    // TODO Auto-generated method stub
681  1 return null;
682    }
683   
 
684  15 toggle @Override
685    public MajorDisciplineInfo getMajorDiscipline(String majorDisciplineId)
686    throws DoesNotExistException, InvalidParameterException,
687    MissingParameterException, OperationFailedException,
688    PermissionDeniedException {
689   
690   
691  15 MajorDisciplineInfo majorDiscipline = null;
692   
693  15 try {
694  15 CluInfo clu = luService.getClu(majorDisciplineId);
695  15 if ( ! ProgramAssemblerConstants.MAJOR_DISCIPLINE.equals(clu.getType()) ) {
696  1 throw new DoesNotExistException("Specified CLU is not a Major Discipline");
697    }
698  14 majorDiscipline = majorDisciplineAssembler.assemble(clu, null, false);
699    } catch (AssemblyException e) {
700  0 LOG.error("Error assembling MajorDiscipline", e);
701  0 throw new OperationFailedException("Error assembling MajorDiscipline");
702    }
703  14 return majorDiscipline;
704    // comment out the above, and uncomment below to get auto-generated data
705    // (and vice-versa)
706    // try {
707    // return new MajorDisciplineDataGenerator().getMajorDisciplineInfoTestData();
708    // } catch (Exception e) {
709    // return null;
710    // }
711    }
712   
 
713  1 toggle @Override
714    public List<String> getMajorIdsByCredentialProgramType(String programType)
715    throws DoesNotExistException, InvalidParameterException,
716    MissingParameterException, OperationFailedException {
717    // TODO Auto-generated method stub
718  1 return null;
719    }
720   
 
721  1 toggle @Override
722    public MinorDisciplineInfo getMinorDiscipline(String minorDisciplineId)
723    throws DoesNotExistException, InvalidParameterException,
724    MissingParameterException, OperationFailedException,
725    PermissionDeniedException {
726    // TODO Auto-generated method stub
727  1 return null;
728    }
729   
 
730  1 toggle @Override
731    public List<String> getMinorsByCredentialProgramType(String programType)
732    throws DoesNotExistException, InvalidParameterException,
733    MissingParameterException, OperationFailedException {
734    // TODO Auto-generated method stub
735  1 return null;
736    }
737   
 
738  8 toggle @Override
739    public ProgramRequirementInfo getProgramRequirement(String programRequirementId, String nlUsageTypeKey, String language) throws DoesNotExistException,
740    InvalidParameterException, MissingParameterException,
741    OperationFailedException, PermissionDeniedException {
742   
743  8 checkForMissingParameter(programRequirementId, "programRequirementId");
744   
745  7 CluInfo clu = luService.getClu(programRequirementId);
746  5 if (!ProgramAssemblerConstants.PROGRAM_REQUIREMENT.equals(clu.getType())) {
747  0 throw new DoesNotExistException("Specified CLU is not a Program Requirement");
748    }
749  5 try {
750  5 ProgramRequirementInfo progReqInfo = programRequirementAssembler.assemble(clu, null, false);
751  5 return progReqInfo;
752    } catch (AssemblyException e) {
753  0 LOG.error("Error assembling program requirement", e);
754  0 throw new OperationFailedException("Error assembling program requirement: " + e.getMessage(), e);
755    }
756    }
757   
 
758  5 toggle @Override
759    public List<ProgramVariationInfo> getVariationsByMajorDisciplineId(
760    String majorDisciplineId) throws DoesNotExistException,
761    InvalidParameterException, MissingParameterException,
762    OperationFailedException {
763  5 List<ProgramVariationInfo> pvInfos = new ArrayList<ProgramVariationInfo>();
764   
765  5 try {
766  5 List<CluInfo> clus = luService.getRelatedClusByCluId(majorDisciplineId, ProgramAssemblerConstants.HAS_PROGRAM_VARIATION);
767   
768  5 if(clus != null && clus.size() > 0){
769  5 for(CluInfo clu : clus){
770  12 ProgramVariationInfo pvInfo = majorDisciplineAssembler.getProgramVariationAssembler().assemble(clu, null, false);
771  12 if(pvInfo != null){
772  12 pvInfos.add(pvInfo);
773    }
774    }
775    }
776    } catch (AssemblyException e) {
777  0 LOG.error("Error assembling ProgramVariation", e);
778  0 throw new OperationFailedException("Error assembling ProgramVariation");
779    }
780   
781  5 return pvInfos;
782    }
783   
 
784  1 toggle @Override
785    @Transactional(readOnly=false)
786    public CredentialProgramInfo updateCredentialProgram(
787    CredentialProgramInfo credentialProgramInfo)
788    throws DataValidationErrorException, DoesNotExistException,
789    InvalidParameterException, MissingParameterException,
790    VersionMismatchException, OperationFailedException,
791    PermissionDeniedException {
792   
793  1 checkForMissingParameter(credentialProgramInfo, "CredentialProgramInfo");
794   
795    // Validate
796  1 List<ValidationResultInfo> validationResults = validateCredentialProgram("OBJECT", credentialProgramInfo);
797  1 if (ValidatorUtils.hasErrors(validationResults)) {
798  0 throw new DataValidationErrorException("Validation error!", validationResults);
799    }
800   
801  1 try {
802   
803  1 return processCredentialProgramInfo(credentialProgramInfo, NodeOperation.UPDATE);
804   
805    } catch (AssemblyException e) {
806  0 LOG.error("Error disassembling Credential Program", e);
807  0 throw new OperationFailedException("Error disassembling Credential Program");
808    }
809    }
810   
 
811  1 toggle @Override
812    @Transactional(readOnly=false)
813    public HonorsProgramInfo updateHonorsProgram(
814    HonorsProgramInfo honorsProgramInfo)
815    throws DataValidationErrorException, DoesNotExistException,
816    InvalidParameterException, MissingParameterException,
817    VersionMismatchException, OperationFailedException,
818    PermissionDeniedException {
819    // TODO Auto-generated method stub
820  1 return null;
821    }
822   
 
823  6 toggle @Override
824    @Transactional(readOnly=false)
825    public MajorDisciplineInfo updateMajorDiscipline(
826    MajorDisciplineInfo majorDisciplineInfo)
827    throws DataValidationErrorException, DoesNotExistException,
828    InvalidParameterException, MissingParameterException,
829    VersionMismatchException, OperationFailedException,
830    PermissionDeniedException {
831   
832  6 checkForMissingParameter(majorDisciplineInfo, "MajorDisciplineInfo");
833   
834    // Validate
835  6 List<ValidationResultInfo> validationResults = validateMajorDiscipline("OBJECT", majorDisciplineInfo);
836  6 if (ValidatorUtils.hasErrors(validationResults)) {
837  0 throw new DataValidationErrorException("Validation error!", validationResults);
838    }
839   
840  6 try {
841   
842  6 return processMajorDisciplineInfo(majorDisciplineInfo, NodeOperation.UPDATE);
843   
844    } catch (AssemblyException e) {
845  0 LOG.error("Error disassembling majorDiscipline", e);
846  0 throw new OperationFailedException("Error disassembling majorDiscipline");
847    }
848    }
849   
 
850  1 toggle @Override
851    @Transactional(readOnly=false)
852    public MinorDisciplineInfo updateMinorDiscipline(
853    MinorDisciplineInfo minorDisciplineInfo)
854    throws DataValidationErrorException, DoesNotExistException,
855    InvalidParameterException, MissingParameterException,
856    VersionMismatchException, OperationFailedException,
857    PermissionDeniedException {
858    // TODO Auto-generated method stub
859  1 return null;
860    }
861   
 
862  1 toggle @Override
863    @Transactional(readOnly=false)
864    public ProgramRequirementInfo updateProgramRequirement(
865    ProgramRequirementInfo programRequirementInfo)
866    throws DataValidationErrorException, DoesNotExistException,
867    InvalidParameterException, MissingParameterException,
868    VersionMismatchException, OperationFailedException,
869    PermissionDeniedException {
870  1 checkForMissingParameter(programRequirementInfo, "programRequirementInfo");
871    // Validate
872  1 List<ValidationResultInfo> validationResults = validateProgramRequirement("OBJECT", programRequirementInfo);
873  1 if (ValidatorUtils.hasErrors(validationResults)) {
874  0 throw new DataValidationErrorException("Validation error!", validationResults);
875    }
876   
877  1 try {
878  1 return processProgramRequirement(programRequirementInfo, NodeOperation.UPDATE);
879    } catch (AssemblyException e) {
880  0 throw new OperationFailedException("Unable to update ProgramRequirement", e);
881    }
882    }
883   
 
884  2 toggle @Override
885    public List<ValidationResultInfo> validateCredentialProgram(
886    String validationType, CredentialProgramInfo credentialProgramInfo)
887    throws InvalidParameterException,
888    MissingParameterException, OperationFailedException {
889   
890  2 List<ValidationResultInfo> validationResults = new ArrayList<ValidationResultInfo>();
891    // if ( ! ProgramAssemblerConstants.DRAFT.equals(credentialProgramInfo.getState()) ) {
892  2 ObjectStructureDefinition objStructure = this.getObjectStructure(CredentialProgramInfo.class.getName());
893  2 Validator validator = validatorFactory.getValidator();
894  2 validationResults.addAll(validator.validateObject(credentialProgramInfo, objStructure));
895    // }
896   
897  2 return validationResults;
898    }
899   
 
900  1 toggle @Override
901    public List<ValidationResultInfo> validateHonorsProgram(
902    String validationType, HonorsProgramInfo honorsProgramInfo)
903    throws InvalidParameterException,
904    MissingParameterException, OperationFailedException {
905    // TODO Auto-generated method stub
906  1 return null;
907    }
908   
 
909  9 toggle @Override
910    public List<ValidationResultInfo> validateMajorDiscipline(
911    String validationType, MajorDisciplineInfo majorDisciplineInfo)
912    throws InvalidParameterException,
913    MissingParameterException, OperationFailedException {
914   
915  9 List<ValidationResultInfo> validationResults = new ArrayList<ValidationResultInfo>();
916    // if ( ! ProgramAssemblerConstants.DRAFT.equalsIgnoreCase(majorDisciplineInfo.getState()) ) {
917  9 ObjectStructureDefinition objStructure = this.getObjectStructure(MajorDisciplineInfo.class.getName());
918  9 Validator validator = validatorFactory.getValidator();
919  9 validationResults.addAll(validator.validateObject(majorDisciplineInfo, objStructure));
920    // }
921  9 validateMajorDisciplineAtps(majorDisciplineInfo,validationResults);
922  9 return validationResults;
923    }
924   
 
925  1 toggle @Override
926    public List<ValidationResultInfo> validateMinorDiscipline(
927    String validationType, MinorDisciplineInfo minorDisciplineInfo)
928    throws InvalidParameterException,
929    MissingParameterException, OperationFailedException {
930    // TODO Auto-generated method stub
931  1 return null;
932    }
933   
 
934  7 toggle @Override
935    public List<ValidationResultInfo> validateProgramRequirement(
936    String validationType, ProgramRequirementInfo programRequirementInfo)
937    throws InvalidParameterException,
938    MissingParameterException, OperationFailedException {
939   
940  7 ObjectStructureDefinition objStructure = this.getObjectStructure(ProgramRequirementInfo.class.getName());
941  7 Validator validator = validatorFactory.getValidator();
942  7 List<ValidationResultInfo> validationResults = validator.validateObject(programRequirementInfo, objStructure);
943   
944  7 return validationResults;
945    }
946   
 
947  23 toggle @Override
948    public ObjectStructureDefinition getObjectStructure(String objectTypeKey) {
949  23 return dictionaryService.getObjectStructure(objectTypeKey);
950    }
951   
 
952  1 toggle @Override
953    public List<String> getObjectTypes() {
954  1 return dictionaryService.getObjectTypes();
955    }
956   
 
957  1 toggle @Override
958    public SearchCriteriaTypeInfo getSearchCriteriaType(
959    String searchCriteriaTypeKey) throws DoesNotExistException,
960    InvalidParameterException, MissingParameterException,
961    OperationFailedException {
962    // TODO Auto-generated method stub
963  1 return null;
964    }
965   
 
966  1 toggle @Override
967    public List<SearchCriteriaTypeInfo> getSearchCriteriaTypes()
968    throws OperationFailedException {
969    // TODO Auto-generated method stub
970  1 return null;
971    }
972   
 
973  1 toggle @Override
974    public SearchResultTypeInfo getSearchResultType(String searchResultTypeKey)
975    throws DoesNotExistException, InvalidParameterException,
976    MissingParameterException, OperationFailedException {
977    // TODO Auto-generated method stub
978  1 return null;
979    }
980   
 
981  1 toggle @Override
982    public List<SearchResultTypeInfo> getSearchResultTypes()
983    throws OperationFailedException {
984    // TODO Auto-generated method stub
985  1 return null;
986    }
987   
 
988  1 toggle @Override
989    public SearchTypeInfo getSearchType(String searchTypeKey)
990    throws DoesNotExistException, InvalidParameterException,
991    MissingParameterException, OperationFailedException {
992    // TODO Auto-generated method stub
993  1 return null;
994    }
995   
 
996  1 toggle @Override
997    public List<SearchTypeInfo> getSearchTypes()
998    throws OperationFailedException {
999    // TODO Auto-generated method stub
1000  1 return null;
1001    }
1002   
 
1003  1 toggle @Override
1004    public List<SearchTypeInfo> getSearchTypesByCriteria(
1005    String searchCriteriaTypeKey) throws DoesNotExistException,
1006    InvalidParameterException, MissingParameterException,
1007    OperationFailedException {
1008    // TODO Auto-generated method stub
1009  1 return null;
1010    }
1011   
 
1012  1 toggle @Override
1013    public List<SearchTypeInfo> getSearchTypesByResult(
1014    String searchResultTypeKey) throws DoesNotExistException,
1015    InvalidParameterException, MissingParameterException,
1016    OperationFailedException {
1017    // TODO Auto-generated method stub
1018  1 return null;
1019    }
1020   
 
1021  1 toggle @Override
1022    public SearchResult search(SearchRequest searchRequest)
1023    throws MissingParameterException {
1024    // TODO Auto-generated method stub
1025  1 return null;
1026    }
1027   
1028    /**
1029    * Check for missing parameter and throw localized exception if missing
1030    *
1031    * @param param
1032    * @param parameter name
1033    * @throws MissingParameterException
1034    */
 
1035  33 toggle private void checkForMissingParameter(Object param, String paramName)
1036    throws MissingParameterException {
1037  33 if (param == null) {
1038  2 throw new MissingParameterException(paramName + " can not be null");
1039    }
1040    }
1041   
1042    // TODO - when CRUD for a second ProgramInfo is implemented, pull common code up from its process*() and this
1043   
 
1044  9 toggle private MajorDisciplineInfo processMajorDisciplineInfo(MajorDisciplineInfo majorDisciplineInfo, NodeOperation operation) throws AssemblyException {
1045   
1046  9 BaseDTOAssemblyNode<MajorDisciplineInfo, CluInfo> results = majorDisciplineAssembler.disassemble(majorDisciplineInfo, operation);
1047  9 invokeServiceCalls(results);
1048  9 return results.getBusinessDTORef();
1049    }
1050   
 
1051  2 toggle private CredentialProgramInfo processCredentialProgramInfo(CredentialProgramInfo credentialProgramInfo, NodeOperation operation) throws AssemblyException {
1052   
1053  2 BaseDTOAssemblyNode<CredentialProgramInfo, CluInfo> results = credentialProgramAssembler.disassemble(credentialProgramInfo, operation);
1054  2 invokeServiceCalls(results);
1055  2 return results.getBusinessDTORef();
1056    }
1057   
 
1058  9 toggle private ProgramRequirementInfo processProgramRequirement(ProgramRequirementInfo programRequirementInfo, NodeOperation operation) throws AssemblyException {
1059  9 BaseDTOAssemblyNode<ProgramRequirementInfo, CluInfo> results = programRequirementAssembler.disassemble(programRequirementInfo, operation);
1060  9 invokeServiceCalls(results);
1061  9 return results.getBusinessDTORef();
1062    }
1063   
 
1064  24 toggle private void invokeServiceCalls(BaseDTOAssemblyNode<?, CluInfo> results) throws AssemblyException{
1065    // Use the results to make the appropriate service calls here
1066  24 try {
1067  24 programServiceMethodInvoker.invokeServiceCalls(results);
1068    } catch (AssemblyException e) {
1069  0 throw e;
1070    } catch (Exception e) {
1071  0 throw new AssemblyException(e);
1072    }
1073    }
1074   
1075    //Spring setters. Used by spring container to inject corresponding dependencies.
1076   
 
1077  1 toggle public void setLuService(LuService luService) {
1078  1 this.luService = luService;
1079    }
1080   
 
1081  0 toggle public LuService getLuService() {
1082  0 return luService;
1083    }
1084   
 
1085  1 toggle public void setDictionaryService(DictionaryService dictionaryService) {
1086  1 this.dictionaryService = dictionaryService;
1087    }
1088   
 
1089  0 toggle public DictionaryService getDictionaryService() {
1090  0 return dictionaryService;
1091    }
1092   
 
1093  0 toggle public void setSearchManager(SearchManager searchManager) {
1094  0 this.searchManager = searchManager;
1095    }
1096   
 
1097  0 toggle public SearchManager getSearchManager() {
1098  0 return searchManager;
1099    }
1100   
 
1101  1 toggle public void setMajorDisciplineAssembler(MajorDisciplineAssembler majorDisciplineAssembler) {
1102  1 this.majorDisciplineAssembler = majorDisciplineAssembler;
1103    }
1104   
 
1105  0 toggle public MajorDisciplineAssembler getMajorDisciplineAssembler() {
1106  0 return majorDisciplineAssembler;
1107    }
1108   
 
1109  1 toggle public void setCredentialProgramAssembler(
1110    CredentialProgramAssembler credentialProgramAssembler) {
1111  1 this.credentialProgramAssembler = credentialProgramAssembler;
1112    }
1113   
 
1114  0 toggle public CredentialProgramAssembler getCredentialProgramAssembler() {
1115  0 return credentialProgramAssembler;
1116    }
1117   
 
1118  1 toggle public void setProgramRequirementAssembler(ProgramRequirementAssembler programRequirementAssembler) {
1119  1 this.programRequirementAssembler = programRequirementAssembler;
1120    }
1121   
 
1122  0 toggle public ProgramRequirementAssembler getProgramRequirementAssembler() {
1123  0 return programRequirementAssembler;
1124    }
1125   
 
1126  1 toggle public void setProgramServiceMethodInvoker(BusinessServiceMethodInvoker serviceMethodInvoker) {
1127  1 this.programServiceMethodInvoker = serviceMethodInvoker;
1128    }
1129   
 
1130  0 toggle public BusinessServiceMethodInvoker getProgramServiceMethodInvoker() {
1131  0 return programServiceMethodInvoker;
1132    }
1133   
 
1134  1 toggle public void setValidatorFactory(ValidatorFactory validatorFactory) {
1135  1 this.validatorFactory = validatorFactory;
1136    }
1137   
 
1138  0 toggle public ValidatorFactory getValidatorFactory() {
1139  0 return validatorFactory;
1140    }
1141   
 
1142  1 toggle public void setCoreProgramAssembler(CoreProgramAssembler coreProgramAssembler) {
1143  1 this.coreProgramAssembler = coreProgramAssembler;
1144    }
1145   
 
1146  0 toggle public CoreProgramAssembler getCoreProgramAssembler() {
1147  0 return coreProgramAssembler;
1148    }
1149   
 
1150  2 toggle private StatusInfo getStatus(){
1151  2 StatusInfo status = new StatusInfo();
1152  2 status.setSuccess(true);
1153  2 return status;
1154    }
1155   
 
1156  4 toggle private CoreProgramInfo processCoreProgramInfo(CoreProgramInfo coreProgramInfo, NodeOperation operation) throws AssemblyException {
1157   
1158  4 BaseDTOAssemblyNode<CoreProgramInfo, CluInfo> results = coreProgramAssembler.disassemble(coreProgramInfo, operation);
1159  4 invokeServiceCalls(results);
1160  4 return results.getBusinessDTORef();
1161    }
1162   
 
1163  3 toggle @Override
1164    @Transactional(readOnly=false)
1165    public CoreProgramInfo createCoreProgram(CoreProgramInfo coreProgramInfo) throws AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
1166  3 checkForMissingParameter(coreProgramInfo, "CoreProgramInfo");
1167   
1168    // Validate
1169  3 List<ValidationResultInfo> validationResults = validateCoreProgram("OBJECT", coreProgramInfo);
1170  3 if (ValidatorUtils.hasErrors(validationResults)) {
1171  0 throw new DataValidationErrorException("Validation error!", validationResults);
1172    }
1173   
1174  3 try {
1175  3 return processCoreProgramInfo(coreProgramInfo, NodeOperation.CREATE);
1176    } catch (AssemblyException e) {
1177  0 LOG.error("Error disassembling CoreProgram", e);
1178  0 throw new OperationFailedException("Error disassembling CoreProgram");
1179    }
1180    }
1181   
 
1182  2 toggle @Override
1183    @Transactional(readOnly=false)
1184    public CoreProgramInfo createNewCoreProgramVersion(
1185    String coreProgramId, String versionComment)
1186    throws DoesNotExistException, InvalidParameterException,
1187    MissingParameterException, OperationFailedException,
1188    PermissionDeniedException, VersionMismatchException,
1189    DataValidationErrorException {
1190    //step one, get the original
1191  2 VersionDisplayInfo currentVersion = luService.getCurrentVersion(LuServiceConstants.CLU_NAMESPACE_URI, coreProgramId);
1192  2 CoreProgramInfo originalCoreProgram = getCoreProgram(currentVersion.getId());
1193   
1194    //Version the Clu
1195  2 CluInfo newVersionClu = luService.createNewCluVersion(coreProgramId, versionComment);
1196   
1197  2 try {
1198  2 BaseDTOAssemblyNode<CoreProgramInfo, CluInfo> results;
1199   
1200    //Integrate changes into the original. (should this just be just the id?)
1201  2 coreProgramAssembler.assemble(newVersionClu, originalCoreProgram, true);
1202   
1203    //Clear Ids from the original so it will make a copy and do other processing
1204  2 processCopy(originalCoreProgram, currentVersion.getId());
1205   
1206    //Disassemble the new
1207  2 results = coreProgramAssembler.disassemble(originalCoreProgram, NodeOperation.UPDATE);
1208   
1209    // Use the results to make the appropriate service calls here
1210  2 programServiceMethodInvoker.invokeServiceCalls(results);
1211   
1212  2 return results.getBusinessDTORef();
1213    } catch(AssemblyException e) {
1214  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1215    } catch (AlreadyExistsException e) {
1216  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1217    } catch (DependentObjectsExistException e) {
1218  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1219    } catch (CircularRelationshipException e) {
1220  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1221    } catch (UnsupportedActionException e) {
1222  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1223    } catch (CircularReferenceException e) {
1224  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1225    }
1226    }
1227   
1228   
1229   
 
1230  1 toggle @Override
1231    @Transactional(readOnly=false)
1232    public StatusInfo deleteCoreProgram(String coreProgramId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
1233    // try {
1234    // CoreProgramInfo coreProgramInfo = getCoreProgram(coreProgramId);
1235    //
1236    // processCoreProgramInfo(coreProgramInfo, NodeOperation.DELETE);
1237    //
1238    // return getStatus();
1239    //
1240    // } catch (AssemblyException e) {
1241    // LOG.error("Error disassembling CoreProgram", e);
1242    // throw new OperationFailedException("Error disassembling CoreProgram");
1243    // }
1244  1 throw new OperationFailedException("Deletion of CoreProgram is not supported.");
1245    }
1246   
 
1247  7 toggle @Override
1248    public CoreProgramInfo getCoreProgram(String coreProgramId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
1249  7 CoreProgramInfo coreProgramInfo = null;
1250   
1251  7 try {
1252  7 CluInfo clu = luService.getClu(coreProgramId);
1253  7 if ( ! ProgramAssemblerConstants.CORE_PROGRAM.equals(clu.getType()) ) {
1254  1 throw new DoesNotExistException("Specified CLU is not a CoreProgram");
1255    }
1256  6 coreProgramInfo = coreProgramAssembler.assemble(clu, null, false);
1257    } catch (AssemblyException e) {
1258  0 LOG.error("Error assembling CoreProgram", e);
1259  0 throw new OperationFailedException("Error assembling CoreProgram");
1260    }
1261  6 return coreProgramInfo;
1262    // comment out the above, and uncomment below to get auto-generated data
1263    // (and vice-versa)
1264    // try {
1265    // return new CoreProgramDataGenerator().getCoreProgramInfoTestData();
1266    // } catch (Exception e) {
1267    // return null;
1268    // }
1269    }
1270   
 
1271  1 toggle @Override
1272    @Transactional(readOnly=false)
1273    public CoreProgramInfo updateCoreProgram(CoreProgramInfo coreProgramInfo) throws DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, VersionMismatchException, OperationFailedException, PermissionDeniedException {
1274  1 checkForMissingParameter(coreProgramInfo, "CoreProgramInfo");
1275   
1276    // Validate
1277  1 List<ValidationResultInfo> validationResults = validateCoreProgram("OBJECT", coreProgramInfo);
1278  1 if (ValidatorUtils.hasErrors(validationResults)) {
1279  0 throw new DataValidationErrorException("Validation error!", validationResults);
1280    }
1281   
1282  1 try {
1283   
1284  1 return processCoreProgramInfo(coreProgramInfo, NodeOperation.UPDATE);
1285   
1286    } catch (AssemblyException e) {
1287  0 LOG.error("Error disassembling CoreProgram", e);
1288  0 throw new OperationFailedException("Error disassembling CoreProgram");
1289    }
1290    }
1291   
 
1292  4 toggle @Override
1293    public List<ValidationResultInfo> validateCoreProgram(String validationType, CoreProgramInfo coreProgramInfo) throws InvalidParameterException, MissingParameterException, OperationFailedException {
1294  4 List<ValidationResultInfo> validationResults = new ArrayList<ValidationResultInfo>();
1295    // if ( ! ProgramAssemblerConstants.DRAFT.equals(coreProgramInfo.getState()) ) {
1296  4 ObjectStructureDefinition objStructure = this.getObjectStructure(CoreProgramInfo.class.getName());
1297  4 Validator validator = validatorFactory.getValidator();
1298  4 validationResults.addAll(validator.validateObject(coreProgramInfo, objStructure));
1299    // }
1300  4 return validationResults;
1301    }
1302   
1303   
 
1304  0 toggle @Override
1305    @Transactional(readOnly=false)
1306    public CredentialProgramInfo createNewCredentialProgramVersion(
1307    String credentialProgramId, String versionComment)
1308    throws DoesNotExistException, InvalidParameterException,
1309    MissingParameterException, OperationFailedException,
1310    PermissionDeniedException, VersionMismatchException,
1311    DataValidationErrorException {
1312    //step one, get the original
1313  0 VersionDisplayInfo currentVersion = luService.getCurrentVersion(LuServiceConstants.CLU_NAMESPACE_URI, credentialProgramId);
1314  0 CredentialProgramInfo originaCredentialProgram = getCredentialProgram(currentVersion.getId());
1315   
1316    //Version the Clu
1317  0 CluInfo newVersionClu = luService.createNewCluVersion(credentialProgramId, versionComment);
1318   
1319  0 try {
1320  0 BaseDTOAssemblyNode<CredentialProgramInfo, CluInfo> results;
1321   
1322    //Integrate changes into the original. (should this just be just the id?)
1323  0 credentialProgramAssembler.assemble(newVersionClu, originaCredentialProgram, true);
1324   
1325    //Clear Ids from the original so it will make a copy and do other processing
1326  0 processCopy(originaCredentialProgram, currentVersion.getId());
1327   
1328    //Disassemble the new
1329  0 results = credentialProgramAssembler.disassemble(originaCredentialProgram, NodeOperation.UPDATE);
1330   
1331    // Use the results to make the appropriate service calls here
1332  0 programServiceMethodInvoker.invokeServiceCalls(results);
1333   
1334  0 return results.getBusinessDTORef();
1335    } catch(AssemblyException e) {
1336  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1337    } catch (AlreadyExistsException e) {
1338  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1339    } catch (DependentObjectsExistException e) {
1340  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1341    } catch (CircularRelationshipException e) {
1342  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1343    } catch (UnsupportedActionException e) {
1344  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1345    } catch (CircularReferenceException e) {
1346  0 throw new OperationFailedException("Error creating new MajorDiscipline version",e);
1347    }
1348    }
1349   
1350   
 
1351  1 toggle @Override
1352    @Transactional(readOnly=false)
1353    public StatusInfo setCurrentCoreProgramVersion(String coreProgramId,
1354    Date currentVersionStart) throws DoesNotExistException,
1355    InvalidParameterException, MissingParameterException,
1356    IllegalVersionSequencingException, OperationFailedException,
1357    PermissionDeniedException {
1358  1 StatusInfo status = luService.setCurrentCluVersion(coreProgramId, currentVersionStart);
1359   
1360  1 return status;
1361    }
1362   
 
1363  0 toggle @Override
1364    @Transactional(readOnly=false)
1365    public StatusInfo setCurrentCredentialProgramVersion(
1366    String credentialProgramId, Date currentVersionStart)
1367    throws DoesNotExistException, InvalidParameterException,
1368    MissingParameterException, IllegalVersionSequencingException,
1369    OperationFailedException, PermissionDeniedException {
1370  0 StatusInfo status = luService.setCurrentCluVersion(credentialProgramId, currentVersionStart);
1371   
1372  0 return status;
1373    }
1374   
 
1375  1 toggle @Override
1376    public VersionDisplayInfo getCurrentVersion(String refObjectTypeURI,
1377    String refObjectId) throws DoesNotExistException,
1378    InvalidParameterException, MissingParameterException,
1379    OperationFailedException, PermissionDeniedException {
1380  1 if(ProgramServiceConstants.PROGRAM_NAMESPACE_MAJOR_DISCIPLINE_URI.equals(refObjectTypeURI)){
1381  0 return luService.getCurrentVersion(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId);
1382    }
1383  1 throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
1384    }
1385   
 
1386  1 toggle @Override
1387    public VersionDisplayInfo getCurrentVersionOnDate(String refObjectTypeURI,
1388    String refObjectId, Date date) throws DoesNotExistException,
1389    InvalidParameterException, MissingParameterException,
1390    OperationFailedException, PermissionDeniedException {
1391  1 if(ProgramServiceConstants.PROGRAM_NAMESPACE_MAJOR_DISCIPLINE_URI.equals(refObjectTypeURI)){
1392  0 return luService.getCurrentVersionOnDate(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId, date);
1393    }
1394  1 throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
1395    }
1396   
 
1397  1 toggle @Override
1398    public VersionDisplayInfo getFirstVersion(String refObjectTypeURI,
1399    String refObjectId) throws DoesNotExistException,
1400    InvalidParameterException, MissingParameterException,
1401    OperationFailedException, PermissionDeniedException {
1402  1 if(ProgramServiceConstants.PROGRAM_NAMESPACE_MAJOR_DISCIPLINE_URI.equals(refObjectTypeURI)){
1403  0 return luService.getFirstVersion(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId);
1404    }
1405  1 throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
1406   
1407    }
1408   
 
1409  0 toggle @Override
1410    public VersionDisplayInfo getLatestVersion(String refObjectTypeURI,
1411    String refObjectId) throws DoesNotExistException,
1412    InvalidParameterException, MissingParameterException,
1413    OperationFailedException, PermissionDeniedException {
1414  0 if(ProgramServiceConstants.PROGRAM_NAMESPACE_MAJOR_DISCIPLINE_URI.equals(refObjectTypeURI)){
1415  0 return luService.getLatestVersion(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId);
1416    }
1417  0 throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
1418   
1419    }
1420   
 
1421  1 toggle @Override
1422    public VersionDisplayInfo getVersionBySequenceNumber(
1423    String refObjectTypeURI, String refObjectId, Long sequence)
1424    throws DoesNotExistException, InvalidParameterException,
1425    MissingParameterException, OperationFailedException,
1426    PermissionDeniedException {
1427  1 if(ProgramServiceConstants.PROGRAM_NAMESPACE_MAJOR_DISCIPLINE_URI.equals(refObjectTypeURI)){
1428  0 return luService.getVersionBySequenceNumber(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId, sequence);
1429    }
1430  1 throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
1431    }
1432   
 
1433  1 toggle @Override
1434    public List<VersionDisplayInfo> getVersions(String refObjectTypeURI,
1435    String refObjectId) throws DoesNotExistException,
1436    InvalidParameterException, MissingParameterException,
1437    OperationFailedException, PermissionDeniedException {
1438  1 if(ProgramServiceConstants.PROGRAM_NAMESPACE_MAJOR_DISCIPLINE_URI.equals(refObjectTypeURI)){
1439  0 return luService.getVersions(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId);
1440    }
1441  1 throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
1442    }
1443   
 
1444  1 toggle @Override
1445    public List<VersionDisplayInfo> getVersionsInDateRange(
1446    String refObjectTypeURI, String refObjectId, Date from, Date to)
1447    throws DoesNotExistException, InvalidParameterException,
1448    MissingParameterException, OperationFailedException,
1449    PermissionDeniedException {
1450  1 if(ProgramServiceConstants.PROGRAM_NAMESPACE_MAJOR_DISCIPLINE_URI.equals(refObjectTypeURI)){
1451  0 return luService.getVersionsInDateRange(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId, from, to);
1452    }
1453  1 throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
1454    }
1455   
 
1456  1 toggle public void setAtpService(AtpService atpService) {
1457  1 this.atpService = atpService;
1458    }
1459   
 
1460  0 toggle public AtpService getAtpService() {
1461  0 return atpService;
1462    }
1463   
 
1464  9 toggle private void validateMajorDisciplineAtps(MajorDisciplineInfo majorDisciplineInfo, List<ValidationResultInfo> validationResults) throws InvalidParameterException, MissingParameterException, OperationFailedException{
1465   
1466  9 String startTerm = majorDisciplineInfo.getStartTerm();
1467   
1468  9 if(!isEmpty(majorDisciplineInfo.getAttributes().get("endInstAdmitTerm"))){
1469  0 compareAtps(startTerm, majorDisciplineInfo.getAttributes().get("endInstAdmitTerm"), validationResults, "End Inst Admin Term", "endInstAdmitTerm");
1470    }
1471   
1472  9 if(!isEmpty(majorDisciplineInfo.getEndProgramEntryTerm())){
1473  9 compareAtps(startTerm, majorDisciplineInfo.getEndProgramEntryTerm(), validationResults, "End Program Entry Term", "endProgramEntryTerm");
1474    }
1475   
1476  9 if(!isEmpty(majorDisciplineInfo.getEndTerm())){
1477  9 compareAtps(startTerm, majorDisciplineInfo.getEndTerm(), validationResults, "End Program Enroll Term", "endTerm");
1478    }
1479   
1480  9 List<ProgramVariationInfo> variations = majorDisciplineInfo.getVariations();
1481  9 if(variations != null && !variations.isEmpty()){
1482  9 int idx = 0;
1483  9 for(ProgramVariationInfo variation : variations){
1484  19 validateVariationAtps(variation, validationResults, idx);
1485  19 idx ++;
1486    }
1487    }
1488    }
1489   
1490    //FIXME, this validation should be moved into a custom validation class + configuration
 
1491  19 toggle private void validateVariationAtps(ProgramVariationInfo programVariationInfo, List<ValidationResultInfo> validationResults, int idx) throws InvalidParameterException, MissingParameterException, OperationFailedException{
1492   
1493  19 String startTerm = programVariationInfo.getStartTerm();
1494   
1495  19 if(!isEmpty(programVariationInfo.getAttributes().get("endInstAdmitTerm"))){
1496  0 compareAtps(startTerm, programVariationInfo.getAttributes().get("endInstAdmitTerm"), validationResults, "End Inst Admin Term", "variations/" + idx + "/endInstAdmitTerm");
1497    }
1498   
1499  19 if(!isEmpty(programVariationInfo.getEndProgramEntryTerm())){
1500  19 compareAtps(startTerm, programVariationInfo.getEndProgramEntryTerm(), validationResults, "End Program Entry Term", "variations/" + idx + "/endProgramEntryTerm");
1501    }
1502   
1503  19 if(!isEmpty(programVariationInfo.getEndTerm())){
1504  19 compareAtps(startTerm, programVariationInfo.getEndTerm(), validationResults, "End Program Enroll Term", "variations/" + idx + "/endTerm");
1505    }
1506    }
1507   
 
1508  56 toggle private AtpInfo getAtpInfo(String atpKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException{
1509  56 if(atpKey==null){
1510  0 return null;
1511    }
1512  56 return atpService.getAtp(atpKey);
1513    }
1514    //FIXME error should return using message service and not static text
 
1515  56 toggle private void compareAtps(String aptKey1, String aptKey2, List<ValidationResultInfo> validationResults, String field, String path) throws InvalidParameterException, MissingParameterException, OperationFailedException{
1516  56 AtpInfo atpInfo1 = null;
1517  56 AtpInfo atpInfo2 = null;
1518   
1519  56 try{
1520  56 atpInfo1 = getAtpInfo(aptKey1);
1521  0 atpInfo2 = getAtpInfo(aptKey2);
1522    }catch(DoesNotExistException e){}
1523   
1524  56 if(atpInfo1 != null && atpInfo1 != null){
1525  0 if(atpInfo1.getStartDate()!= null && atpInfo2.getStartDate() != null){
1526  0 boolean compareResult = ValidatorUtils.compareValues(atpInfo2.getStartDate(), atpInfo1.getStartDate(), DataType.DATE, "greater_than_equal", true, new ServerDateParser());
1527  0 if(!compareResult){
1528  0 ValidationResultInfo vri = new ValidationResultInfo();
1529  0 vri.setElement(path);
1530  0 vri.setError(field + " should be greater than Start Term");
1531  0 validationResults.add(vri);
1532    }
1533    }
1534    }
1535   
1536    }
1537   
 
1538  84 toggle private boolean isEmpty(String value){
1539  84 return value == null || (value != null && "".equals(value));
1540    }
1541   
 
1542  1 toggle public void setDocumentService(DocumentService documentService) {
1543  1 this.documentService = documentService;
1544    }
1545   
 
1546  0 toggle public DocumentService getDocumentService() {
1547  0 return documentService;
1548    }
1549   
1550    }