001    package org.hackystat.utilities.time.interval;
002    
003    import java.util.Iterator;
004    
005    import javax.xml.datatype.XMLGregorianCalendar;
006    
007    import org.hackystat.utilities.time.period.Day;
008    
009    /**
010     * Represents an interval as a set of Days.
011     * 
012     * @author Hongbing Kou, Philip Johnson
013     */
014    public class DayInterval extends Interval implements Iterable<Day> {
015    
016      /** Start day of the interval. */
017      private Day startDay;
018    
019      /** End day of the interval. */
020      private Day endDay;
021    
022      /**
023       * Instantiates DayInterval with start day and end day.
024       * 
025       * @param startYear Interval's start year.
026       * @param startMonth Interval's start month.
027       * @param startDay Interval's start day.
028       * @param endYear Interval's end year.
029       * @param endMonth Interval's end month.
030       * @param endDay Interval's end day.
031       * @throws IllegalIntervalException If start day is later than end day.
032       */
033      public DayInterval(String startYear, String startMonth, String startDay, String endYear,
034          String endMonth, String endDay) throws IllegalIntervalException {
035        super("Day");
036        IntervalUtility utility = IntervalUtility.getInstance();
037        this.startDay = utility.getDay(startYear, startMonth, startDay);
038        this.endDay = utility.getDay(endYear, endMonth, endDay);
039        if (this.startDay.compareTo(this.endDay) > 0) {
040          throw new IllegalIntervalException("Start day " + this.startDay + " is later than end day "
041              + this.endDay);
042        }
043      }
044    
045      /**
046       * Instantiates DayInterval with start day and end day.
047       * 
048       * @param startDay The starting day.
049       * @param endDay The ending day.
050       * @throws IllegalIntervalException If start day is later than end day.
051       */
052      public DayInterval(Day startDay, Day endDay) throws IllegalIntervalException {
053        super("Day");
054        this.startDay = startDay;
055        this.endDay = endDay;
056        if (this.startDay.compareTo(this.endDay) > 0) {
057          throw new IllegalIntervalException("Start day " + this.startDay + " is later than end day "
058              + this.endDay);
059        }
060      }
061      
062      /**
063       * Instantiates DayInterval with start day and end day.
064       * 
065       * @param xmlStartDay The starting day.
066       * @param xmlEndDay The ending day.
067       * @throws IllegalIntervalException If start day is later than end day.
068       */
069      public DayInterval(XMLGregorianCalendar xmlStartDay, XMLGregorianCalendar xmlEndDay) 
070      throws IllegalIntervalException {
071        this(Day.getInstance(xmlStartDay), Day.getInstance(xmlEndDay));
072      }
073    
074      /**
075       * Gets the start day of this interval.
076       * 
077       * @return Start day of this interval.
078       */
079      public Day getStartDay() {
080        return this.startDay;
081      }
082    
083      /**
084       * Gets the end day of this interval.
085       * 
086       * @return End day of this interval.
087       */
088      public Day getEndDay() {
089        return this.endDay;
090      }
091    
092      /**
093       * Returns an iterator over the days in this interval.
094       * 
095       * @return Iterator over a period.
096       */
097      @Override
098      public Iterator<Day> iterator() {
099        return new DayIterator(this);
100      }
101    
102      /**
103       * String representation of this interval.
104       * 
105       * @return Day interval string
106       */
107      @Override
108      public String toString() {
109        StringBuffer buffer = new StringBuffer(55);
110        buffer.append("Day Interval : ");
111        buffer.append(this.startDay);
112        buffer.append(" ~ ");
113        buffer.append(this.endDay);
114    
115        return buffer.toString();
116      }
117    
118      /**
119       * Gets the hash code.
120       * 
121       * @return The hash code.
122       */
123      @Override
124      public int hashCode() {
125        return this.startDay.hashCode() / 2 + this.endDay.hashCode() / 2;
126      }
127    
128      /**
129       * Indicates whether some other object is "equal to" this one.
130       * 
131       * @param obj Another instance of <code>DayInterval</code>.
132       * 
133       * @return True if they are equal, false otherwise.
134       */
135      @Override
136      public boolean equals(Object obj) {
137        if (!(obj instanceof DayInterval)) {
138          return false;
139        }
140        DayInterval another = (DayInterval) obj;
141        return this.startDay.equals(another.startDay) && this.endDay.equals(another.endDay);
142      }
143    }