/* * 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.planner.limiting.entities; import static org.libreplan.business.i18n.I18nHelper._; import java.util.EnumMap; import org.apache.commons.lang3.Validate; import org.libreplan.business.common.BaseEntity; import org.libreplan.business.planner.entities.Dependency; import org.libreplan.business.planner.entities.Dependency.Type; /** * Entity which represents the relationships between two * @{link LimitingResourceQueueElement}. One of the * @{link LimitingResourceQueueElement} is the origin of the relationship * and the other is the destiny of the relationship. * * @author Javier Moran Rua <jmoran@igalia.com> * */ public class LimitingResourceQueueDependency extends BaseEntity { public static enum QueueDependencyType { START_START(Type.START_START), END_START(Type.END_START), END_END(Type.END_END), START_END(Type.START_END); private static EnumMap<Type, QueueDependencyType> toQueueDependencyType; private static EnumMap<QueueDependencyType, Type> toDependencyType; static { toQueueDependencyType = new EnumMap<Type, QueueDependencyType>( Type.class); toDependencyType = new EnumMap<QueueDependencyType, Type>( QueueDependencyType.class); for (QueueDependencyType each : QueueDependencyType.values()) { toQueueDependencyType.put(each.associatedType, each); toDependencyType.put(each, each.associatedType); } } public static LimitingResourceQueueDependency.QueueDependencyType toQueueDependencyType( Type type) { return toQueueDependencyType.get(type); } public static Type toDependencyType(QueueDependencyType type) { return toDependencyType.get(type); } private final Type associatedType; private QueueDependencyType(Type associatedType) { this.associatedType = associatedType; } boolean propagatesThrough(QueueDependencyType nextType) { switch (this) { case END_START: case START_START: return true; case START_END: case END_END: return nextType.comesFromEnd(); default: throw new RuntimeException("unknown type: " + this); } } private boolean comesFromEnd() { switch (this) { case START_END: case START_START: return false; case END_START: case END_END: return true; default: throw new RuntimeException("unknown type: " + this); } } private Dependency.Type getDependencyType() { return QueueDependencyType.toDependencyType(this); } public boolean modifiesDestinationStart() { return getDependencyType().modifiesDestinationStart(); } public boolean modifiesDestinationEnd() { return getDependencyType().modifiesDestinationEnd(); } public DateAndHour calculateDateTargetFrom(DateAndHour previousStartTime, DateAndHour previousEndTime) { switch (this) { case START_END: case START_START: return previousStartTime; case END_END: case END_START: return previousEndTime; default: throw new RuntimeException("unknown type: " + this); } } }; public static LimitingResourceQueueDependency.QueueDependencyType toQueueDependencyType( Dependency.Type type) { return QueueDependencyType.toQueueDependencyType(type); } private LimitingResourceQueueElement hasAsOrigin; private LimitingResourceQueueElement hasAsDestiny; private Dependency ganttDependency; private QueueDependencyType type; public static LimitingResourceQueueDependency create( LimitingResourceQueueElement origin, LimitingResourceQueueElement destiny, Dependency ganttDependency, QueueDependencyType type) { LimitingResourceQueueDependency dependency = new LimitingResourceQueueDependency(origin,destiny,ganttDependency,type); dependency.setNewObject(true); origin.add(dependency); destiny.add(dependency); ganttDependency.setQueueDependency(dependency); return dependency; } /** * Contructor for Hibernate. Do not use ! */ public LimitingResourceQueueDependency() {} private LimitingResourceQueueDependency(LimitingResourceQueueElement origin, LimitingResourceQueueElement destiny, Dependency ganttDependency, QueueDependencyType type) { Validate.notNull(origin); Validate.notNull(destiny); Validate.notNull(ganttDependency); Validate.isTrue(!origin.equals(destiny), _("A queue dependency has to " + "have an origin different from destiny")); this.hasAsOrigin = origin; this.hasAsDestiny = destiny; this.ganttDependency = ganttDependency; this.type = type; } public LimitingResourceQueueElement getHasAsOrigin() { return hasAsOrigin; } public void setOrigin(LimitingResourceQueueElement origin) { this.hasAsOrigin = origin; } public LimitingResourceQueueElement getHasAsDestiny() { return hasAsDestiny; } public void setDestiny(LimitingResourceQueueElement destiny) { this.hasAsDestiny = destiny; } public QueueDependencyType getType() { return type; } public Dependency getGanttDependency() { return ganttDependency; } public boolean isOriginNotDetached() { return !hasAsOrigin.isDetached(); } public boolean modifiesDestinationStart() { return type.modifiesDestinationStart(); } public boolean modifiesDestinationEnd() { return type.modifiesDestinationEnd(); } public DateAndHour getDateFromOrigin() { if (hasAsOrigin.isDetached()) { throw new IllegalStateException("origin detached"); } return type.calculateDateTargetFrom(hasAsOrigin.getStartTime(), hasAsOrigin .getEndTime()); } public boolean propagatesThrough(LimitingResourceQueueDependency transitive) { return getHasAsDestiny().equals(transitive.getHasAsOrigin()) && type.propagatesThrough(transitive.getType()); } }