001: /* ========================================================================
002: * JCommon : a free general purpose class library for the Java(tm) platform
003: * ========================================================================
004: *
005: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jcommon/index.html
008: *
009: * This library is free software; you can redistribute it and/or modify it
010: * under the terms of the GNU Lesser General Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but
015: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017: * License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022: * USA.
023: *
024: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * --------------------------
028: * RelativeDayOfWeekRule.java
029: * --------------------------
030: * (C) Copyright 2000-2003, by Object Refinery Limited and Contributors.
031: *
032: * Original Author: David Gilbert (for Object Refinery Limited);
033: * Contributor(s): -;
034: *
035: * $Id: RelativeDayOfWeekRule.java,v 1.6 2005/11/16 15:58:40 taqua Exp $
036: *
037: * Changes (from 26-Oct-2001)
038: * --------------------------
039: * 26-Oct-2001 : Changed package to com.jrefinery.date.*;
040: * 03-Oct-2002 : Fixed errors reported by Checkstyle (DG);
041: *
042: */
043:
044: package org.jfree.date;
045:
046: /**
047: * An annual date rule that returns a date for each year based on (a) a
048: * reference rule; (b) a day of the week; and (c) a selection parameter
049: * (SerialDate.PRECEDING, SerialDate.NEAREST, SerialDate.FOLLOWING).
050: * <P>
051: * For example, Good Friday can be specified as 'the Friday PRECEDING Easter
052: * Sunday'.
053: *
054: * @author David Gilbert
055: */
056: public class RelativeDayOfWeekRule extends AnnualDateRule {
057:
058: /** A reference to the annual date rule on which this rule is based. */
059: private AnnualDateRule subrule;
060:
061: /**
062: * The day of the week (SerialDate.MONDAY, SerialDate.TUESDAY, and so on).
063: */
064: private int dayOfWeek;
065:
066: /** Specifies which day of the week (PRECEDING, NEAREST or FOLLOWING). */
067: private int relative;
068:
069: /**
070: * Default constructor - builds a rule for the Monday following 1 January.
071: */
072: public RelativeDayOfWeekRule() {
073: this (new DayAndMonthRule(), SerialDate.MONDAY,
074: SerialDate.FOLLOWING);
075: }
076:
077: /**
078: * Standard constructor - builds rule based on the supplied sub-rule.
079: *
080: * @param subrule the rule that determines the reference date.
081: * @param dayOfWeek the day-of-the-week relative to the reference date.
082: * @param relative indicates *which* day-of-the-week (preceding, nearest
083: * or following).
084: */
085: public RelativeDayOfWeekRule(final AnnualDateRule subrule,
086: final int dayOfWeek, final int relative) {
087: this .subrule = subrule;
088: this .dayOfWeek = dayOfWeek;
089: this .relative = relative;
090: }
091:
092: /**
093: * Returns the sub-rule (also called the reference rule).
094: *
095: * @return The annual date rule that determines the reference date for this
096: * rule.
097: */
098: public AnnualDateRule getSubrule() {
099: return this .subrule;
100: }
101:
102: /**
103: * Sets the sub-rule.
104: *
105: * @param subrule the annual date rule that determines the reference date
106: * for this rule.
107: */
108: public void setSubrule(final AnnualDateRule subrule) {
109: this .subrule = subrule;
110: }
111:
112: /**
113: * Returns the day-of-the-week for this rule.
114: *
115: * @return the day-of-the-week for this rule.
116: */
117: public int getDayOfWeek() {
118: return this .dayOfWeek;
119: }
120:
121: /**
122: * Sets the day-of-the-week for this rule.
123: *
124: * @param dayOfWeek the day-of-the-week (SerialDate.MONDAY,
125: * SerialDate.TUESDAY, and so on).
126: */
127: public void setDayOfWeek(final int dayOfWeek) {
128: this .dayOfWeek = dayOfWeek;
129: }
130:
131: /**
132: * Returns the 'relative' attribute, that determines *which*
133: * day-of-the-week we are interested in (SerialDate.PRECEDING,
134: * SerialDate.NEAREST or SerialDate.FOLLOWING).
135: *
136: * @return The 'relative' attribute.
137: */
138: public int getRelative() {
139: return this .relative;
140: }
141:
142: /**
143: * Sets the 'relative' attribute (SerialDate.PRECEDING, SerialDate.NEAREST,
144: * SerialDate.FOLLOWING).
145: *
146: * @param relative determines *which* day-of-the-week is selected by this
147: * rule.
148: */
149: public void setRelative(final int relative) {
150: this .relative = relative;
151: }
152:
153: /**
154: * Creates a clone of this rule.
155: *
156: * @return a clone of this rule.
157: *
158: * @throws CloneNotSupportedException this should never happen.
159: */
160: public Object clone() throws CloneNotSupportedException {
161: final RelativeDayOfWeekRule duplicate = (RelativeDayOfWeekRule) super
162: .clone();
163: duplicate.subrule = (AnnualDateRule) duplicate.getSubrule()
164: .clone();
165: return duplicate;
166: }
167:
168: /**
169: * Returns the date generated by this rule, for the specified year.
170: *
171: * @param year the year (1900 <= year <= 9999).
172: *
173: * @return The date generated by the rule for the given year (possibly
174: * <code>null</code>).
175: */
176: public SerialDate getDate(final int year) {
177:
178: // check argument...
179: if ((year < SerialDate.MINIMUM_YEAR_SUPPORTED)
180: || (year > SerialDate.MAXIMUM_YEAR_SUPPORTED)) {
181: throw new IllegalArgumentException(
182: "RelativeDayOfWeekRule.getDate(): year outside valid range.");
183: }
184:
185: // calculate the date...
186: SerialDate result = null;
187: final SerialDate base = this.subrule.getDate(year);
188:
189: if (base != null) {
190: switch (this.relative) {
191: case (SerialDate.PRECEDING):
192: result = SerialDate.getPreviousDayOfWeek(
193: this.dayOfWeek, base);
194: break;
195: case (SerialDate.NEAREST):
196: result = SerialDate.getNearestDayOfWeek(this.dayOfWeek,
197: base);
198: break;
199: case (SerialDate.FOLLOWING):
200: result = SerialDate.getFollowingDayOfWeek(
201: this.dayOfWeek, base);
202: break;
203: default:
204: break;
205: }
206: }
207: return result;
208:
209: }
210:
211: }
|