/* * This file is part of LibrePlan * * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e * Desenvolvemento Tecnolóxico de Galicia * Copyright (C) 2010-2011 Igalia, S.L. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.libreplan.business.resources.entities; import java.util.Comparator; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.ToStringBuilder; import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotNull; import org.joda.time.LocalDate; import org.libreplan.business.common.IntegrationEntity; import org.libreplan.business.common.Registry; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.resources.daos.ICriterionSatisfactionDAO; import org.libreplan.business.resources.daos.ICriterionTypeDAO; /** * Declares a interval of time in which the criterion is satisfied. * <br /> * * @author Óscar González Fernández <ogonzalez@igalia.com> * @author Fernando Bellas Permuy <fbellas@udc.es> */ public class CriterionSatisfaction extends IntegrationEntity { public static final Comparator<CriterionSatisfaction> BY_START_COMPARATOR; static { BY_START_COMPARATOR = new Comparator<CriterionSatisfaction>() { @Override public int compare(CriterionSatisfaction o1, CriterionSatisfaction o2) { return o1.getStartDate().compareTo(o2.getStartDate()); } }; } private LocalDate startDate; private LocalDate finishDate; private Criterion criterion; private Resource resource; private Boolean isDeleted = false; /** * Constructor for hibernate. Do not use! */ public CriterionSatisfaction() {} private CriterionSatisfaction(LocalDate startDate, Criterion criterion, Resource resource) { Validate.notNull(startDate, "startDate must be not null"); Validate.notNull(criterion, "criterion must be not null"); Validate.notNull(resource, "resource must be not null"); this.startDate = startDate; this.criterion = criterion; this.resource = resource; } private CriterionSatisfaction(Criterion criterion, Resource resource, Interval interval) { this(interval.getStart(), criterion, resource); if (interval.getEnd() != null) { this.finish(interval.getEnd()); } } public static CriterionSatisfaction create() { return create(new CriterionSatisfaction()); } public static CriterionSatisfaction create(LocalDate startDate, Criterion criterion, Resource resource) { return create(new CriterionSatisfaction(startDate, criterion, resource)); } public static CriterionSatisfaction create(Criterion criterion, Resource resource, Interval interval) { return create(new CriterionSatisfaction(criterion, resource, interval)); } /** * @throws InstanceNotFoundException if criterion type or criterion does * not exist */ public static CriterionSatisfaction createUnvalidated(String code, String criterionTypeName, String criterionName, Resource resource, LocalDate startDate, LocalDate finishDate) throws InstanceNotFoundException { ICriterionTypeDAO criterionTypeDAO = Registry.getCriterionTypeDAO(); /* Get CriterionType */ CriterionType criterionType = criterionTypeDAO.findUniqueByName(criterionTypeName); /* Get Criterion */ Criterion criterion = criterionType.getCriterion(criterionName); /* Create instance of CriterionSatisfaction */ CriterionSatisfaction criterionSatisfaction = create(new CriterionSatisfaction(), code); criterionSatisfaction.criterion = criterion; criterionSatisfaction.resource = resource; criterionSatisfaction.startDate = startDate; criterionSatisfaction.finishDate = finishDate; return criterionSatisfaction; } /** * @throws InstanceNotFoundException if criterion type or criterion does * not exist */ public void updateUnvalidated(String criterionTypeName, String criterionName, LocalDate startDate, LocalDate finishDate) throws InstanceNotFoundException { CriterionType criterionType; if (StringUtils.isBlank(criterionTypeName)) { criterionType = criterion.getType(); } else { criterionType = Registry.getCriterionTypeDAO().findUniqueByName(criterionTypeName); } String newCriterionName; if (StringUtils.isBlank(criterionName)) { newCriterionName = StringUtils.trim(criterion.getName()); } else { newCriterionName = criterionName; } this.criterion = criterionType.getCriterion(newCriterionName); if (startDate != null) { this.startDate = startDate; } if (finishDate != null) { this.finishDate = finishDate; } } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } public CriterionSatisfaction copy() { CriterionSatisfaction result = create(); result.startDate = startDate; result.finishDate = finishDate; result.criterion = criterion; result.resource = resource; return result; } @NotNull(message="start date not specified") public LocalDate getStartDate() { return startDate; } public LocalDate getEndDate() { return finishDate; } public Interval getInterval() { return Interval.range(startDate, finishDate); } @NotNull(message="criterion not specified") public Criterion getCriterion() { return criterion; } public void setCriterion(Criterion criterion) { this.criterion = criterion; } @NotNull(message="resource not specified") public Resource getResource() { return resource; } public void setResource(Resource resource) { this.resource = resource; } public boolean isCurrent() { LocalDate today = new LocalDate(); return isEnforcedAt(today); } public boolean isEnforcedAt(LocalDate date) { return getInterval().contains(date); } public boolean isAlwaysEnforcedIn(Interval interval) { return getInterval().includes(interval); } public void finish(LocalDate finish) { Validate.notNull(finish); Validate.isTrue(getStartDate() == null || getStartDate().compareTo(finish) <= 0); Validate.isTrue( finishDate == null || isNewObject() || getEndDate().equals(finish) || getEndDate().isBefore(finish)); this.finishDate = finish; } public void noFinish() { this.finishDate = null; } public boolean isFinished() { return finishDate != null; } public void setEndDate(LocalDate date) { if (date != null) { finish(date); } this.finishDate = date; } public void setStartDate(LocalDate date) { if(date != null) { Validate.isTrue( startDate == null || isNewObject() || getStartDate().equals(date) || getStartDate().isAfter(date)); } startDate = date; } public void setIsDeleted(boolean isDeleted) { this.isDeleted = isDeleted; } public boolean isIsDeleted() { return isDeleted == null ? false : isDeleted; } public boolean overlapsWith(Interval interval) { return getInterval().overlapsWith(interval); } public boolean goesBeforeWithoutOverlapping(CriterionSatisfaction other) { int compare = BY_START_COMPARATOR.compare(this, other); if (compare > 0) { return false; } else { Interval thisInterval = getInterval(); return !thisInterval.overlapsWith(other.getInterval()); } } public ResourceEnum getResourceType() { return criterion.getType().getResource(); } @AssertTrue(message = "criterion satisfaction with end date before start") public boolean isPositiveTimeInterval() { /* Check if it makes sense to check the constraint */ if (!isStartDateSpecified()) { return true; } /* Check the constraint */ if (finishDate == null) { return true; } return finishDate.isAfter(startDate) || startDate.equals(finishDate); } public boolean isStartDateSpecified() { return startDate != null; } @Override protected ICriterionSatisfactionDAO getIntegrationEntityDAO() { return Registry.getCriterionSatisfactionDAO(); } }