package org.fenixedu.bennu.core.domain; import java.util.Comparator; import java.util.Objects; import jvstm.cps.ConsistencyPredicate; import org.fenixedu.bennu.core.domain.exceptions.BennuCoreDomainException; import org.joda.time.LocalDate; /** * Represents a period in time in which the associated {@link User} is allowed to log in to the application. * * Note that a user may have several active Periods at the same time, but can only have one open period (i.e. a period without a * end date). * * @author João Carvalho (joao.pedro.carvalho@ist.utl.pt) * */ public class UserLoginPeriod extends UserLoginPeriod_Base implements Comparable<UserLoginPeriod> { UserLoginPeriod(User user) { setUser(user); super.setBeginDate(LocalDate.now()); } /** * Creates a {@link UserLoginPeriod} for the given {@link User} with the exact dates. * * @param user {@link User} instance * @param beginDate {@link LocalDate} when the period started * @param endDate {@link LocalDate} when the period ended */ public UserLoginPeriod(User user, LocalDate beginDate, LocalDate endDate) { setUser(Objects.requireNonNull(user)); setBeginDate(Objects.requireNonNull(beginDate, "beginDate cannot be null")); setEndDate(Objects.requireNonNull(endDate, "endDate cannot be null")); } @Override public User getUser() { // FIXME: remove when the framework supports read-only slots return super.getUser(); } @Override public LocalDate getBeginDate() { // FIXME: remove when the framework supports read-only slots return super.getBeginDate(); } @Override public LocalDate getEndDate() { // FIXME: remove when the framework supports read-only slots return super.getEndDate(); } /** * Edits this period. Changing the begin date is only allowed if the period is not already started, and changing the end date * is only allowed if such date is in the future. * * @param beginDate {@link LocalDate} when the period started * @param endDate {@link LocalDate} when the period ended */ public void edit(LocalDate beginDate, LocalDate endDate) { if (isClosed()) { throw BennuCoreDomainException.cannotEditClosedLogin(); } if (!getBeginDate().equals(beginDate) && isStarted()) { throw BennuCoreDomainException.cannotEditOpenPeriodStartDate(); } setBeginDate(beginDate); setEndDate(endDate); } /** * Returns whether this period is already closed, i.e. its end date is in the past. * * @return true if period is closed (ended), false otherwise */ public boolean isClosed() { return getEndDate() != null && getEndDate().isBefore(LocalDate.now()); } /** * Returns whether this period has already started, i.e. its begin date is not in the future. * * @return true if period has started, false otherwise */ public boolean isStarted() { return !getBeginDate().isAfter(LocalDate.now()); } /** * Returns whether this period matches exactly the given dates. * * @param beginDate start {@link LocalDate} to test against * @param endDate end {@link LocalDate} to test against * @return true if matches, false otherwise */ public boolean matches(LocalDate beginDate, LocalDate endDate) { return getBeginDate().equals(beginDate) && Objects.equals(getEndDate(), endDate); } /** * Deletes this period. If the period is already started, it throws an exception. * * @see org.fenixedu.bennu.core.domain.UserLoginPeriod#isStarted() */ public void delete() { if (isStarted()) { throw BennuCoreDomainException.cannotDeleteStartedLoginPeriod(); } else { setUser(null); deleteDomainObject(); } } @Override public int compareTo(UserLoginPeriod o) { return Comparator.comparing(UserLoginPeriod::getEndDate, Comparator.nullsLast(Comparator.<LocalDate> naturalOrder()).reversed()).compare(this, o); } @ConsistencyPredicate protected boolean checkDateInterval() { return getEndDate() == null || !getBeginDate().isAfter(getEndDate()); } }