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.Week;
008    
009    /**
010     * Provides week interval. 
011     * 
012     * @author Hongbing Kou, Philip Johnson
013     */
014    public class WeekInterval extends Interval implements Iterable<Week> {
015      /** Start week. */
016      private final Week startWeek;
017      /** End week. */ 
018      private final Week endWeek;
019      
020      /**
021       * Creates a WeekInterval object with start and end information.
022       * 
023       * @param startWeek Start week string.
024       * @param endWeek   End week string.
025       * @throws IllegalIntervalException If the given start and end are invalid.
026       */
027      public WeekInterval(String startWeek, String endWeek) throws IllegalIntervalException {
028        super("Week");
029        
030        IntervalUtility utility = IntervalUtility.getInstance();
031        this.startWeek = utility.getWeek(startWeek);
032        this.endWeek = utility.getWeek(endWeek);
033        
034        if (this.startWeek.compareTo(this.endWeek) > 0) {
035          throw new IllegalIntervalException("Start week " + this.startWeek + " is later than end week "
036                                            + this.endWeek);       
037        }
038      }
039      
040      /**
041       * Creates a week-based interval with start and end information.
042       * @param startWeek An XMLGregorianCalendar indicating the start week.
043       * @param endWeek An XMLGregorianCalendar indicating the end week.
044       * @throws IllegalIntervalException If problems occur.
045       */
046      public WeekInterval(XMLGregorianCalendar startWeek, XMLGregorianCalendar endWeek)
047      throws IllegalIntervalException {
048        super("Week");
049        this.startWeek = new Week(startWeek);
050        this.endWeek = new Week(endWeek);
051        if (this.startWeek.compareTo(this.endWeek) > 0) {
052          throw new IllegalIntervalException("Start week " + this.startWeek + " is later than end week "
053                                            + this.endWeek);       
054        }
055      }
056    
057      /**
058       * Gets start week. 
059       * 
060       * @return Start week.
061       */
062      public Week getStartWeek () {
063        return this.startWeek;
064      }
065      
066      /**
067       * Gets end week. 
068       * 
069       * @return End week.
070       */
071      public Week getEndWeek () {
072        return this.endWeek;
073      }
074    
075      /**
076       * Gets the iterator over the week period.
077       * 
078       * @return Iterator over week period. 
079       */
080      @Override
081      public Iterator<Week> iterator() {
082        return new WeekIterator(this);  
083      }
084      
085      /**
086       * String representaiton of the WeekInterval object.
087       * 
088       * @return Week interval string  
089       */
090      @Override
091      public String toString() {
092        StringBuffer buffer = new StringBuffer(80);
093        buffer.append("Week Interval : ");
094        buffer.append(this.startWeek);
095        buffer.append(" ~ ");
096        buffer.append(this.endWeek);
097        return buffer.toString();
098      }    
099      
100      /**
101       * Gets the hash code.
102       * 
103       * @return The hash code.
104       */
105      @Override
106      public int hashCode() {
107        return this.startWeek.hashCode() / 2 + this.endWeek.hashCode() / 2;
108      }
109      
110      /**
111       * Indicates whether some other object is "equal to" this one. 
112       * 
113       * @param obj Another instance of <code>DayInterval</code>.
114       * 
115       * @return True if they are equal, false otherwise.
116       */
117      @Override
118      public boolean equals(Object obj) {
119        if (!(obj instanceof WeekInterval)) {
120          return false;
121        }    
122        WeekInterval another = (WeekInterval) obj;
123        return this.startWeek.equals(another.startWeek) && this.endWeek.equals(another.endWeek);
124      }
125    }