001    /**
002     * Copyright (c) 2000-present 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                    Class<?> clazz = getClass();
279    
280                    sb.append(clazz.getName());
281    
282                    sb.append("[weeks=");
283                    sb.append(_weeks);
284                    sb.append(",days=");
285                    sb.append(_days);
286                    sb.append(",hours=");
287                    sb.append(_hours);
288                    sb.append(",minutes=");
289                    sb.append(_minutes);
290                    sb.append(",seconds=");
291                    sb.append(_seconds);
292                    sb.append("]");
293    
294                    return sb.toString();
295            }
296    
297            /**
298             * Method checkNonWeeksOkay
299             */
300            protected void checkNonWeeksOkay(int f) {
301                    if ((f != 0) && (_weeks != 0)) {
302                            throw new IllegalStateException(
303                                    "Weeks and non-weeks are incompatible");
304                    }
305            }
306    
307            /**
308             * Method checkWeeksOkay
309             */
310            protected void checkWeeksOkay(int f) {
311                    if ((f != 0) &&
312                            ((_days != 0) || (_hours != 0) || (_minutes != 0) ||
313                             (_seconds != 0))) {
314    
315                            throw new IllegalStateException(
316                                    "Weeks and non-weeks are incompatible");
317                    }
318            }
319    
320            /**
321             * Method normalize
322             */
323            protected void normalize() {
324                    _minutes += _seconds / _SECONDS_PER_MINUTE;
325                    _seconds %= _SECONDS_PER_MINUTE;
326                    _hours += _minutes / _MINUTES_PER_HOUR;
327                    _minutes %= _MINUTES_PER_HOUR;
328                    _days += _hours / _HOURS_PER_DAY;
329                    _hours %= _HOURS_PER_DAY;
330            }
331    
332            /**
333             * Field DAYS_PER_WEEK
334             */
335            private static final int _DAYS_PER_WEEK = 7;
336    
337            /**
338             * Field HOURS_PER_DAY
339             */
340            private static final int _HOURS_PER_DAY = 24;
341    
342            /**
343             * Field MILLIS_PER_DAY
344             */
345            private static final long _MILLIS_PER_DAY =
346                    Duration._HOURS_PER_DAY * Duration._MILLIS_PER_HOUR;
347    
348            /**
349             * Field MILLIS_PER_HOUR
350             */
351            private static final long _MILLIS_PER_HOUR =
352                    Duration._MINUTES_PER_HOUR * Duration._MILLIS_PER_MINUTE;
353    
354            /**
355             * Field MILLIS_PER_MINUTE
356             */
357            private static final long _MILLIS_PER_MINUTE =
358                    Duration._SECONDS_PER_MINUTE * Duration._MILLIS_PER_SECOND;
359    
360            /**
361             * Field MILLIS_PER_SECOND
362             */
363            private static final long _MILLIS_PER_SECOND = 1000;
364    
365            /**
366             * Field MILLIS_PER_WEEK
367             */
368            private static final long _MILLIS_PER_WEEK =
369                    Duration._DAYS_PER_WEEK * Duration._MILLIS_PER_DAY;
370    
371            /**
372             * Field MINUTES_PER_HOUR
373             */
374            private static final int _MINUTES_PER_HOUR = 60;
375    
376            /**
377             * Field SECONDS_PER_MINUTE
378             */
379            private static final int _SECONDS_PER_MINUTE = 60;
380    
381            /**
382             * Field days
383             */
384            private int _days;
385    
386            /**
387             * Field hours
388             */
389            private int _hours;
390    
391            /**
392             * Field minutes
393             */
394            private int _minutes;
395    
396            /**
397             * Field seconds
398             */
399            private int _seconds;
400    
401            /**
402             * Field weeks
403             */
404            private int _weeks;
405    
406    }