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    package com.liferay.portlet.social.util;
016    
017    import com.liferay.portal.kernel.util.GetterUtil;
018    import com.liferay.portal.kernel.util.PropsKeys;
019    import com.liferay.portal.kernel.util.PropsUtil;
020    import com.liferay.portal.kernel.util.Time;
021    
022    import java.util.Calendar;
023    import java.util.Date;
024    import java.util.GregorianCalendar;
025    
026    /**
027     * @author Zsolt Berentey
028     */
029    public class SocialCounterPeriodUtil {
030    
031            public static int getActivityDay() {
032                    return getActivityDay(System.currentTimeMillis());
033            }
034    
035            public static int getActivityDay(Calendar calendar) {
036                    Date date = calendar.getTime();
037    
038                    return getActivityDay(date.getTime());
039            }
040    
041            public static int getActivityDay(long time) {
042                    return (int)((time / Time.DAY) - (_BASE_TIME / Time.DAY));
043            }
044    
045            public static Date getDate(int activityDay) {
046                    return new Date(_BASE_TIME + activityDay * Time.DAY);
047            }
048    
049            public static int getEndPeriod() {
050                    if (_isWithinPeriod(_startPeriod, _endPeriod, getActivityDay())) {
051                            return _endPeriod;
052                    }
053    
054                    _endPeriod = getStartPeriod() + getPeriodLength() - 1;
055    
056                    return _endPeriod;
057            }
058    
059            public static int getEndPeriod(int offset) {
060                    if (_isMonthlyPeriod()) {
061                            Calendar calendar = new GregorianCalendar();
062    
063                            calendar.set(Calendar.DATE, 1);
064    
065                            calendar.add(Calendar.MONTH, offset + 1);
066                            calendar.add(Calendar.DATE, -1);
067    
068                            calendar.set(Calendar.HOUR_OF_DAY, 0);
069                            calendar.set(Calendar.MINUTE, 0);
070                            calendar.set(Calendar.SECOND, 0);
071                            calendar.set(Calendar.MILLISECOND, 0);
072    
073                            return getActivityDay(calendar);
074                    }
075    
076                    return getEndPeriod() - offset * getPeriodLength();
077            }
078    
079            public static int getEndPeriod(long time) {
080                    int activityDay = getActivityDay(time);
081    
082                    int offset = 0;
083    
084                    while (getStartPeriod(offset) > activityDay) {
085                            offset--;
086                    }
087    
088                    return getEndPeriod(offset);
089            }
090    
091            public static int getFirstActivityDayOfYear() {
092                    Calendar calendar = new GregorianCalendar();
093    
094                    calendar.set(Calendar.MONTH, 0);
095                    calendar.set(Calendar.DATE, 1);
096                    calendar.set(Calendar.HOUR_OF_DAY, 0);
097                    calendar.set(Calendar.MINUTE, 0);
098                    calendar.set(Calendar.SECOND, 0);
099                    calendar.set(Calendar.MILLISECOND, 0);
100    
101                    return getActivityDay(calendar);
102            }
103    
104            public static int getOffset(int activityDay) {
105                    if (_isMonthlyPeriod()) {
106                            Calendar calendar = new GregorianCalendar();
107    
108                            Calendar calendar2 = new GregorianCalendar();
109    
110                            calendar2.setTimeInMillis(_BASE_TIME + activityDay * Time.DAY);
111    
112                            int monthDelta =
113                                    calendar.get(Calendar.MONTH) - calendar2.get(Calendar.MONTH);
114                            int yearDelta =
115                                    calendar.get(Calendar.YEAR) - calendar2.get(Calendar.YEAR);
116    
117                            return -(yearDelta * 12 + monthDelta);
118                    }
119    
120                    return -((getStartPeriod() - activityDay) / getPeriodLength());
121            }
122    
123            public static int getPeriodLength() {
124                    if (_isMonthlyPeriod()) {
125                            if (_isWithinPeriod(_startPeriod, _endPeriod, getActivityDay())) {
126                                    return _periodLength;
127                            }
128    
129                            Calendar calendar = new GregorianCalendar();
130    
131                            calendar.set(Calendar.DATE, 1);
132                            calendar.set(Calendar.HOUR_OF_DAY, 0);
133                            calendar.set(Calendar.MINUTE, 0);
134                            calendar.set(Calendar.SECOND, 0);
135                            calendar.set(Calendar.MILLISECOND, 0);
136    
137                            _startPeriod = getActivityDay(calendar);
138    
139                            _periodLength = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
140    
141                            _endPeriod = _startPeriod + _periodLength - 1;
142    
143                            return _periodLength;
144                    }
145    
146                    if (_periodLength == -1) {
147                            _periodLength = GetterUtil.getInteger(
148                                    _SOCIAL_ACTIVITY_COUNTER_PERIOD_LENGTH);
149                    }
150    
151                    return _periodLength;
152            }
153    
154            public static int getPeriodLength(int offset) {
155                    if (_isMonthlyPeriod()) {
156                            Calendar calendar = new GregorianCalendar();
157    
158                            calendar.set(Calendar.DATE, 1);
159                            calendar.set(Calendar.HOUR_OF_DAY, 0);
160                            calendar.set(Calendar.MINUTE, 0);
161                            calendar.set(Calendar.SECOND, 0);
162                            calendar.set(Calendar.MILLISECOND, 0);
163    
164                            calendar.add(Calendar.MONTH, offset);
165    
166                            return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
167                    }
168    
169                    return getPeriodLength();
170            }
171    
172            public static int getStartPeriod() {
173                    if (_isWithinPeriod(_startPeriod, _endPeriod, getActivityDay())) {
174                            return _startPeriod;
175                    }
176    
177                    if (_isMonthlyPeriod()) {
178                            Calendar calendar = new GregorianCalendar();
179    
180                            calendar.set(Calendar.DATE, 1);
181                            calendar.set(Calendar.HOUR_OF_DAY, 0);
182                            calendar.set(Calendar.MINUTE, 0);
183                            calendar.set(Calendar.SECOND, 0);
184                            calendar.set(Calendar.MILLISECOND, 0);
185    
186                            _startPeriod = getActivityDay(calendar);
187    
188                            return _startPeriod;
189                    }
190    
191                    _startPeriod = getActivityDay() / getPeriodLength() * getPeriodLength();
192    
193                    return _startPeriod;
194            }
195    
196            public static int getStartPeriod(int offset) {
197                    if (_isMonthlyPeriod()) {
198                            Calendar calendar = new GregorianCalendar();
199    
200                            calendar.set(Calendar.DATE, 1);
201    
202                            calendar.add(Calendar.MONTH, offset);
203    
204                            calendar.set(Calendar.HOUR_OF_DAY, 0);
205                            calendar.set(Calendar.MINUTE, 0);
206                            calendar.set(Calendar.SECOND, 0);
207                            calendar.set(Calendar.MILLISECOND, 0);
208    
209                            return getActivityDay(calendar.getTime().getTime());
210                    }
211    
212                    return getStartPeriod() + offset * getPeriodLength();
213            }
214    
215            public static int getStartPeriod(long time) {
216                    int activityDay = getActivityDay(time);
217    
218                    int offset = 0;
219    
220                    while (getStartPeriod(offset) > activityDay) {
221                            offset--;
222                    }
223    
224                    return getStartPeriod(offset);
225            }
226    
227            private static boolean _isMonthlyPeriod() {
228                    if (_SOCIAL_ACTIVITY_COUNTER_PERIOD_LENGTH.equals("month")) {
229                            return true;
230                    }
231                    else {
232                            return false;
233                    }
234            }
235    
236            private static boolean _isWithinPeriod(
237                    int startPeriod, int endPeriod, int activityDay) {
238    
239                    if ((activityDay >= startPeriod) && (activityDay <= endPeriod)) {
240                            return true;
241                    }
242                    else {
243                            return false;
244                    }
245            }
246    
247            private static final long _BASE_TIME = new GregorianCalendar(
248                    2011, Calendar.JANUARY, 1).getTimeInMillis();
249    
250            private static final String _SOCIAL_ACTIVITY_COUNTER_PERIOD_LENGTH =
251                    PropsUtil.get(PropsKeys.SOCIAL_ACTIVITY_COUNTER_PERIOD_LENGTH);
252    
253            private static int _endPeriod;
254            private static int _periodLength = -1;
255            private static int _startPeriod;
256    
257    }