package org.oddjob.schedules.schedules; import java.io.Serializable; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import org.oddjob.schedules.AbstractSchedule; import org.oddjob.schedules.Interval; import org.oddjob.schedules.IntervalTo; import org.oddjob.schedules.ScheduleContext; import org.oddjob.schedules.ScheduleResult; import org.oddjob.schedules.SimpleScheduleResult; /** * @oddjob.description A schedule that returns the day before when it's * parent schedule is due. * <p> * This is designed to be used with the {@link BrokenSchedule}'s alternative * property to move processing to the day before the holiday. * <p> * * @oddjob.example * * A schedule for the last day of the month, or the previous working day * if the last day falls on a non working day. * * {@oddjob.xml.resource org/oddjob/schedules/schedules/DayBeforeScheduleExample.xml} * * Note that the refinement schedules for a different time when the day before is * used. This reflects the situation where data is often available later before * a weekend or holiday. * * @author Rob Gordon */ public class DayBeforeSchedule extends AbstractSchedule implements Serializable { private static final long serialVersionUID = 2011092200L; /* * (non-Javadoc) * @see org.oddjob.schedules.Schedule#nextDue(org.oddjob.schedules.ScheduleContext) */ public ScheduleResult nextDue(ScheduleContext context) { Date use = null; Date useNext = null; Interval interval = context.getParentInterval(); if (interval != null) { use = interval.getFromDate(); useNext = interval.getToDate(); } else { use = context.getDate(); useNext = use; } if (use == null) { return null; } Calendar useCal = Calendar.getInstance(context.getTimeZone()); useCal.setTime(use); Calendar startCal = Calendar.getInstance(context.getTimeZone()); startCal.clear(); startCal.set( useCal.get(Calendar.YEAR), useCal.get(Calendar.MONTH), useCal.get(Calendar.DATE) - 1); Calendar endCal = new GregorianCalendar(); endCal.clear(); endCal.set( useCal.get(Calendar.YEAR), useCal.get(Calendar.MONTH), useCal.get(Calendar.DATE)); Interval newInterval = new IntervalTo( startCal.getTime(), endCal.getTime()); Interval result; if (getRefinement() != null) { ScheduleContext shiftedContext = context.spawn( startCal.getTime(), newInterval); result = getRefinement().nextDue(shiftedContext); } else { result = newInterval; } if (result == null) { return null; } return new SimpleScheduleResult(result, useNext); } /** * Override toString. */ public String toString() { String description = ""; if (getRefinement() != null) { description = " with refinement " + getRefinement(); } return "Day Before" + description; } }