Java tutorial
/** * This file was created by Quorum Born IT <http://www.qub-it.com/> and its * copyright terms are bind to the legal agreement regulating the FenixEdu@ULisboa * software development project between Quorum Born IT and Servios Partilhados da * Universidade de Lisboa: * - Copyright 2015 Quorum Born IT (until any Go-Live phase) * - Copyright 2015 Universidade de Lisboa (after any Go-Live phase) * * Contributors: anil.mamede@qub-it.com * Contributors: luis.egidio@qub-it.com * * * This file is part of FenixEdu Specifications. * * FenixEdu Specifications is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FenixEdu Specifications is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FenixEdu Specifications. If not, see <http://www.gnu.org/licenses/>. */ package org.fenixedu.ulisboa.specifications.ui.evaluation.managelooseevaluation; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.fenixedu.academic.domain.Enrolment; import org.fenixedu.academic.domain.EnrolmentEvaluation; import org.fenixedu.academic.domain.EvaluationSeason; import org.fenixedu.academic.domain.ExecutionSemester; import org.fenixedu.academic.domain.Grade; import org.fenixedu.academic.domain.GradeScale; import org.fenixedu.academic.domain.StudentCurricularPlan; import org.fenixedu.academic.util.Bundle; import org.fenixedu.academic.util.EnrolmentEvaluationState; import org.fenixedu.bennu.TupleDataSourceBean; import org.fenixedu.bennu.core.domain.exceptions.DomainException; import org.fenixedu.bennu.core.i18n.BundleUtil; import org.fenixedu.bennu.core.security.Authenticate; import org.fenixedu.bennu.spring.portal.SpringFunctionality; import org.fenixedu.ulisboa.specifications.domain.evaluation.season.EvaluationSeasonServices; import org.fenixedu.ulisboa.specifications.domain.services.CurriculumLineServices; import org.fenixedu.ulisboa.specifications.domain.services.enrollment.EnrolmentServices; import org.fenixedu.ulisboa.specifications.domain.services.evaluation.EnrolmentEvaluationServices; import org.fenixedu.ulisboa.specifications.ui.FenixeduUlisboaSpecificationsBaseController; import org.fenixedu.ulisboa.specifications.ui.FenixeduUlisboaSpecificationsController; import org.fenixedu.ulisboa.specifications.util.ULisboaSpecificationsUtil; import org.joda.time.LocalDate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.stereotype.Component; import org.springframework.ui.Model; 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.servlet.mvc.support.RedirectAttributes; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import pt.ist.fenixWebFramework.servlets.filters.contentRewrite.GenericChecksumRewriter; import pt.ist.fenixframework.Atomic; import pt.ist.fenixframework.FenixFramework; @Component("org.fenixedu.ulisboa.specifications.ui.evaluation.managelooseevaluation") @SpringFunctionality(app = FenixeduUlisboaSpecificationsController.class, title = "label.LooseEvaluationBean", accessGroup = "academic(MANAGE_MARKSHEETS)") @RequestMapping(LooseEvaluationController.CONTROLLER_URL) public class LooseEvaluationController extends FenixeduUlisboaSpecificationsBaseController { public static final String CONTROLLER_URL = "/fenixedu-ulisboa-specifications/evaluation/managelooseevaluation"; private static final String JSP_PATH = CONTROLLER_URL.substring(1); private String jspPage(final String page) { return JSP_PATH + "/" + page; } @Autowired private HttpSession session; @Autowired private HttpServletRequest request; private static final String _CREATE_URI = "/create/"; public static final String CREATE_URL = CONTROLLER_URL + _CREATE_URI; @RequestMapping(value = _CREATE_URI + "{scpId}/{executionSemesterId}", method = RequestMethod.GET) public String create(@PathVariable("scpId") final StudentCurricularPlan studentCurricularPlan, @PathVariable("executionSemesterId") final ExecutionSemester executionSemester, final Model model) { model.addAttribute("studentCurricularPlan", studentCurricularPlan); model.addAttribute("LooseEvaluationBean_enrolment_options", studentCurricularPlan.getEnrolmentsSet().stream() .filter(e -> e.getExecutionPeriod() == executionSemester) .sorted(CurriculumLineServices.COMPARATOR).collect(Collectors.toList())); final boolean possibleOldData = executionSemester.getExecutionYear().getEndCivilYear() < 2016; final Stream<EvaluationSeason> evaluationSeasons = possibleOldData ? EvaluationSeasonServices.findAll() : EvaluationSeasonServices.findByActive(true); model.addAttribute("typeValues", evaluationSeasons.sorted(EvaluationSeasonServices.SEASON_ORDER_COMPARATOR) .collect(Collectors.toList())); model.addAttribute("gradeScaleValues", Arrays.<GradeScale>asList(GradeScale.values()).stream().map( l -> new TupleDataSourceBean(((GradeScale) l).name(), ((GradeScale) l).getDescription())) .collect(Collectors.<TupleDataSourceBean>toList())); model.addAttribute("improvementSemesterValues", ExecutionSemester.readNotClosedPublicExecutionPeriods().stream() .sorted(ExecutionSemester.COMPARATOR_BY_BEGIN_DATE.reversed()) .collect(Collectors.toList())); model.addAttribute("executionSemester", executionSemester); final String url = String.format( "/academicAdministration/studentEnrolmentsExtended.do?scpID=%s&executionSemesterID=%s&method=prepare", studentCurricularPlan.getExternalId(), executionSemester.getExternalId()); final String backUrl = GenericChecksumRewriter.injectChecksumInUrl(request.getContextPath(), url, session); model.addAttribute("backUrl", backUrl); final List<EnrolmentEvaluation> evaluations = studentCurricularPlan.getEnrolmentsSet().stream() .filter(e -> e.getExecutionPeriod() == executionSemester).map(l -> l.getEvaluationsSet()) .reduce((a, c) -> Sets.union(a, c)).orElse(Sets.newHashSet()).stream() .filter(l -> l.getMarkSheet() == null && l.getCompetenceCourseMarkSheet() == null && l.getGrade() != null && !l.getGrade().isEmpty()) .sorted((x, y) -> CurriculumLineServices.COMPARATOR.compare(x.getEnrolment(), y.getEnrolment())) .collect(Collectors.toList()); model.addAttribute("evaluationsSet", evaluations); return jspPage("create"); } @RequestMapping(value = _CREATE_URI + "{scpId}/{executionSemesterId}", method = RequestMethod.POST) public String create(@PathVariable("scpId") final StudentCurricularPlan studentCurricularPlan, @PathVariable("executionSemesterId") final ExecutionSemester executionSemester, @RequestParam(value = "enrolment", required = false) Enrolment enrolment, @RequestParam(value = "availabledate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate availableDate, @RequestParam(value = "examdate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate examDate, @RequestParam(value = "gradescale", required = false) GradeScale gradeScale, @RequestParam(value = "grade", required = false) String grade, @RequestParam(value = "type", required = false) EvaluationSeason type, @RequestParam(value = "improvementsemester", required = false) ExecutionSemester improvementSemester, Model model, final RedirectAttributes redirectAttributes) { try { final List<String> others = checkIfAllGradesAreSameScale(enrolment, gradeScale); if (!others.isEmpty()) { addErrorMessage(ULisboaSpecificationsUtil.bundle("error.LooseEvaluationBean.grade.not.same.scale", others.stream().collect(Collectors.joining(", "))), model); return create(studentCurricularPlan, executionSemester, model); } createLooseEvaluation(enrolment, examDate, Grade.createGrade(grade, gradeScale), availableDate, type, improvementSemester); return redirect( CREATE_URL + studentCurricularPlan.getExternalId() + "/" + executionSemester.getExternalId(), model, redirectAttributes); } catch (final DomainException e) { addErrorMessage(e, model); return create(studentCurricularPlan, executionSemester, model); } } private void addErrorMessage(final DomainException e, final Model model) { if (!e.getLocalizedMessage().startsWith("!")) { addErrorMessage(e.getLocalizedMessage(), model); } else { addErrorMessage(BundleUtil.getString(Bundle.ACADEMIC, e.getKey()), model); } } static private List<String> checkIfAllGradesAreSameScale(final Enrolment enrolment, final GradeScale gradeScale) { final List<String> result = Lists.newArrayList(); for (final EnrolmentEvaluation iter : enrolment.getEvaluationsSet()) { final GradeScale other = iter.getGrade().getGradeScale(); if (!iter.getGrade().isEmpty() && other != gradeScale) { result.add(other.getDescription()); } } return result; } @Atomic public void createLooseEvaluation(Enrolment enrolment, LocalDate examDate, Grade grade, LocalDate availableDate, EvaluationSeason type, ExecutionSemester improvementSemester) { final EnrolmentEvaluation evaluation = new EnrolmentEvaluation(enrolment, type); if (type.isImprovement()) { evaluation.setExecutionPeriod(improvementSemester); } evaluation.edit(Authenticate.getUser().getPerson(), grade, availableDate.toDate(), examDate.toDateTimeAtStartOfDay().toDate()); evaluation.confirmSubmission(Authenticate.getUser().getPerson(), ""); EnrolmentServices.updateState(enrolment); CurriculumLineServices.updateAggregatorEvaluation(enrolment); EnrolmentEvaluationServices.onStateChange(evaluation); } private static final String _DELETE_URI = "/delete/"; public static final String DELETE_URL = CONTROLLER_URL + _DELETE_URI; @RequestMapping(value = _DELETE_URI + "{scpId}/{evaluationId}/{executionSemesterId}", method = RequestMethod.POST) public String delete(@PathVariable("scpId") final StudentCurricularPlan studentCurricularPlan, @PathVariable("evaluationId") EnrolmentEvaluation enrolmentEvaluation, @PathVariable("executionSemesterId") final ExecutionSemester executionSemester, Model model, final RedirectAttributes redirectAttributes) { try { deleteLooseEvaluation(enrolmentEvaluation); } catch (final DomainException e) { addErrorMessage(e, model); } return redirect( CREATE_URL + studentCurricularPlan.getExternalId() + "/" + executionSemester.getExternalId(), model, redirectAttributes); } @Atomic private void deleteLooseEvaluation(EnrolmentEvaluation enrolmentEvaluation) { final Enrolment enrolment = enrolmentEvaluation.getEnrolment(); enrolmentEvaluation.setEnrolmentEvaluationState(EnrolmentEvaluationState.TEMPORARY_OBJ); EnrolmentEvaluationServices.onStateChange(enrolmentEvaluation); if (FenixFramework.isDomainObjectValid(enrolmentEvaluation)) { //TODO: hack since listeners can cause object to be deleted //logic should be two-step, first change to Temporary and if it still exists delete enrolmentEvaluation.delete(); } EnrolmentServices.updateState(enrolment); CurriculumLineServices.updateAggregatorEvaluation(enrolment); } }