Issue #1453 Fix handling of active period across year boundary

Change-Id: I6bd5f075d74d394eab2a47a2b5fee3e2d91fd272

Former-commit-id: c4068d27bf [formerly eb1c45cff6c9b0a6b5d194e8f5b9b582646ebde2]
Former-commit-id: 7716f1baa9
This commit is contained in:
Dustin Johnson 2013-01-11 12:23:15 -06:00
parent eaf0cbc118
commit 3e1878c5f9
5 changed files with 265 additions and 8 deletions

View file

@ -99,6 +99,7 @@ import com.raytheon.viz.ui.presenter.components.WidgetConf;
* Jan 02, 2012 1345 djohnson Use gui thread task executor.
* Jan 02, 2013 1441 djohnson Access GroupDefinitionManager in a static fashion.
* Jan 04, 2012 1420 mpduff Add Latency to PriorityComp.
* Jan 11, 2013 1453 djohnson Sets cycle times on construction.
* </pre>
*
* @author mpduff
@ -165,8 +166,7 @@ public class CreateSubscriptionDlgPresenter {
private final IGuiThreadTaskExecutor guiThreadTaskExecutor;
@VisibleForTesting
Set<Integer> cycleTimes;
private final Set<Integer> cycleTimes;
private final ISubscriptionNotificationService subscriptionNotificationService = DataDeliveryServices
.getSubscriptionNotificationService();
@ -188,6 +188,10 @@ public class CreateSubscriptionDlgPresenter {
this.create = create;
this.guiThreadTaskExecutor = guiThreadTaskExecutor;
// Get cycles
cycleTimes = Sets.newTreeSet(((OpenDapGriddedDataSet) dataSet)
.getCycles());
groupComboAction = new Runnable() {
@Override
public void run() {
@ -227,9 +231,6 @@ public class CreateSubscriptionDlgPresenter {
init();
}
};
// Get cycles
cycleTimes = Sets.newTreeSet(((OpenDapGriddedDataSet) dataSet)
.getCycles());
this.view.setCycleTimes(cycleTimes);
this.view.setSubscription(this.subscription);
this.view.setPreOpenCallback(callback);

View file

@ -872,6 +872,12 @@ public class Subscription implements ISerializableObject, Serializable {
endCal.setTime(activePeriodEnd);
endCal = TimeUtil.maxCalendarFields(endCal, Calendar.HOUR_OF_DAY,
Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND);
// If the period crosses a year boundary, add a year to the end
if (endCal.before(startCal)) {
endCal.add(Calendar.YEAR, 1);
}
activePeriodEnd = endCal.getTime();

View file

@ -0,0 +1,174 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.time;
import java.util.Calendar;
import java.util.TimeZone;
import com.raytheon.uf.common.time.util.TimeUtil;
/**
* Build {@link Calendar} objects. Note: Defaults to the GMT timezone since that
* is most often used.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 11, 2013 1453 djohnson Initial creation
*
* </pre>
*
* @author djohnson
* @version 1.0
*/
public class CalendarBuilder {
private static final int UNSET = -1;
private int year = UNSET;
private int month = UNSET;
private int dayOfMonth = UNSET;
private int hourOfDay = UNSET;
private int minute = UNSET;
private int second = UNSET;
private int millisecond = UNSET;
private TimeZone timeZone = TimeZone.getTimeZone("GMT");
/**
* @param timeZone
* the timeZone to set
* @return a {@link CalendarBuilder} to keep building with
*/
public CalendarBuilder withTimeZone(TimeZone timeZone) {
this.timeZone = timeZone;
return this;
}
/**
* @param year
* the year to set
* @return a {@link CalendarBuilder} to keep building with
*/
public CalendarBuilder withYear(int year) {
this.year = year;
return this;
}
/**
* @param month
* the month to set
* @return a {@link CalendarBuilder} to keep building with
*/
public CalendarBuilder withMonth(int month) {
this.month = month;
return this;
}
/**
* @param dayOfMonth
* the dayOfMonth to set
* @return a {@link CalendarBuilder} to keep building with
*/
public CalendarBuilder withDayOfMonth(int dayOfMonth) {
this.dayOfMonth = dayOfMonth;
return this;
}
/**
* @param hourOfDay
* the hourOfDay to set
* @return a {@link CalendarBuilder} to keep building with
*/
public CalendarBuilder withHourOfDay(int hour) {
this.hourOfDay = hour;
return this;
}
/**
* @param minute
* the minute to set
* @return a {@link CalendarBuilder} to keep building with
*/
public CalendarBuilder withMinute(int minute) {
this.minute = minute;
return this;
}
/**
* @param second
* the second to set
* @return a {@link CalendarBuilder} to keep building with
*/
public CalendarBuilder withSecond(int second) {
this.second = second;
return this;
}
/**
* @param millisecond
* the millisecond to set
* @return a {@link CalendarBuilder} to keep building with
*/
public CalendarBuilder withMillisecond(int millisecond) {
this.millisecond = millisecond;
return this;
}
public Calendar build() {
Calendar calendar = TimeUtil.newCalendar(timeZone);
setIfRequired(Calendar.YEAR, year, calendar);
setIfRequired(Calendar.MONTH, month, calendar);
setIfRequired(Calendar.DAY_OF_MONTH, dayOfMonth, calendar);
setIfRequired(Calendar.HOUR_OF_DAY, hourOfDay, calendar);
setIfRequired(Calendar.MINUTE, minute, calendar);
setIfRequired(Calendar.SECOND, second, calendar);
setIfRequired(Calendar.MILLISECOND, millisecond, calendar);
return calendar;
}
/**
* Set the {@link Calendar} field if required.
*
* @param field
* the calendar field constant, example: {@link Calendar#YEAR}.
* @param value
* the int value
* @param calendar
* the calendar instance
*/
private void setIfRequired(int field, int value, Calendar calendar) {
if (value != UNSET) {
calendar.set(field, value);
}
}
}

View file

@ -33,6 +33,7 @@ import org.junit.Before;
import org.junit.Test;
import com.raytheon.uf.common.datadelivery.registry.Utils.SubscriptionStatus;
import com.raytheon.uf.common.time.CalendarBuilder;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.common.time.util.TimeUtilTest;
@ -46,7 +47,8 @@ import com.raytheon.uf.common.time.util.TimeUtilTest;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 27, 2012 0743 djohnson Initial creation
* Jan 02, 2012 1345 djohnson Fix broken assertion that id matches copied object.
* Jan 02, 2013 1345 djohnson Fix broken assertion that id matches copied object.
* Jan 11, 2013 1453 djohnson Add test for active period crossing year boundary.
*
* </pre>
*
@ -176,4 +178,23 @@ public class SubscriptionTest {
assertThat(subscription.getStatus(),
is(equalTo(SubscriptionStatus.INACTIVE.toString())));
}
@Test
public void testGetStatusReturnsActiveForSubscriptionWithinActiveWindowCrossingYearBoundary() {
CalendarBuilder calBuilder = new CalendarBuilder()
.withMonth(Calendar.JANUARY).withDayOfMonth(10).withYear(1970);
Calendar cal = calBuilder.build();
final Date januaryTenth = cal.getTime();
final Date januaryFirst = calBuilder.withDayOfMonth(1).build()
.getTime();
Subscription subscription = new SubscriptionBuilder()
.withActivePeriodStart(januaryTenth)
.withActivePeriodEnd(januaryFirst).build();
assertThat(subscription.getStatus(),
is(equalTo(SubscriptionStatus.ACTIVE.toString())));
}
}

View file

@ -46,6 +46,7 @@ import com.raytheon.uf.common.datadelivery.registry.Subscription;
import com.raytheon.uf.common.datadelivery.registry.SubscriptionBuilder;
import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture;
import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
import com.raytheon.uf.common.time.CalendarBuilder;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.common.time.util.TimeUtilTest;
import com.raytheon.uf.viz.core.SameThreadGuiTaskExecutor;
@ -69,6 +70,7 @@ import com.raytheon.uf.viz.datadelivery.subscription.view.ICreateSubscriptionDlg
* Nov 20, 2012 1286 djohnson {@link ISubscriptionService} now takes the view.
* Jan 02, 2012 1345 djohnson Remove obsolete test.
* Jan 04, 2013 1453 djohnson Add tests for setting the active period.
* Jan 11, 2013 1453 djohnson Add test from failed test scenario.
*
* </pre>
*
@ -305,7 +307,6 @@ public class CreateSubscriptionPresenterTest {
@Test
public void testActivePeriodEndCrossingYearBoundary() throws ParseException {
Calendar cal = TimeUtil.newGmtCalendar();
cal.set(Calendar.MONTH, Calendar.DECEMBER);
cal.set(Calendar.DAY_OF_MONTH, 30);
@ -349,14 +350,68 @@ public class CreateSubscriptionPresenterTest {
argThat(yyyyMmDdMatches(expectedEndCalendar.getTime())));
}
/**
* Taken from the following tester comments:<br>
* When creating a subscription, if the Active Period End date is set to a
* month/day that is earlier than the month/day of the Active Period Start
* date (e.g., Active Period Start date = 01/10/2013 and Active Period End
* date = 01/01/2014), the subscription will go through successfully. Then,
* when editing the subscription and clicking on the Select Date for both
* the Active Period Start and End dates, the Active Period Start date
* (01/10/2014) is after the Active Period End date (01/01/2014). A check
* needs to be added such that if the Start date is after the End date, the
* year for the End date needs to increase by 1 (year + 1). While the year
* has no affect on the Active Period Start and End dates (and associated
* functionality), there may be confusion with the end user.
*
* @throws ParseException
*/
@Test
public void testActivePeriodWhereStartIsDayOfYearAfterEnd()
throws ParseException {
Calendar cal = new CalendarBuilder().withMonth(Calendar.JANUARY)
.withDayOfMonth(10).withYear(2013).build();
final Date januaryTenth = cal.getTime();
cal.set(Calendar.YEAR, 1970);
final Date startDate = cal.getTime();
Calendar cal2 = new CalendarBuilder().withMonth(Calendar.JANUARY)
.withDayOfMonth(1).withYear(2014).build();
final Date januaryFirstYearLater = cal2.getTime();
cal2.set(Calendar.YEAR, 1970);
final Date endDate = cal2.getTime();
Subscription subscription = new SubscriptionBuilder()
.withActivePeriodStart(startDate).withActivePeriodEnd(endDate)
.build();
// freeze time at start date plus a minute
TimeUtilTest.freezeTime(januaryTenth.getTime()
+ TimeUtil.MILLIS_PER_MINUTE);
CreateSubscriptionDlgPresenter presenter = new CreateSubscriptionDlgPresenter(
view, dataSet, true, new SameThreadGuiTaskExecutor());
presenter.setSubscriptionData(subscription);
presenter.init();
verify(view).setActiveStartDate(argThat(yyyyMmDdMatches(januaryTenth)));
verify(view).setActiveEndDate(
argThat(yyyyMmDdMatches(januaryFirstYearLater)));
}
@Test
public void verifySubscriptionSetToView() {
presenter.open();
verify(view).setSubscription(presenter.getSubscription());
}
@Test
public void verifyCycleTimesSetToView() {
verify(view).setCycleTimes(presenter.cycleTimes);
presenter.open();
verify(view).setCycleTimes(dataSet.getCycles());
}
}