protected boolean _validateTermRecursive( String termId, Set<String> processedTermIds, ContextInfo context) throws PermissionDeniedException, MissingParameterException, InvalidParameterException, OperationFailedException, DoesNotExistException { List<TermInfo> childTerms = acalService.getIncludedTermsInTerm(termId, context); TermInfo term = acalService.getTerm(termId, context); if (AtpServiceConstants.ATP_DRAFT_STATE_KEY.equals(term.getStateKey())) { for (TermInfo subterm : childTerms) { // Worth checking all subterms regardless of whether it's been processed or not if (AtpServiceConstants.ATP_OFFICIAL_STATE_KEY.equals(subterm.getStateKey())) { return false; // Automatically false } } } // Otherwise recurse for (TermInfo subterm : childTerms) { if (processedTermIds.contains(subterm.getId())) { // To prevent accidental infinite recursion continue; } processedTermIds.add(subterm.getId()); // Add this to processed boolean result = _validateTermRecursive(subterm.getId(), processedTermIds, context); if (!result) { return result; // Validation failed, so return false } } // If we got here, then must be true return true; }
@Override public boolean validateCalendar(String acalId, ContextInfo context) throws PermissionDeniedException, MissingParameterException, InvalidParameterException, OperationFailedException, DoesNotExistException { AcademicCalendarInfo cal = acalService.getAcademicCalendar(acalId, context); List<TermInfo> parentTerms = acalService.getTermsForAcademicCalendar(acalId, context); if (AtpServiceConstants.ATP_DRAFT_STATE_KEY.equals(cal.getStateKey())) { for (TermInfo term : parentTerms) { if (AtpServiceConstants.ATP_OFFICIAL_STATE_KEY.equals(term.getStateKey())) { return false; } } } // If we get here, then recursively validate each term for (TermInfo term : parentTerms) { boolean result = validateTerm(term.getId(), context); if (!result) { return false; } } return true; }
@Override public StatusInfo makeTermOfficialCascaded(String termId, ContextInfo contextInfo) throws PermissionDeniedException, MissingParameterException, InvalidParameterException, OperationFailedException, DoesNotExistException { StatusInfo statusInfo = new StatusInfo(); // KSENROLL-7251 Implement a new servies process ot change the state of the Academic Calendar // from draft to official TermInfo termInfo = acalService.getTerm(termId, contextInfo); if (AtpServiceConstants.ATP_OFFICIAL_STATE_KEY.equals(termInfo.getStateKey())) { // If official, then should have already cascaded. statusInfo.setSuccess(Boolean.TRUE); return statusInfo; } // Assumes state propagation not wired in yet. Map<String, TermInfo> termIdToTermInfoProcessed = new HashMap<String, TermInfo>(); Map<String, TermInfo> termIdToTermInfoToBeProcessed = new HashMap<String, TermInfo>(); Set<String> parentTermIds = new HashSet<String>(); termIdToTermInfoToBeProcessed.put(termId, termInfo); // Put initial term while (!termIdToTermInfoToBeProcessed.keySet().isEmpty()) { String nextTermId = termIdToTermInfoToBeProcessed.keySet().iterator().next(); TermInfo nextTerm = termIdToTermInfoToBeProcessed.get(nextTermId); if (termIdToTermInfoProcessed.keySet().contains(nextTermId)) { // Skip over ones we've seen continue; } // Change the state acalService.changeTermState( nextTermId, AtpServiceConstants.ATP_OFFICIAL_STATE_KEY, contextInfo); // Change the state of the associated exam period changeExamPeriodStateByTermId( nextTermId, AtpServiceConstants.ATP_OFFICIAL_STATE_KEY, contextInfo); termIdToTermInfoProcessed.put(nextTermId, nextTerm); // Add to processed termIdToTermInfoToBeProcessed.remove(nextTermId); // No longer needs processing, so remove // Now visit all parents List<TermInfo> terms = acalService.getContainingTerms(nextTermId, contextInfo); if (terms.isEmpty()) { // Assume only parent terms are connected to calendars // Given a tree like structure, there should only ever be one parentTermId in the list parentTermIds.add(nextTermId); } else { for (TermInfo term : terms) { if (!termIdToTermInfoProcessed.keySet().contains(term.getId()) && AtpServiceConstants.ATP_DRAFT_STATE_KEY.equals(term.getStateKey())) { // Only add if still draft and not yet processed termIdToTermInfoToBeProcessed.put(term.getId(), term); } } } } // Access calendar Map<String, AcademicCalendarInfo> idToCalendar = new HashMap<String, AcademicCalendarInfo>(); for (String parentTermId : parentTermIds) { List<AcademicCalendarInfo> cals = acalService.getAcademicCalendarsForTerm(parentTermId, contextInfo); for (AcademicCalendarInfo cal : cals) { idToCalendar.put(cal.getId(), cal); } } // Now iterate over all calendars and make them official for (Map.Entry<String, AcademicCalendarInfo> entry : idToCalendar.entrySet()) { if (AtpServiceConstants.ATP_DRAFT_STATE_KEY.equals(entry.getValue().getStateKey())) { // Only set it if it's still draft acalService.changeAcademicCalendarState( entry.getKey(), AtpServiceConstants.ATP_OFFICIAL_STATE_KEY, contextInfo); } } statusInfo.setSuccess(Boolean.TRUE); return statusInfo; }