Java tutorial
/** * Licensed to Apereo under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Apereo licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at the following location: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.ssp.web.api.reports; // NOPMD import java.io.IOException; import java.text.SimpleDateFormat; import java.util.*; import javax.annotation.Nullable; import javax.servlet.http.HttpServletResponse; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; import com.google.common.primitives.Ints; import net.sf.jasperreports.engine.JRException; import org.apache.commons.lang.StringUtils; import org.jasig.ssp.factory.EarlyAlertTOFactory; import org.jasig.ssp.factory.JournalEntryTOFactory; import org.jasig.ssp.factory.PersonTOFactory; import org.jasig.ssp.factory.TaskTOFactory; import org.jasig.ssp.model.*; import org.jasig.ssp.model.external.ExternalPersonPlanStatus; import org.jasig.ssp.model.external.ExternalStudentRecordsLite; import org.jasig.ssp.model.external.Term; import org.jasig.ssp.security.SspUser; import org.jasig.ssp.security.permissions.Permission; import org.jasig.ssp.service.*; import org.jasig.ssp.service.external.ExternalPersonPlanStatusService; import org.jasig.ssp.service.external.ExternalStudentAcademicProgramService; import org.jasig.ssp.service.external.ExternalStudentFinancialAidAwardTermService; import org.jasig.ssp.service.external.ExternalStudentFinancialAidFileService; import org.jasig.ssp.service.external.ExternalStudentFinancialAidService; import org.jasig.ssp.service.external.ExternalStudentTranscriptService; import org.jasig.ssp.service.external.RegistrationStatusByTermService; import org.jasig.ssp.service.external.TermService; import org.jasig.ssp.transferobject.*; import org.jasig.ssp.transferobject.external.ExternalPersonPlanStatusTO; import org.jasig.ssp.transferobject.external.ExternalStudentRecordsLiteTO; import org.jasig.ssp.transferobject.reports.PersonReportTO; import org.jasig.ssp.transferobject.reports.StudentHistoryTO; import org.jasig.ssp.util.DateTimeUtils; import org.jasig.ssp.util.sort.PagingWrapper; import org.jasig.ssp.web.api.validation.ValidationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.google.common.collect.Maps; /** * Service methods for manipulating data about people in the system. * <p> * Mapped to URI path <code>/1/person</code> */ @Controller @RequestMapping("/1/person") public class PersonHistoryReportController extends ReportBaseController<StudentHistoryTO> { private static final String REPORT_URL = "/reports/studentHistoryMaster.jasper"; private static final String REPORT_FILE_TITLE = "StudentHistoryReport-"; private static final String STUDENT_TO = "studentTO"; private static final String STUDENT_RECORD_TO = "studentRecordTO"; private static final String STUDENT_PLAN_TO = "studentPlanTO"; private static final String STUDENT_MAP_STATUS_TO = "studentMapStatusTO"; private static final String STUDENT_MAP_PROJECTED_GRADUATION_TERM = "planProjectedGraduationTerm"; private static final String STUDENT_EVALUATED_SUCCESS_INDICATORS = "studentEvaluatedSuccessIndicators"; private static final String INTERVENTION_EVALUATED_SUCCESS_INDICATORS = "interventionEvaluatedSuccessIndicators"; private static final String RISK_EVALUATED_SUCCESS_INDICATORS = "riskEvaluatedSuccessIndicators"; private static final Ordering<EvaluatedSuccessIndicatorTO> INDICATOR_ORDERING = new Ordering<EvaluatedSuccessIndicatorTO>() { public int compare(EvaluatedSuccessIndicatorTO left, EvaluatedSuccessIndicatorTO right) { return Ints.compare(left.getIndicatorSortOrder(), right.getIndicatorSortOrder()); } }.compound(new Ordering<EvaluatedSuccessIndicatorTO>() { public int compare(EvaluatedSuccessIndicatorTO left, EvaluatedSuccessIndicatorTO right) { return Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst().compare(left.getIndicatorModelName(), right.getIndicatorModelName()); } }).compound(new Ordering<EvaluatedSuccessIndicatorTO>() { public int compare(EvaluatedSuccessIndicatorTO left, EvaluatedSuccessIndicatorTO right) { return Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst().compare(left.getIndicatorName(), right.getIndicatorName()); } }); private static final Logger LOGGER = LoggerFactory.getLogger(PersonHistoryReportController.class); @Autowired private transient PersonService personService; @Autowired private transient PersonTOFactory personTOFactory; @Autowired private transient JournalEntryService journalEntryService; @Autowired private transient JournalEntryTOFactory journalEntryTOFactory; @Autowired private transient EarlyAlertService earlyAlertService; @Autowired private transient EarlyAlertTOFactory earlyAlertTOFactory; @Autowired private transient TaskService taskService; @Autowired private transient TaskTOFactory taskTOFactory; @Autowired private transient ExternalStudentTranscriptService externalStudentTranscriptService; @Autowired private transient ExternalStudentAcademicProgramService externalStudentAcademicProgramService; @Autowired private transient ExternalStudentFinancialAidService externalStudentFinancialAidService; @Autowired private transient ExternalStudentFinancialAidAwardTermService externalStudentFinancialAidAwardTermService; @Autowired private transient ExternalStudentFinancialAidFileService externalStudentFinancialAidFileService; @Autowired private transient RegistrationStatusByTermService registrationStatusByTermService; @Autowired private transient ExternalPersonPlanStatusService planStatusService; @Autowired private transient PlanService planService; @Autowired protected transient SecurityService securityService; @Autowired protected transient TermService termService; @Autowired private transient EvaluatedSuccessIndicatorService evaluatedSuccessIndicatorService; @RequestMapping(value = "/{personId}/history/print", method = RequestMethod.GET) @PreAuthorize(Permission.SECURITY_PERSON_READ) public @ResponseBody void getReport(final HttpServletResponse response, final @PathVariable UUID personId, final @RequestParam(required = false, defaultValue = DEFAULT_REPORT_TYPE) String reportType) throws ObjectNotFoundException, IOException { final Person person = personService.get(personId); final PersonReportTO personTO = new PersonReportTO(person); final SspUser requestor = securityService.currentUser(); final String schoolId = person.getSchoolId(); try { personTO.setRegistrationStatusByTerm(registrationStatusByTermService.getCurrentAndFutureTerms(person)); } catch (ObjectNotFoundException e) { // nothing to be done... either no current/future terms or person has no registrations in them } LOGGER.debug("Requester id: " + requestor.getPerson().getId()); // get all the journal entries for this person final PagingWrapper<JournalEntry> journalEntrys = journalEntryService.getAllForPerson(person, requestor, null); final List<JournalEntryTO> journalEntryTOs = journalEntryTOFactory.asTOList(journalEntrys.getRows()); LOGGER.debug("JournalEntryTOs.size(): " + journalEntryTOs.size()); // get all the early alerts for this person final PagingWrapper<EarlyAlert> earlyAlert = earlyAlertService.getAllForPerson(person, null); final Set<EarlyAlertTO> earlyAlertTOs = earlyAlertTOFactory.asTOSet(earlyAlert.getRows()); LOGGER.debug("EarlyAlertTOs.size(): " + earlyAlertTOs.size()); // get all the tasks for this person final Map<String, List<Task>> taskMap = taskService.getAllGroupedByTaskGroup(person, requestor, null); final Map<String, List<TaskTO>> taskTOMap = new HashMap<String, List<TaskTO>>(); LOGGER.debug("taskTOMap.size(): " + taskMap.size()); // change all tasks to TaskTOs for (final Map.Entry<String, List<Task>> entry : taskMap.entrySet()) { final String groupName = entry.getKey(); final List<Task> tasks = entry.getValue(); taskTOMap.put(groupName, taskTOFactory.asTOList(tasks)); } // get financial aid, academic, and transcript info for student summary final ExternalStudentRecordsLite record = new ExternalStudentRecordsLite(); record.setPrograms(externalStudentAcademicProgramService.getAcademicProgramsBySchoolId(schoolId)); record.setGPA(externalStudentTranscriptService.getRecordsBySchoolId(schoolId)); record.setFinancialAid(externalStudentFinancialAidService.getStudentFinancialAidBySchoolId(schoolId)); record.setFinancialAidAcceptedTerms( externalStudentFinancialAidAwardTermService.getStudentFinancialAidAwardsBySchoolId(schoolId)); record.setFinancialAidFiles( externalStudentFinancialAidFileService.getStudentFinancialAidFilesBySchoolId(schoolId)); final ExternalStudentRecordsLiteTO recordTO = new ExternalStudentRecordsLiteTO(record, null); //null because don't need balance owed //get current plan for student summary add projected graduation date as an additional parameter Plan checkPlan = planService.getCurrentForStudent(personId); PlanTO plan = new PlanTO(); String planGraduateTerm = ""; if (checkPlan != null) { plan.from(checkPlan); if (plan.getPersonId().equals(personId)) { plan = planService.validate(plan); } Term latestTerm = null; if (plan.getPlanCourses() != null && !plan.getPlanCourses().isEmpty()) for (PlanCourseTO planCourseTO : plan.getPlanCourses()) { Term term = termService.getByCode(planCourseTO.getTermCode()); if (latestTerm == null || latestTerm.getEndDate().before(term.getEndDate())) { latestTerm = term; } } planGraduateTerm = latestTerm.getCode(); } final PlanTO planTO = plan; final String planProjectedGraduationTerm = planGraduateTerm; //get current plan status for student summary final ExternalPersonPlanStatusTO mapStatusTO = new ExternalPersonPlanStatusTO(); ExternalPersonPlanStatus planStatus = planStatusService.getBySchoolId(schoolId); if (planStatus != null) { mapStatusTO.from(planStatus); } // separate the Students into bands by date final List<StudentHistoryTO> studentHistoryTOs = sort(earlyAlertTOs, taskTOMap, journalEntryTOs); final List<EvaluatedSuccessIndicatorTO> evaluatedSuccessIndicators = evaluatedSuccessIndicatorService .getForPerson(personId, ObjectStatus.ACTIVE); final List<EvaluatedSuccessIndicatorTO> studentEvaluatedSuccessIndicators = filteredAndSortedIndicators( evaluatedSuccessIndicators, SuccessIndicatorGroup.STUDENT); final List<EvaluatedSuccessIndicatorTO> interventionEvaluatedSuccessIndicators = filteredAndSortedIndicators( evaluatedSuccessIndicators, SuccessIndicatorGroup.INTERVENTION); final List<EvaluatedSuccessIndicatorTO> riskEvaluatedSuccessIndicators = filteredAndSortedIndicators( evaluatedSuccessIndicators, SuccessIndicatorGroup.RISK); final Map<String, Object> parameters = Maps.newHashMap(); SearchParameters.addReportDateToMap(parameters); parameters.put(STUDENT_TO, personTO); parameters.put(STUDENT_RECORD_TO, recordTO); parameters.put(STUDENT_PLAN_TO, planTO); parameters.put(STUDENT_MAP_STATUS_TO, mapStatusTO); parameters.put(STUDENT_MAP_PROJECTED_GRADUATION_TERM, planProjectedGraduationTerm); parameters.put(STUDENT_EVALUATED_SUCCESS_INDICATORS, studentEvaluatedSuccessIndicators); parameters.put(INTERVENTION_EVALUATED_SUCCESS_INDICATORS, interventionEvaluatedSuccessIndicators); parameters.put(RISK_EVALUATED_SUCCESS_INDICATORS, riskEvaluatedSuccessIndicators); this.renderReport(response, parameters, studentHistoryTOs, REPORT_URL, reportType, REPORT_FILE_TITLE + personTO.getLastName()); } private List<EvaluatedSuccessIndicatorTO> filteredAndSortedIndicators(List<EvaluatedSuccessIndicatorTO> from, SuccessIndicatorGroup inGroup) { return INDICATOR_ORDERING.sortedCopy(Iterables.filter(from, inGroup.transferObjectPredicate())); } @Override protected Logger getLogger() { return LOGGER; } private static final SimpleDateFormat getDateFormatter() { return new SimpleDateFormat(DEFAULT_DATE_FORMAT, Locale.US); } private static int sortDateDescending(Date date1, Date date2) { if (date1.compareTo(date2) < 0) { return 1; } else if (date1.compareTo(date2) > 0) { return -1; } else { return 0; } } public static List<StudentHistoryTO> sort(final Set<EarlyAlertTO> earlyAlerts, final Map<String, List<TaskTO>> taskMap, final List<JournalEntryTO> journalEntries) { //TreeMap assures modified date order is preserved (sorted by modified date descending) final TreeMap<Date, StudentHistoryTO> studentHistoryMap = new TreeMap(new Comparator<Date>() { public int compare(Date o1, Date o2) { return sortDateDescending(o1, o2); } }); //Sort early alerts by modified date descending final List<EarlyAlertTO> earlyAlertsSorted = new ArrayList(earlyAlerts); Collections.sort(earlyAlertsSorted, new Comparator<EarlyAlertTO>() { @Override public int compare(final EarlyAlertTO o1, final EarlyAlertTO o2) { return sortDateDescending(o1.getModifiedDate(), o2.getModifiedDate()); } }); //Sort journal entries by modified date descending final List journalEntriesSorted = journalEntries; Collections.sort(journalEntriesSorted, new Comparator<JournalEntryTO>() { @Override public int compare(final JournalEntryTO o1, final JournalEntryTO o2) { return sortDateDescending(o1.getModifiedDate(), o2.getModifiedDate()); } }); //First, iterate over each EarlyAlertTO, looking for matching dates in the PersonHistoryTO final Iterator<EarlyAlertTO> alertIter = earlyAlertsSorted.iterator(); while (alertIter.hasNext()) { final EarlyAlertTO thisEarlyAlertTO = alertIter.next(); final Date snewDate = DateTimeUtils.midnightOn(thisEarlyAlertTO.getModifiedDate()); if (studentHistoryMap.containsKey(snewDate)) { final StudentHistoryTO studentHistoryTO = studentHistoryMap.get(snewDate); studentHistoryTO.addEarlyAlertTO(thisEarlyAlertTO); } else { final StudentHistoryTO thisStudentHistoryTO = new StudentHistoryTO( getDateFormatter().format(snewDate)); thisStudentHistoryTO.addEarlyAlertTO(thisEarlyAlertTO); studentHistoryMap.put(snewDate, thisStudentHistoryTO); } } //Second, iterate over each JournalEntryTO, looking for matching dates in the PersonHistoryTO final Iterator<JournalEntryTO> journalEntryIter = journalEntriesSorted.iterator(); while (journalEntryIter.hasNext()) { final JournalEntryTO thisJournalEntryTO = journalEntryIter.next(); final Date snewDate = DateTimeUtils.midnightOn(thisJournalEntryTO.getModifiedDate()); if (studentHistoryMap.containsKey(snewDate)) { final StudentHistoryTO studentHistoryTO = studentHistoryMap.get(snewDate); studentHistoryTO.addJournalEntryTO(thisJournalEntryTO); } else { final StudentHistoryTO thisStudentHistoryTO = new StudentHistoryTO( getDateFormatter().format(snewDate)); thisStudentHistoryTO.addJournalEntryTO(thisJournalEntryTO); studentHistoryMap.put(snewDate, thisStudentHistoryTO); } } // Per the API, the tasks are already broken down into a map, sorted by group. // We want to maintain this grouping, but sort these based date //Third, iterate over each TaskTO in each group, looking for matching dates in the PersonHistoryTO for (final Map.Entry<String, List<TaskTO>> entry : taskMap.entrySet()) { final String groupName = entry.getKey(); final List<TaskTO> tasksSorted = entry.getValue(); //Sort tasks by modified date descending Collections.sort(tasksSorted, new Comparator<TaskTO>() { @Override public int compare(final TaskTO o1, final TaskTO o2) { return sortDateDescending(o1.getModifiedDate(), o2.getModifiedDate()); } }); final Iterator<TaskTO> taskIter = tasksSorted.iterator(); while (taskIter.hasNext()) { final TaskTO thisTask = taskIter.next(); final Date snewDate = DateTimeUtils.midnightOn(thisTask.getModifiedDate()); if (studentHistoryMap.containsKey(snewDate)) { final StudentHistoryTO studentHistoryTO = studentHistoryMap.get(snewDate); studentHistoryTO.addTask(groupName, thisTask); } else { final StudentHistoryTO thisStudentHistoryTO = new StudentHistoryTO( getDateFormatter().format(snewDate)); thisStudentHistoryTO.addTask(groupName, thisTask); studentHistoryMap.put(snewDate, thisStudentHistoryTO); } } } // at this point, we should have a StudentHistoryTO map with Dates final Collection<StudentHistoryTO> studentHistoryTOs = studentHistoryMap.values(); final List<StudentHistoryTO> retVal = new ArrayList<StudentHistoryTO>(); final Iterator<StudentHistoryTO> studentHistoryTOIter = studentHistoryTOs.iterator(); while (studentHistoryTOIter.hasNext()) { final StudentHistoryTO currentStudentHistoryTO = studentHistoryTOIter.next(); currentStudentHistoryTO.createTaskList(); retVal.add(currentStudentHistoryTO); } return retVal; } }