List of usage examples for com.google.common.collect Range encloseAll
public static <C extends Comparable<?>> Range<C> encloseAll(Iterable<C> values)
From source file:net.sourceforge.ganttproject.task.algorithm.SchedulerImpl.java
private void schedule(Node node) { Logger logger = GPLogger.getLogger(this); GPLogger.debug(logger, "Scheduling node %s", node); Range<Date> startRange = Range.all(); Range<Date> endRange = Range.all(); Range<Date> weakStartRange = Range.all(); Range<Date> weakEndRange = Range.all(); List<Date> subtaskRanges = Lists.newArrayList(); List<DependencyEdge> incoming = node.getIncoming(); GPLogger.debug(logger, ".. #incoming edges=%d", incoming.size()); for (DependencyEdge edge : incoming) { if (!edge.refresh()) { continue; }//from w w w. j av a 2 s . c o m if (edge instanceof ImplicitSubSuperTaskDependency) { subtaskRanges.add(edge.getStartRange().upperEndpoint()); subtaskRanges.add(edge.getEndRange().lowerEndpoint()); } else { if (edge.isWeak()) { weakStartRange = weakStartRange.intersection(edge.getStartRange()); weakEndRange = weakEndRange.intersection(edge.getEndRange()); } else { startRange = startRange.intersection(edge.getStartRange()); endRange = endRange.intersection(edge.getEndRange()); } } if (startRange.isEmpty() || endRange.isEmpty()) { GPLogger.logToLogger("both start and end ranges were calculated as empty for task=" + node.getTask() + ". Skipping it"); } } GPLogger.debug(logger, "..Ranges: start=%s end=%s weakStart=%s weakEnd=%s", startRange, endRange, weakStartRange, weakEndRange); Range<Date> subtasksSpan = subtaskRanges.isEmpty() ? Range.closed(node.getTask().getStart().getTime(), node.getTask().getEnd().getTime()) : Range.encloseAll(subtaskRanges); Range<Date> subtreeStartUpwards = subtasksSpan .span(Range.downTo(node.getTask().getStart().getTime(), BoundType.CLOSED)); Range<Date> subtreeEndDownwards = subtasksSpan .span(Range.upTo(node.getTask().getEnd().getTime(), BoundType.CLOSED)); GPLogger.debug(logger, "..Subtasks span=%s", subtasksSpan); if (!startRange.equals(Range.all())) { startRange = startRange.intersection(weakStartRange); } else if (!weakStartRange.equals(Range.all())) { startRange = weakStartRange.intersection(subtreeStartUpwards); } if (!endRange.equals(Range.all())) { endRange = endRange.intersection(weakEndRange); } else if (!weakEndRange.equals(Range.all())) { endRange = weakEndRange.intersection(subtreeEndDownwards); } if (node.getTask().getThirdDateConstraint() == TaskImpl.EARLIESTBEGIN && node.getTask().getThird() != null) { startRange = startRange .intersection(Range.downTo(node.getTask().getThird().getTime(), BoundType.CLOSED)); GPLogger.debug(logger, ".. applying earliest start=%s. Now start range=%s", node.getTask().getThird(), startRange); } if (!subtaskRanges.isEmpty()) { startRange = startRange.intersection(subtasksSpan); endRange = endRange.intersection(subtasksSpan); } GPLogger.debug(logger, ".. finally, start range=%s", startRange); if (startRange.hasLowerBound()) { modifyTaskStart(node.getTask(), startRange.lowerEndpoint()); } if (endRange.hasUpperBound()) { GPCalendarCalc cal = node.getTask().getManager().getCalendar(); Date endDate = endRange.upperEndpoint(); TimeUnit timeUnit = node.getTask().getDuration().getTimeUnit(); if (DayMask.WORKING == (cal.getDayMask(endDate) & DayMask.WORKING)) { // in case if calculated end date falls on first day after holidays (say, on Monday) // we'll want to modify it a little bit, so that it falls on that holidays start // If we don't do this, it will be done automatically the next time task activities are recalculated, // and thus task end date will keep changing Date closestWorkingEndDate = cal.findClosest(endDate, timeUnit, GPCalendarCalc.MoveDirection.BACKWARD, GPCalendar.DayType.WORKING); Date closestNonWorkingEndDate = cal.findClosest(endDate, timeUnit, GPCalendarCalc.MoveDirection.BACKWARD, GPCalendar.DayType.NON_WORKING, closestWorkingEndDate); // If there is a non-working date between current task end and closest working date // then we're really just after holidays if (closestNonWorkingEndDate != null && closestWorkingEndDate.before(closestNonWorkingEndDate)) { // we need to adjust-right closest working date to position to the very beginning of the holidays interval Date nonWorkingPeriodStart = timeUnit.adjustRight(closestWorkingEndDate); if (nonWorkingPeriodStart.after(node.getTask().getStart().getTime())) { endDate = nonWorkingPeriodStart; } } } modifyTaskEnd(node.getTask(), endDate); } }