/** * 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.domain.phd; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import org.fenixedu.academic.domain.Coordinator; import org.fenixedu.academic.domain.Degree; import org.fenixedu.academic.domain.DomainObjectUtil; import org.fenixedu.academic.domain.ExecutionDegree; import org.fenixedu.academic.domain.ExecutionYear; import org.fenixedu.academic.domain.Person; import org.fenixedu.academic.domain.degree.DegreeType; import org.fenixedu.academic.domain.degreeStructure.CycleType; import org.fenixedu.academic.domain.exceptions.DomainException; import org.fenixedu.academic.domain.organizationalStructure.Unit; import org.fenixedu.academic.util.Bundle; import org.fenixedu.academic.util.MultiLanguageString; import org.fenixedu.bennu.core.domain.Bennu; import org.fenixedu.bennu.core.i18n.BundleUtil; import org.fenixedu.bennu.core.security.Authenticate; import org.fenixedu.commons.i18n.I18N; import org.joda.time.DateTime; import org.joda.time.LocalDate; import pt.ist.fenixframework.Atomic; public class PhdProgram extends PhdProgram_Base { static public Comparator<PhdProgram> COMPARATOR_BY_NAME = new Comparator<PhdProgram>() { @Override public int compare(final PhdProgram p1, final PhdProgram p2) { int res = p1.getName().compareTo(p2.getName()); return res != 0 ? res : DomainObjectUtil.COMPARATOR_BY_ID.compare(p1, p2); } }; private PhdProgram() { super(); setRootDomainObject(Bennu.getInstance()); setWhenCreated(new DateTime()); setCreator(Authenticate.getUser().getUsername()); new PhdProgramServiceAgreementTemplate(this); } private PhdProgram(final Degree degree, final MultiLanguageString name, final String acronym) { this(); checkDegree(degree); checkAcronym(acronym); setDegree(degree); setName(name); setAcronym(acronym); } private PhdProgram(final Degree degree, final MultiLanguageString name, final String acronym, final Unit parentProgramUnit) { this(degree, name, acronym); PhdProgramUnit.create(this, getName(), getWhenCreated().toYearMonthDay(), null, parentProgramUnit); } private void checkDegree(final Degree degree) { String[] args = {}; if (degree == null) { throw new DomainException("error.PhdProgram.invalid.degree", args); } if (!degree.getDegreeType().isAdvancedSpecializationDiploma()) { throw new DomainException("error.PhdProgram.invalid.degree"); } } private void checkAcronym(final String acronym) { String[] args = {}; if (acronym == null || acronym.isEmpty()) { throw new DomainException("error.PhdProgram.invalid.acronym", args); } final PhdProgram program = readByAcronym(acronym); if (program != null && program != this) { throw new DomainException("error.PhdProgram.acronym.already.exists", acronym); } } @Override public DegreeType getDegreeType() { return null; } @Override public Collection<CycleType> getCycleTypes() { return Collections.singletonList(CycleType.THIRD_CYCLE); } private boolean hasAcronym(final String acronym) { return getAcronym() != null && getAcronym().equalsIgnoreCase(acronym); } public String getPresentationName() { return getPresentationName(I18N.getLocale()); } private String getPresentationName(final Locale locale) { return getPrefix(locale) + getNameFor(locale); } private String getNameFor(final Locale locale) { return getName().hasContent(locale) ? getName().getContent(locale) : getName().getPreferedContent(); } private String getPrefix(final Locale locale) { return BundleUtil.getString(Bundle.PHD, locale, "label.php.program") + " " + BundleUtil.getString(Bundle.APPLICATION, "label.in") + " "; } @Override protected void checkForDeletionBlockers(Collection<String> blockers) { super.checkForDeletionBlockers(blockers); if (!getIndividualProgramProcessesSet().isEmpty()) { blockers.add(BundleUtil.getString(Bundle.APPLICATION, "error.PhdProgram.cannot.delete.has.individual.php.program.processes")); } } @Override protected void disconnect() { getPhdProgramUnit().delete(); setDegree(null); setServiceAgreementTemplate(null); setRootDomainObject(null); super.disconnect(); } public Set<Person> getCoordinatorsFor(ExecutionYear executionYear) { if (getDegree() == null) { return Collections.emptySet(); } final ExecutionDegree executionDegree = getDegree().getLastActiveDegreeCurricularPlan().getExecutionDegreeByYear(executionYear); final Set<Person> result = new HashSet<Person>(); if (executionDegree != null) { for (final Coordinator coordinator : executionDegree.getCoordinatorsListSet()) { result.add(coordinator.getPerson()); } } return result; } public Set<Person> getResponsibleCoordinatorsFor(ExecutionYear executionYear) { if (getDegree() == null) { return new HashSet<Person>(); } final ExecutionDegree executionDegree = getDegree().getLastActiveDegreeCurricularPlan().getExecutionDegreeByYear(executionYear); final Set<Person> result = new HashSet<Person>(); if (executionDegree != null) { for (final Coordinator coordinator : executionDegree.getCoordinatorsListSet()) { if (coordinator.isResponsible()) { result.add(coordinator.getPerson()); } } } return result; } public boolean isCoordinatorFor(Person person, ExecutionYear executionYear) { return getCoordinatorsFor(executionYear).contains(person); } @Atomic static public PhdProgram create(final Degree degree, final MultiLanguageString name, final String acronym) { return new PhdProgram(degree, name, acronym); } @Atomic static public PhdProgram create(final Degree degree, final MultiLanguageString name, final String acronym, final Unit parent) { return new PhdProgram(degree, name, acronym, parent); } static public PhdProgram readByAcronym(final String acronym) { for (final PhdProgram program : Bennu.getInstance().getPhdProgramsSet()) { if (program.hasAcronym(acronym)) { return program; } } return null; } public PhdProgramContextPeriod getMostRecentPeriod() { List<PhdProgramContextPeriod> periods = new ArrayList<PhdProgramContextPeriod>(); periods.addAll(getPhdProgramContextPeriodsSet()); Collections.sort(periods, Collections.reverseOrder(PhdProgramContextPeriod.COMPARATOR_BY_BEGIN_DATE)); if (periods.isEmpty()) { return null; } return periods.iterator().next(); } public boolean isActiveNow() { return isActive(new DateTime()); } public boolean isActive(DateTime date) { for (PhdProgramContextPeriod period : getPhdProgramContextPeriodsSet()) { if (period.contains(date)) { return true; } } return false; } public boolean isActive(final ExecutionYear executionYear) { PhdProgramContextPeriod mostRecentPeriod = getMostRecentPeriod(); if (mostRecentPeriod.getEndDate() == null) { DateTime beginDate = mostRecentPeriod.getBeginDate(); return beginDate.isBefore(executionYear.getBeginDateYearMonthDay().toDateMidnight()) || executionYear.containsDate(beginDate); } return mostRecentPeriod.getInterval().overlaps(executionYear.getAcademicInterval()); } public PhdProgramInformation getMostRecentPhdProgramInformation() { return getPhdProgramInformationByDate(new LocalDate()); } public PhdProgramInformation getPhdProgramInformationByDate(LocalDate localDate) { PhdProgramInformation mostRecent = null; for (PhdProgramInformation phdProgramInformation : getPhdProgramInformationsSet()) { if (phdProgramInformation.getBeginDate().isAfter(localDate)) { continue; } if (mostRecent == null) { mostRecent = phdProgramInformation; continue; } if (phdProgramInformation.getBeginDate().isAfter(mostRecent.getBeginDate())) { mostRecent = phdProgramInformation; } } return mostRecent; } @Atomic public PhdProgramContextPeriod create(PhdProgramContextPeriodBean bean) { return PhdProgramContextPeriod.create(bean); } }