001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    /*
016     * Copyright (c) 2000, Columbia University.  All rights reserved.
017     *
018     * Redistribution and use in source and binary forms, with or without
019     * modification, are permitted provided that the following conditions are met:
020     *
021     * 1. Redistributions of source code must retain the above copyright
022     *        notice, this list of conditions and the following disclaimer.
023     *
024     * 2. Redistributions in binary form must reproduce the above copyright
025     *        notice, this list of conditions and the following disclaimer in the
026     *        documentation and/or other materials provided with the distribution.
027     *
028     * 3. Neither the name of the University nor the names of its contributors
029     *        may be used to endorse or promote products derived from this software
030     *        without specific prior written permission.
031     *
032     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
033     * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
034     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
035     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
036     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
037     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
038     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
039     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
040     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
041     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
042     * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
043     */
044    
045    package com.liferay.portal.kernel.cal;
046    
047    import com.liferay.portal.kernel.util.StringBundler;
048    
049    import java.io.Serializable;
050    
051    /**
052     * @author Jonathan Lennox
053     */
054    public class Duration implements Cloneable, Serializable {
055    
056            /**
057             * Constructor Duration
058             */
059            public Duration() {
060    
061                    // Zero-initialization of all fields happens by default
062    
063            }
064    
065            /**
066             * Constructor Duration
067             */
068            public Duration(int w) {
069                    _weeks = w;
070            }
071    
072            /**
073             * Constructor Duration
074             */
075            public Duration(int h, int m, int s) {
076                    this(0, h, m, s);
077            }
078    
079            /**
080             * Constructor Duration
081             */
082            public Duration(int d, int h, int m, int s) {
083                    _days = d;
084                    _hours = h;
085                    _minutes = m;
086                    _seconds = s;
087            }
088    
089            /**
090             * Method clear
091             */
092            public void clear() {
093                    _weeks = 0;
094                    _days = 0;
095                    _hours = 0;
096                    _minutes = 0;
097                    _seconds = 0;
098            }
099    
100            /**
101             * Method clone
102             *
103             * @return Object
104             */
105            @Override
106            public Object clone() {
107                    try {
108                            Duration other = (Duration)super.clone();
109    
110                            other._weeks = _weeks;
111                            other._days = _days;
112                            other._hours = _hours;
113                            other._minutes = _minutes;
114                            other._seconds = _seconds;
115    
116                            return other;
117                    }
118                    catch (CloneNotSupportedException cnse) {
119                            throw new InternalError();
120                    }
121            }
122    
123            /**
124             * Method getDays
125             *
126             * @return int
127             */
128            public int getDays() {
129                    return _days;
130            }
131    
132            /**
133             * Method getHours
134             *
135             * @return int
136             */
137            public int getHours() {
138                    return _hours;
139            }
140    
141            /**
142             * Method getInterval
143             *
144             * @return long
145             */
146            public long getInterval() {
147                    return
148                            _seconds * _MILLIS_PER_SECOND + _minutes * _MILLIS_PER_MINUTE +
149                            _hours * _MILLIS_PER_HOUR + _days * _MILLIS_PER_DAY +
150                            _weeks * _MILLIS_PER_WEEK;
151            }
152    
153            /**
154             * Method getMinutes
155             *
156             * @return int
157             */
158            public int getMinutes() {
159                    return _minutes;
160            }
161    
162            /**
163             * Method getSeconds
164             *
165             * @return int
166             */
167            public int getSeconds() {
168                    return _seconds;
169            }
170    
171            /**
172             * Method getWeeks
173             *
174             * @return int
175             */
176            public int getWeeks() {
177                    return _weeks;
178            }
179    
180            /**
181             * Method setDays
182             */
183            public void setDays(int d) {
184                    if (d < 0) {
185                            throw new IllegalArgumentException("Day value out of range");
186                    }
187    
188                    checkNonWeeksOkay(d);
189    
190                    _days = d;
191    
192                    normalize();
193            }
194    
195            /**
196             * Method setHours
197             */
198            public void setHours(int h) {
199                    if (h < 0) {
200                            throw new IllegalArgumentException("Hour value out of range");
201                    }
202    
203                    checkNonWeeksOkay(h);
204    
205                    _hours = h;
206    
207                    normalize();
208            }
209    
210            /**
211             * Method setInterval
212             */
213            public void setInterval(long millis) {
214                    if (millis < 0) {
215                            throw new IllegalArgumentException("Negative-length interval");
216                    }
217    
218                    clear();
219    
220                    _days = (int)(millis / _MILLIS_PER_DAY);
221                    _seconds = (int)((millis % _MILLIS_PER_DAY) / _MILLIS_PER_SECOND);
222    
223                    normalize();
224            }
225    
226            /**
227             * Method setMinutes
228             */
229            public void setMinutes(int m) {
230                    if (m < 0) {
231                            throw new IllegalArgumentException("Minute value out of range");
232                    }
233    
234                    checkNonWeeksOkay(m);
235    
236                    _minutes = m;
237    
238                    normalize();
239            }
240    
241            /**
242             * Method setSeconds
243             */
244            public void setSeconds(int s) {
245                    if (s < 0) {
246                            throw new IllegalArgumentException("Second value out of range");
247                    }
248    
249                    checkNonWeeksOkay(s);
250    
251                    _seconds = s;
252    
253                    normalize();
254            }
255    
256            /**
257             * Method setWeeks
258             */
259            public void setWeeks(int w) {
260                    if (w < 0) {
261                            throw new IllegalArgumentException("Week value out of range");
262                    }
263    
264                    checkWeeksOkay(w);
265    
266                    _weeks = w;
267            }
268    
269            /**
270             * Method toString
271             *
272             * @return String
273             */
274            @Override
275            public String toString() {
276                    StringBundler sb = new StringBundler(12);
277    
278                    sb.append(getClass().getName());
279                    sb.append("[weeks=");
280                    sb.append(_weeks);
281                    sb.append(",days=");
282                    sb.append(_days);
283                    sb.append(",hours=");
284                    sb.append(_hours);
285                    sb.append(",minutes=");
286                    sb.append(_minutes);
287                    sb.append(",seconds=");
288                    sb.append(_seconds);
289                    sb.append("]");
290    
291                    return sb.toString();
292            }
293    
294            /**
295             * Method checkNonWeeksOkay
296             */
297            protected void checkNonWeeksOkay(int f) {
298                    if ((f != 0) && (_weeks != 0)) {
299                            throw new IllegalStateException(
300                                    "Weeks and non-weeks are incompatible");
301                    }
302            }
303    
304            /**
305             * Method checkWeeksOkay
306             */
307            protected void checkWeeksOkay(int f) {
308                    if ((f != 0) &&
309                            ((_days != 0) || (_hours != 0) || (_minutes != 0) ||
310                             (_seconds != 0))) {
311    
312                            throw new IllegalStateException(
313                                    "Weeks and non-weeks are incompatible");
314                    }
315            }
316    
317            /**
318             * Method normalize
319             */
320            protected void normalize() {
321                    _minutes += _seconds / _SECONDS_PER_MINUTE;
322                    _seconds %= _SECONDS_PER_MINUTE;
323                    _hours += _minutes / _MINUTES_PER_HOUR;
324                    _minutes %= _MINUTES_PER_HOUR;
325                    _days += _hours / _HOURS_PER_DAY;
326                    _hours %= _HOURS_PER_DAY;
327            }
328    
329            /**
330             * Field DAYS_PER_WEEK
331             */
332            private static final int _DAYS_PER_WEEK = 7;
333    
334            /**
335             * Field HOURS_PER_DAY
336             */
337            private static final int _HOURS_PER_DAY = 24;
338    
339            /**
340             * Field MILLIS_PER_DAY
341             */
342            private static final long _MILLIS_PER_DAY =
343                    Duration._HOURS_PER_DAY * Duration._MILLIS_PER_HOUR;
344    
345            /**
346             * Field MILLIS_PER_HOUR
347             */
348            private static final long _MILLIS_PER_HOUR =
349                    Duration._MINUTES_PER_HOUR * Duration._MILLIS_PER_MINUTE;
350    
351            /**
352             * Field MILLIS_PER_MINUTE
353             */
354            private static final long _MILLIS_PER_MINUTE =
355                    Duration._SECONDS_PER_MINUTE * Duration._MILLIS_PER_SECOND;
356    
357            /**
358             * Field MILLIS_PER_SECOND
359             */
360            private static final long _MILLIS_PER_SECOND = 1000;
361    
362            /**
363             * Field MILLIS_PER_WEEK
364             */
365            private static final long _MILLIS_PER_WEEK =
366                    Duration._DAYS_PER_WEEK * Duration._MILLIS_PER_DAY;
367    
368            /**
369             * Field MINUTES_PER_HOUR
370             */
371            private static final int _MINUTES_PER_HOUR = 60;
372    
373            /**
374             * Field SECONDS_PER_MINUTE
375             */
376            private static final int _SECONDS_PER_MINUTE = 60;
377    
378            /**
379             * Field days
380             */
381            private int _days;
382    
383            /**
384             * Field hours
385             */
386            private int _hours;
387    
388            /**
389             * Field minutes
390             */
391            private int _minutes;
392    
393            /**
394             * Field seconds
395             */
396            private int _seconds;
397    
398            /**
399             * Field weeks
400             */
401            private int _weeks;
402    
403    }