From cbfe6fe18875a47fb28ea7ed1ea694423a52c22f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Sun, 28 Feb 2010 17:00:32 +0100 Subject: [PATCH] ItEr49S10CUVisualizacionResponsabilidadesTRaballoNaPlanificacionItEr48S10: Now can calculate the valid intervals for a AvailabilityTimeLine --- .../entities/AvailabilityTimeLine.java | 38 ++++- .../entities/AvailabilityTimeLineTest.java | 137 +++++++++++++++++- 2 files changed, 168 insertions(+), 7 deletions(-) diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/AvailabilityTimeLine.java b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/AvailabilityTimeLine.java index 4097b11b5..2644aed99 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/AvailabilityTimeLine.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/calendars/entities/AvailabilityTimeLine.java @@ -34,7 +34,7 @@ import org.joda.time.LocalDate; */ public class AvailabilityTimeLine { - private static abstract class DatePoint implements Comparable { + public static abstract class DatePoint implements Comparable { protected abstract int compareTo(FixedPoint fixedPoint); @@ -86,10 +86,10 @@ public class AvailabilityTimeLine { } - private static class FixedPoint extends DatePoint { + public static class FixedPoint extends DatePoint { private final LocalDate date; - private FixedPoint(LocalDate date) { + public FixedPoint(LocalDate date) { Validate.notNull(date); this.date = date; } @@ -135,7 +135,7 @@ public class AvailabilityTimeLine { } } - private static class EndOfTime extends DatePoint { + public static class EndOfTime extends DatePoint { private static final EndOfTime INSTANCE = new EndOfTime(); public static EndOfTime create() { @@ -184,7 +184,7 @@ public class AvailabilityTimeLine { } - private static class StartOfTime extends DatePoint { + public static class StartOfTime extends DatePoint { private static final StartOfTime INSTANCE = new StartOfTime(); public static StartOfTime create() { @@ -232,7 +232,7 @@ public class AvailabilityTimeLine { } } - private static class Interval implements + public static class Interval implements Comparable { static Interval create(LocalDate start, LocalDate end) { @@ -267,6 +267,14 @@ public class AvailabilityTimeLine { this.end = end; } + public DatePoint getStart() { + return start; + } + + public DatePoint getEnd() { + return end; + } + @Override public int compareTo(Interval other) { return this.start.compareTo(other.start) * 2 @@ -433,4 +441,22 @@ public class AvailabilityTimeLine { result.insert(each); } } + + public List getValidPeriods() { + List result = new ArrayList(); + DatePoint previous = StartOfTime.create(); + for (Interval each : invalids) { + DatePoint invalidStart = each.start; + if (!invalidStart.equals(StartOfTime.create()) + && !invalidStart.equals(EndOfTime.create())) { + result.add(new Interval(previous, invalidStart)); + } + previous = each.getEnd(); + } + if (!previous.equals(EndOfTime.create())) { + result.add(new Interval(previous, EndOfTime.create())); + } + return result; + } + } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/AvailabilityTimeLineTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/AvailabilityTimeLineTest.java index 59ea6e1d3..b9da4449a 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/AvailabilityTimeLineTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/calendars/entities/AvailabilityTimeLineTest.java @@ -21,15 +21,27 @@ package org.navalplanner.business.test.calendars.entities; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; import org.joda.time.LocalDate; import org.junit.Test; import org.navalplanner.business.calendars.entities.AvailabilityTimeLine; +import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.DatePoint; +import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.EndOfTime; +import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.FixedPoint; +import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.Interval; +import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.StartOfTime; /** * @author Óscar González Fernández - * */ public class AvailabilityTimeLineTest { @@ -221,4 +233,127 @@ public class AvailabilityTimeLineTest { current = current.plusDays(1); } } + + @Test + public void anAllValidPeriodsGeneratesAnAllEncompassingInterval() { + AvailabilityTimeLine timeLine = AvailabilityTimeLine.allValid(); + List validPeriods = timeLine.getValidPeriods(); + + assertThat(validPeriods, definedBy(StartOfTime.create(), EndOfTime + .create())); + } + + @Test + public void anInvalidPeriodUntilGeneratesAValidIntervalAfterwards() { + AvailabilityTimeLine timeLine = AvailabilityTimeLine.allValid(); + timeLine.invalidUntil(contemporaryExample); + List validPeriods = timeLine.getValidPeriods(); + + assertThat(validPeriods, definedBy(point(contemporaryExample), + EndOfTime.create())); + } + + @Test + public void anInvalidFromPeriodGeneratesAValidIntervalBefore() { + AvailabilityTimeLine timeLine = AvailabilityTimeLine.allValid(); + timeLine.invalidFrom(contemporaryExample); + List validPeriods = timeLine.getValidPeriods(); + + assertThat(validPeriods, definedBy(StartOfTime.create(), + new FixedPoint(contemporaryExample))); + } + + @Test + public void anInvalidityPeriodGeneratesTwoValidIntervals() { + AvailabilityTimeLine timeLine = AvailabilityTimeLine.allValid(); + timeLine.invalidAt(contemporaryExample, lateExample); + List validPeriods = timeLine.getValidPeriods(); + + assertThat(validPeriods, definedBy(StartOfTime.create(), + point(contemporaryExample), point(lateExample), EndOfTime + .create())); + } + + @Test + public void anAllInvalidTimelineGeneratesZeroValidIntervals() { + AvailabilityTimeLine timeLine = AvailabilityTimeLine.allValid(); + timeLine.allInvalid(); + assertTrue(timeLine.getValidPeriods().isEmpty()); + } + + @Test + public void anInvalidPointGeneratesTwoValidPeriods() { + AvailabilityTimeLine timeLine = AvailabilityTimeLine.allValid(); + timeLine.invalidAt(contemporaryExample); + assertThat(timeLine.getValidPeriods(), definedBy(StartOfTime.create(), + point(contemporaryExample), point(contemporaryExample + .plusDays(1)), EndOfTime.create())); + } + + private static FixedPoint point(LocalDate param) { + return new FixedPoint(param); + } + + @Test + public void aCombinationOfSeveralInvalidPeriods() { + AvailabilityTimeLine timeLine = AvailabilityTimeLine.allValid(); + timeLine.invalidUntil(earlyExample); + timeLine.invalidAt(contemporaryExample, lateExample); + timeLine.invalidFrom(lateExample.plusDays(10)); + assertThat(timeLine.getValidPeriods(), definedBy(point(earlyExample), + point(contemporaryExample), point(lateExample), + point(lateExample.plusDays(10)))); + } + + private static Matcher> definedBy(final DatePoint... points) { + Validate.isTrue(points.length % 2 == 0, + "number of points provided must be even"); + return new BaseMatcher>() { + + @SuppressWarnings("unchecked") + @Override + public boolean matches(Object object) { + if (object instanceof List) { + List intervals = (List) object; + List pairsOfPoints = pointsAsPairs(); + for (int i = 0; i < intervals.size(); i++) { + Interval interval = intervals.get(i); + DatePoint[] pair = pairsOfPoints.get(i); + if (!(pair[0].equals(interval.getStart()) && pair[1] + .equals(interval.getEnd()))) { + return false; + } + } + return true; + } + return false; + } + + private List pointsAsPairs() { + List result = new ArrayList(); + for (int i = 0; i < points.length / 2; i++) { + DatePoint[] pair = { points[i * 2], points[i * 2 + 1] }; + result.add(pair); + } + return result; + } + + @Override + public void describeTo(Description description) { + StringBuilder text = new StringBuilder(); + boolean first = true; + for (DatePoint[] each : pointsAsPairs()) { + DatePoint start = each[0]; + DatePoint end = each[1]; + if (!first) { + text.append(", "); + } + text.append(String.format("[%s, %s]", start, end)); + first = false; + } + description.appendText(text.toString()); + } + }; + } + }