001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.social.util;
016    
017    import com.liferay.ibm.icu.util.Calendar;
018    import com.liferay.ibm.icu.util.GregorianCalendar;
019    import com.liferay.portal.kernel.util.GetterUtil;
020    import com.liferay.portal.kernel.util.Time;
021    import com.liferay.portal.util.PropsValues;
022    
023    import java.util.Date;
024    
025    /**
026     * @author Zsolt Berentey
027     */
028    public class SocialCounterPeriodUtil {
029    
030            public static int getActivityDay() {
031                    return getActivityDay(System.currentTimeMillis());
032            }
033    
034            public static int getActivityDay(Calendar calendar) {
035                    Date date = calendar.getTime();
036    
037                    return getActivityDay(date.getTime());
038            }
039    
040            public static int getActivityDay(long time) {
041                    return (int)((time / Time.DAY) - (_BASE_TIME / Time.DAY));
042            }
043    
044            public static Date getDate(int activityDay) {
045                    return new Date(_BASE_TIME + activityDay * Time.DAY);
046            }
047    
048            public static int getEndPeriod() {
049                    if (_isWithinPeriod(_startPeriod, _endPeriod, getActivityDay())) {
050                            return _endPeriod;
051                    }
052    
053                    _endPeriod = getStartPeriod() + getPeriodLength() - 1;
054    
055                    return _endPeriod;
056            }
057    
058            public static int getEndPeriod(int offset) {
059                    if (_isMonthlyPeriod()) {
060                            Calendar calendar = new GregorianCalendar();
061    
062                            calendar.set(Calendar.DATE, 1);
063    
064                            calendar.add(Calendar.MONTH, offset + 1);
065                            calendar.add(Calendar.DATE, -1);
066    
067                            calendar.set(Calendar.HOUR_OF_DAY, 0);
068                            calendar.set(Calendar.MINUTE, 0);
069                            calendar.set(Calendar.SECOND, 0);
070                            calendar.set(Calendar.MILLISECOND, 0);
071    
072                            return getActivityDay(calendar);
073                    }
074    
075                    return getEndPeriod() - offset * getPeriodLength();
076            }
077    
078            public static int getEndPeriod(long time) {
079                    int activityDay = getActivityDay(time);
080    
081                    int offset = 0;
082    
083                    while (getStartPeriod(offset) > activityDay) {
084                            offset--;
085                    }
086    
087                    return getEndPeriod(offset);
088            }
089    
090            public static int getFirstActivityDayOfYear() {
091                    Calendar calendar = new GregorianCalendar();
092    
093                    calendar.set(Calendar.MONTH, 0);
094                    calendar.set(Calendar.DATE, 1);
095                    calendar.set(Calendar.HOUR_OF_DAY, 0);
096                    calendar.set(Calendar.MINUTE, 0);
097                    calendar.set(Calendar.SECOND, 0);
098                    calendar.set(Calendar.MILLISECOND, 0);
099    
100                    return getActivityDay(calendar);
101            }
102    
103            public static int getPeriodLength() {
104                    if (_isMonthlyPeriod()) {
105                            if (_isWithinPeriod(_startPeriod, _endPeriod, getActivityDay())) {
106                                    return _periodLength;
107                            }
108    
109                            Calendar calendar = new GregorianCalendar();
110    
111                            calendar.set(Calendar.DATE, 1);
112                            calendar.set(Calendar.HOUR_OF_DAY, 0);
113                            calendar.set(Calendar.MINUTE, 0);
114                            calendar.set(Calendar.SECOND, 0);
115                            calendar.set(Calendar.MILLISECOND, 0);
116    
117                            _startPeriod = getActivityDay(calendar);
118    
119                            _periodLength = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
120    
121                            _endPeriod = _startPeriod + _periodLength - 1;
122    
123                            return _periodLength;
124                    }
125    
126                    if (_periodLength == 0) {
127                            _periodLength = GetterUtil.getInteger(
128                                    PropsValues.SOCIAL_ACTIVITY_COUNTER_PERIOD_LENGTH);
129                    }
130    
131                    return _periodLength;
132            }
133    
134            public static int getStartPeriod() {
135                    if (_isWithinPeriod(_startPeriod, _endPeriod, getActivityDay())) {
136                            return _startPeriod;
137                    }
138    
139                    if (_isMonthlyPeriod()) {
140                            Calendar calendar = new GregorianCalendar();
141    
142                            calendar.set(Calendar.DATE, 1);
143                            calendar.set(Calendar.HOUR_OF_DAY, 0);
144                            calendar.set(Calendar.MINUTE, 0);
145                            calendar.set(Calendar.SECOND, 0);
146                            calendar.set(Calendar.MILLISECOND, 0);
147    
148                            _startPeriod = getActivityDay(calendar);
149    
150                            return _startPeriod;
151                    }
152    
153                    _startPeriod = getActivityDay() / getPeriodLength() * getPeriodLength();
154    
155                    return _startPeriod;
156            }
157    
158            public static int getStartPeriod(int offset) {
159                    if (_isMonthlyPeriod()) {
160                            Calendar calendar = new GregorianCalendar();
161    
162                            calendar.set(Calendar.DATE, 1);
163    
164                            calendar.add(Calendar.MONTH, offset);
165    
166                            calendar.set(Calendar.HOUR_OF_DAY, 0);
167                            calendar.set(Calendar.MINUTE, 0);
168                            calendar.set(Calendar.SECOND, 0);
169                            calendar.set(Calendar.MILLISECOND, 0);
170    
171                            return getActivityDay(calendar.getTime().getTime());
172                    }
173    
174                    return getStartPeriod() - offset * getPeriodLength();
175            }
176    
177            public static int getStartPeriod(long time) {
178                    int activityDay = getActivityDay(time);
179    
180                    int offset = 0;
181    
182                    while (getStartPeriod(offset) > activityDay) {
183                            offset--;
184                    }
185    
186                    return getStartPeriod(offset);
187            }
188    
189            private static boolean _isMonthlyPeriod() {
190                    if (PropsValues.SOCIAL_ACTIVITY_COUNTER_PERIOD_LENGTH.equals("month")) {
191                            return true;
192                    }
193                    else {
194                            return false;
195                    }
196            }
197    
198            private static boolean _isWithinPeriod(
199                    int startPeriod, int endPeriod, int activityDay) {
200    
201                    if ((activityDay >= startPeriod) && (activityDay <= endPeriod)) {
202                            return true;
203                    }
204                    else {
205                            return false;
206                    }
207            }
208    
209            private static final long _BASE_TIME =
210                    new GregorianCalendar(2011, Calendar.JANUARY, 1).getTimeInMillis();
211    
212            private static int _endPeriod;
213            private static int _periodLength = -1;
214            private static int _startPeriod;
215    
216    }