From b76faa2411b3bf21cfac408ed9855caa2397f0c6 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Mon, 24 May 2010 16:49:10 +0200 Subject: [PATCH] ItEr58S10CUAsignacionRecursosLimitantesItEr57S11: For a generic resource allocation, split a gap into several gaps matching resourceAllocation.criteria --- .../entities/LimitingResourceAllocator.java | 128 +++++++++++++----- 1 file changed, 94 insertions(+), 34 deletions(-) diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/LimitingResourceAllocator.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/LimitingResourceAllocator.java index f9a09831a..147fd9441 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/LimitingResourceAllocator.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/LimitingResourceAllocator.java @@ -23,6 +23,7 @@ package org.navalplanner.business.planner.entities; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -84,36 +85,107 @@ public class LimitingResourceAllocator { return null; } - if (canFitIntoGap(element, gap, resource)) { + if (isSpecific(element) && gap.canFit(element)) { return gap; + } else if (isGeneric(element)){ + final List gaps = splitIntoGapsSatisfyingCriteria( + resource, getCriteria(element), gap); + for (LimitingResourceQueueElementGap subGap: gaps) { + if (subGap.canFit(element)) { + return subGap; + } + } } } while (pos <= size); return null; } - private static boolean canFitIntoGap(LimitingResourceQueueElement element, - LimitingResourceQueueElementGap gap, final Resource resource) { - - final boolean canfit = gap.canFit(element); - final ResourceAllocation resourceAllocation = element - .getResourceAllocation(); - - if (resourceAllocation instanceof SpecificResourceAllocation) { - return canfit; - } else if (resourceAllocation instanceof GenericResourceAllocation) { - // Resource must satisfy element.criteria during for the - // period of time the element will be allocated in the - // queue - final GenericResourceAllocation generic = (GenericResourceAllocation) resourceAllocation; - List dayAssignments = generateDayAssignments( - resourceAllocation, resource, gap.getStartTime()); - DateAndHour[] startAndEndTime = calculateStartAndEndTime(dayAssignments); - return canfit - && (satisfiesCriteriaDuringInterval(resource, generic - .getCriterions(), startAndEndTime)); + private void print(List criteria) { + System.out.println("### print"); + for (Criterion each: criteria) { + System.out.println("### each: " + each); } - return false; + System.out.println("### "); + } + + private static boolean isGeneric(LimitingResourceQueueElement element) { + return element.getResourceAllocation() instanceof GenericResourceAllocation; + } + + private static boolean isSpecific(LimitingResourceQueueElement element) { + return element.getResourceAllocation() instanceof SpecificResourceAllocation; + } + + private static Set getCriteria(LimitingResourceQueueElement element) { + final ResourceAllocation resourceAllocation = element.getResourceAllocation(); + if (resourceAllocation instanceof GenericResourceAllocation) { + return ((GenericResourceAllocation) resourceAllocation).getCriterions(); + } + return null; + } + + private static Date toDate(LocalDate date) { + return date != null ? date.toDateTimeAtStartOfDay().toDate() : null; + } + + private static List splitIntoGapsSatisfyingCriteria( + Resource resource, Set criteria, LimitingResourceQueueElementGap gap) { + return splitIntoGapsSatisfyingCriteria(resource, criteria, gap.getStartTime(), gap.getEndTime()); + } + + /** + * Returns a set of {@link LimitingResourceQueueElementGap} composed by those gaps + * which satisfy criteria within the period: gapStartTime till gapEndTime + * + * @param resource + * @param criteria + * criteria to be satisfied by resource + * @param gapStartTime + * start time of gap + * @param gapEndTime + * end time of gap + * @return + */ + private static List splitIntoGapsSatisfyingCriteria( + Resource resource, Set criteria, DateAndHour gapStartTime, + DateAndHour gapEndTime) { + + final ICriterion compositedCriterion = CriterionCompounder.buildAnd(criteria) + .getResult(); + final ResourceCalendar calendar = resource.getCalendar(); + + // FIXME: If endTime is null (lastGap), set endTime as 100 years ahead startTime + final LocalDate gapEndDate = gapEndTime != null ? gapEndTime.getDate().plusDays(1) + : gapStartTime.getDate().plusYears(10); + final LocalDate gapStartDate = gapStartTime.getDate(); + + List result = new ArrayList(); + + LocalDate date = gapStartDate; + boolean open = compositedCriterion.isSatisfiedBy(resource, toDate(date)); + DateAndHour startTime = gapStartTime, endTime; + while (date.isBefore(gapEndDate)) { + if (calendar.getCapacityAt(date) == 0) { + date = date.plusDays(1); + continue; + } + + if (open == false && compositedCriterion.isSatisfiedBy(resource, toDate(date))) { + startTime = new DateAndHour(date, 0); + open = true; + } + if (open == true && !compositedCriterion.isSatisfiedBy(resource, toDate(date))) { + endTime = new DateAndHour(date, 0); + result.add(LimitingResourceQueueElementGap.create(resource, + startTime, endTime)); + open = false; + } + date = date.plusDays(1); + } + result.add(LimitingResourceQueueElementGap.create(resource, startTime, gapEndTime)); + + return result; } /** @@ -135,18 +207,6 @@ public class LimitingResourceAllocator { return result; } - private static boolean satisfiesCriteriaDuringInterval(Resource resource, Set criteria, DateAndHour[] interval) { - final Date startDate = interval[0].getDate().toDateTimeAtStartOfDay().toDate(); - final Date endDate = interval[1].getDate().toDateTimeAtStartOfDay().toDate(); - return satisfiesCriteriaDuringInterval(resource, criteria, startDate, endDate); - } - - private static boolean satisfiesCriteriaDuringInterval(Resource resource, Set criteria, Date startDate, Date endDate) { - ICriterion compositedCriterion = CriterionCompounder.buildAnd(criteria) - .getResult(); - return compositedCriterion.isSatisfiedBy(resource, startDate, endDate); - } - private static LimitingResourceQueueElementGap getGapInQueueAtPosition( Resource resource, List elements, LimitingResourceQueueElement element, int pos) {