001/*
002 * #%L
003 * Netarchivesuite - harvester
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023
024package dk.netarkivet.harvester.datamodel;
025
026import java.util.Date;
027
028import dk.netarkivet.common.exceptions.ArgumentNotValid;
029
030/**
031 * This class implements a schedule that runs over a specified period of time.
032 */
033@SuppressWarnings({"serial"})
034public class TimedSchedule extends Schedule {
035
036    /** The day this schedule should end. */
037    private final Date endDate;
038
039    /**
040     * Create a new TimedSchedule that runs over a period of time.
041     *
042     * @param startDate The time at which the schedule starts running. This is not necessarily the time of the first
043     * event, but no events will happen before this. May be null, meaning start any time.
044     * @param endDate The time at which the schedule stops running. No events will happen after this. May be null,
045     * meaning continue forever.
046     * @param frequency How frequently the event should happen.
047     * @param comments Comments entered by the user
048     * @param name The unique name of the schedule.
049     * @throws ArgumentNotValid if frequency, name or comments is null, or name is "" or
050     */
051    TimedSchedule(Date startDate, Date endDate, Frequency frequency, String name, String comments) {
052        super(startDate, frequency, name, comments);
053        this.endDate = endDate;
054    }
055
056    /**
057     * Autogenerated equals.
058     *
059     * @param o The object to compare with
060     * @return Whether objects are equal
061     */
062    public boolean equals(Object o) {
063        if (this == o) {
064            return true;
065        }
066        if (!(o instanceof TimedSchedule)) {
067            return false;
068        }
069        if (!super.equals(o)) {
070            return false;
071        }
072
073        final TimedSchedule timedSchedule = (TimedSchedule) o;
074
075        if (endDate != null ? !endDate.equals(timedSchedule.endDate) : timedSchedule.endDate != null) {
076            return false;
077        }
078
079        return true;
080    }
081
082    /**
083     * Autogenerated hashcode method.
084     *
085     * @return the hashcode
086     */
087    public int hashCode() {
088        int result = super.hashCode();
089        result = 29 * result + (endDate != null ? endDate.hashCode() : 0);
090        return result;
091    }
092
093    /**
094     * Return the date at which the next event will happen. If the calculated next date is exactly equal to the end date
095     * then that value is returned. If it is after the end date, null is returned.
096     *
097     * @param lastEvent The time at which the previous event happened. If this is null, then the method returns null. Ie
098     * once one is after the last event one is always after the last event.
099     * @param numPreviousEvents How many events have previously happened (ignored).
100     * @return The date of the next event to happen or null for no more events.
101     * @throws ArgumentNotValid if numPreviousEvents is negative
102     */
103    public Date getNextEvent(Date lastEvent, int numPreviousEvents) {
104        ArgumentNotValid.checkNotNegative(numPreviousEvents, "numPreviousEvents");
105
106        if (lastEvent == null) {
107            return null;
108        }
109        Date nextEvent = frequency.getNextEvent(lastEvent);
110        if (endDate == null) {
111            return nextEvent;
112        } else if (nextEvent.after(endDate)) {
113            return null;
114        } else {
115            return nextEvent;
116        }
117    }
118
119    /**
120     * Get the last possible time an event may be allowed.
121     *
122     * @return The last date, null means no last date, continue forever.
123     */
124    public Date getEndDate() {
125        return endDate;
126    }
127
128    /**
129     * Human readable represenation of this object.
130     *
131     * @return Human readble representation
132     */
133    public String toString() {
134        if (startDate == null && endDate == null) {
135            return name + ": " + frequency + "(" + comments + ")";
136        } else if (endDate == null) {
137            return name + ": from " + startDate + " forever " + frequency + "(" + comments + ")";
138        } else if (startDate == null) {
139            return name + ": until " + endDate.getTime() + " " + frequency + "(" + comments + ")";
140        } else {
141            return name + ": from " + startDate + " to " + endDate.getTime() + " " + frequency + "(" + comments + ")";
142        }
143    }
144
145}