TimeUtils needs to output localized strings like "5 days ago" and "6 months". In order to do this it needs a translation resource. Additionally, that resource can not be static because the single Gitblit server can handle multiple connections in different locales/languages. TimeUtils has changed from a collection of static methods to some static methods and some instance methods. A TimeUtils is instantiated with an optional resource bundle which contains the preferred translation. If the resourec bundle is null or the requested translation key does not exist, an English default will be used. This change required adjusting the signatures of several key methods and that cascaded out to adjusting those methods calls in many, many classes.tags/v1.0.0
@@ -37,7 +37,7 @@ public class DateCellRenderer extends DefaultTableCellRenderer { | |||
private static final long serialVersionUID = 1L; | |||
private final String pattern; | |||
public DateCellRenderer(String pattern, Color foreground) { | |||
this.pattern = (pattern == null ? "yyyy-MM-dd HH:mm" : pattern); | |||
setForeground(foreground); | |||
@@ -55,7 +55,7 @@ public class DateCellRenderer extends DefaultTableCellRenderer { | |||
title = "--"; | |||
dateString = "never"; | |||
} else { | |||
title = TimeUtils.timeAgo(date); | |||
title = Translation.getTimeUtils().timeAgo(date); | |||
dateString = new SimpleDateFormat(pattern).format((Date) value); | |||
} | |||
@@ -35,7 +35,6 @@ import com.gitblit.Constants; | |||
import com.gitblit.Constants.RpcRequest; | |||
import com.gitblit.models.ServerStatus; | |||
import com.gitblit.utils.ByteFormat; | |||
import com.gitblit.utils.TimeUtils; | |||
/** | |||
* This panel displays the server status. | |||
@@ -155,8 +154,8 @@ public class StatusPanel extends JPanel { | |||
ServerStatus status = gitblit.getStatus(); | |||
header.setText(Translation.get("gb.status")); | |||
version.setText(Constants.NAME + (status.isGO ? " GO v" : " WAR v") + status.version); | |||
releaseDate.setText(status.releaseDate); | |||
bootDate.setText(status.bootDate.toString() + " (" + TimeUtils.timeAgo(status.bootDate) | |||
releaseDate.setText(status.releaseDate); | |||
bootDate.setText(status.bootDate.toString() + " (" + Translation.getTimeUtils().timeAgo(status.bootDate) | |||
+ ")"); | |||
url.setText(gitblit.url); | |||
servletContainer.setText(status.servletContainer); |
@@ -18,6 +18,8 @@ package com.gitblit.client; | |||
import java.util.MissingResourceException; | |||
import java.util.ResourceBundle; | |||
import com.gitblit.utils.TimeUtils; | |||
/** | |||
* Loads the Gitblit language resource file. | |||
* | |||
@@ -27,6 +29,8 @@ import java.util.ResourceBundle; | |||
public class Translation { | |||
private final static ResourceBundle translation; | |||
private final static TimeUtils timeUtils; | |||
static { | |||
ResourceBundle bundle; | |||
@@ -38,6 +42,8 @@ public class Translation { | |||
bundle = ResourceBundle.getBundle("GitBlitWebApp"); | |||
} | |||
translation = bundle; | |||
timeUtils = new TimeUtils(translation); | |||
} | |||
public static String get(String key) { | |||
@@ -46,4 +52,8 @@ public class Translation { | |||
} | |||
return key; | |||
} | |||
public static TimeUtils getTimeUtils() { | |||
return timeUtils; | |||
} | |||
} |
@@ -297,8 +297,8 @@ public class IssueModel implements Serializable, Comparable<IssueModel> { | |||
@Override | |||
public String toString() { | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append(TimeUtils.timeAgo(created)); | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append(new TimeUtils().timeAgo(created)); | |||
switch (code) { | |||
case '+': | |||
sb.append(" created by "); |
@@ -15,9 +15,11 @@ | |||
*/ | |||
package com.gitblit.utils; | |||
import java.text.MessageFormat; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Calendar; | |||
import java.util.Date; | |||
import java.util.ResourceBundle; | |||
/** | |||
* Utility class of time functions. | |||
@@ -35,6 +37,16 @@ public class TimeUtils { | |||
public static final long ONEDAY = ONEHOUR * 24L; | |||
public static final long ONEYEAR = ONEDAY * 365L; | |||
private final ResourceBundle translation; | |||
public TimeUtils() { | |||
this(null); | |||
} | |||
public TimeUtils(ResourceBundle translation) { | |||
this.translation = translation; | |||
} | |||
/** | |||
* Returns true if date is today. | |||
@@ -67,21 +79,21 @@ public class TimeUtils { | |||
* @param days | |||
* @return duration as string in days, months, and/or years | |||
*/ | |||
public static String duration(int days) { | |||
public String duration(int days) { | |||
if (days <= 60) { | |||
return days + (days > 1 ? " days" : " day"); | |||
return (days > 1 ? translate(days, "gb.duration.days", "{0} days") : translate("gb.duration.oneDay", "1 day")); | |||
} else if (days < 365) { | |||
int rem = days % 30; | |||
return ((days / 30) + (rem >= 15 ? 1 : 0)) + " months"; | |||
return translate(((days / 30) + (rem >= 15 ? 1 : 0)), "gb.duration.months", "{0} months"); | |||
} else { | |||
int years = days / 365; | |||
int rem = days % 365; | |||
String yearsString = years + (years > 1 ? " years" : " year"); | |||
String yearsString = (years > 1 ? translate(years, "gb.duration.years", "{0} years") : translate("gb.duration.oneYear", "1 year")); | |||
if (rem < 30) { | |||
if (rem == 0) { | |||
return yearsString; | |||
} else { | |||
return yearsString + (rem >= 15 ? ", 1 month" : ""); | |||
return yearsString + (rem >= 15 ? (", " + translate("gb.duration.oneMonth", "1 month")): ""); | |||
} | |||
} else { | |||
int months = rem / 30; | |||
@@ -89,8 +101,8 @@ public class TimeUtils { | |||
if (remDays >= 15) { | |||
months++; | |||
} | |||
String monthsString = yearsString + ", " + months | |||
+ (months > 1 ? " months" : " month"); | |||
String monthsString = yearsString + ", " | |||
+ (months > 1 ? translate(months, "gb.duration.months", "{0} months") : translate("gb.duration.oneMonth", "1 month")); | |||
return monthsString; | |||
} | |||
} | |||
@@ -155,6 +167,14 @@ public class TimeUtils { | |||
return days; | |||
} | |||
public String today() { | |||
return translate("gb.time.today", "today"); | |||
} | |||
public String yesterday() { | |||
return translate("gb.time.yesterday", "yesterday"); | |||
} | |||
/** | |||
* Returns the string representation of the duration between now and the | |||
* date. | |||
@@ -162,7 +182,7 @@ public class TimeUtils { | |||
* @param date | |||
* @return duration as a string | |||
*/ | |||
public static String timeAgo(Date date) { | |||
public String timeAgo(Date date) { | |||
return timeAgo(date, false); | |||
} | |||
@@ -172,7 +192,7 @@ public class TimeUtils { | |||
* @param date | |||
* @return the css class | |||
*/ | |||
public static String timeAgoCss(Date date) { | |||
public String timeAgoCss(Date date) { | |||
return timeAgo(date, true); | |||
} | |||
@@ -184,7 +204,7 @@ public class TimeUtils { | |||
* @param css | |||
* @return the string representation of the duration OR the css class | |||
*/ | |||
private static String timeAgo(Date date, boolean css) { | |||
private String timeAgo(Date date, boolean css) { | |||
if (isToday(date) || isYesterday(date)) { | |||
int mins = minutesAgo(date, true); | |||
if (mins >= 120) { | |||
@@ -193,15 +213,18 @@ public class TimeUtils { | |||
} | |||
int hours = hoursAgo(date, true); | |||
if (hours > 23) { | |||
return "yesterday"; | |||
return yesterday(); | |||
} else { | |||
return hours + " hours ago"; | |||
return translate(hours, "gb.time.hoursAgo", "{0} hours ago"); | |||
} | |||
} | |||
if (css) { | |||
return "age0"; | |||
} | |||
return mins + " min" + (mins > 1 ? "s" : "") + " ago"; | |||
if (mins > 2) { | |||
return translate(mins, "gb.time.minsAgo", "{0} mins ago"); | |||
} | |||
return translate("gb.time.justNow", "just now"); | |||
} else { | |||
int days = daysAgo(date); | |||
if (css) { | |||
@@ -215,13 +238,13 @@ public class TimeUtils { | |||
} | |||
if (days < 365) { | |||
if (days <= 30) { | |||
return days + " days ago"; | |||
return translate(days, "gb.time.daysAgo", "{0} days ago"); | |||
} else if (days <= 90) { | |||
int weeks = days / 7; | |||
if (weeks == 12) { | |||
return "3 months ago"; | |||
return translate(3, "gb.time.monthsAgo", "{0} months ago"); | |||
} else { | |||
return weeks + " weeks ago"; | |||
return translate(weeks, "gb.time.weeksAgo", "{0} weeks ago"); | |||
} | |||
} | |||
int months = days / 30; | |||
@@ -229,21 +252,43 @@ public class TimeUtils { | |||
if (weeks >= 2) { | |||
months++; | |||
} | |||
return months + " months ago"; | |||
return translate(months, "gb.time.monthsAgo", "{0} months ago"); | |||
} else if (days == 365) { | |||
return "1 year ago"; | |||
return translate("gb.time.oneYearAgo", "1 year ago"); | |||
} else { | |||
int yr = days / 365; | |||
days = days % 365; | |||
int months = (yr * 12) + (days / 30); | |||
if (months > 23) { | |||
return yr + " years ago"; | |||
return translate(yr, "gb.time.yearsAgo", "{0} years ago"); | |||
} else { | |||
return months + " months ago"; | |||
return translate(months, "gb.time.monthsAgo", "{0} months ago"); | |||
} | |||
} | |||
} | |||
} | |||
private String translate(String key, String defaultValue) { | |||
String value = defaultValue; | |||
if (translation != null && translation.containsKey(key)) { | |||
String aValue = translation.getString(key); | |||
if (!StringUtils.isEmpty(aValue)) { | |||
value = aValue; | |||
} | |||
} | |||
return value; | |||
} | |||
private String translate(int val, String key, String defaultPattern) { | |||
String pattern = defaultPattern; | |||
if (translation != null && translation.containsKey(key)) { | |||
String aValue = translation.getString(key); | |||
if (!StringUtils.isEmpty(aValue)) { | |||
pattern = aValue; | |||
} | |||
} | |||
return MessageFormat.format(pattern, val); | |||
} | |||
/** | |||
* Convert a frequency string into minutes. |
@@ -418,7 +418,7 @@ public class WicketUtils { | |||
return params.getString("n", ""); | |||
} | |||
public static Label createDateLabel(String wicketId, Date date, TimeZone timeZone) { | |||
public static Label createDateLabel(String wicketId, Date date, TimeZone timeZone, TimeUtils timeUtils) { | |||
String format = GitBlit.getString(Keys.web.datestampShortFormat, "MM/dd/yy"); | |||
DateFormat df = new SimpleDateFormat(format); | |||
if (timeZone == null) { | |||
@@ -434,7 +434,7 @@ public class WicketUtils { | |||
String title = null; | |||
if (date.getTime() <= System.currentTimeMillis()) { | |||
// past | |||
title = TimeUtils.timeAgo(date); | |||
title = timeUtils.timeAgo(date); | |||
} | |||
if ((System.currentTimeMillis() - date.getTime()) < 10 * 24 * 60 * 60 * 1000L) { | |||
String tmp = dateString; | |||
@@ -442,14 +442,14 @@ public class WicketUtils { | |||
title = tmp; | |||
} | |||
Label label = new Label(wicketId, dateString); | |||
WicketUtils.setCssClass(label, TimeUtils.timeAgoCss(date)); | |||
WicketUtils.setCssClass(label, timeUtils.timeAgoCss(date)); | |||
if (!StringUtils.isEmpty(title)) { | |||
WicketUtils.setHtmlTooltip(label, title); | |||
} | |||
return label; | |||
} | |||
public static Label createTimeLabel(String wicketId, Date date, TimeZone timeZone) { | |||
public static Label createTimeLabel(String wicketId, Date date, TimeZone timeZone, TimeUtils timeUtils) { | |||
String format = GitBlit.getString(Keys.web.timeFormat, "HH:mm"); | |||
DateFormat df = new SimpleDateFormat(format); | |||
if (timeZone == null) { | |||
@@ -462,7 +462,7 @@ public class WicketUtils { | |||
} else { | |||
timeString = df.format(date); | |||
} | |||
String title = TimeUtils.timeAgo(date); | |||
String title = timeUtils.timeAgo(date); | |||
Label label = new Label(wicketId, timeString); | |||
if (!StringUtils.isEmpty(title)) { | |||
WicketUtils.setHtmlTooltip(label, title); | |||
@@ -470,7 +470,7 @@ public class WicketUtils { | |||
return label; | |||
} | |||
public static Label createDatestampLabel(String wicketId, Date date, TimeZone timeZone) { | |||
public static Label createDatestampLabel(String wicketId, Date date, TimeZone timeZone, TimeUtils timeUtils) { | |||
String format = GitBlit.getString(Keys.web.datestampLongFormat, "EEEE, MMMM d, yyyy"); | |||
DateFormat df = new SimpleDateFormat(format); | |||
if (timeZone == null) { | |||
@@ -485,12 +485,12 @@ public class WicketUtils { | |||
} | |||
String title = null; | |||
if (TimeUtils.isToday(date)) { | |||
title = "today"; | |||
title = timeUtils.today(); | |||
} else if (TimeUtils.isYesterday(date)) { | |||
title = "yesterday"; | |||
title = timeUtils.yesterday(); | |||
} else if (date.getTime() <= System.currentTimeMillis()) { | |||
// past | |||
title = TimeUtils.timeAgo(date); | |||
title = timeUtils.timeAgo(date); | |||
} | |||
if ((System.currentTimeMillis() - date.getTime()) < 10 * 24 * 60 * 60 * 1000L) { | |||
String tmp = dateString; | |||
@@ -504,7 +504,7 @@ public class WicketUtils { | |||
return label; | |||
} | |||
public static Label createTimestampLabel(String wicketId, Date date, TimeZone timeZone) { | |||
public static Label createTimestampLabel(String wicketId, Date date, TimeZone timeZone, TimeUtils timeUtils) { | |||
String format = GitBlit.getString(Keys.web.datetimestampLongFormat, | |||
"EEEE, MMMM d, yyyy HH:mm Z"); | |||
DateFormat df = new SimpleDateFormat(format); | |||
@@ -521,7 +521,7 @@ public class WicketUtils { | |||
String title = null; | |||
if (date.getTime() <= System.currentTimeMillis()) { | |||
// past | |||
title = TimeUtils.timeAgo(date); | |||
title = timeUtils.timeAgo(date); | |||
} | |||
Label label = new Label(wicketId, dateString); | |||
if (!StringUtils.isEmpty(title)) { |
@@ -17,6 +17,7 @@ package com.gitblit.wicket.pages; | |||
import java.util.LinkedHashMap; | |||
import java.util.Map; | |||
import java.util.ResourceBundle; | |||
import java.util.TimeZone; | |||
import javax.servlet.http.Cookie; | |||
@@ -47,6 +48,7 @@ import com.gitblit.GitBlit; | |||
import com.gitblit.Keys; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.utils.TimeUtils; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.WicketUtils; | |||
import com.gitblit.wicket.panels.LinkPanel; | |||
@@ -54,6 +56,8 @@ import com.gitblit.wicket.panels.LinkPanel; | |||
public abstract class BasePage extends WebPage { | |||
private final Logger logger; | |||
private transient TimeUtils timeUtils; | |||
public BasePage() { | |||
super(); | |||
@@ -75,6 +79,23 @@ public abstract class BasePage extends WebPage { | |||
} | |||
} | |||
protected String getLanguageCode() { | |||
return GitBlitWebSession.get().getLocale().getLanguage(); | |||
} | |||
protected TimeUtils getTimeUtils() { | |||
if (timeUtils == null) { | |||
ResourceBundle bundle; | |||
try { | |||
bundle = ResourceBundle.getBundle("com.gitblit.wicket.GitBlitWebApp", GitBlitWebSession.get().getLocale()); | |||
} catch (Throwable t) { | |||
bundle = ResourceBundle.getBundle("com.gitblit.wicket.GitBlitWebApp"); | |||
} | |||
timeUtils = new TimeUtils(bundle); | |||
} | |||
return timeUtils; | |||
} | |||
@Override | |||
protected void onBeforeRender() { | |||
if (GitBlit.isDebugMode()) { |
@@ -81,12 +81,12 @@ public class CommitPage extends RepositoryPage { | |||
// author | |||
add(createPersonPanel("commitAuthor", c.getAuthorIdent(), Constants.SearchType.AUTHOR)); | |||
add(WicketUtils.createTimestampLabel("commitAuthorDate", c.getAuthorIdent().getWhen(), | |||
getTimeZone())); | |||
getTimeZone(), getTimeUtils())); | |||
// committer | |||
add(createPersonPanel("commitCommitter", c.getCommitterIdent(), Constants.SearchType.COMMITTER)); | |||
add(WicketUtils.createTimestampLabel("commitCommitterDate", | |||
c.getCommitterIdent().getWhen(), getTimeZone())); | |||
c.getCommitterIdent().getWhen(), getTimeZone(), getTimeUtils())); | |||
add(new Label("commitId", c.getName())); | |||
@@ -129,7 +129,7 @@ public class CommitPage extends RepositoryPage { | |||
Constants.SearchType.AUTHOR)); | |||
item.add(new GravatarImage("noteAuthorAvatar", entry.notesRef.getAuthorIdent())); | |||
item.add(WicketUtils.createTimestampLabel("authorDate", entry.notesRef | |||
.getAuthorIdent().getWhen(), getTimeZone())); | |||
.getAuthorIdent().getWhen(), getTimeZone(), getTimeUtils())); | |||
item.add(new Label("noteContent", GitBlit.self().processCommitMessage( | |||
repositoryName, entry.content)).setEscapeModelStrings(false)); | |||
} |
@@ -52,8 +52,8 @@ public class FederationRegistrationPage extends RootSubPage { | |||
add(new Label("frequency", registration.frequency)); | |||
add(new Label("folder", registration.folder)); | |||
add(new Label("token", showAdmin ? registration.token : "--")); | |||
add(WicketUtils.createTimestampLabel("lastPull", registration.lastPull, getTimeZone())); | |||
add(WicketUtils.createTimestampLabel("nextPull", registration.nextPull, getTimeZone())); | |||
add(WicketUtils.createTimestampLabel("lastPull", registration.lastPull, getTimeZone(), getTimeUtils())); | |||
add(WicketUtils.createTimestampLabel("nextPull", registration.nextPull, getTimeZone(), getTimeUtils())); | |||
StringBuilder inclusions = new StringBuilder(); | |||
for (String inc : registration.inclusions) { |
@@ -234,7 +234,7 @@ public class LuceneSearchPage extends RootPage { | |||
item.add(new LinkPanel("branch", "branch", StringUtils.getRelativePath(Constants.R_HEADS, sr.branch), LogPage.class, WicketUtils.newObjectParameter(sr.repository, sr.branch))); | |||
} | |||
item.add(new Label("author", sr.author)); | |||
item.add(WicketUtils.createDatestampLabel("date", sr.date, getTimeZone())); | |||
item.add(WicketUtils.createDatestampLabel("date", sr.date, getTimeZone(), getTimeUtils())); | |||
} | |||
}; | |||
add(resultsView.setVisible(results.size() > 0)); |
@@ -41,7 +41,6 @@ import org.wicketstuff.googlecharts.ShapeMarker; | |||
import com.gitblit.models.Metric; | |||
import com.gitblit.utils.MetricUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.TimeUtils; | |||
import com.gitblit.wicket.WicketUtils; | |||
public class MetricsPage extends RepositoryPage { | |||
@@ -62,7 +61,7 @@ public class MetricsPage extends RepositoryPage { | |||
} else { | |||
add(new Label("branchStats", | |||
MessageFormat.format(getString("gb.branchStats"), metricsTotal.count, | |||
metricsTotal.tag, TimeUtils.duration(metricsTotal.duration)))); | |||
metricsTotal.tag, getTimeUtils().duration(metricsTotal.duration)))); | |||
} | |||
insertLinePlot("commitsChart", metrics); | |||
insertBarPlot("dayOfWeekChart", getDayOfWeekMetrics(r, objectId)); |
@@ -54,7 +54,7 @@ public class ReviewProposalPage extends RootSubPage { | |||
add(new Label("url", proposal.url)); | |||
add(new Label("message", proposal.message)); | |||
add(WicketUtils.createTimestampLabel("received", proposal.received, getTimeZone())); | |||
add(WicketUtils.createTimestampLabel("received", proposal.received, getTimeZone(), getTimeUtils())); | |||
add(new Label("token", proposal.token)); | |||
add(new Label("tokenType", proposal.tokenType.name())); | |||
@@ -49,7 +49,6 @@ import com.gitblit.utils.ArrayUtils; | |||
import com.gitblit.utils.JGitUtils; | |||
import com.gitblit.utils.MarkdownUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.TimeUtils; | |||
import com.gitblit.wicket.WicketUtils; | |||
import com.gitblit.wicket.panels.BranchesPanel; | |||
import com.gitblit.wicket.panels.LogPanel; | |||
@@ -84,13 +83,13 @@ public class SummaryPage extends RepositoryPage { | |||
add(new Label("repositoryOwner", getRepositoryModel().owner)); | |||
add(WicketUtils.createTimestampLabel("repositoryLastChange", | |||
JGitUtils.getLastChange(r), getTimeZone())); | |||
JGitUtils.getLastChange(r), getTimeZone(), getTimeUtils())); | |||
if (metricsTotal == null) { | |||
add(new Label("branchStats", "")); | |||
} else { | |||
add(new Label("branchStats", | |||
MessageFormat.format(getString("gb.branchStats"), metricsTotal.count, | |||
metricsTotal.tag, TimeUtils.duration(metricsTotal.duration)))); | |||
metricsTotal.tag, getTimeUtils().duration(metricsTotal.duration)))); | |||
} | |||
add(new BookmarkablePageLink<Void>("metrics", MetricsPage.class, | |||
WicketUtils.newRepositoryParameter(repositoryName))); |
@@ -87,7 +87,7 @@ public class TagPage extends RepositoryPage { | |||
if (tagRef.getAuthorIdent() != null) { | |||
when = tagRef.getAuthorIdent().getWhen(); | |||
} | |||
add(WicketUtils.createTimestampLabel("tagDate", when, getTimeZone())); | |||
add(WicketUtils.createTimestampLabel("tagDate", when, getTimeZone(), getTimeUtils())); | |||
addFullText("fullMessage", tagRef.getFullMessage(), true); | |||
} |
@@ -42,7 +42,7 @@ public class TicketPage extends RepositoryPage { | |||
add(new Label("ticketTitle", t.title)); | |||
add(new Label("ticketId", t.id)); | |||
add(new Label("ticketHandler", t.handler.toLowerCase())); | |||
add(WicketUtils.createTimestampLabel("ticketOpenDate", t.date, getTimeZone())); | |||
add(WicketUtils.createTimestampLabel("ticketOpenDate", t.date, getTimeZone(), getTimeUtils())); | |||
Label stateLabel = new Label("ticketState", t.state); | |||
WicketUtils.setTicketCssClass(stateLabel, t.state); | |||
add(stateLabel); | |||
@@ -56,7 +56,7 @@ public class TicketPage extends RepositoryPage { | |||
public void populateItem(final Item<Comment> item) { | |||
final Comment entry = item.getModelObject(); | |||
item.add(WicketUtils.createDateLabel("commentDate", entry.date, GitBlitWebSession | |||
.get().getTimezone())); | |||
.get().getTimezone(), getTimeUtils())); | |||
item.add(new Label("commentAuthor", entry.author.toLowerCase())); | |||
item.add(new Label("commentText", prepareComment(entry.text)) | |||
.setEscapeModelStrings(false)); |
@@ -52,7 +52,7 @@ public class TicketsPage extends RepositoryPage { | |||
WicketUtils.setTicketCssClass(stateLabel, entry.state); | |||
item.add(stateLabel); | |||
item.add(WicketUtils.createDateLabel("ticketDate", entry.date, GitBlitWebSession | |||
.get().getTimezone())); | |||
.get().getTimezone(), getTimeUtils())); | |||
item.add(new Label("ticketHandler", StringUtils.trimString( | |||
entry.handler.toLowerCase(), 30))); | |||
item.add(new LinkPanel("ticketTitle", "list subject", StringUtils.trimString( |
@@ -56,7 +56,7 @@ public class ActivityPanel extends BasePanel { | |||
public void populateItem(final Item<Activity> activityItem) { | |||
final Activity entry = activityItem.getModelObject(); | |||
activityItem.add(WicketUtils.createDatestampLabel("title", entry.startDate, getTimeZone())); | |||
activityItem.add(WicketUtils.createDatestampLabel("title", entry.startDate, getTimeZone(), getTimeUtils())); | |||
// display the commits in chronological order | |||
DataView<RepositoryCommit> commits = new DataView<RepositoryCommit>("commit", | |||
@@ -68,7 +68,7 @@ public class ActivityPanel extends BasePanel { | |||
// commit time of day | |||
commitItem.add(WicketUtils.createTimeLabel("time", commit.getCommitterIdent() | |||
.getWhen(), getTimeZone())); | |||
.getWhen(), getTimeZone(), getTimeUtils())); | |||
// avatar | |||
commitItem.add(new GravatarImage("avatar", commit.getAuthorIdent(), 36)); |
@@ -15,6 +15,7 @@ | |||
*/ | |||
package com.gitblit.wicket.panels; | |||
import java.util.ResourceBundle; | |||
import java.util.TimeZone; | |||
import org.apache.wicket.AttributeModifier; | |||
@@ -25,12 +26,15 @@ import org.apache.wicket.model.Model; | |||
import com.gitblit.Constants; | |||
import com.gitblit.GitBlit; | |||
import com.gitblit.Keys; | |||
import com.gitblit.utils.TimeUtils; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.WicketUtils; | |||
public abstract class BasePanel extends Panel { | |||
private static final long serialVersionUID = 1L; | |||
private transient TimeUtils timeUtils; | |||
public BasePanel(String wicketId) { | |||
super(wicketId); | |||
@@ -40,6 +44,19 @@ public abstract class BasePanel extends Panel { | |||
return GitBlit.getBoolean(Keys.web.useClientTimezone, false) ? GitBlitWebSession.get() | |||
.getTimezone() : GitBlit.getTimezone(); | |||
} | |||
protected TimeUtils getTimeUtils() { | |||
if (timeUtils == null) { | |||
ResourceBundle bundle; | |||
try { | |||
bundle = ResourceBundle.getBundle("com.gitblit.wicket.GitBlitWebApp", GitBlitWebSession.get().getLocale()); | |||
} catch (Throwable t) { | |||
bundle = ResourceBundle.getBundle("com.gitblit.wicket.GitBlitWebApp"); | |||
} | |||
timeUtils = new TimeUtils(bundle); | |||
} | |||
return timeUtils; | |||
} | |||
protected void setPersonSearchTooltip(Component component, String value, Constants.SearchType searchType) { | |||
if (searchType.equals(Constants.SearchType.AUTHOR)) { |
@@ -83,7 +83,7 @@ public class BranchesPanel extends BasePanel { | |||
public void populateItem(final Item<RefModel> item) { | |||
final RefModel entry = item.getModelObject(); | |||
item.add(WicketUtils.createDateLabel("branchDate", entry.getDate(), getTimeZone())); | |||
item.add(WicketUtils.createDateLabel("branchDate", entry.getDate(), getTimeZone(), getTimeUtils())); | |||
item.add(new LinkPanel("branchName", "list name", StringUtils.trimString( | |||
entry.displayName, 28), LogPage.class, WicketUtils.newObjectParameter( |
@@ -42,7 +42,7 @@ public class CommitHeaderPanel extends BasePanel { | |||
WicketUtils.newObjectParameter(repositoryName, c.getName()))); | |||
add(new Label("commitid", c.getName())); | |||
add(new Label("author", c.getAuthorIdent().getName())); | |||
add(WicketUtils.createDateLabel("date", c.getAuthorIdent().getWhen(), getTimeZone())); | |||
add(WicketUtils.createDateLabel("date", c.getAuthorIdent().getWhen(), getTimeZone(), getTimeUtils())); | |||
add(new GravatarImage("authorAvatar", c.getAuthorIdent())); | |||
} | |||
} |
@@ -56,7 +56,7 @@ public class FederationProposalsPanel extends BasePanel { | |||
final FederationProposal entry = item.getModelObject(); | |||
item.add(new LinkPanel("url", "list", entry.url, ReviewProposalPage.class, | |||
WicketUtils.newTokenParameter(entry.token))); | |||
item.add(WicketUtils.createDateLabel("received", entry.received, getTimeZone())); | |||
item.add(WicketUtils.createDateLabel("received", entry.received, getTimeZone(), getTimeUtils())); | |||
item.add(new Label("tokenType", entry.tokenType.name())); | |||
item.add(new LinkPanel("token", "list", entry.token, ReviewProposalPage.class, | |||
WicketUtils.newTokenParameter(entry.token))); |
@@ -66,9 +66,9 @@ public class FederationRegistrationsPanel extends BasePanel { | |||
item.add(WicketUtils.getRegistrationImage("typeIcon", entry, this)); | |||
item.add(WicketUtils.createDateLabel("lastPull", entry.lastPull, getTimeZone())); | |||
item.add(WicketUtils.createDateLabel("lastPull", entry.lastPull, getTimeZone(), getTimeUtils())); | |||
item.add(WicketUtils | |||
.createTimestampLabel("nextPull", entry.nextPull, getTimeZone())); | |||
.createTimestampLabel("nextPull", entry.nextPull, getTimeZone(), getTimeUtils())); | |||
item.add(new Label("frequency", entry.frequency)); | |||
WicketUtils.setAlternatingBackground(item, counter); | |||
counter++; |
@@ -103,7 +103,7 @@ public class HistoryPanel extends BasePanel { | |||
final RevCommit entry = item.getModelObject(); | |||
final Date date = JGitUtils.getCommitDate(entry); | |||
item.add(WicketUtils.createDateLabel("commitDate", date, getTimeZone())); | |||
item.add(WicketUtils.createDateLabel("commitDate", date, getTimeZone(), getTimeUtils())); | |||
// author search link | |||
String author = entry.getAuthorIdent().getName(); |
@@ -91,7 +91,7 @@ public class LogPanel extends BasePanel { | |||
final RevCommit entry = item.getModelObject(); | |||
final Date date = JGitUtils.getCommitDate(entry); | |||
item.add(WicketUtils.createDateLabel("commitDate", date, getTimeZone())); | |||
item.add(WicketUtils.createDateLabel("commitDate", date, getTimeZone(), getTimeUtils())); | |||
// author search link | |||
String author = entry.getAuthorIdent().getName(); |
@@ -49,7 +49,6 @@ import com.gitblit.SyndicationServlet; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.TimeUtils; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.WicketUtils; | |||
import com.gitblit.wicket.pages.BasePage; | |||
@@ -242,11 +241,11 @@ public class RepositoriesPanel extends BasePanel { | |||
if (entry.lastChange.getTime() == 0) { | |||
lastChange = "--"; | |||
} else { | |||
lastChange = TimeUtils.timeAgo(entry.lastChange); | |||
lastChange = getTimeUtils().timeAgo(entry.lastChange); | |||
} | |||
Label lastChangeLabel = new Label("repositoryLastChange", lastChange); | |||
row.add(lastChangeLabel); | |||
WicketUtils.setCssClass(lastChangeLabel, TimeUtils.timeAgoCss(entry.lastChange)); | |||
WicketUtils.setCssClass(lastChangeLabel, getTimeUtils().timeAgoCss(entry.lastChange)); | |||
boolean showOwner = user != null && user.username.equalsIgnoreCase(entry.owner); | |||
if (showAdmin) { |
@@ -87,7 +87,7 @@ public class SearchPanel extends BasePanel { | |||
final RevCommit entry = item.getModelObject(); | |||
final Date date = JGitUtils.getCommitDate(entry); | |||
item.add(WicketUtils.createDateLabel("commitDate", date, getTimeZone())); | |||
item.add(WicketUtils.createDateLabel("commitDate", date, getTimeZone(), getTimeUtils())); | |||
// author search link | |||
String author = entry.getAuthorIdent().getName(); |
@@ -69,7 +69,7 @@ public class TagsPanel extends BasePanel { | |||
public void populateItem(final Item<RefModel> item) { | |||
RefModel entry = item.getModelObject(); | |||
item.add(WicketUtils.createDateLabel("tagDate", entry.getDate(), getTimeZone())); | |||
item.add(WicketUtils.createDateLabel("tagDate", entry.getDate(), getTimeZone(), getTimeUtils())); | |||
Class<? extends RepositoryPage> linkClass; | |||
switch (entry.getReferencedObjectType()) { |
@@ -53,50 +53,52 @@ public class TimeUtilsTest { | |||
@Test | |||
public void testDurations() throws Exception { | |||
assertEquals("1 day", TimeUtils.duration(1)); | |||
assertEquals("5 days", TimeUtils.duration(5)); | |||
assertEquals("3 months", TimeUtils.duration(75)); | |||
assertEquals("12 months", TimeUtils.duration(364)); | |||
assertEquals("1 year", TimeUtils.duration(365 + 0)); | |||
assertEquals("1 year", TimeUtils.duration(365 + 10)); | |||
assertEquals("1 year, 1 month", TimeUtils.duration(365 + 15)); | |||
assertEquals("1 year, 1 month", TimeUtils.duration(365 + 30)); | |||
assertEquals("1 year, 1 month", TimeUtils.duration(365 + 44)); | |||
assertEquals("1 year, 2 months", TimeUtils.duration(365 + 45)); | |||
assertEquals("1 year, 2 months", TimeUtils.duration(365 + 60)); | |||
assertEquals("2 years", TimeUtils.duration(2 * 365 + 0)); | |||
assertEquals("2 years", TimeUtils.duration(2 * 365 + 10)); | |||
assertEquals("2 years, 1 month", TimeUtils.duration(2 * 365 + 15)); | |||
assertEquals("2 years, 1 month", TimeUtils.duration(2 * 365 + 30)); | |||
assertEquals("2 years, 1 month", TimeUtils.duration(2 * 365 + 44)); | |||
assertEquals("2 years, 2 months", TimeUtils.duration(2 * 365 + 45)); | |||
assertEquals("2 years, 2 months", TimeUtils.duration(2 * 365 + 60)); | |||
TimeUtils timeUtils = new TimeUtils(); | |||
assertEquals("1 day", timeUtils.duration(1)); | |||
assertEquals("5 days", timeUtils.duration(5)); | |||
assertEquals("3 months", timeUtils.duration(75)); | |||
assertEquals("12 months", timeUtils.duration(364)); | |||
assertEquals("1 year", timeUtils.duration(365 + 0)); | |||
assertEquals("1 year", timeUtils.duration(365 + 10)); | |||
assertEquals("1 year, 1 month", timeUtils.duration(365 + 15)); | |||
assertEquals("1 year, 1 month", timeUtils.duration(365 + 30)); | |||
assertEquals("1 year, 1 month", timeUtils.duration(365 + 44)); | |||
assertEquals("1 year, 2 months", timeUtils.duration(365 + 45)); | |||
assertEquals("1 year, 2 months", timeUtils.duration(365 + 60)); | |||
assertEquals("2 years", timeUtils.duration(2 * 365 + 0)); | |||
assertEquals("2 years", timeUtils.duration(2 * 365 + 10)); | |||
assertEquals("2 years, 1 month", timeUtils.duration(2 * 365 + 15)); | |||
assertEquals("2 years, 1 month", timeUtils.duration(2 * 365 + 30)); | |||
assertEquals("2 years, 1 month", timeUtils.duration(2 * 365 + 44)); | |||
assertEquals("2 years, 2 months", timeUtils.duration(2 * 365 + 45)); | |||
assertEquals("2 years, 2 months", timeUtils.duration(2 * 365 + 60)); | |||
} | |||
@Test | |||
public void testTimeAgo() throws Exception { | |||
// standard time ago tests | |||
assertEquals("1 min ago", TimeUtils.timeAgo(offset(1 * TimeUtils.MIN))); | |||
assertEquals("60 mins ago", TimeUtils.timeAgo(offset(60 * TimeUtils.MIN))); | |||
assertEquals("2 hours ago", TimeUtils.timeAgo(offset(120 * TimeUtils.MIN))); | |||
assertEquals("15 hours ago", TimeUtils.timeAgo(offset(15 * TimeUtils.ONEHOUR))); | |||
assertEquals("yesterday", TimeUtils.timeAgo(offset(24 * TimeUtils.ONEHOUR))); | |||
assertEquals("2 days ago", TimeUtils.timeAgo(offset(2 * TimeUtils.ONEDAY))); | |||
assertEquals("5 weeks ago", TimeUtils.timeAgo(offset(35 * TimeUtils.ONEDAY))); | |||
assertEquals("3 months ago", TimeUtils.timeAgo(offset(84 * TimeUtils.ONEDAY))); | |||
assertEquals("3 months ago", TimeUtils.timeAgo(offset(95 * TimeUtils.ONEDAY))); | |||
assertEquals("4 months ago", TimeUtils.timeAgo(offset(104 * TimeUtils.ONEDAY))); | |||
assertEquals("1 year ago", TimeUtils.timeAgo(offset(365 * TimeUtils.ONEDAY))); | |||
assertEquals("13 months ago", TimeUtils.timeAgo(offset(395 * TimeUtils.ONEDAY))); | |||
assertEquals("2 years ago", TimeUtils.timeAgo(offset((2 * 365 + 30) * TimeUtils.ONEDAY))); | |||
TimeUtils timeUtils = new TimeUtils(); | |||
assertEquals("just now", timeUtils.timeAgo(offset(1 * TimeUtils.MIN))); | |||
assertEquals("60 mins ago", timeUtils.timeAgo(offset(60 * TimeUtils.MIN))); | |||
assertEquals("2 hours ago", timeUtils.timeAgo(offset(120 * TimeUtils.MIN))); | |||
assertEquals("15 hours ago", timeUtils.timeAgo(offset(15 * TimeUtils.ONEHOUR))); | |||
assertEquals("yesterday", timeUtils.timeAgo(offset(24 * TimeUtils.ONEHOUR))); | |||
assertEquals("2 days ago", timeUtils.timeAgo(offset(2 * TimeUtils.ONEDAY))); | |||
assertEquals("5 weeks ago", timeUtils.timeAgo(offset(35 * TimeUtils.ONEDAY))); | |||
assertEquals("3 months ago", timeUtils.timeAgo(offset(84 * TimeUtils.ONEDAY))); | |||
assertEquals("3 months ago", timeUtils.timeAgo(offset(95 * TimeUtils.ONEDAY))); | |||
assertEquals("4 months ago", timeUtils.timeAgo(offset(104 * TimeUtils.ONEDAY))); | |||
assertEquals("1 year ago", timeUtils.timeAgo(offset(365 * TimeUtils.ONEDAY))); | |||
assertEquals("13 months ago", timeUtils.timeAgo(offset(395 * TimeUtils.ONEDAY))); | |||
assertEquals("2 years ago", timeUtils.timeAgo(offset((2 * 365 + 30) * TimeUtils.ONEDAY))); | |||
// css class tests | |||
assertEquals("age0", TimeUtils.timeAgoCss(offset(1 * TimeUtils.MIN))); | |||
assertEquals("age0", TimeUtils.timeAgoCss(offset(60 * TimeUtils.MIN))); | |||
assertEquals("age1", TimeUtils.timeAgoCss(offset(120 * TimeUtils.MIN))); | |||
assertEquals("age1", TimeUtils.timeAgoCss(offset(24 * TimeUtils.ONEHOUR))); | |||
assertEquals("age2", TimeUtils.timeAgoCss(offset(2 * TimeUtils.ONEDAY))); | |||
assertEquals("age0", timeUtils.timeAgoCss(offset(1 * TimeUtils.MIN))); | |||
assertEquals("age0", timeUtils.timeAgoCss(offset(60 * TimeUtils.MIN))); | |||
assertEquals("age1", timeUtils.timeAgoCss(offset(120 * TimeUtils.MIN))); | |||
assertEquals("age1", timeUtils.timeAgoCss(offset(24 * TimeUtils.ONEHOUR))); | |||
assertEquals("age2", timeUtils.timeAgoCss(offset(2 * TimeUtils.ONEDAY))); | |||
} | |||
@Test |