/**
* Copyright © 2002 Instituto Superior Técnico
*
* This file is part of FenixEdu Academic.
*
* FenixEdu Academic 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 Academic 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 Academic. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fenixedu.academic.ui.struts.action.phd;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.TreeSet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.fenixedu.academic.domain.DegreeCurricularPlan;
import org.fenixedu.academic.domain.ExecutionYear;
import org.fenixedu.academic.domain.Person;
import org.fenixedu.academic.domain.exceptions.DomainException;
import org.fenixedu.academic.domain.phd.PhdIndividualProgramProcess;
import org.fenixedu.academic.domain.phd.PhdParticipant;
import org.fenixedu.academic.domain.phd.PhdProgramDocumentUploadBean;
import org.fenixedu.academic.domain.phd.SearchPhdIndividualProgramProcessBean;
import org.fenixedu.academic.domain.phd.alert.PhdAlertMessage;
import org.fenixedu.academic.domain.phd.guidance.PhdGuidanceDocument;
import org.fenixedu.academic.domain.phd.individualProcess.activities.DeleteGuidanceDocument;
import org.fenixedu.academic.domain.phd.individualProcess.activities.ExemptPublicPresentationSeminarComission;
import org.fenixedu.academic.domain.phd.individualProcess.activities.RequestPublicPresentationSeminarComission;
import org.fenixedu.academic.domain.phd.individualProcess.activities.UploadGuidanceDocument;
import org.fenixedu.academic.domain.phd.seminar.PublicPresentationSeminarProcessBean;
import org.fenixedu.academic.dto.phd.YearMonth;
import org.fenixedu.academic.predicate.AccessControl;
import org.fenixedu.academic.service.services.caseHandling.ExecuteProcessActivity;
import org.fenixedu.academic.ui.struts.action.phd.academicAdminOffice.PhdRegistrationConclusionBean;
import org.fenixedu.academic.util.Month;
import org.fenixedu.bennu.struts.portal.EntryPoint;
import pt.ist.fenixWebFramework.renderers.utils.RenderUtils;
import pt.utl.ist.fenix.tools.predicates.PredicateContainer;
abstract public class CommonPhdIndividualProgramProcessDA extends PhdProcessDA {
private static final int FIRST_YEAR_TO_SHOW_ARCHIVE_MESSAGES_FROM = 2002;
private static final int NUMBER_OF_LAST_MESSAGES = 100;
@Override
public ActionForward execute(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request,
HttpServletResponse response) throws Exception {
final PhdIndividualProgramProcess process = getProcess(request);
loadProcessAlertMessagesToNotify(request, process);
return super.execute(mapping, actionForm, request, response);
}
private void loadProcessAlertMessagesToNotify(HttpServletRequest request, final PhdIndividualProgramProcess process) {
if (process != null) {
request.setAttribute("processAlertMessagesToNotify", process.getUnreadedAlertMessagesFor(getLoggedPerson(request)));
}
}
public ActionForward manageProcesses(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
SearchPhdIndividualProgramProcessBean searchBean = getOrCreateSearchBean(request);
RenderUtils.invalidateViewState();
return forwardToManageProcesses(mapping, request, searchBean);
}
private SearchPhdIndividualProgramProcessBean getOrCreateSearchBean(HttpServletRequest request) {
SearchPhdIndividualProgramProcessBean searchBean =
(SearchPhdIndividualProgramProcessBean) getObjectFromViewState("searchProcessBean");
if (searchBean == null) {
searchBean = initializeSearchBean(request);
}
return searchBean;
}
protected ActionForward forwardToManageProcesses(ActionMapping mapping, HttpServletRequest request,
SearchPhdIndividualProgramProcessBean searchBean) {
request.setAttribute("searchProcessBean", searchBean);
request.setAttribute("candidacyCategory", getCandidacyCategory());
request.setAttribute("seminarCategory", getSeminarCategory());
request.setAttribute("thesisCategory", getThesisCategory());
request.setAttribute("concludedThisYearContainer", getConcludedContainer());
return mapping.findForward("manageProcesses");
}
abstract protected PhdInactivePredicateContainer getConcludedContainer();
abstract protected List<PredicateContainer<?>> getThesisCategory();
abstract protected List<PredicateContainer<?>> getSeminarCategory();
abstract protected List<PredicateContainer<?>> getCandidacyCategory();
abstract protected SearchPhdIndividualProgramProcessBean initializeSearchBean(HttpServletRequest request);
public ActionForward viewInactiveProcesses(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
SearchPhdIndividualProgramProcessBean searchBean = getOrCreateSearchBean(request);
RenderUtils.invalidateViewState();
request.setAttribute("searchProcessBean", searchBean);
request.setAttribute("suspendedContainer", PhdInactivePredicateContainer.SUSPENDED);
request.setAttribute("concludedContainer", PhdInactivePredicateContainer.CONCLUDED);
request.setAttribute("abolishedContainer", PhdInactivePredicateContainer.ABOLISHED);
return mapping.findForward("viewInactiveProcesses");
}
public ActionForward searchAllProcesses(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
SearchPhdIndividualProgramProcessBean searchBean = getOrCreateSearchBean(request);
RenderUtils.invalidateViewState();
List<PhdIndividualProgramProcess> processes;
try {
processes = PhdIndividualProgramProcess.search(searchBean.getPredicates());
} catch (NumberFormatException ex) {
addActionMessage("searchError", request, "error.invalidFormat");
return forwardToManageProcesses(mapping, request, searchBean);
}
if (processes.isEmpty()) {
addActionMessage("searchResults", request, "message.noResults");
return forwardToManageProcesses(mapping, request, searchBean);
}
if (processes.size() == 1) {
request.setAttribute("process", processes.iterator().next());
loadProcessAlertMessagesToNotify(request, processes.iterator().next());
Collection<PhdParticipant> guidingsList = processes.iterator().next().getGuidingsSet();
Collection<PhdParticipant> assistantGuidingsList = processes.iterator().next().getAssistantGuidingsSet();
request.setAttribute("guidingsList", guidingsList);
request.setAttribute("assistantGuidingsList", assistantGuidingsList);
return mapping.findForward("viewProcess");
}
request.setAttribute("searchProcessBean", searchBean);
request.setAttribute("processes", processes);
return mapping.findForward("searchResults");
}
@EntryPoint
public ActionForward viewProcess(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
RenderUtils.invalidateViewState();
final PhdIndividualProgramProcess process = getProcess(request);
if (process != null && process.getRegistration() != null) {
request.setAttribute("registrationConclusionBean", new PhdRegistrationConclusionBean(process.getRegistration()));
}
Collection<PhdParticipant> guidingsList = process.getGuidingsSet();
Collection<PhdParticipant> assistantGuidingsList = process.getAssistantGuidingsSet();
request.setAttribute("guidingsList", guidingsList);
request.setAttribute("assistantGuidingsList", assistantGuidingsList);
return forwardToViewProcess(mapping, request);
}
protected ActionForward forwardToViewProcess(ActionMapping mapping, HttpServletRequest request) {
request.setAttribute("backMethod", getFromRequest(request, "backMethod"));
return mapping.findForward("viewProcess");
}
@Override
protected PhdIndividualProgramProcess getProcess(HttpServletRequest request) {
return (PhdIndividualProgramProcess) super.getProcess(request);
}
protected DegreeCurricularPlan getDegreeCurricularPlan(HttpServletRequest request) {
return getDomainObject(request, "degreeCurricularPlanID");
}
// Alerts Management
public ActionForward viewAlertMessages(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
TreeSet<PhdAlertMessage> orderedMessages =
new TreeSet<PhdAlertMessage>(Collections.reverseOrder(PhdAlertMessage.COMPARATOR_BY_WHEN_CREATED_AND_ID));
orderedMessages.addAll(getLoggedPerson(request).getPhdAlertMessagesSet());
ArrayList<PhdAlertMessage> lastMessages = new ArrayList<PhdAlertMessage>();
lastMessages.addAll(orderedMessages);
request.setAttribute("unread", "false");
request.setAttribute("alertMessages", lastMessages.subList(0, Math.min(lastMessages.size(), NUMBER_OF_LAST_MESSAGES)));
request.setAttribute("tooManyMessages", (lastMessages.size() > NUMBER_OF_LAST_MESSAGES) ? "true" : "false");
return mapping.findForward("viewAlertMessages");
}
public ActionForward viewUnreadAlertMessages(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
TreeSet<PhdAlertMessage> orderedMessages =
new TreeSet<PhdAlertMessage>(Collections.reverseOrder(PhdAlertMessage.COMPARATOR_BY_WHEN_CREATED_AND_ID));
orderedMessages.addAll(getLoggedPerson(request).getUnreadedPhdAlertMessages());
request.setAttribute("unread", "true");
request.setAttribute("alertMessages", orderedMessages);
return mapping.findForward("viewAlertMessages");
}
public ActionForward viewAlertMessageArchive(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
YearMonth yearMonthBean = getOrCreateBean(request);
return forwardToAlertMessageArchive(mapping, request, yearMonthBean);
}
private ActionForward forwardToAlertMessageArchive(ActionMapping mapping, HttpServletRequest request, YearMonth yearMonthBean) {
Integer year = yearMonthBean.getYear();
if (year == null) {
year = Integer.valueOf(ExecutionYear.readCurrentExecutionYear().getYear());
}
Month month = yearMonthBean.getMonth();
TreeSet<PhdAlertMessage> orderedMessages =
new TreeSet<PhdAlertMessage>(Collections.reverseOrder(PhdAlertMessage.COMPARATOR_BY_WHEN_CREATED_AND_ID));
if (month == null) {
for (PhdAlertMessage message : getLoggedPerson(request).getPhdAlertMessagesSet()) {
if (year == message.getWhenCreated().getYear()) {
orderedMessages.add(message);
}
}
} else {
for (PhdAlertMessage message : getLoggedPerson(request).getPhdAlertMessagesSet()) {
if ((year == message.getWhenCreated().getYear())
&& (month.getNumberOfMonth() == message.getWhenCreated().getMonthOfYear())) {
orderedMessages.add(message);
}
}
}
request.setAttribute("yearMonthBean", yearMonthBean);
request.setAttribute("alertMessages", orderedMessages);
return mapping.findForward("viewAlertMessageArchive");
}
public YearMonth getOrCreateBean(HttpServletRequest request) {
YearMonth yearMonthBean = getRenderedObject("yearMonthBean");
RenderUtils.invalidateViewState();
if (yearMonthBean == null) {
yearMonthBean = createBeanFromRequest(request);
}
return yearMonthBean;
}
public YearMonth createBeanFromRequest(HttpServletRequest request) {
String year = (String) getFromRequest(request, "year");
String month = (String) getFromRequest(request, "month");
YearMonth yearMonthBean;
if (StringUtils.isEmpty(year)) {
yearMonthBean = new YearMonth(Calendar.getInstance().get(Calendar.YEAR), null);
} else if (StringUtils.isEmpty(month)) {
yearMonthBean = new YearMonth(Integer.valueOf(year), null);
} else {
yearMonthBean = new YearMonth(Integer.valueOf(year), Integer.valueOf(month));
}
yearMonthBean.setFirstYear(FIRST_YEAR_TO_SHOW_ARCHIVE_MESSAGES_FROM);
return yearMonthBean;
}
public ActionForward viewProcessAlertMessages(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
TreeSet<PhdAlertMessage> orderedMessages =
new TreeSet<PhdAlertMessage>(Collections.reverseOrder(PhdAlertMessage.COMPARATOR_BY_WHEN_CREATED_AND_ID));
orderedMessages.addAll(getProcess(request).getAlertMessagesForLoggedPerson());
ArrayList<PhdAlertMessage> lastMessages = new ArrayList<PhdAlertMessage>();
lastMessages.addAll(orderedMessages);
request.setAttribute("unread", "false");
request.setAttribute("alertMessages", lastMessages.subList(0, Math.min(lastMessages.size(), NUMBER_OF_LAST_MESSAGES)));
request.setAttribute("tooManyMessages", (lastMessages.size() > NUMBER_OF_LAST_MESSAGES) ? "true" : "false");
return mapping.findForward("viewProcessAlertMessages");
}
public ActionForward viewUnreadProcessAlertMessages(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
TreeSet<PhdAlertMessage> orderedMessages =
new TreeSet<PhdAlertMessage>(Collections.reverseOrder(PhdAlertMessage.COMPARATOR_BY_WHEN_CREATED_AND_ID));
orderedMessages.addAll(getProcess(request).getUnreadAlertMessagesForLoggedPerson());
request.setAttribute("unread", "true");
request.setAttribute("alertMessages", orderedMessages);
return mapping.findForward("viewProcessAlertMessages");
}
public ActionForward viewProcessAlertMessageArchive(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
YearMonth yearMonthBean = getOrCreateBean(request);
return forwardToProcessAlertMessageArchive(mapping, request, yearMonthBean);
}
private ActionForward forwardToProcessAlertMessageArchive(ActionMapping mapping, HttpServletRequest request,
YearMonth yearMonthBean) throws NumberFormatException {
Integer year = yearMonthBean.getYear();
if (year == null) {
year = Integer.valueOf(ExecutionYear.readCurrentExecutionYear().getYear());
}
Month month = yearMonthBean.getMonth();
TreeSet<PhdAlertMessage> orderedMessages =
new TreeSet<PhdAlertMessage>(Collections.reverseOrder(PhdAlertMessage.COMPARATOR_BY_WHEN_CREATED_AND_ID));
if (month == null) {
for (PhdAlertMessage message : getProcess(request).getAlertMessagesForLoggedPerson()) {
if (year == message.getWhenCreated().getYear()) {
orderedMessages.add(message);
}
}
} else {
for (PhdAlertMessage message : getProcess(request).getAlertMessagesForLoggedPerson()) {
if ((year == message.getWhenCreated().getYear())
&& (month.getNumberOfMonth() == message.getWhenCreated().getMonthOfYear())) {
orderedMessages.add(message);
}
}
}
request.setAttribute("yearMonthBean", yearMonthBean);
request.setAttribute("alertMessages", orderedMessages);
return mapping.findForward("viewProcessAlertMessageArchive");
}
public ActionForward readAlertMessage(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
PhdAlertMessage alertMessage = getAlertMessage(request);
alertMessage.markAsReaded(getLoggedPerson(request));
// back information
String unread = (String) getFromRequest(request, "unread");
String global = (String) getFromRequest(request, "global");
String archive = (String) getFromRequest(request, "archive");
String year = (String) getFromRequest(request, "year");
String month = (String) getFromRequest(request, "month");
request.setAttribute("unread", (unread != null) ? unread : "false");
request.setAttribute("global", (global != null) ? global : "true");
request.setAttribute("archive", (archive != null) ? archive : "false");
request.setAttribute("year", (year != null) ? year : String.valueOf(Calendar.getInstance().get(Calendar.YEAR)));
request.setAttribute("month", (month != null) ? month : "");
request.setAttribute("alertMessage", alertMessage);
return mapping.findForward("viewAlertMessage");
}
public ActionForward markAlertMessageAsUnread(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
PhdAlertMessage alertMessage = getAlertMessage(request);
alertMessage.markAsUnread();
Person loggedPerson = AccessControl.getPerson();
boolean global = Boolean.valueOf((String) getFromRequest(request, "global"));
boolean unread = Boolean.valueOf((String) getFromRequest(request, "unread"));
boolean archive = Boolean.valueOf((String) getFromRequest(request, "archive"));
request.setAttribute("global", global);
if (global) {
request.setAttribute("alertMessagesToNotify", loggedPerson.getUnreadedPhdAlertMessages());
if (unread) {
return viewUnreadAlertMessages(mapping, form, request, response);
}
if (archive) {
return forwardToAlertMessageArchive(mapping, request, createBeanFromRequest(request));
}
return viewAlertMessages(mapping, form, request, response);
}
request.setAttribute("processAlertMessagesToNotify",
getProcess(request).getUnreadedAlertMessagesFor(getLoggedPerson(request)));
if (unread) {
return viewUnreadProcessAlertMessages(mapping, form, request, response);
}
if (archive) {
return forwardToProcessAlertMessageArchive(mapping, request, createBeanFromRequest(request));
}
return viewProcessAlertMessages(mapping, form, request, response);
}
private PhdAlertMessage getAlertMessage(HttpServletRequest request) {
return getDomainObject(request, "alertMessageId");
}
// End of Alerts Management
// Request Public Presentation Seminar Comission
public ActionForward prepareRequestPublicPresentationSeminarComission(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
PhdIndividualProgramProcess process = getProcess(request);
request.setAttribute("requestPublicPresentationSeminarComissionBean", new PublicPresentationSeminarProcessBean(process));
return mapping.findForward("requestPublicPresentationSeminarComission");
}
public ActionForward prepareRequestPublicPresentationSeminarComissionPostback(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
request.setAttribute("requestPublicPresentationSeminarComissionBean",
getRenderedObject("requestPublicPresentationSeminarComissionBean"));
RenderUtils.invalidateViewState();
return mapping.findForward("requestPublicPresentationSeminarComission");
}
public ActionForward prepareRequestPublicPresentationSeminarComissionInvalid(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
request.setAttribute("requestPublicPresentationSeminarComissionBean",
getRenderedObject("requestPublicPresentationSeminarComissionBean"));
return mapping.findForward("requestPublicPresentationSeminarComission");
}
public ActionForward requestPublicPresentationSeminarComission(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
final PublicPresentationSeminarProcessBean bean = getRenderedObject("requestPublicPresentationSeminarComissionBean");
request.setAttribute("requestPublicPresentationSeminarComissionBean", bean);
return executeActivity(RequestPublicPresentationSeminarComission.class, bean, request, mapping,
"requestPublicPresentationSeminarComission", "viewProcess");
}
public ActionForward prepareExemptPublicPresentationSeminarComission(ActionMapping mapping, ActionForm actionForm,
HttpServletRequest request, HttpServletResponse response) {
return mapping.findForward("exemptPublicPresentationSeminarComission");
}
public ActionForward exemptPublicPresentationSeminarComission(ActionMapping mapping, ActionForm actionForm,
HttpServletRequest request, HttpServletResponse response) {
try {
ExecuteProcessActivity.run(getProcess(request), ExemptPublicPresentationSeminarComission.class,
new PublicPresentationSeminarProcessBean());
} catch (final DomainException e) {
addErrorMessage(request, e.getMessage(), e.getArgs());
return prepareExemptPublicPresentationSeminarComission(mapping, actionForm, request, response);
}
return viewProcess(mapping, actionForm, request, response);
}
// End of Request Public Presentation Seminar Comission
// View curriculum
public ActionForward viewCurriculum(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
request.setAttribute("curriculumFilter", new PhdCurriculumFilterOptions(getProcess(request).getRegistration()));
return mapping.findForward("viewCurriculum");
}
public ActionForward changeViewCurriculumFilterOptions(ActionMapping mapping, ActionForm actionForm,
HttpServletRequest request, HttpServletResponse response) {
request.setAttribute("curriculumFilter", getRenderedObject("curriculumFilter"));
return mapping.findForward("viewCurriculum");
}
// End of view curriculum
/* Phd guidance documents */
public ActionForward manageGuidanceDocuments(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
return mapping.findForward("manageGuidanceDocuments");
}
public ActionForward prepareUploadGuidanceDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
PhdProgramDocumentUploadBean bean = new PhdProgramDocumentUploadBean();
request.setAttribute("documentBean", bean);
return mapping.findForward("uploadGuidanceDocument");
}
public ActionForward uploadGuidanceDocumentInvalid(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
PhdProgramDocumentUploadBean bean = (PhdProgramDocumentUploadBean) getRenderedObject("documentBean");
request.setAttribute("documentBean", bean);
return mapping.findForward("uploadGuidanceDocument");
}
public ActionForward uploadGuidanceDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
PhdProgramDocumentUploadBean bean = (PhdProgramDocumentUploadBean) getRenderedObject("documentBean");
ExecuteProcessActivity.run(getProcess(request), UploadGuidanceDocument.class, bean);
return manageGuidanceDocuments(mapping, form, request, response);
}
public ActionForward deleteGuidanceDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
PhdGuidanceDocument document = getDomainObject(request, "phdDocument");
ExecuteProcessActivity.run(getProcess(request), DeleteGuidanceDocument.class, document);
return manageGuidanceDocuments(mapping, form, request, response);
}
public ActionForward downloadGuidanceDocuments(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
writeFile(response, getGuidanceDocumentsFilename(request), PhdDocumentsZip.ZIP_MIME_TYPE,
createGuidanceDocumentsZip(request));
return null;
}
protected String getGuidanceDocumentsFilename(HttpServletRequest request) {
final PhdIndividualProgramProcess process = getProcess(request);
return String.format("%s-%s.zip", process.getProcessNumber().replace("/", "-"),
getMessageFromResource("label.phd.guidance.documents").replace(" ", "_"));
}
/* End of phd guidance documents */
}