diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/GriddedTimingSelectionPresenter.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/GriddedTimingSelectionPresenter.java index 29cefc9159..e7ab74b795 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/GriddedTimingSelectionPresenter.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/subset/presenter/GriddedTimingSelectionPresenter.java @@ -19,8 +19,8 @@ **/ package com.raytheon.uf.viz.datadelivery.subscription.subset.presenter; -import java.util.ArrayList; -import java.util.Collections; +import static com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils.getMaxLatency; + import java.util.List; import com.google.common.annotations.VisibleForTesting; @@ -44,6 +44,7 @@ import com.raytheon.viz.ui.presenter.components.ListConf; * Sep 27, 2012 1202 bgonzale Set selectionDate to date and cycle. * Oct 11, 2012 1263 jpiatt Modified for cancel flag. * Jan 04, 2013 1420 mpduff Add the dataset object. + * Jan 22, 2013 1519 djohnson Use DataDeliveryUtils.getMaxLatency(). * * * @@ -173,7 +174,7 @@ public class GriddedTimingSelectionPresenter { } DataDeliveryGUIUtils.latencyValidChk(view.getLatency(), - getMaxLatency()); + getMaxLatency(dataSet)); // parse off the date/cycle time selected String[] parts = selection.split(" - "); @@ -188,29 +189,6 @@ public class GriddedTimingSelectionPresenter { return true; } - /** - * Max latency value in minutes. - * - * @return - */ - private int getMaxLatency() { - List cycleList = new ArrayList(dataSet.getCycles()); - Collections.sort(cycleList); - - int max = 0; - - for (int i = 0; i < cycleList.size(); i++) { - if (i + 1 <= cycleList.size()) { - int tempMax = cycleList.get(i + 1) - cycleList.get(i); - if (tempMax > max) { - max = tempMax; - } - } - } - - return max * 60; - } - /** * This method is called via the "Use Latest Data" checkbox being * selected/unselected. diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtils.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtils.java index 4c6a91e566..ccca8f2a19 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtils.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtils.java @@ -32,6 +32,7 @@ import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.datadelivery.registry.Coverage; import com.raytheon.uf.common.datadelivery.registry.DataLevelType; +import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet; import com.raytheon.uf.common.datadelivery.registry.Parameter; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.Time; @@ -57,10 +58,11 @@ import com.vividsolutions.jts.geom.Coordinate; * Jul 25, 2012 955 djohnson Use List instead of ArrayList, thread-safe access to DecimalFormat. * Aug 29, 2012 223 mpduff Add cycles to the subscription details. * Oct 31, 2012 1278 mpduff Moved spatial methods to SpatialUtils. - * Nov 20, 2012 1286 djohnson Add showYesNoMessage. - * Dec 20, 2012 1413 bgonzale Added PendingSubColumnNames.valueOfColumnName(String). - * Jan 10, 2013 1420 mdpuff Added getMaxLatency(). + * Nov 20, 2012 1286 djohnson Add showYesNoMessage. + * Dec 20, 2012 1413 bgonzale Added PendingSubColumnNames.valueOfColumnName(String). + * Jan 10, 2013 1420 mdpuff Added getMaxLatency(). * Jan 14, 2013 1286 djohnson Fix IndexOutOfBounds exception from getMaxLatency. + * Jan 22, 2013 1519 djohnson Correct getMaxLatency() calculations. * * * @author mpduff @@ -69,6 +71,18 @@ import com.vividsolutions.jts.geom.Coordinate; public class DataDeliveryUtils { + /** + * Default latency applied to hourly datasets. + */ + public static final int HOURLY_DATASET_LATENCY_IN_MINUTES = 40; + + /** + * Default latency applied non-hourly datasets. + */ + public static final int NON_HOURLY_DATASET_LATENCY_IN_MINUTES = 75; + + private static final int UNSET = -1; + /** Decimal format */ private final static ThreadLocal format = new ThreadLocal() { @@ -551,20 +565,48 @@ public class DataDeliveryUtils { * @return the maximum latency in minutes */ public static int getMaxLatency(Subscription subscription) { - List cycles = subscription.getTime().getCycleTimes(); + return getMaxLatency(subscription.getTime().getCycleTimes()); + } + + /** + * Get the maximum latency for the provided cycles. Calculated as the + * maximum cyclic difference. + * + * @param cycles + * The list of cycles + * @return the maximum latency in minutes + */ + public static int getMaxLatency(List cycles) { Collections.sort(cycles); - int max = TimeUtil.HOURS_PER_DAY * TimeUtil.MINUTES_PER_HOUR; + int maximumTimeBetweenCycles = UNSET; final int size = cycles.size(); for (int i = 0; i < size; i++) { final int nextIndex = i + 1; if (nextIndex < size) { int tempMax = cycles.get(nextIndex) - cycles.get(i); - if (tempMax > max) { - max = tempMax; - } + maximumTimeBetweenCycles = Math.max(maximumTimeBetweenCycles, tempMax); } } - return max; + + // If there was only one cycle, then default to the number of minutes in + // the day + if (maximumTimeBetweenCycles == UNSET) { + maximumTimeBetweenCycles = TimeUtil.HOURS_PER_DAY; + } + + return maximumTimeBetweenCycles * TimeUtil.MINUTES_PER_HOUR; + } + + /** + * Get the maximum latency for the provided dataSet. Calculated as the + * maximum cyclic difference. + * + * @param dataSet + * the dataset + * @return the maximum latency in minutes + */ + public static int getMaxLatency(GriddedDataSet dataSet) { + return getMaxLatency(new ArrayList(dataSet.getCycles())); } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSetFrequency.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSetFrequency.java index e655eec99e..70d49d782c 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSetFrequency.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/utils/DataSetFrequency.java @@ -21,6 +21,8 @@ package com.raytheon.uf.viz.datadelivery.utils; import java.util.List; +import com.raytheon.uf.common.time.util.TimeUtil; + /** * Data Set Frequency Enumeration. * @@ -30,7 +32,8 @@ import java.util.List; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 8, 2013 1420 mpduff Initial creation. + * Jan 08, 2013 1420 mpduff Initial creation. + * Jan 22, 2013 1519 djohnson Correct the non-hourly default latency to match requirements. * * * @@ -39,8 +42,11 @@ import java.util.List; */ public enum DataSetFrequency { - HOURLY(40), SIX_HOURLY(115), TWELVE_HOURLY(115), DAILY(115); - + HOURLY(DataDeliveryUtils.HOURLY_DATASET_LATENCY_IN_MINUTES), SIX_HOURLY( + DataDeliveryUtils.NON_HOURLY_DATASET_LATENCY_IN_MINUTES), TWELVE_HOURLY( + DataDeliveryUtils.NON_HOURLY_DATASET_LATENCY_IN_MINUTES), DAILY( + DataDeliveryUtils.NON_HOURLY_DATASET_LATENCY_IN_MINUTES); + private int defaultLatency; private DataSetFrequency(int defaultLatency) { @@ -49,13 +55,14 @@ public enum DataSetFrequency { public static DataSetFrequency fromCycleTimes(List cycleTimes) { if (cycleTimes.size() > 1) { - if ((cycleTimes.get(1) - cycleTimes.get(0)) == 1) { + final int hoursBetweenCycles = cycleTimes.get(1) - cycleTimes.get(0); + if (hoursBetweenCycles == 1) { return DataSetFrequency.HOURLY; - } else if ((cycleTimes.get(1) - cycleTimes.get(0)) == 6) { + } else if (hoursBetweenCycles == TimeUtil.HOURS_PER_QUARTER_DAY) { return DataSetFrequency.SIX_HOURLY; - } else if ((cycleTimes.get(1) - cycleTimes.get(0)) == 12) { + } else if (hoursBetweenCycles == TimeUtil.HOURS_PER_HALF_DAY) { return DataSetFrequency.TWELVE_HOURLY; - } else if ((cycleTimes.get(1) - cycleTimes.get(0)) == 24) { + } else if (hoursBetweenCycles == TimeUtil.HOURS_PER_DAY) { return DataSetFrequency.DAILY; } } diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimeUtil.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimeUtil.java index aa760e8c2a..d7555357a5 100644 --- a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimeUtil.java +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/util/TimeUtil.java @@ -45,14 +45,14 @@ import com.raytheon.uf.common.time.domain.api.ITimePoint; * Nov 21, 2012 728 mpduff Added MILLIS_PER_MONTH. * Jan 07, 2013 1451 djohnson Add newGmtCalendar() and time constants. * Jan 22, 2013 1484 mpduff Add HOURS_PER_WEEK. + * Jan 22, 2013 1519 djohnson Add MINUTES_PER_DAY. * * * * @author njensen * @version 1.0 */ - -public class TimeUtil { +public final class TimeUtil { /** * A clock that does not really return the current time. Useful when you @@ -97,6 +97,12 @@ public class TimeUtil { public static final int HOURS_PER_DAY = 24; + public static final int HOURS_PER_HALF_DAY = HOURS_PER_DAY / 2; + + public static final int HOURS_PER_QUARTER_DAY = HOURS_PER_HALF_DAY / 2; + + public static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY; + private static final int DAYS_PER_WEEK = 7; public static final int HOURS_PER_WEEK = HOURS_PER_DAY * DAYS_PER_WEEK; @@ -385,4 +391,10 @@ public class TimeUtil { } return calendar; } + + /** + * Disabled constructor. + */ + private TimeUtil() { + } } diff --git a/tests/unit/com/raytheon/uf/common/datadelivery/registry/OpenDapGriddedDataSetFixture.java b/tests/unit/com/raytheon/uf/common/datadelivery/registry/OpenDapGriddedDataSetFixture.java index 12c01faea7..1e522d47ca 100644 --- a/tests/unit/com/raytheon/uf/common/datadelivery/registry/OpenDapGriddedDataSetFixture.java +++ b/tests/unit/com/raytheon/uf/common/datadelivery/registry/OpenDapGriddedDataSetFixture.java @@ -76,6 +76,7 @@ public class OpenDapGriddedDataSetFixture extends obj.setDataSetName("dataSetName" + seedValue); obj.setDataSetType(DataType.GRID); obj.setForecastHours(CollectionUtil.asSet(0)); + obj.setTime(TimeFixture.INSTANCE.get(seedValue)); // TODO: ParameterFixture obj.setParameters(Collections. emptyMap()); obj.setProviderName(ProviderFixture.INSTANCE.get(seedValue).getName()); diff --git a/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtilsTest.java b/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtilsTest.java index 1af63c3f8b..afb47cae91 100644 --- a/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtilsTest.java +++ b/tests/unit/com/raytheon/uf/viz/datadelivery/utils/DataDeliveryUtilsTest.java @@ -20,17 +20,23 @@ package com.raytheon.uf.viz.datadelivery.utils; import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Sets.newHashSet; +import static org.junit.Assert.assertEquals; import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; import org.junit.Test; +import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSet; +import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSetFixture; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture; import com.raytheon.uf.common.datadelivery.registry.Time; /** - * TODO Add Description + * Test {@link DataDeliveryUtils}. * *
  * 
@@ -39,31 +45,75 @@ import com.raytheon.uf.common.datadelivery.registry.Time;
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Jan 14, 2013 1286       djohnson     Initial creation
+ * Jan 22, 2013 1519       djohnson     Add tests for getMaxLatency calculations.
  * 
  * 
* * @author djohnson * @version 1.0 */ - public class DataDeliveryUtilsTest { - /** - * The method was throwing {@link IndexOutOfBoundsException}, this will - * prevent that regression. - */ + // These constants are not using TimeUtil to make sure we get a + // "second opinion" when using TimeUtil in the code under test + private static final long THREE_HOURS_AS_MINUTES = TimeUnit.HOURS + .toMinutes(3); + + private static final long MINUTES_PER_DAY = TimeUnit.DAYS.toMinutes(1); + @Test - public void testMaxLatencyDoesntOverrunListIndex() { + public void maxLatencyReturnsMaxCyclicDifferenceForSubscribedToCycles() { List cycleTimes = newArrayList(); cycleTimes.add(0); cycleTimes.add(1); - cycleTimes.add(2); + cycleTimes.add(4); Subscription subscription = SubscriptionFixture.INSTANCE.get(); Time subTime = subscription.getTime(); subTime.setCycleTimes(cycleTimes); - DataDeliveryUtils.getMaxLatency(subscription); + assertEquals(THREE_HOURS_AS_MINUTES, + DataDeliveryUtils.getMaxLatency(subscription)); + } + + @Test + public void maxLatencyDefaultsToOneDayForSubscriptionWithOneCycle() { + List cycleTimes = newArrayList(); + cycleTimes.add(0); + + Subscription subscription = SubscriptionFixture.INSTANCE.get(); + Time subTime = subscription.getTime(); + subTime.setCycleTimes(cycleTimes); + + assertEquals(MINUTES_PER_DAY, + DataDeliveryUtils.getMaxLatency(subscription)); + } + + @Test + public void maxLatencyForDataSetWithOneCycleDefaultsToOneDay() { + Set cycleTimes = newHashSet(); + cycleTimes.add(0); + + OpenDapGriddedDataSet dataset = OpenDapGriddedDataSetFixture.INSTANCE + .get(); + dataset.setCycles(cycleTimes); + + assertEquals(MINUTES_PER_DAY, DataDeliveryUtils.getMaxLatency(dataset)); + } + + @Test + public void maxLatencyForDataSetWithMultipleCyclesReturnsMaxCyclicDifference() { + Set cycleTimes = newHashSet(); + cycleTimes.add(0); + cycleTimes.add(1); + cycleTimes.add(4); + + OpenDapGriddedDataSet dataset = OpenDapGriddedDataSetFixture.INSTANCE + .get(); + dataset.setCycles(cycleTimes); + + assertEquals(THREE_HOURS_AS_MINUTES, + DataDeliveryUtils.getMaxLatency(dataset)); } }