package org.openntf.calendars; import java.util.Calendar; import java.util.Set; import org.openntf.domino.utils.Dates; /** * Carrier for a pair of two Calendar objects specifying a range of time. */ public class CalendarRange implements CalendarRangeInterface { private static final long serialVersionUID = 1L; private Calendar _alpha; private Calendar _omega; /** * Zero-Argument Constructor */ public CalendarRange() { } /** * Default Constructor * * @param first * The first Calendar entry for the range. * @param last * The last Calendar entry for the range. */ public CalendarRange(final Calendar first, final Calendar last) { this.setFirst(first); this.setLast(last); } /* * *************************************************** * *************************************************** * * PUBLIC Setters * * *************************************************** * *************************************************** */ /** * @param first * the first date in the range */ public void setFirst(final Calendar first) { this._alpha = first; } /** * @param first * the first date in the range */ public void setFirst(final Object first) { if (null == first) { this._alpha = null; } else { this.setFirst(Dates.getCalendar(first)); } } /** * @param last * the last date in the range */ public void setLast(final Calendar last) { this._omega = last; } /** * @param last * the last date in the range */ public void setLast(final Object last) { if (null == last) { this._omega = null; } else { this.setLast(Dates.getCalendar(last)); } } /* * *************************************************** * *************************************************** * * PUBLIC Methods * * *************************************************** * *************************************************** */ public void setFirstTime(final Object time) { if (null != time) { this.setFirst((null == this._alpha) ? time : Dates.getDate(this._alpha, time)); } } public void setLastTime(final Object time) { if (null != time) { this.setLast((null == this._omega) ? time : Dates.getDate(this._omega, time)); } } /** * Validates the order of entries within this object. * * If a non-null entry exists for both the first and last entries, this method verifies that the first entry represents a moment in time * NOT AFTER to that of the last entry. If the first entry represents a moment AFTER that of the last entry, this method swaps them. * * * @return Flag indicating if the Calendar range is Valid. * * @see CalendarRange#isValid() * */ public boolean validate() { if (this.isValid()) { return true; } final Calendar alpha = this._alpha; final Calendar omega = this._omega; if ((null != alpha) && (null != omega) && Dates.isAfter(alpha, omega)) { final Calendar temp = alpha; this._alpha = omega; this._omega = temp; return this.isValid(); } return false; } /* * *************************************************** * *************************************************** * * CalendarRangeInterface Methods * * *************************************************** * *************************************************** */ @Override public boolean add(final Calendar calendar) { if (null != calendar) { if (null == this._alpha) { if (null == this._omega) { this._alpha = calendar; return true; } else { if (Dates.isBefore(calendar, this._omega)) { this._alpha = calendar; return true; } if (Dates.isAfter(calendar, this._omega)) { this._alpha = this._omega; this._omega = calendar; } return false; } } if (null == this._omega) { if (Dates.isAfter(calendar, this._alpha)) { this._omega = calendar; return true; } else if (Dates.isBefore(calendar, this._alpha)) { this._omega = this._alpha; this._alpha = calendar; return true; } } if (Dates.isBefore(calendar, this._alpha)) { this._alpha = calendar; return true; } if (Dates.isAfter(calendar, this._omega)) { this._omega = calendar; return true; } } return false; } @Override public boolean addObject(final Object object) { if (null != object) { final Calendar c = Dates.getCalendar(object); return (null == c) ? false : this.add(c); } return false; } /** * Adds all non-null values from set to this object. * * @param set * Set from which to construct this object. All non-null values from set will be added to this object. * * @return Flag indicating if this set changed as a result of the call. */ @Override public boolean addAll(final Set<Calendar> set) { if ((null == set) || set.isEmpty()) { return false; } boolean result = false; this.validate(); for (final Calendar calendar : set) { final boolean temp = this.add(calendar); if (temp && !result) { result = true; } } return result; } /** * Gets the first entry in the range * * NOTE: No guarantee is made that the first entry is PRIOR to the last entry unless {@link CalendarRange#validate()} is called * immediately prior calling this method. * * @return the first Calendar entry in the object */ @Override public Calendar first() { // this.validate(); return this._alpha; } /** * Gets the last entry in the range * * NOTE: No guarantee is made that the last entry is AFTER the first entry unless {@link CalendarRange#validate()} is called immediately * prior calling this method. * * @return the last Calendar entry in the object */ @Override public Calendar last() { // this.validate(); return this._omega; } @Override public boolean isValid() { return ((null != this.first()) && (null != this.last()) && !Dates.isBefore(this.last(), this.first())); } @Override public boolean contains(final Calendar calendar) { return (null == calendar) ? false : (calendar.equals(this.first()) || calendar.equals(this.last())); } @Override public boolean contains(final Object object) { if (null != object) { final Calendar calendar = Dates.getCalendar(object); return (null == calendar) ? false : this.contains(calendar); } return false; } @Override public boolean isInRange(final Object object) { return this.isInRange(object, true); } @Override public boolean isInRange(final Object object, final boolean inclusive) { return Dates.isInRange(object, this.first(), this.last(), inclusive); } @Override public CalendarRange getIntersection(final CalendarRange cr) { if ((null != cr) && this.isValid() && cr.isValid()) { final Calendar first = (this.first().equals(cr.first()) || Dates.isAfter(this.first(), cr.first())) ? this.first() : cr.first(); final Calendar last = (this.last().equals(cr.last()) || Dates.isBefore(this.last(), cr.last())) ? this.last() : cr.last(); return (!Dates.isAfter(first, last)) ? new CalendarRange(first, last) : null; } return null; } @Override public boolean isIntersectionExists(final CalendarRange cr) { return (null != this.getIntersection(cr)); } @Override public String getHoursMinutes() { return (this.isValid()) ? Dates.getHoursMinutesBetween(this.first(), this.last()) : ""; } @Override public long getMinutes() { return (this.isValid()) ? Dates.getMinutesBetween(this.first(), this.last()) : 0; } @Override public CalendarRange getUnion(final CalendarRange cr) { if ((null != cr) && this.isValid() && cr.isValid()) { final Calendar first = (Dates.isBefore(this.first(), cr.first())) ? this.first() : cr.first(); final Calendar last = (Dates.isAfter(this.last(), cr.last())) ? this.last() : cr.last(); return new CalendarRange(first, last); } return null; } @Override public boolean isUnionExists(final CalendarRange cr) { return (null != this.getUnion(cr)); } @Override public CalendarRange toCalendarRange() { final CalendarRange result = new CalendarRange(); result.setFirst(this.first()); result.setLast(this.last()); return result; } }