Skip to content

Commit

Permalink
add native calendar widget to choose a custom period
Browse files Browse the repository at this point in the history
  • Loading branch information
evernat committed Jul 1, 2018
1 parent 1341680 commit 84a1d63
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 40 deletions.
Expand Up @@ -43,6 +43,7 @@ public enum HttpParameter {
WIDTH("width"),
HEIGHT("height"),
MAX("max"),
PATTERN("pattern"),
REPORT("report"),
TOKEN("token"),
CLASS("class"),
Expand Down
Expand Up @@ -104,7 +104,7 @@ public static Range createCustomRange(Date startDate, Date endDate) {
return new Range(null, normalizedStartDate, normalizedEndDate);
}

public static Range parse(String value) {
public static Range parse(String value, DateFormat dateFormat) {
final int index = value.indexOf(CUSTOM_PERIOD_SEPARATOR);
if (index == -1) {
try {
Expand All @@ -115,7 +115,6 @@ public static Range parse(String value) {
}
// rq: on pourrait essayer aussi des dateFormat alternatifs,
// par exemple même pattern mais sans les slashs ou juste avec jour et mois
final DateFormat dateFormat = I18N.createDateFormat();
Date startDate;
try {
startDate = dateFormat.parse(value.substring(0, index));
Expand Down
Expand Up @@ -17,11 +17,15 @@
*/
package net.bull.javamelody.internal.web;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.bull.javamelody.internal.common.HttpParameter;
import net.bull.javamelody.internal.common.I18N;
import net.bull.javamelody.internal.model.Period;
import net.bull.javamelody.internal.model.Range;

Expand All @@ -36,6 +40,13 @@ public class HttpCookieManager {
private static Range defaultRange = Period.JOUR.getRange();

public Range getRange(HttpServletRequest req, HttpServletResponse resp) {
final DateFormat dateFormat;
final String pattern = HttpParameter.PATTERN.getParameterFrom(req);
if (pattern == null || pattern.isEmpty()) {
dateFormat = I18N.createDateFormat();
} else {
dateFormat = new SimpleDateFormat(pattern);
}
final Range range;
if (HttpParameter.PERIOD.getParameterFrom(req) == null) {
// pas de paramètre period dans la requête, on cherche le cookie
Expand All @@ -44,10 +55,10 @@ public Range getRange(HttpServletRequest req, HttpServletResponse resp) {
// pas de cookie, période par défaut
range = defaultRange;
} else {
range = Range.parse(cookie.getValue());
range = Range.parse(cookie.getValue(), dateFormat);
}
} else {
range = Range.parse(HttpParameter.PERIOD.getParameterFrom(req));
range = Range.parse(HttpParameter.PERIOD.getParameterFrom(req), dateFormat);
// un paramètre period est présent dans la requête :
// l'utilisateur a choisi une période, donc on fixe le cookie
addCookie(req, resp, PERIOD_COOKIE_NAME, range.getValue());
Expand Down
Expand Up @@ -20,6 +20,8 @@
import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
Expand Down Expand Up @@ -384,7 +386,14 @@ public Range getRangeForSerializable(HttpServletRequest httpRequest) {
// période tout par défaut pour Serializable, notamment pour le serveur de collecte
range = Period.TOUT.getRange();
} else {
range = Range.parse(period);
final DateFormat dateFormat;
final String pattern = HttpParameter.PATTERN.getParameterFrom(httpRequest);
if (pattern == null) {
dateFormat = I18N.createDateFormat();
} else {
dateFormat = new SimpleDateFormat(pattern);
}
range = Range.parse(period, dateFormat);
}
return range;
}
Expand Down
Expand Up @@ -59,42 +59,70 @@ void writeCustomPeriodLinks(Map<String, Date> datesByWebappVersions, Range curre
private void writeCustomPeriodDiv(Range currentRange, String graphName, String part)
throws IOException {
writeln("<div id='customPeriod' style='display: none;'>");
writeln("<script type='text/javascript'>");
writeln("function validateCustomPeriodForm() {");
writeln(" periodForm = document.customPeriodForm;");
writelnCheckMandatory("periodForm.startDate", "dates_mandatory");
writelnCheckMandatory("periodForm.endDate", "dates_mandatory");
writeln(" periodForm.period.value=periodForm.startDate.value + '"
+ Range.CUSTOM_PERIOD_SEPARATOR + "' + periodForm.endDate.value;");
writeln(" return true;");
writeln("}");
writeln("</script>");
writeln("<br/>");
final DateFormat dateFormat = I18N.createDateFormat();
final String dateFormatPattern;
if (getString("dateFormatPattern").isEmpty()) {
final String pattern = ((SimpleDateFormat) dateFormat).toPattern();
dateFormatPattern = pattern.toLowerCase(I18N.getCurrentLocale());
} else {
dateFormatPattern = getString("dateFormatPattern");
}
// yyyy-MM-dd is always the pattern of the input type=date
final String pattern = "yyyy-MM-dd";
final DateFormat dateFormat = new SimpleDateFormat(pattern);
final String max = dateFormat.format(new Date());
writeln("<form name='customPeriodForm' method='get' action='' onsubmit='return validateCustomPeriodForm();'>");
writeln("<br/><b>#startDate#</b>&nbsp;&nbsp;<input type='text' size='10' name='startDate' ");
writeln("<br/><b><label for='customPeriodStartDate'>#startDate#</label></b>&nbsp;&nbsp;");
writeln("<input type='date' id='customPeriodStartDate' name='startDate' size='10' required max='"
+ max + "' ");
if (currentRange.getStartDate() != null) {
writeln("value='" + dateFormat.format(currentRange.getStartDate()) + '\'');
}
writeln("/>&nbsp;&nbsp;<b>#endDate#</b>&nbsp;&nbsp;<input type='text' size='10' name='endDate' ");
writeln("/>&nbsp;&nbsp;<b><label for='customPeriodEndDate'>#endDate#</label></b>&nbsp;&nbsp;");
writeln("<input type='date' id='customPeriodEndDate' name='endDate' size='10' required max='"
+ max + "' ");
if (currentRange.getEndDate() != null) {
writeln("value='" + dateFormat.format(currentRange.getEndDate()) + '\'');
}
writeln("/>&nbsp;&nbsp;");
writeDirectly('(' + dateFormatPattern + ')');
final DateFormat localeDateFormat = I18N.createDateFormat();
final String localeDateFormatPattern;
if (getString("dateFormatPattern").isEmpty()) {
localeDateFormatPattern = ((SimpleDateFormat) localeDateFormat).toPattern()
.toLowerCase(I18N.getCurrentLocale());
} else {
localeDateFormatPattern = getString("dateFormatPattern");
}
// ce customPeriodPattern ne sera pas affiché si html5
writeDirectly("<span id='customPeriodPattern' style='display: none;'>("
+ localeDateFormatPattern + ")</span>");
writeln("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='submit' value='#ok#'/><br/><br/>");
writeln("<input type='hidden' name='period' value=''/>");
writeln("<input type='hidden' name='pattern' value='" + pattern + "'/>");
if (graphName != null) {
writeln("<input type='hidden' name='part' value='" + part + "'/>");
writeln("<input type='hidden' name='graph' value='" + urlEncode(graphName) + "'/>");
}
writeln("<script type='text/javascript'>");
// On teste si l'élément <input type='date'> se transforme en <input type='text'
writeln("var test = document.createElement('input'); test.type = 'date';");
// Si c'est le cas, cela signifie que l'élément (html5) n'est pas pris en charge
writeln("if(test.type === 'text') {");
// si pas html5, on vide le champ pattern car il n'est pas au bon format
// et on affiche le format en langue du navigateur
writeln(" document.customPeriodForm.pattern.value = '';");
writeln(" document.getElementById('customPeriodPattern').style.display='inline';");
if (currentRange.getStartDate() != null) {
writeln(" document.customPeriodForm.startDate.value = '"
+ localeDateFormat.format(currentRange.getStartDate()) + "';");
}
if (currentRange.getEndDate() != null) {
writeln(" document.customPeriodForm.endDate.value = '"
+ localeDateFormat.format(currentRange.getEndDate()) + "';");
}
writeln("}");
writeln("function validateCustomPeriodForm() {");
writeln(" periodForm = document.customPeriodForm;");
writelnCheckMandatory("periodForm.startDate", "dates_mandatory");
writelnCheckMandatory("periodForm.endDate", "dates_mandatory");
writeln(" periodForm.period.value=periodForm.startDate.value + '"
+ Range.CUSTOM_PERIOD_SEPARATOR + "' + periodForm.endDate.value;");
writeln(" return true;");
writeln("}");
writeln("</script>");
writeln("</form><br/>");
writeln("</div>");
}
Expand Down Expand Up @@ -175,8 +203,8 @@ void writeAddAndRemoveApplicationLinks(String currentApplication) throws IOExcep
writeln("</script>");
writeln("<br/> <br/>");
writeln("<form name='appForm' method='post' action='' onsubmit='return validateAppForm();'>");
writeln("<br/><b>#app_name_to_monitor# :</b>&nbsp;&nbsp;<input type='text' size='15' name='appName'/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
writeln("<b>#app_urls# :</b>&nbsp;&nbsp;<input type='text' size='50' name='appUrls'/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
writeln("<br/><b><label for='appName'>#app_name_to_monitor#</label> :</b>&nbsp;&nbsp;<input type='text' size='15' id='appName' name='appName' required/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
writeln("<b><label for='appUrls'>#app_urls#</label> :</b>&nbsp;&nbsp;<input type='text' size='50' id='appUrls' name='appUrls' required/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
writeln("<input type='submit' value='#add#'/><br/>");
writeln("#urls_sample# : <i>http://myhost/myapp/</i> #or# <i>http://host1/myapp/,http://host2/myapp/</i>");
writeln("<br/> <br/>");
Expand Down
Expand Up @@ -23,6 +23,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
Expand Down Expand Up @@ -86,29 +87,33 @@ public void testGetValue() {
public void testParse() {
I18N.bindLocale(Locale.FRENCH);
try {
final DateFormat dateFormat = I18N.createDateFormat();
assertEquals("parse1", periodRange.getPeriod(),
Range.parse(periodRange.getValue()).getPeriod());
Range.parse(periodRange.getValue(), dateFormat).getPeriod());
assertTrue("parse2", isSameDay(customRange.getStartDate(),
Range.parse(customRange.getValue()).getStartDate()));
Range.parse(customRange.getValue(), dateFormat).getStartDate()));
assertTrue("parse3", isSameDay(customRange.getEndDate(),
Range.parse(customRange.getValue()).getEndDate()));
Range.parse(customRange.getValue(), dateFormat).getEndDate()));

// on teste le résultat en cas d'erreur de format
assertNotNull("parse4",
Range.parse("xxxxxx" + Range.CUSTOM_PERIOD_SEPARATOR + "01/01/2010"));
assertNotNull("parse5",
Range.parse("01/01/2010" + Range.CUSTOM_PERIOD_SEPARATOR + "xxxxxx"));
assertNotNull("parse6", Range.parse("01/01/2010" + Range.CUSTOM_PERIOD_SEPARATOR));
assertNotNull("parse6b", Range.parse("01/01/2011"));
assertNotNull("parse4", Range
.parse("xxxxxx" + Range.CUSTOM_PERIOD_SEPARATOR + "01/01/2010", dateFormat));
assertNotNull("parse5", Range
.parse("01/01/2010" + Range.CUSTOM_PERIOD_SEPARATOR + "xxxxxx", dateFormat));
assertNotNull("parse6",
Range.parse("01/01/2010" + Range.CUSTOM_PERIOD_SEPARATOR, dateFormat));
assertNotNull("parse6b", Range.parse("01/01/2011", dateFormat));
// on teste les bornes min et max
final Calendar calendar = Calendar.getInstance();
final int currentYear = calendar.get(Calendar.YEAR);
Range range = Range.parse("01/01/2000" + Range.CUSTOM_PERIOD_SEPARATOR + "01/01/2030");
Range range = Range.parse("01/01/2000" + Range.CUSTOM_PERIOD_SEPARATOR + "01/01/2030",
dateFormat);
calendar.setTime(range.getStartDate());
assertTrue("parse7", calendar.get(Calendar.YEAR) >= currentYear - 2);
calendar.setTime(range.getEndDate());
assertTrue("parse7", calendar.get(Calendar.YEAR) <= currentYear);
range = Range.parse("01/01/2030" + Range.CUSTOM_PERIOD_SEPARATOR + "01/01/2030");
range = Range.parse("01/01/2030" + Range.CUSTOM_PERIOD_SEPARATOR + "01/01/2030",
dateFormat);
calendar.setTime(range.getStartDate());
assertTrue("parse8", calendar.get(Calendar.YEAR) <= currentYear);
} finally {
Expand Down
4 changes: 3 additions & 1 deletion javamelody-swing/src/main/java/net/bull/javamelody/Main.java
Expand Up @@ -23,6 +23,7 @@
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.URL;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -112,7 +113,8 @@ static void showFrame() throws IOException {
final boolean collectorServer = Boolean
.parseBoolean(System.getProperty("javamelody.collectorServer"));
final List<URL> urls = Arrays.asList(new URL(url));
final Range selectedRange = Range.parse(range);
final DateFormat dateFormat = I18N.createDateFormat();
final Range selectedRange = Range.parse(range, dateFormat);
log("Monitoring of " + application + " on " + url);
log("creating frame");
final RemoteCollector remoteCollector = new RemoteCollector(application, urls);
Expand Down

0 comments on commit 84a1d63

Please sign in to comment.