001    /**
002     * Copyright (c) 2000-2012 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 d, int h, int m, int s) {
069                    _days = d;
070                    _hours = h;
071                    _minutes = m;
072                    _seconds = s;
073            }
074    
075            /**
076             * Constructor Duration
077             */
078            public Duration(int h, int m, int s) {
079                    this(0, h, m, s);
080            }
081    
082            /**
083             * Constructor Duration
084             */
085            public Duration(int w) {
086                    _weeks = w;
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 e) {
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 _seconds * _MILLIS_PER_SECOND + _minutes * _MILLIS_PER_MINUTE
148                               + _hours * _MILLIS_PER_HOUR + _days * _MILLIS_PER_DAY
149                               + _weeks * _MILLIS_PER_WEEK;
150            }
151    
152            /**
153             * Method getMinutes
154             *
155             * @return int
156             */
157            public int getMinutes() {
158                    return _minutes;
159            }
160    
161            /**
162             * Method getSeconds
163             *
164             * @return int
165             */
166            public int getSeconds() {
167                    return _seconds;
168            }
169    
170            /**
171             * Method getWeeks
172             *
173             * @return int
174             */
175            public int getWeeks() {
176                    return _weeks;
177            }
178    
179            /**
180             * Method setDays
181             */
182            public void setDays(int d) {
183                    if (d < 0) {
184                            throw new IllegalArgumentException("Day value out of range");
185                    }
186    
187                    checkNonWeeksOkay(d);
188    
189                    _days = d;
190    
191                    normalize();
192            }
193    
194            /**
195             * Method setHours
196             */
197            public void setHours(int h) {
198                    if (h < 0) {
199                            throw new IllegalArgumentException("Hour value out of range");
200                    }
201    
202                    checkNonWeeksOkay(h);
203    
204                    _hours = h;
205    
206                    normalize();
207            }
208    
209            /**
210             * Method setInterval
211             */
212            public void setInterval(long millis) {
213                    if (millis < 0) {
214                            throw new IllegalArgumentException("Negative-length interval");
215                    }
216    
217                    clear();
218    
219                    _days = (int)(millis / _MILLIS_PER_DAY);
220                    _seconds = (int)((millis % _MILLIS_PER_DAY) / _MILLIS_PER_SECOND);
221    
222                    normalize();
223            }
224    
225            /**
226             * Method setMinutes
227             */
228            public void setMinutes(int m) {
229                    if (m < 0) {
230                            throw new IllegalArgumentException("Minute value out of range");
231                    }
232    
233                    checkNonWeeksOkay(m);
234    
235                    _minutes = m;
236    
237                    normalize();
238            }
239    
240            /**
241             * Method setSeconds
242             */
243            public void setSeconds(int s) {
244                    if (s < 0) {
245                            throw new IllegalArgumentException("Second value out of range");
246                    }
247    
248                    checkNonWeeksOkay(s);
249    
250                    _seconds = s;
251    
252                    normalize();
253            }
254    
255            /**
256             * Method setWeeks
257             */
258            public void setWeeks(int w) {
259                    if (w < 0) {
260                            throw new IllegalArgumentException("Week value out of range");
261                    }
262    
263                    checkWeeksOkay(w);
264    
265                    _weeks = w;
266            }
267    
268            /**
269             * Method toString
270             *
271             * @return String
272             */
273            @Override
274            public String toString() {
275                    StringBundler sb = new StringBundler(12);
276    
277                    sb.append(getClass().getName());
278                    sb.append("[weeks=");
279                    sb.append(_weeks);
280                    sb.append(",days=");
281                    sb.append(_days);
282                    sb.append(",hours=");
283                    sb.append(_hours);
284                    sb.append(",minutes=");
285                    sb.append(_minutes);
286                    sb.append(",seconds=");
287                    sb.append(_seconds);
288                    sb.append("]");
289    
290                    return sb.toString();
291            }
292    
293            /**
294             * Method checkNonWeeksOkay
295             */
296            protected void checkNonWeeksOkay(int f) {
297                    if ((f != 0) && (_weeks != 0)) {
298                            throw new IllegalStateException(
299                                    "Weeks and non-weeks are incompatible");
300                    }
301            }
302    
303            /**
304             * Method checkWeeksOkay
305             */
306            protected void checkWeeksOkay(int f) {
307                    if ((f != 0)
308                            && ((_days != 0) || (_hours != 0) || (_minutes != 0)
309                                    || (_seconds != 0))) {
310                            throw new IllegalStateException(
311                                    "Weeks and non-weeks are incompatible");
312                    }
313            }
314    
315            /**
316             * Method normalize
317             */
318            protected void normalize() {
319                    _minutes += _seconds / _SECONDS_PER_MINUTE;
320                    _seconds %= _SECONDS_PER_MINUTE;
321                    _hours += _minutes / _MINUTES_PER_HOUR;
322                    _minutes %= _MINUTES_PER_HOUR;
323                    _days += _hours / _HOURS_PER_DAY;
324                    _hours %= _HOURS_PER_DAY;
325            }
326    
327            /**
328             * Field DAYS_PER_WEEK
329             */
330            private static final int _DAYS_PER_WEEK = 7;
331    
332            /**
333             * Field HOURS_PER_DAY
334             */
335            private static final int _HOURS_PER_DAY = 24;
336    
337            /**
338             * Field MILLIS_PER_DAY
339             */
340            private static final long _MILLIS_PER_DAY =
341                    Duration._HOURS_PER_DAY * Duration._MILLIS_PER_HOUR;
342    
343            /**
344             * Field MILLIS_PER_HOUR
345             */
346            private static final long _MILLIS_PER_HOUR =
347                    Duration._MINUTES_PER_HOUR * Duration._MILLIS_PER_MINUTE;
348    
349            /**
350             * Field MILLIS_PER_MINUTE
351             */
352            private static final long _MILLIS_PER_MINUTE =
353                    Duration._SECONDS_PER_MINUTE * Duration._MILLIS_PER_SECOND;
354    
355            /**
356             * Field MILLIS_PER_SECOND
357             */
358            private static final long _MILLIS_PER_SECOND = 1000;
359    
360            /**
361             * Field MILLIS_PER_WEEK
362             */
363            private static final long _MILLIS_PER_WEEK =
364                    Duration._DAYS_PER_WEEK * Duration._MILLIS_PER_DAY;
365    
366            /**
367             * Field MINUTES_PER_HOUR
368             */
369            private static final int _MINUTES_PER_HOUR = 60;
370    
371            /**
372             * Field SECONDS_PER_MINUTE
373             */
374            private static final int _SECONDS_PER_MINUTE = 60;
375    
376            /**
377             * Field days
378             */
379            private int _days;
380    
381            /**
382             * Field hours
383             */
384            private int _hours;
385    
386            /**
387             * Field minutes
388             */
389            private int _minutes;
390    
391            /**
392             * Field seconds
393             */
394            private int _seconds;
395    
396            /**
397             * Field weeks
398             */
399            private int _weeks;
400    
401    }