Coverage Report - org.kuali.student.lum.lu.ui.course.server.gwt.CourseStateChangeServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
CourseStateChangeServiceImpl
0%
0/76
0%
0/56
5.143
 
 1  
 package org.kuali.student.lum.lu.ui.course.server.gwt;
 2  
 
 3  
 import java.util.Iterator;
 4  
 import java.util.List;
 5  
 
 6  
 import org.kuali.student.common.dto.DtoConstants;
 7  
 import org.kuali.student.common.dto.StatusInfo;
 8  
 import org.kuali.student.common.exceptions.CircularReferenceException;
 9  
 import org.kuali.student.common.exceptions.DataValidationErrorException;
 10  
 import org.kuali.student.common.exceptions.DoesNotExistException;
 11  
 import org.kuali.student.common.exceptions.InvalidParameterException;
 12  
 import org.kuali.student.common.exceptions.MissingParameterException;
 13  
 import org.kuali.student.common.exceptions.OperationFailedException;
 14  
 import org.kuali.student.common.exceptions.PermissionDeniedException;
 15  
 import org.kuali.student.common.exceptions.VersionMismatchException;
 16  
 import org.kuali.student.common.versionmanagement.dto.VersionDisplayInfo;
 17  
 import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
 18  
 import org.kuali.student.lum.common.server.StatementUtil;
 19  
 import org.kuali.student.lum.course.dto.CourseInfo;
 20  
 import org.kuali.student.lum.course.service.CourseService;
 21  
 import org.kuali.student.lum.course.service.CourseServiceConstants;
 22  
 import org.springframework.transaction.annotation.Transactional;
 23  
 
 24  
 @Transactional(noRollbackFor = { DoesNotExistException.class }, rollbackFor = { Throwable.class })
 25  0
 public class CourseStateChangeServiceImpl {
 26  
         private CourseService courseService;
 27  
 
 28  
         /**
 29  
          * Change the state of a course to a new state
 30  
          * 
 31  
          * @param courseId id of course
 32  
          * @param newState the new state for the course
 33  
          * @param prevEndTermAtpId the current version end date of course
 34  
          * @return
 35  
          * @throws Exception
 36  
          */
 37  
         public StatusInfo changeState(String courseId, String newState,        String prevEndTermAtpId) throws Exception {
 38  
 
 39  0
                 CourseInfo courseInfo = courseService.getCourse(courseId);
 40  
 
 41  0
                 StatusInfo ret = new StatusInfo();
 42  
                 try {
 43  0
                         if (newState.equals(DtoConstants.STATE_ACTIVE)) {
 44  0
                                 activateCourse(courseInfo, prevEndTermAtpId);
 45  0
                         } else if (newState.equals(DtoConstants.STATE_RETIRED)) {
 46  0
                                 retireCourse(courseInfo);
 47  
                         }
 48  
 
 49  0
                         ret.setSuccess(new Boolean(true));
 50  0
                 } catch (Exception e) {
 51  0
                         ret.setSuccess(new Boolean(false));
 52  0
                         ret.setMessage(e.getMessage());
 53  0
                 }
 54  
 
 55  0
                 return ret;
 56  
         }
 57  
 
 58  
         /**
 59  
          * Activate a course version. Only course with a state of "Approved" can be activated.
 60  
          * 
 61  
          * @param courseToActivate
 62  
          * @param prevEndTermAtpId the end term we set on the current version
 63  
          */
 64  
         protected void activateCourse(CourseInfo courseToActivate, String prevEndTermAtpId) throws Exception{
 65  0
             CourseInfo currVerCourse = getCurrentVersionOfCourse(courseToActivate);
 66  0
             String existingState = courseToActivate.getState();
 67  0
                 String currVerState = currVerCourse.getState();
 68  0
                 boolean isCurrVer = (courseToActivate.getId().equals(currVerCourse.getId()));
 69  
                 
 70  0
                 if (existingState.equals(DtoConstants.STATE_DRAFT)) {
 71  
                         // since this is approved if isCurrVer we can assume there are no previously active versions to deal with
 72  0
                         if (isCurrVer) {
 73  
                                 // setstate for thisVerCourse and setCurrentVersion(courseId)
 74  0
                                 updateCourseVersionStates(courseToActivate, DtoConstants.STATE_ACTIVE, currVerCourse, null, true, prevEndTermAtpId);
 75  0
                         } else if (currVerState.equals(DtoConstants.STATE_ACTIVE) ||
 76  
                                         currVerState.equals(DtoConstants.STATE_SUSPENDED)) {
 77  0
                                 updateCourseVersionStates(courseToActivate, DtoConstants.STATE_ACTIVE, currVerCourse, DtoConstants.STATE_SUPERSEDED, true, prevEndTermAtpId);
 78  
                         }
 79  
                 }
 80  0
         }
 81  
         
 82  
         /**
 83  
          * Retire a course version. Only course with a state of "Active" or "Suspended" can be retired
 84  
          * 
 85  
          * @param courseToRetire the course to retire
 86  
          */
 87  
         protected void retireCourse(CourseInfo courseToRetire) throws Exception{
 88  0
             String existingState = courseToRetire.getState();                
 89  
                 
 90  0
             if (existingState.equals(DtoConstants.STATE_ACTIVE) || existingState.equals(DtoConstants.STATE_SUSPENDED)){
 91  0
                     courseToRetire.setState(DtoConstants.STATE_RETIRED);
 92  
 
 93  0
                     courseService.updateCourse(courseToRetire);
 94  0
                         updateStatementTreeViewInfoState(courseToRetire);                    
 95  
             }
 96  0
         }
 97  
         
 98  
         /**
 99  
          * Get the current version of course from another version of course
 100  
          * 
 101  
          * @param verIndId
 102  
          */
 103  
         protected CourseInfo getCurrentVersionOfCourse(CourseInfo course)
 104  
                         throws Exception {
 105  
                 // Get version independent id of course
 106  0
                 String verIndId = course.getVersionInfo().getVersionIndId();
 107  
 
 108  
                 // Get id of current version of course given the versionindependen id
 109  0
                 VersionDisplayInfo curVerDisplayInfo = courseService.getCurrentVersion(
 110  
                                 CourseServiceConstants.COURSE_NAMESPACE_URI, verIndId);
 111  0
                 String curVerId = curVerDisplayInfo.getId();
 112  
 
 113  
                 // Return the current version of the course
 114  0
                 CourseInfo currVerCourse = courseService.getCourse(curVerId);
 115  
 
 116  0
                 return currVerCourse;
 117  
         }
 118  
 
 119  
         /**
 120  
          * Based on null values, updates states of thisVerCourse and currVerCourse
 121  
          * and sets thisVerCourse as the current version. Attempts to rollback
 122  
          * transaction on exception.
 123  
          * 
 124  
          * @param thisVerCourse
 125  
          *            this is the version that the user selected to change the state
 126  
          * @param thisVerNewState
 127  
          *            this is state that the user selected to change thisVerCourse
 128  
          *            to
 129  
          * @param currVerCourse
 130  
          *            this is the current version of the course
 131  
          *            (currentVersionStartDt <= now && currentVersionEndDt > now)
 132  
          * @param currVerNewState
 133  
          *            this is the state that we need to set the current version to.
 134  
          *            Set to null to not update the currVerCourse state.
 135  
          * @param makeCurrent
 136  
          *            if true we'll set thisVerCourse as the current version.
 137  
          * @param prevEndTermAtpId
 138  
          *            the end term for the previous version to end on
 139  
          * @throws Exception
 140  
          */
 141  
         @Transactional(readOnly = false)
 142  
         private void updateCourseVersionStates(CourseInfo thisVerCourse,
 143  
                         String thisVerNewState, CourseInfo currVerCourse,
 144  
                         String currVerNewState, boolean makeCurrent,
 145  
                         String prevEndTermAtpId) throws Exception {
 146  0
                 String thisVerPrevState = thisVerCourse.getState();
 147  
 
 148  
                 // if already current, will throw error if you try to make the current
 149  
                 // version the current version.
 150  0
                 boolean isCurrent = thisVerCourse.getId().equals(currVerCourse.getId());
 151  0
                 if(!makeCurrent || !isCurrent || !thisVerCourse.getVersionInfo().getSequenceNumber().equals(1)){
 152  0
                         makeCurrent &= !isCurrent;
 153  
                 }
 154  
 
 155  0
                 if (thisVerNewState == null) {
 156  0
                         throw new InvalidParameterException("new state cannot be null");
 157  
                 } else {
 158  0
                         thisVerCourse.setState(thisVerNewState);
 159  0
                         courseService.updateCourse(thisVerCourse);
 160  0
                         updateStatementTreeViewInfoState(thisVerCourse);
 161  
                 }
 162  
 
 163  
                 // won't get called if previous exception was thrown
 164  0
                 if (currVerNewState != null) {
 165  0
                         currVerCourse.setState(currVerNewState);
 166  0
                         if(currVerCourse.getEndTerm()==null){
 167  0
                                 currVerCourse.setEndTerm(prevEndTermAtpId);
 168  
                         }
 169  0
                         courseService.updateCourse(currVerCourse);
 170  0
                         updateStatementTreeViewInfoState(currVerCourse);
 171  
                 }
 172  
 
 173  0
                 if (makeCurrent == true) {
 174  0
                         courseService.setCurrentCourseVersion(thisVerCourse.getId(),
 175  
                                         null);
 176  
                 }
 177  
 
 178  
                 // for all draft and approved courses set the state to superseded.
 179  
                 // we should only need to evaluated versions with sequence number
 180  
                 // higher than previous active course. If the course you're
 181  
                 // activating is the current course check all versions.
 182  0
                 if (thisVerPrevState.equals(DtoConstants.STATE_APPROVED)
 183  
                                 && thisVerNewState.equals(DtoConstants.STATE_ACTIVE)) {
 184  
 
 185  0
                         List<VersionDisplayInfo> versions = courseService.getVersions(
 186  
                                         CourseServiceConstants.COURSE_NAMESPACE_URI, thisVerCourse
 187  
                                                         .getVersionInfo().getVersionIndId());
 188  0
                         Long startSeq = new Long(1);
 189  
 
 190  0
                         if (!isCurrent && (currVerCourse.getId() != thisVerCourse.getId())) {
 191  0
                                 startSeq = currVerCourse.getVersionInfo().getSequenceNumber() + 1;
 192  
                         }
 193  
 
 194  0
                         for (VersionDisplayInfo versionInfo : versions) {
 195  0
                                 if (versionInfo.getSequenceNumber() >= startSeq) {
 196  0
                                         CourseInfo otherCourse = courseService
 197  
                                                         .getCourse(versionInfo.getId());
 198  0
                                         if (otherCourse.getState().equals(
 199  
                                                         DtoConstants.STATE_APPROVED)
 200  
                                                         || otherCourse.getState().equals(
 201  
                                                                         DtoConstants.STATE_SUBMITTED)
 202  
                                                         || otherCourse.getState().equals(
 203  
                                                                         DtoConstants.STATE_DRAFT)) {
 204  0
                                                 otherCourse.setState(DtoConstants.STATE_SUPERSEDED);
 205  0
                                                 courseService.updateCourse(otherCourse);
 206  0
                                                 updateStatementTreeViewInfoState(otherCourse);
 207  
                                         }
 208  0
                                 }
 209  
                         }
 210  
                 }
 211  
 
 212  0
         }
 213  
 
 214  
         public void setCourseService(CourseService courseService) {
 215  0
                 this.courseService = courseService;
 216  0
         }
 217  
 
 218  
         /**
 219  
          * This method will load all the statements in a course from the course web
 220  
          * service, recursively update the state of each statement in the statement
 221  
          * tree, and save the update statements back to the web service.
 222  
          * 
 223  
          * 
 224  
          * @param courseInfo
 225  
          *            The course to update (call setState() in this object to set
 226  
          *            the state)
 227  
          * @throws DoesNotExistException
 228  
          * @throws InvalidParameterException
 229  
          * @throws MissingParameterException
 230  
          * @throws OperationFailedException
 231  
          * @throws PermissionDeniedException
 232  
          * @throws DataValidationErrorException
 233  
          * @throws CircularReferenceException
 234  
          * @throws VersionMismatchException
 235  
          */
 236  
         public void updateStatementTreeViewInfoState(CourseInfo courseInfo)
 237  
                         throws DoesNotExistException, InvalidParameterException,
 238  
                         MissingParameterException, OperationFailedException,
 239  
                         PermissionDeniedException, DataValidationErrorException,
 240  
                         CircularReferenceException, VersionMismatchException {
 241  
 
 242  
                 // Call course web service to get all requirements/statements for this
 243  
                 // course
 244  0
                 List<StatementTreeViewInfo> statementTreeViewInfos = courseService
 245  
                                 .getCourseStatements(courseInfo.getId(), null, null);
 246  
 
 247  0
                 if (statementTreeViewInfos != null){
 248  
                         // Recursively update state on all requirements/statements in the tree
 249  0
                         for (Iterator<StatementTreeViewInfo> it = statementTreeViewInfos
 250  0
                                         .iterator(); it.hasNext();)
 251  0
                                 StatementUtil.updateStatementTreeViewInfoState(courseInfo
 252  
                                                 .getState(), it.next());
 253  
         
 254  
                         // Call the course web service and update the requirement/statement tree
 255  
                         // with the new state
 256  0
                         for (Iterator<StatementTreeViewInfo> it = statementTreeViewInfos
 257  0
                                         .iterator(); it.hasNext();)
 258  0
                                 courseService.updateCourseStatement(courseInfo.getId(), it.next());
 259  
                 }
 260  0
         }
 261  
 
 262  
 }