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));
+ }
+
+}