001    /**
002     * Copyright 2007 Mike Kroutikov.
003     *
004     * This program is free software; you can redistribute it and/or modify
005     *   it under the terms of the Lesser GNU General Public License as 
006     *   published by the Free Software Foundation; either version 3 of
007     *   the License, or (at your option) any later version.
008     *
009     *   This program is distributed in the hope that it will be useful,
010     *   but WITHOUT ANY WARRANTY; without even the implied warranty of
011     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012     *   Lesser GNU General Public License for more details.
013     *
014     *   You should have received a copy of the Lesser GNU General Public License
015     *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
016     */
017    package org.otfeed.command;
018    
019    import java.io.Serializable;
020    
021    import org.otfeed.protocol.request.Check;
022    
023    /**
024     * Represents aggregation time span.
025     * <p/>
026     * Time span can range from 2 ticks, to years.
027     */
028    public class AggregationSpan implements Serializable, Comparable<AggregationSpan> {
029            private static final long serialVersionUID = -5332228523232654411L;
030    
031            public final TimeUnitEnum units;
032            public final int          length;
033            
034            /**
035             * Creates a new aggreagation span.
036             * 
037             * @param units time units (DAYS, WEEKS, etc.). A special
038             * unit of {@link TimeUnitEnum#TICKS TICKS} will mean that 
039             * the aggregation will be done over that many ticks.
040             * 
041             * @param length length of aggregation span.
042             */
043            public AggregationSpan(TimeUnitEnum units, int length) {
044                    Check.notNull(units, "null units noit allowed");
045                    
046                    if(units == TimeUnitEnum.TICKS && length < 2) {
047                            throw new IllegalArgumentException("tick span must be 2 or greater");
048                    } else if(length < 1) {
049                            throw new IllegalArgumentException("span length must be greater than zero");
050                    }
051                    this.units  = units;
052                    this.length = length;
053            }
054            
055            /**
056             * Returns aggregation span measured in years.
057             * 
058             * @param num number of years (1 or greater).
059             * @return aggregation span.
060             */
061            public static AggregationSpan years(int num) {
062                    return new AggregationSpan(TimeUnitEnum.YEARS, num);
063            }
064    
065            /**
066             * Returns a one-year aggregation span.
067             * 
068             * @return aggregation span.
069             */
070            public static AggregationSpan years() {
071                    return years(1);
072            }
073            
074            /**
075             * Returns aggregation span measured in months.
076             * 
077             * @param num number of months (1 or greater).
078             * @return aggregation span.
079             */
080            public static AggregationSpan months(int num) {
081                    return new AggregationSpan(TimeUnitEnum.MONTHS, num);
082            }
083    
084            /**
085             * Returns a one-month aggregation span.
086             * 
087             * @return aggregation span.
088             */
089            public static AggregationSpan months() {
090                    return months(1);
091            }
092    
093            /**
094             * Returns aggregation span measured in weeks.
095             * 
096             * @param num number of weeks (1 or greater).
097             * @return aggregation span.
098             */
099            public static AggregationSpan weeks(int num) {
100                    return new AggregationSpan(TimeUnitEnum.WEEKS, num);
101            }
102    
103            /**
104             * Returns a one-week aggregation span.
105             * 
106             * @return aggregation span.
107             */
108            public static AggregationSpan weeks() {
109                    return weeks(1);
110            }
111    
112            /**
113             * Returns aggregation span measured in days.
114             * 
115             * @param num number of days (1 or greater).
116             * @return aggregation span.
117             */
118            public static AggregationSpan days(int num) {
119                    return new AggregationSpan(TimeUnitEnum.DAYS, num);
120            }
121    
122            /**
123             * Returns a one-day aggregation span.
124             * 
125             * @return aggregation span.
126             */
127            public static AggregationSpan days() {
128                    return days(1);
129            }
130    
131            /**
132             * Returns aggregation span measured in hours.
133             * 
134             * @param num number of hours (1 or greater).
135             * @return aggregation span.
136             */
137            public static AggregationSpan hours(int num) {
138                    return new AggregationSpan(TimeUnitEnum.HOURS, num);
139            }
140    
141            /**
142             * Returns a one-hour aggregation span.
143             * 
144             * @return aggregation span.
145             */
146            public static AggregationSpan hours() {
147                    return hours(1);
148            }
149    
150            /**
151             * Returns aggregation span measured in minutes.
152             * 
153             * @param num number of minutes (1 or greater).
154             * @return aggregation span.
155             */
156            public static AggregationSpan minutes(int num) {
157                    return new AggregationSpan(TimeUnitEnum.MINUTES, num);
158            }
159    
160            /**
161             * Returns a one-minute aggregation span.
162             * 
163             * @return aggregation span.
164             */
165            public static AggregationSpan minutes() {
166                    return minutes(1);
167            }
168    
169            /**
170             * Returns aggregation span measured in ticks.
171             * 
172             * @param num number of ticks (2 or greater).
173             * @return aggregation span.
174             */
175            public static AggregationSpan ticks(int num) {
176                    return new AggregationSpan(TimeUnitEnum.TICKS, num);
177            }
178            
179            @Override
180            public String toString() {
181                    return "(" + length + " " + units + ")";
182            }
183            
184            @Override
185            public int hashCode() {
186                    return units.hashCode() + new Integer(length).hashCode();
187            }
188            
189            @Override
190            public boolean equals(Object other) {
191                    if(!(other instanceof AggregationSpan)) return false;
192                    return this.compareTo((AggregationSpan) other) == 0;
193            }
194            
195            public int compareTo(AggregationSpan other) {
196                    if(other == null) return 1;
197                    int rc;
198                    rc = units.compareTo(other.units);
199                    if(rc != 0) return rc;
200                    rc = (new Integer(length)).compareTo(other.length);
201                    if(rc != 0) return rc;
202                    
203                    return 0;
204            }
205    }