diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/Gap.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/Gap.java index 697434fc7..f3a0eebd6 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/Gap.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/limiting/entities/Gap.java @@ -21,6 +21,7 @@ package org.navalplanner.business.planner.limiting.entities; import java.util.ArrayList; +import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; @@ -33,6 +34,7 @@ import org.navalplanner.business.calendars.entities.ResourceCalendar; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionCompounder; import org.navalplanner.business.resources.entities.ICriterion; +import org.navalplanner.business.resources.entities.LimitingResourceQueue; import org.navalplanner.business.resources.entities.Resource; /** @@ -42,6 +44,43 @@ import org.navalplanner.business.resources.entities.Resource; */ public class Gap implements Comparable { + public static class GapOnQueue { + + public static List onQueue(LimitingResourceQueue queue, + Collection gaps) { + List result = new ArrayList(); + for (Gap each : gaps) { + result.add(each.onQueue(queue)); + } + return result; + } + + private final LimitingResourceQueue originQueue; + + private final Gap gap; + + GapOnQueue(LimitingResourceQueue originQueue, Gap gap) { + this.originQueue = originQueue; + this.gap = gap; + } + + public LimitingResourceQueue getOriginQueue() { + return originQueue; + } + + public Gap getGap() { + return gap; + } + + public List splitIntoGapsSatisfyingCriteria( + Set criteria) { + return GapOnQueue.onQueue(originQueue, gap + .splitIntoGapsSatisfyingCriteria(originQueue.getResource(), + criteria)); + } + + } + private DateAndHour startTime; private DateAndHour endTime; @@ -55,6 +94,10 @@ public class Gap implements Comparable { hoursInGap = calculateHoursInGap(resource, startTime, endTime); } + public GapOnQueue onQueue(LimitingResourceQueue queue) { + return new GapOnQueue(queue, this); + } + private Integer calculateHoursInGap(Resource resource, DateAndHour startTime, DateAndHour endTime) { return (endTime == null) ? Integer.MAX_VALUE : calculateHoursInGap( resource, startTime.getDate(), startTime.getHour(), endTime diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/LimitingResourceQueue.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/LimitingResourceQueue.java index 6a10a3e9c..2974473cf 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/LimitingResourceQueue.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/LimitingResourceQueue.java @@ -20,12 +20,18 @@ package org.navalplanner.business.resources.entities; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import org.navalplanner.business.common.BaseEntity; +import org.navalplanner.business.planner.limiting.entities.DateAndHour; +import org.navalplanner.business.planner.limiting.entities.Gap; +import org.navalplanner.business.planner.limiting.entities.GapRequirements; import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement; +import org.navalplanner.business.planner.limiting.entities.Gap.GapOnQueue; /** * @@ -39,6 +45,8 @@ public class LimitingResourceQueue extends BaseEntity { private SortedSet limitingResourceQueueElements = new TreeSet(new LimitingResourceQueueElementComparator()); + private List cachedGaps; + public static LimitingResourceQueue create() { return create(new LimitingResourceQueue()); } @@ -58,15 +66,53 @@ public class LimitingResourceQueue extends BaseEntity { public void addLimitingResourceQueueElement(LimitingResourceQueueElement element) { element.setLimitingResourceQueue(this); limitingResourceQueueElements.add(element); + cachedGaps = null; } public void removeLimitingResourceQueueElement(LimitingResourceQueueElement element) { limitingResourceQueueElements.remove(element); element.detach(); + cachedGaps = null; + } + + public List getGaps() { + if (cachedGaps == null) { + cachedGaps = calculateGaps(); + } + return cachedGaps; + } + + private List calculateGaps() { + List result = new ArrayList(); + DateAndHour previousEnd = null; + for (LimitingResourceQueueElement each : limitingResourceQueueElements) { + DateAndHour startTime = each.getStartTime(); + if (startTime.isAfter(startTime)) { + result.add(Gap.create(resource, previousEnd, startTime)); + } + previousEnd = each.getEndTime(); + } + result.add(Gap.create(resource, previousEnd, null)); + return GapOnQueue.onQueue(this, result); } public SortedSet getLimitingResourceQueueElements() { return Collections.unmodifiableSortedSet(limitingResourceQueueElements); } + /** + * @return the gaps that could potentially be valid for + * requirements ordered by start date + */ + public List getGapsPotentiallyValidFor( + GapRequirements requirements) { + List result = new ArrayList(); + for (GapOnQueue each : getGaps()) { + if (requirements.isPotentiallyValid(each.getGap())) { + result.add(each); + } + } + return result; + } + }