001    package org.hackystat.telemetry.analyzer.reducer.util;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    
006    import org.hackystat.utilities.time.interval.DayInterval;
007    import org.hackystat.utilities.time.interval.IllegalIntervalException;
008    import org.hackystat.utilities.time.interval.Interval;
009    import org.hackystat.utilities.time.interval.MonthInterval;
010    import org.hackystat.utilities.time.interval.WeekInterval;
011    import org.hackystat.utilities.time.period.Day;
012    import org.hackystat.utilities.time.period.Month;
013    import org.hackystat.utilities.time.period.TimePeriod;
014    import org.hackystat.utilities.time.period.Week;
015    
016    /**
017     * Provides utility functions for processing Intervals. 
018     * 
019     * @author (Cedric) Qin Zhang, Philip Johnson
020     */
021    public class IntervalUtility {
022     
023      /**
024       * Gets time periods in the interval.
025       * 
026       * @param interval The interval.
027       * @return A ordered list of <code>IntervalUtility.Period</code> objects.
028       * 
029       * @throws IllegalIntervalException If the interval is not recognized.
030       */
031      public static List<IntervalUtility.Period> getPeriods(Interval interval) 
032                                                          throws IllegalIntervalException {
033        ArrayList<IntervalUtility.Period> list = new ArrayList<IntervalUtility.Period>();
034        
035        if (interval instanceof DayInterval) {
036          DayInterval dayInterval = (DayInterval) interval;
037          for (Day day : dayInterval) {
038            list.add(new Period(day));
039          }
040        }
041        else if (interval instanceof WeekInterval) {
042          WeekInterval weekInterval = (WeekInterval) interval;
043          for (Week week : weekInterval) {
044            list.add(new Period(week));
045          }      
046        }
047        else if (interval instanceof MonthInterval) {
048          MonthInterval monthInterval = (MonthInterval) interval;
049          for (Month month : monthInterval) {
050            list.add(new Period(month));
051          }  
052        }
053        else {
054          throw new IllegalIntervalException("Unknown interval.");
055        }
056        
057        return list;
058      }
059      
060      /**
061       * Provides a Time period, which is either day, week or month.
062       * 
063       * @author (Cedric) Qin Zhang.
064       */
065      public static class Period {
066        
067        private TimePeriod rawPeriod;
068        private Day startDay;
069        private Day endDay;
070        
071        /**
072         * Constructs this instance from day.
073         * 
074         * @param day The day.
075         */
076        public Period(Day day) {
077          this.rawPeriod = day;
078          this.startDay = day;
079          this.endDay = day;
080        }
081        
082        /**
083         * Constructs this instance from week.
084         * 
085         * @param week The week.
086         */
087        public Period(Week week) {
088          this.rawPeriod = week;
089          this.startDay = week.getFirstDay();
090          this.endDay = week.getLastDay();
091        }
092        
093        /**
094         * Constructs this instance from month.
095         * 
096         * @param month The month.
097         */
098        public Period(Month month) {
099          this.rawPeriod = month;
100          this.startDay = month.getFirstDay();
101          this.endDay = month.getLastDay();
102        }
103        
104        /**
105         * Gets the time period wrapped by this instance.
106         * 
107         * @return The wrapped <code>TimePeriod</code> object.
108         */
109        public TimePeriod getTimePeriod() {
110          return this.rawPeriod;
111        }
112        
113        /**
114         * Gets the start day of the period, inclusive.
115         *
116         * @return The start day.
117         */
118        public Day getStartDay() {
119          return this.startDay;
120        }
121        
122        /**
123         * Gets the end day of the period, inclusive.
124         *
125         * @return The start day.
126         */
127        public Day getEndDay() {
128          return this.endDay;
129        }
130        
131        /**
132         * Gets the number of day in this period, including both start day and end day.
133         * 
134         * @return The number of days.
135         */
136        public int getNumOfDays() {
137          return Day.daysBetween(this.startDay, this.endDay) + 1; 
138        }
139      }
140    }