diff --git a/commons-component-common/src/main/java/org/exoplatform/commons/notification/impl/service/template/DigestorServiceImpl.java b/commons-component-common/src/main/java/org/exoplatform/commons/notification/impl/service/template/DigestorServiceImpl.java index e0c3dcf64b..48f4a0e4d9 100644 --- a/commons-component-common/src/main/java/org/exoplatform/commons/notification/impl/service/template/DigestorServiceImpl.java +++ b/commons-component-common/src/main/java/org/exoplatform/commons/notification/impl/service/template/DigestorServiceImpl.java @@ -43,9 +43,9 @@ import org.exoplatform.commons.notification.impl.NotificationContextImpl; import org.exoplatform.commons.notification.job.NotificationJob; import org.exoplatform.commons.notification.template.TemplateUtils; +import org.exoplatform.commons.utils.TimeConvertUtils; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; -import org.exoplatform.webui.utils.TimeConvertUtils; public class DigestorServiceImpl implements DigestorService { private static final Log LOG = ExoLogger.getLogger(DigestorServiceImpl.class); diff --git a/commons-component-common/src/main/java/org/exoplatform/commons/utils/TimeConvertUtils.java b/commons-component-common/src/main/java/org/exoplatform/commons/utils/TimeConvertUtils.java new file mode 100644 index 0000000000..b7f36c21bd --- /dev/null +++ b/commons-component-common/src/main/java/org/exoplatform/commons/utils/TimeConvertUtils.java @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2003-2011 eXo Platform SAS. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see. + */ +package org.exoplatform.commons.utils; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.ResourceBundle; + +import org.apache.commons.lang3.ArrayUtils; +import org.exoplatform.container.ExoContainerContext; +import org.exoplatform.services.log.ExoLogger; +import org.exoplatform.services.log.Log; +import org.exoplatform.services.resources.ResourceBundleService; +import org.exoplatform.web.application.RequestContext; + +/** + * Created by The eXo Platform SAS + * Author : Vu Duy Tu + * tu.duy@exoplatform.com + * Jul 5, 2011 + */ +public class TimeConvertUtils { + private static final Log LOG = ExoLogger.getLogger(TimeConvertUtils.class); + + public static String[] strs = new String[] { "SECOND", "MINUTE", "HOUR", "DAY", + "WEEK", "MONTH", "YEAR", "DECADE"}; + + public static int DAY = 3; + + public static int WEEK = 4; + + public static int MONTH = 5; + + public static int YEAR = 6; + + private static float MINISECOND_OF_MINUTE = 60 * 1000.0f; + + private static float MINUTE_OF_HOUR = 60.0f; + + private static float HOUR_OF_DAY = 24.0f; + + private static float DAY_OF_WEEK = 7.0f; + + private static float WEEK_OF_MONTH = 4.33f; + + private static float MONTH_OF_YEAR = 12; + + private static float YEAR_OF_DECADE = 10.0f; + + private static Float[] timeLength = new Float[] { MINISECOND_OF_MINUTE, MINUTE_OF_HOUR, HOUR_OF_DAY, + DAY_OF_WEEK, WEEK_OF_MONTH, MONTH_OF_YEAR, + YEAR_OF_DECADE, YEAR_OF_DECADE }; + private static String JUSTNOW = "JUSTNOW"; + + private static String SPACE = " "; + + private static String STR_EMPTY = ""; + + private static String STR_S = "_S"; + + private static String UNDERSCORE = "_"; + + private static String RESOURCE_KEY = "TimeConvert.type."; + + private static String convertXTimeAgo(Date myDate, Date baseDate){ + float delta = (baseDate.getTime() - myDate.getTime()); + int i = 0; + for (i = 0; (delta >= timeLength[i]) && i < timeLength.length - 1; i++) { + delta = delta / timeLength[i]; + } + int l = (int) delta; + if (l < 0 || i < 1) { + return JUSTNOW; + } + return new StringBuilder().append(l).append(SPACE) + .append(strs[i]).append((l > 1) ? STR_S : STR_EMPTY).toString(); + } + + public static String convertXTimeAgo(Date myDate, String format) { + return convertXTimeAgo(myDate, format, null); + } + + public static String convertXTimeAgo(Date myDate, String format, Locale locale) { + return convertXTimeAgo(myDate, format, locale, 0); + } + + public static String convertXTimeAgo(Date myDate, String format, int limit) { + return convertXTimeAgo(myDate, format, null, limit); + } + + /** + * Convert date to display string with format X time ago + * + * @param myDate The object date input for convert, it must has ZoneTime is server ZoneTime + * @param format The date/time format + * @param locale The Local of current location(language/country). + * @param limit The value set for limit convert x time ago. It must is: TimeConvertUtils.YEAR, MONTH, WEEK, DAY. + * @return String + */ + public static String convertXTimeAgoByTimeServer(Date myDate, String format, Locale locale, int limit) { + Date baseDate = Calendar.getInstance().getTime(); + return convertXTimeAgo(myDate, baseDate, format, locale, limit); + } + + /** + * Convert date to display string with format X time ago + * + * @param myDate The object date input for convert, it must has ZoneTime is GMT+0 + * @param format The date/time format + * @param locale The Local of current location(language/country). + * @param limit The value set for limit convert x time ago. It must is: TimeConvertUtils.YEAR, MONTH, WEEK, DAY. + * @return String + */ + public static String convertXTimeAgo(Date myDate, String format, Locale locale, int limit) { + Date baseDate = getGreenwichMeanTime().getTime(); + return convertXTimeAgo(myDate, baseDate, format, locale, limit); + } + + private static String convertXTimeAgo(Date myDate, Date baseDate, String format, Locale locale, int limit) { + String[] values = convertXTimeAgo(myDate, baseDate).split(SPACE); + if (values[0].equals(JUSTNOW)) + return getResourceBundle(RESOURCE_KEY + JUSTNOW, locale); + int i = ArrayUtils.indexOf(strs, values[1].replace(STR_S, STR_EMPTY)); + if (limit == 0 || i < limit) { + return getMessage(getResourceBundle(RESOURCE_KEY + values[1].replace(UNDERSCORE, STR_EMPTY), + locale), + new String[] { values[0] }); + } + + if (locale != null) { + return getFormatDate(myDate, format, locale); + } else { + return getFormatDate(myDate, format); + } + } + + public static String getFormatDate(Date myDate, String format) { + return getFormatDate(myDate, format, getLocale()); + } + + public static String getFormatDate(Date myDate, String format, Locale locale) { + /* h,hh,H, m, mm, d, dd, EEE, EEEE, M, MM, MMM, MMMM, yy, yyyy */ + if (myDate == null) + return STR_EMPTY; + return new SimpleDateFormat(format, locale).format(myDate); + } + + private static String getResourceBundle(String key, Locale locale) { + if (locale == null) { + locale = getLocale(); + } + ResourceBundle res = null; + RequestContext ctx = RequestContext.getCurrentInstance(); + if (ctx != null) { + res = ctx.getApplicationResourceBundle(); + } + // if null, try another way + ResourceBundleService bundleService = ExoContainerContext.getCurrentContainer() + .getComponentInstanceOfType(ResourceBundleService.class); + if (res == null && bundleService != null) { + res = bundleService.getResourceBundle("locale.commons.Commons", locale); + } + // still null + String keyString = key.substring(key.lastIndexOf(".") + 1).toLowerCase(); + if (res == null) { + LOG.warn("Can not resource bundle by key: " + key); + return keyString; + } + try { + return res.getString(key); + } catch (java.util.MissingResourceException missingResourceException) { + LOG.warn("Can't find resource for key {}, language {}", key, locale.toString()); + return keyString; + } + } + + private static String getMessage(String message, String[] args) { + if (message != null && args != null) { + String oldMes = message; + for (int i = 0; i < args.length; i++) { + message = message.replace("{" + i + "}", args[i]); + } + if(message.equals(oldMes) && args.length == 1) { + message = args[0] + SPACE + message; + } + } + return message; + } + + /** + * Get current {@link Locale} + * @return {@link Locale} + */ + public static Locale getLocale() { + RequestContext ctx = RequestContext.getCurrentInstance(); + if (ctx == null) { + return Locale.ENGLISH; + } + + Locale locale = ctx.getLocale(); + if (locale == null) { + return Locale.ENGLISH; + } + + return locale; + } + + /** + * Get current time GMT/Zulu or UTC,(zone time is 0+GMT) + * @return Calendar + */ + public static Calendar getGreenwichMeanTime() { + Calendar calendar = GregorianCalendar.getInstance(); + calendar.setLenient(false); + int gmtoffset = calendar.get(Calendar.DST_OFFSET) + calendar.get(Calendar.ZONE_OFFSET); + calendar.setTimeInMillis(System.currentTimeMillis() - gmtoffset); + return calendar; + } + + /** + * Cleanup the string to be valid of Java variable + * Ex: input = "123 sdkjh s;:sdlkjh d" + * output = "_123_sdkjh_s__sdlkjh_d" + * @return + */ + public static String santializeJavaVariable(String input) { + String s = input; + StringBuilder sb = new StringBuilder(); + if(!Character.isJavaIdentifierStart(s.charAt(0))) { + sb.append("_"); + } + for (char c : s.toCharArray()) { + if(!Character.isJavaIdentifierPart(c)) { + sb.append("_"); + } else { + sb.append(c); + } + } + + return sb.toString(); + } +} diff --git a/commons-component-common/src/test/java/org/exoplatform/commons/utils/TestTimeConvertUtils.java b/commons-component-common/src/test/java/org/exoplatform/commons/utils/TestTimeConvertUtils.java new file mode 100644 index 0000000000..fc3fd7d9e8 --- /dev/null +++ b/commons-component-common/src/test/java/org/exoplatform/commons/utils/TestTimeConvertUtils.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2003-2011 eXo Platform SAS. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see. + */ +package org.exoplatform.commons.utils; + +import java.util.Calendar; +import java.util.Locale; + +import junit.framework.TestCase; + +/** + * Created by The eXo Platform SAS + * Author : Vu Duy Tu + * tu.duy@exoplatform.com + * Sep 30, 2011 + */ +public class TestTimeConvertUtils extends TestCase { + public TestTimeConvertUtils() throws Exception { + super(); + } + + public void testConvertDateTimeByCurrentDate() throws Exception { + Calendar cal = Calendar.getInstance(); + long day = 24 * 60 * 60 * 1000; + cal.setTimeInMillis(cal.getTimeInMillis() - 3 * (31 * day)); + assertEquals("3 months", TimeConvertUtils.convertXTimeAgoByTimeServer(cal.getTime(), "EE, dd yyyy", Locale.ENGLISH, TimeConvertUtils.YEAR)); + + cal = Calendar.getInstance(); + cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) - 9); + assertEquals("1 week", TimeConvertUtils.convertXTimeAgoByTimeServer(cal.getTime(), "EE, dd yyyy", Locale.ENGLISH, TimeConvertUtils.YEAR)); + + cal = Calendar.getInstance(); + cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) - 5); + assertEquals("5 days", TimeConvertUtils.convertXTimeAgoByTimeServer(cal.getTime(), "EE, dd yyyy", Locale.ENGLISH, TimeConvertUtils.YEAR)); + + cal = Calendar.getInstance(); + cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) - 1); + assertEquals("1 hour", TimeConvertUtils.convertXTimeAgoByTimeServer(cal.getTime(), "EE, dd yyyy", Locale.ENGLISH, TimeConvertUtils.YEAR)); + + cal = Calendar.getInstance(); + cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) - 25); + assertEquals("25 minutes", TimeConvertUtils.convertXTimeAgoByTimeServer(cal.getTime(), "EE, dd yyyy", Locale.ENGLISH, TimeConvertUtils.YEAR)); + + cal = Calendar.getInstance(); + cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) - 10); + assertEquals("justnow", TimeConvertUtils.convertXTimeAgoByTimeServer(cal.getTime(), "EE, dd yyyy", Locale.ENGLISH, TimeConvertUtils.YEAR)); + } + + public void testConvertDateTime() throws Exception { + long timeNow = TimeConvertUtils.getGreenwichMeanTime().getTimeInMillis(); + Calendar calendar = Calendar.getInstance(); + String format = "M-d-yyyy"; + long day = 24 * 60 * 60 * 1000; + // test for 1 year ago + calendar.setTimeInMillis(timeNow - 366 * day); + assertEquals("1 year", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + assertEquals(TimeConvertUtils.getFormatDate(calendar.getTime(), format), + TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, TimeConvertUtils.YEAR)); + // test for 2 years ago + calendar.setTimeInMillis(timeNow - 2 * 366 * day); + // set limit is year + assertEquals("2 years", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + + // test for 1 month ago + calendar.setTimeInMillis(timeNow - 31 * day); + assertEquals("1 month", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + // set limit is year + assertEquals("1 month", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, TimeConvertUtils.YEAR)); + // test for 2 months ago + calendar.setTimeInMillis(timeNow - (2 * 31 * day)); + assertEquals("2 months", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + // set limit is month + assertEquals(TimeConvertUtils.getFormatDate(calendar.getTime(), format), + TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, TimeConvertUtils.MONTH)); + + // test for 1 week ago + calendar.setTimeInMillis(timeNow - 7 * day); + assertEquals("1 week", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + // set limit is month + assertEquals("1 week", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, TimeConvertUtils.MONTH)); + // test for 2 weeks ago + calendar.setTimeInMillis(timeNow - 2 * 7 * day); + assertEquals("2 weeks", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + + // test for 1 day ago + calendar.setTimeInMillis(timeNow - day); + assertEquals("1 day", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + // test for 2 days ago + calendar.setTimeInMillis(timeNow - 2 * day); + assertEquals("2 days", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + // set limit day + assertEquals(TimeConvertUtils.getFormatDate(calendar.getTime(), format), + TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, TimeConvertUtils.DAY)); + + // test for 1 hour ago + calendar.setTimeInMillis(timeNow - 60 * 60 * 1000); + assertEquals("1 hour", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + // test for 2 hours ago + calendar.setTimeInMillis(timeNow - 2 * 60 * 60 * 1000); + assertEquals("2 hours", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + // set limit day + assertEquals("2 hours", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, TimeConvertUtils.DAY)); + + // test for 1 minute ago + calendar.setTimeInMillis(timeNow - 60 * 1000); + assertEquals("1 minute", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + // test for 2 minute ago + calendar.setTimeInMillis(timeNow - 2 * 60 * 1000); + assertEquals("2 minutes", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + + // test for less than 1 minute ago + calendar.setTimeInMillis(timeNow - 40 * 1000); + assertEquals("justnow", TimeConvertUtils.convertXTimeAgo(calendar.getTime(), format, null, 0)); + } + + public void testGetResourceBundle() { + // Can not test this function because: can not get resource bundle from test case. + } + + public void testGetLocale() { + // Can not test this function because: can not get PortalRequestContext. + } + + public void testGetFormatDate() { + Locale locale = new Locale(Locale.ENGLISH.getLanguage(), Locale.UK.getCountry()); + Calendar calendar = Calendar.getInstance(); + // set date time: 28/08/2011 at 15h 30m + calendar.set(2011, 07, 28, 15, 30); + assertEquals("", TimeConvertUtils.getFormatDate(null, "M-d-yyyy", locale)); + assertEquals("", TimeConvertUtils.getFormatDate(calendar.getTime(), "", locale)); + + assertEquals("8-28-2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "M-d-yyyy", locale)); + assertEquals("8-28-11", TimeConvertUtils.getFormatDate(calendar.getTime(), "M-d-yy", locale)); + assertEquals("08-28-11", TimeConvertUtils.getFormatDate(calendar.getTime(), "MM-dd-yy", locale)); + assertEquals("08-28-2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "MM-dd-yyyy", locale)); + assertEquals("2011-08-28", TimeConvertUtils.getFormatDate(calendar.getTime(), "yyyy-MM-dd", locale)); + assertEquals("11-08-28", TimeConvertUtils.getFormatDate(calendar.getTime(), "yy-MM-dd", locale)); + assertEquals("28-08-2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "dd-MM-yyyy", locale)); + assertEquals("28-08-11", TimeConvertUtils.getFormatDate(calendar.getTime(), "dd-MM-yy", locale)); + assertEquals("8/28/2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "M/d/yyyy", locale)); + assertEquals("8/28/11", TimeConvertUtils.getFormatDate(calendar.getTime(), "M/d/yy", locale)); + assertEquals("08/28/11", TimeConvertUtils.getFormatDate(calendar.getTime(), "MM/dd/yy", locale)); + assertEquals("08/28/2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "MM/dd/yyyy", locale)); + assertEquals("2011/08/28", TimeConvertUtils.getFormatDate(calendar.getTime(), "yyyy/MM/dd", locale)); + assertEquals("11/08/28", TimeConvertUtils.getFormatDate(calendar.getTime(), "yy/MM/dd", locale)); + assertEquals("28/08/2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "dd/MM/yyyy", locale)); + assertEquals("28/08/11", TimeConvertUtils.getFormatDate(calendar.getTime(), "dd/MM/yy", locale)); + + assertEquals("Sun, August 28, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "EEE, MMMM dd, yyyy", locale)); + assertEquals("Sunday, August 28, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "EEEE, MMMM dd, yyyy", locale)); + assertEquals("Sunday, 28 August, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "EEEE, dd MMMM, yyyy", locale)); + assertEquals("Sun, Aug 28, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "EEE, MMM dd, yyyy", locale)); + assertEquals("Sunday, Aug 28, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "EEEE, MMM dd, yyyy", locale)); + assertEquals("Sunday, 28 Aug, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "EEEE, dd MMM, yyyy", locale)); + assertEquals("August 28, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "MMMM dd, yyyy", locale)); + assertEquals("28 August, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "dd MMMM, yyyy", locale)); + assertEquals("Aug 28, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "MMM dd, yyyy", locale)); + assertEquals("28 Aug, 2011", TimeConvertUtils.getFormatDate(calendar.getTime(), "dd MMM, yyyy", locale)); + + assertEquals("28 Aug, 2011, 03:30 PM".toLowerCase(), TimeConvertUtils.getFormatDate(calendar.getTime(), "dd MMM, yyyy, hh:mm a", locale).toLowerCase()); + assertEquals("28 Aug, 2011, 15:30", TimeConvertUtils.getFormatDate(calendar.getTime(), "dd MMM, yyyy, HH:mm", locale)); + } + + + public void testValidJavaVariable() { + String input = "123 sdkjh s;:sdlkjh d"; + assertEquals("_123_sdkjh_s__sdlkjh_d", TimeConvertUtils.santializeJavaVariable(input)); + } + +}