Package org.fenixedu.academic.domain

Source Code of org.fenixedu.academic.domain.ExecutionYear

/**
* 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;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.fenixedu.academic.FenixEduAcademicConfiguration;
import org.fenixedu.academic.domain.accounting.AccountingTransaction;
import org.fenixedu.academic.domain.accounting.events.AnnualEvent;
import org.fenixedu.academic.domain.accounting.events.gratuity.DfaGratuityEvent;
import org.fenixedu.academic.domain.candidacy.StudentCandidacy;
import org.fenixedu.academic.domain.candidacy.degree.ShiftDistribution;
import org.fenixedu.academic.domain.degree.DegreeType;
import org.fenixedu.academic.domain.exceptions.DomainException;
import org.fenixedu.academic.domain.time.calendarStructure.AcademicInterval;
import org.fenixedu.academic.domain.time.calendarStructure.AcademicYearCE;
import org.fenixedu.academic.util.PeriodState;
import org.fenixedu.bennu.core.domain.Bennu;
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.DateTimeFieldType;
import org.joda.time.Interval;
import org.joda.time.LocalDate;
import org.joda.time.Partial;
import org.joda.time.YearMonthDay;

import pt.ist.fenixframework.dml.runtime.RelationAdapter;

/**
* Created on 11/Fev/2003
*
* @author Jo�o Mota ciapl Dominio
*
*/
public class ExecutionYear extends ExecutionYear_Base implements Comparable<ExecutionYear> {

    static {
        getRelationExecutionPeriodExecutionYear().addListener(new ExecutionPeriodExecutionYearListener());
    }

    static final public Comparator<ExecutionYear> COMPARATOR_BY_YEAR = new Comparator<ExecutionYear>() {
        @Override
        public int compare(ExecutionYear o1, ExecutionYear o2) {
            return o1.getYear().compareTo(o2.getYear());
        }
    };

    static final public Comparator<ExecutionYear> REVERSE_COMPARATOR_BY_YEAR = new Comparator<ExecutionYear>() {
        @Override
        public int compare(ExecutionYear o1, ExecutionYear o2) {
            return -COMPARATOR_BY_YEAR.compare(o1, o2);
        }
    };

    private ExecutionYear() {
        super();
        setRootDomainObjectForExecutionYear(Bennu.getInstance());
    }

    public ExecutionYear(AcademicInterval academicInterval, String year) {
        this();
        setAcademicInterval(academicInterval);
        setBeginDateYearMonthDay(academicInterval.getBeginYearMonthDayWithoutChronology());
        setEndDateYearMonthDay(academicInterval.getEndYearMonthDayWithoutChronology());
        setYear(year);
    }

    public String getYear() {
        return getName();
    }

    public void setYear(String year) {
        if (year == null || StringUtils.isEmpty(year.trim())) {
            throw new DomainException("error.ExecutionYear.empty.year");
        }
        super.setName(year);
    }

    @Override
    public String getQualifiedName() {
        return getName();
    }

    public Collection<ExecutionDegree> getExecutionDegreesByType(final DegreeType degreeType) {
        return CollectionUtils.select(getExecutionDegreesSet(), new Predicate() {
            @Override
            public boolean evaluate(Object arg0) {
                ExecutionDegree executionDegree = (ExecutionDegree) arg0;
                return executionDegree.getDegreeCurricularPlan().getDegreeType() == degreeType;
            }
        });
    }

    public ExecutionYear getNextExecutionYear() {
        AcademicYearCE year = getAcademicInterval().plusYear(1);
        return getExecutionYear(year);
    }

    public ExecutionYear getPreviousExecutionYear() {
        AcademicYearCE year = getAcademicInterval().minusYear(1);
        return getExecutionYear(year);
    }

    public ExecutionYear getPreviousExecutionYear(final Integer previousCivilYears) {
        if (previousCivilYears >= 0) {
            AcademicYearCE year = getAcademicInterval().minusYear(previousCivilYears);
            return getExecutionYear(year);
        }
        return null;
    }

    public boolean hasPreviousExecutionYear() {
        return getPreviousExecutionYear() != null;
    }

    public boolean hasNextExecutionYear() {
        return getNextExecutionYear() != null;
    }

    @Override
    public int compareTo(ExecutionYear object) {
        if (object == null) {
            return 1;
        }
        return getAcademicInterval().getStartDateTimeWithoutChronology().compareTo(
                object.getAcademicInterval().getStartDateTimeWithoutChronology());
    }

    public boolean isAfter(final ExecutionYear executionYear) {
        return this.compareTo(executionYear) > 0;
    }

    public boolean isAfterOrEquals(final ExecutionYear executionYear) {
        return this.compareTo(executionYear) >= 0;
    }

    public boolean isBefore(final ExecutionYear executionYear) {
        return this.compareTo(executionYear) < 0;
    }

    public boolean isBeforeOrEquals(final ExecutionYear executionYear) {
        return this.compareTo(executionYear) <= 0;
    }

    public boolean isInclusivelyBetween(final ExecutionYear y1, final ExecutionYear y2) {
        return (isAfterOrEquals(y1) && isBeforeOrEquals(y2));
    }

    public boolean isExclusivelyBetween(final ExecutionYear y1, final ExecutionYear y2) {
        return (isAfter(y1) && isBefore(y2));
    }

    public Collection<ExecutionDegree> getExecutionDegreesSortedByDegreeName() {
        final List<ExecutionDegree> executionDegrees = new ArrayList<ExecutionDegree>(getExecutionDegreesSet());
        Collections.sort(executionDegrees, ExecutionDegree.EXECUTION_DEGREE_COMPARATORY_BY_DEGREE_TYPE_AND_NAME);
        return executionDegrees;
    }

    public ExecutionSemester getExecutionSemesterFor(final Integer semester) {
        for (final ExecutionSemester executionSemester : getExecutionPeriodsSet()) {
            if (executionSemester.isFor(semester)) {
                return executionSemester;
            }
        }
        return null;
    }

    public ExecutionSemester getFirstExecutionPeriod() {
        return Collections.min(this.getExecutionPeriodsSet(), ExecutionSemester.COMPARATOR_BY_SEMESTER_AND_YEAR);
    }

    public ExecutionSemester getLastExecutionPeriod() {
        return Collections.max(this.getExecutionPeriodsSet(), ExecutionSemester.COMPARATOR_BY_SEMESTER_AND_YEAR);
    }

    public List<ExecutionSemester> readNotClosedPublicExecutionPeriods() {
        final List<ExecutionSemester> result = new ArrayList<ExecutionSemester>();
        for (final ExecutionSemester executionSemester : getExecutionPeriodsSet()) {
            if (!executionSemester.isClosed() && !executionSemester.isNotOpen()) {
                result.add(executionSemester);
            }
        }
        return result;
    }

    public ExecutionSemester readExecutionPeriodByName(final String name) {
        for (final ExecutionSemester executionSemester : getExecutionPeriodsSet()) {
            if (executionSemester.getName().equals(name)) {
                return executionSemester;
            }
        }
        return null;
    }

    public String getNextYearsYearString() {
        final int yearPart1 = Integer.parseInt(getYear().substring(0, 4)) + 1;
        final int yearPart2 = Integer.parseInt(getYear().substring(5, 9)) + 1;
        return Integer.toString(yearPart1) + getYear().charAt(4) + Integer.toString(yearPart2);
    }

    public DegreeInfo getDegreeInfo(final Degree degree) {
        for (final DegreeInfo degreeInfo : getDegreeInfosSet()) {
            if (degreeInfo.getDegree() == degree) {
                return degreeInfo;
            }
        }
        return null;
    }

    public boolean containsDate(final DateTime dateTime) {
        final DateMidnight begin = getBeginDateYearMonthDay().toDateMidnight();
        final DateMidnight end = getEndDateYearMonthDay().plusDays(1).toDateMidnight();
        return new Interval(begin, end).contains(dateTime);
    }

    public boolean overlapsInterval(final Interval interval) {
        final DateMidnight begin = getBeginDateYearMonthDay().toDateMidnight();
        final DateMidnight end = getEndDateYearMonthDay().plusDays(1).toDateMidnight();
        return new Interval(begin, end).overlaps(interval);
    }

    public boolean containsDate(final LocalDate date) {
        return !getBeginDateYearMonthDay().isAfter(date) && !getEndDateYearMonthDay().isBefore(date);
    }

    public List<ExecutionDegree> getExecutionDegreesFor(final DegreeType... degreeTypes) {
        final List<ExecutionDegree> result = new ArrayList<ExecutionDegree>();
        final List<DegreeType> degreeTypesList = Arrays.asList(degreeTypes);
        for (final ExecutionDegree executionDegree : getExecutionDegreesSet()) {
            if (degreeTypesList.contains(executionDegree.getDegreeCurricularPlan().getDegree().getDegreeType())) {
                result.add(executionDegree);
            }
        }
        return result;
    }

    @Override
    public boolean isCurrent() {
        return this.getState().equals(PeriodState.CURRENT);
    }

    public boolean isOpen() {
        return getState().equals(PeriodState.OPEN);
    }

    public boolean isClosed() {
        return getState().equals(PeriodState.CLOSED);
    }

    private boolean isNotOpen() {
        return getState().equals(PeriodState.NOT_OPEN);
    }

    public boolean isFor(final String year) {
        return getYear().equals(year);
    }

    public ShiftDistribution createShiftDistribution() {
        return new ShiftDistribution(this);
    }

    public void delete() {
        if (!getExecutionDegreesSet().isEmpty()) {
            throw new Error("cannot.delete.execution.year.because.execution.degrees.exist");
        }
        if (!getStudentGroupSet().isEmpty()) {
            throw new DomainException("error.executionYear.cannotDeleteExecutionYearUsedInAccessControl");
        }
        if (!getTeacherGroupSet().isEmpty()) {
            throw new DomainException("error.executionYear.cannotDeleteExecutionYearUsedInAccessControl");
        }
        if (!getStudentsConcludedInExecutionYearGroupSet().isEmpty()) {
            throw new DomainException("error.executionYear.cannotDeleteExecutionYearUsedInAccessControl");
        }
        for (; !getExecutionPeriodsSet().isEmpty(); getExecutionPeriodsSet().iterator().next().delete()) {
            ;
        }

        setRootDomainObject(null);
        setRootDomainObjectForExecutionYear(null);
        deleteDomainObject();
    }

    public boolean belongsToCivilYear(int civilYear) {
        return (getBeginCivilYear() == civilYear || getEndCivilYear() == civilYear);
    }

    public int getBeginCivilYear() {
        return getBeginDateYearMonthDay().getYear();
    }

    public int getEndCivilYear() {
        return getEndDateYearMonthDay().getYear();
    }

    public boolean belongsToCivilYearInterval(int beginCivilYear, int endCivilYear) {
        for (int year = beginCivilYear; year <= endCivilYear; year++) {
            if (belongsToCivilYear(year)) {
                return true;
            }
        }
        return false;
    }

    public boolean isBeforeCivilYear(int civilYear) {
        return getEndCivilYear() < civilYear;
    }

    public boolean isAfterCivilYear(int civilYear) {
        return getBeginCivilYear() > civilYear;
    }

    public int getDistanceInCivilYears(final ExecutionYear executionYear) {
        if (executionYear == null || executionYear == this) {
            return 0;
        }

        return Math.abs(getBeginCivilYear() - executionYear.getBeginCivilYear());
    }

    public Collection<DegreeCurricularPlan> getDegreeCurricularPlans() {
        final Collection<DegreeCurricularPlan> result = new HashSet<DegreeCurricularPlan>();
        for (final ExecutionDegree executionDegree : getExecutionDegreesSet()) {
            result.add(executionDegree.getDegreeCurricularPlan());
        }
        return result;
    }

    private Set<AccountingTransaction> getPaymentsFor(final Class<? extends AnnualEvent> eventClass) {
        final Set<AccountingTransaction> result = new HashSet<AccountingTransaction>();
        for (final AnnualEvent each : getAnnualEventsSet()) {
            if (eventClass.equals(each.getClass()) && !each.isCancelled()) {
                result.addAll(each.getNonAdjustingTransactions());
            }
        }

        return result;
    }

    public Set<AccountingTransaction> getDFAGratuityPayments() {
        return getPaymentsFor(DfaGratuityEvent.class);
    }

    public List<StudentCandidacy> getStudentCandidacies() {
        final List<StudentCandidacy> result = new ArrayList<StudentCandidacy>();
        for (final ExecutionDegree executionDegree : getExecutionDegreesSet()) {
            result.addAll(executionDegree.getStudentCandidaciesSet());
        }
        return result;
    }

    private static class ExecutionPeriodExecutionYearListener extends RelationAdapter<ExecutionYear, ExecutionSemester> {
        @Override
        public void beforeAdd(ExecutionYear executionYear, ExecutionSemester executionSemester) {
            if (executionYear != null && executionSemester != null && executionYear.getExecutionPeriodsSet().size() == 2) {
                throw new DomainException("error.ExecutionYear.exceeded.number.of.executionPeriods", executionYear.getYear());
            }
        }
    }

    public ExecutionSemester getExecutionSemester(final YearMonthDay date) {
        for (final ExecutionSemester semester : getExecutionPeriodsSet()) {
            if (semester.containsDay(date)) {
                return semester;
            }
        }
        return null;
    }

    // -------------------------------------------------------------
    // read static methods
    // -------------------------------------------------------------

    public static ExecutionYear getExecutionYear(AcademicYearCE entry) {
        if (entry != null) {
            entry = (AcademicYearCE) entry.getOriginalTemplateEntry();
            for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
                if (executionYear.getAcademicInterval().getAcademicCalendarEntry().equals(entry)) {
                    return executionYear;
                }
            }
        }
        return null;
    }

    static public ExecutionYear readCurrentExecutionYear() {
        ExecutionSemester semester = ExecutionSemester.readActualExecutionSemester();
        if (semester != null) {
            return semester.getExecutionYear();
        } else {
            return null;
        }
    }

    static transient private ExecutionYear startExecutionYearForOptionalCurricularCoursesWithLessTenEnrolments = null;

    static private ExecutionYear readFromProperties(ExecutionYear executionYear, String yearString) {
        if (executionYear == null || executionYear.getRootDomainObject() != Bennu.getInstance()) {
            if (yearString == null || yearString.length() == 0) {
                executionYear = null;
            } else {
                executionYear = readExecutionYearByName(yearString);
            }
        }

        return executionYear;
    }

    public static ExecutionYear readStartExecutionYearForOptionalCurricularCoursesWithLessTenEnrolments() {
        startExecutionYearForOptionalCurricularCoursesWithLessTenEnrolments =
                readFromProperties(startExecutionYearForOptionalCurricularCoursesWithLessTenEnrolments, FenixEduAcademicConfiguration
                        .getConfiguration().getStartExecutionYearForAllOptionalCurricularCoursesWithLessTenEnrolments());
        return startExecutionYearForOptionalCurricularCoursesWithLessTenEnrolments;
    }

    static public List<ExecutionYear> readOpenExecutionYears() {
        final List<ExecutionYear> result = new ArrayList<ExecutionYear>();
        for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
            if (executionYear.isOpen()) {
                result.add(executionYear);
            }
        }
        return result;
    }

    static public List<ExecutionYear> readNotClosedExecutionYears() {
        final List<ExecutionYear> result = new ArrayList<ExecutionYear>();
        for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
            if (!executionYear.isClosed()) {
                result.add(executionYear);
            }
        }
        return result;
    }

    public static List<ExecutionYear> readNotOpenExecutionYears() {
        final List<ExecutionYear> result = new ArrayList<ExecutionYear>();
        for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
            if (executionYear.isNotOpen()) {
                result.add(executionYear);
            }
        }
        return result;
    }

    static public List<ExecutionYear> readExecutionYears(ExecutionYear startYear, ExecutionYear endYear) {
        final List<ExecutionYear> result = new ArrayList<ExecutionYear>();
        result.add(startYear);

        ExecutionYear year = startYear.getNextExecutionYear();
        while (year != null && year.isBeforeOrEquals(endYear)) {
            result.add(year);
            year = year.getNextExecutionYear();
        }
        return result;
    }

    static public ExecutionYear readExecutionYearByName(final String year) {
        for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
            if (executionYear.isFor(year)) {
                return executionYear;
            }
        }
        return null;
    }

    static public ExecutionYear readFirstBolonhaExecutionYear() {
        return ExecutionSemester.readFirstBolonhaExecutionPeriod().getExecutionYear();
    }

    public static class ExecutionYearSearchCache {
        private final Map<Integer, Set<ExecutionYear>> map = new HashMap<Integer, Set<ExecutionYear>>();

        private Set<ExecutionYear> updateIfNeeded(final Integer year) {
            Set<ExecutionYear> result = map.get(year);

            // for a given civil year, a maximum of two ExecutionYear can be indexed => must update cache if only one ExecutionYear is cached
            if (result == null || result.size() < 2) {
                for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
                    add(executionYear);
                }
                result = map.get(year);
            }

            return result;
        }

        public ExecutionYear findByDateTime(final DateTime dateTime) {
            final Integer year = Integer.valueOf(dateTime.getYear());
            final Set<ExecutionYear> executionYears = updateIfNeeded(year);
            if (executionYears != null) {
                for (final ExecutionYear executionYear : executionYears) {
                    if (executionYear.containsDate(dateTime)) {
                        return executionYear;
                    }
                }
            }
            return null;
        }

        public ExecutionYear findByPartial(final Partial partial) {
            final Integer year = Integer.valueOf(partial.get(DateTimeFieldType.year()));
            final Set<ExecutionYear> executionYears = updateIfNeeded(year);
            if (executionYears != null) {
                for (final ExecutionYear executionYear : executionYears) {
                    if (executionYear.getBeginDateYearMonthDay().getYear() == year) {
                        return executionYear;
                    }
                }
            }
            return null;
        }

        private void add(final ExecutionYear executionYear) {
            final Integer year1 = executionYear.getBeginDateYearMonthDay().getYear();
            final Integer year2 = executionYear.getEndDateYearMonthDay().getYear();
            add(executionYear, year1);
            add(executionYear, year2);
        }

        private void add(final ExecutionYear executionYear, final Integer year) {
            Set<ExecutionYear> executionYears = map.get(year);
            if (executionYears == null) {
                executionYears = new HashSet<ExecutionYear>();
                map.put(year, executionYears);
            }
            executionYears.add(executionYear);
        }
    }

    private static final ExecutionYearSearchCache executionYearSearchCache = new ExecutionYearSearchCache();

    static public ExecutionYear readByDateTime(final DateTime dateTime) {
        return executionYearSearchCache.findByDateTime(dateTime);
    }

    static public ExecutionYear readByDateTime(final LocalDate localDate) {
        return executionYearSearchCache.findByDateTime(localDate.toDateTimeAtCurrentTime());
    }

    static public ExecutionYear readByPartial(final Partial partial) {
        return executionYearSearchCache.findByPartial(partial);
    }

    public static ExecutionYear readBy(final YearMonthDay begin, YearMonthDay end) {
        for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
            if (executionYear.getBeginDateYearMonthDay().isEqual(begin) && executionYear.getEndDateYearMonthDay().isEqual(end)) {
                return executionYear;
            }
        }
        return null;
    }

    static public ExecutionYear getExecutionYearByDate(final YearMonthDay date) {
        return readByDateTime(date.toDateTimeAtMidnight());
    }

    static public List<ExecutionYear> readExecutionYearsByCivilYear(int civilYear) {
        final List<ExecutionYear> result = new ArrayList<ExecutionYear>();

        for (final ExecutionYear executionYear : executionYearSearchCache.map.get(civilYear)) {
            if (executionYear.belongsToCivilYear(civilYear)) {
                result.add(executionYear);
            }
        }

        return result;

    }

    static public ExecutionYear readFirstExecutionYear() {
        for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
            if (!executionYear.hasPreviousExecutionYear()) {
                return executionYear;
            }
        }
        return null;
    }

    static public ExecutionYear readLastExecutionYear() {
        for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
            if (!executionYear.hasNextExecutionYear()) {
                return executionYear;
            }
        }
        return null;
    }

    public static ExecutionYear readByAcademicInterval(AcademicInterval academicInterval) {
        for (final ExecutionYear executionYear : Bennu.getInstance().getExecutionYearsSet()) {
            if (executionYear.getAcademicInterval().equals(academicInterval)) {
                return executionYear;
            }
        }
        return null;
    }

    public ExecutionDegree getExecutionDegreeByAcronym(String acronym) {
        for (ExecutionDegree executionDegree : getExecutionDegreesSet()) {
            if (executionDegree.getDegree().getSigla().equals(acronym)) {
                return executionDegree;
            }
        }
        return null;
    }

}
TOP

Related Classes of org.fenixedu.academic.domain.ExecutionYear

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.