Extend support to ISO8601 format for sitemap chart period parameter (#3863)

* Extend support to ISO8601 format for sitemap chart period parameter

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
lolodomo 2023-11-24 16:53:10 +01:00 committed by GitHub
parent ae117f6317
commit f71ebfb83c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 155 additions and 14 deletions

View File

@ -27,5 +27,15 @@ public class RESTConstants {
public static final String JAX_RS_NAME = "openhab";
public static final String API_VERSION = "5";
/**
* Version of the openHAB API
*
* Version 1: initial version
* Version 2: include invisible widgets into sitemap response (#499)
* Version 3: Addition of anyFormat icon parameter (#978)
* Version 4: OH3, refactored extensions to addons (#1560)
* Version 5: transparent charts (#2502)
* Version 6: extended chart period parameter format (#3863)
*/
public static final String API_VERSION = "6";
}

View File

@ -12,15 +12,15 @@
*/
package org.openhab.core.ui.internal.chart;
import static java.util.Map.entry;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAmount;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@ -69,6 +69,7 @@ import org.slf4j.LoggerFactory;
*
* @author Chris Jackson - Initial contribution
* @author Holger Reichert - Support for themes, DPI, legend hiding
* @author Laurent Garnier - Extend support to ISO8601 format for chart period parameter
*/
@Component(immediate = true, service = { ChartServlet.class, Servlet.class }, configurationPid = "org.openhab.chart", //
property = Constants.SERVICE_PID + "=org.openhab.chart")
@ -101,16 +102,6 @@ public class ChartServlet extends HttpServlet {
private static final Duration DEFAULT_PERIOD = Duration.ofDays(1);
private static final Map<String, Duration> PERIODS = Map.ofEntries( //
entry("h", Duration.ofHours(1)), entry("4h", Duration.ofHours(4)), //
entry("8h", Duration.ofHours(8)), entry("12h", Duration.ofHours(12)), //
entry("D", Duration.ofDays(1)), entry("2D", Duration.ofDays(2)), //
entry("3D", Duration.ofDays(3)), entry("W", Duration.ofDays(7)), //
entry("2W", Duration.ofDays(14)), entry("M", Duration.ofDays(30)), //
entry("2M", Duration.ofDays(60)), entry("4M", Duration.ofDays(120)), //
entry("Y", Duration.ofDays(365))//
);
protected static final Map<String, ChartProvider> CHART_PROVIDERS = new ConcurrentHashMap<>();
@Activate
@ -233,7 +224,7 @@ public class ChartServlet extends HttpServlet {
}
// Read out the parameter period, begin and end and save them.
Duration period = periodParam == null ? DEFAULT_PERIOD : PERIODS.getOrDefault(periodParam, DEFAULT_PERIOD);
TemporalAmount period = convertToTemporalAmount(periodParam, DEFAULT_PERIOD);
ZonedDateTime timeBegin = null;
ZonedDateTime timeEnd = null;
@ -359,4 +350,37 @@ public class ChartServlet extends HttpServlet {
@Override
public void destroy() {
}
public static TemporalAmount convertToTemporalAmount(@Nullable String periodParam, TemporalAmount defaultPeriod) {
TemporalAmount period = defaultPeriod;
String convertedPeriod = convertPeriodToISO8601(periodParam);
if (convertedPeriod != null) {
boolean failed = false;
try {
period = Period.parse(convertedPeriod);
} catch (DateTimeParseException e) {
failed = true;
}
if (failed) {
try {
period = Duration.parse(convertedPeriod);
} catch (DateTimeParseException e) {
// Ignored
}
}
}
return period;
}
private static @Nullable String convertPeriodToISO8601(@Nullable String period) {
if (period == null || period.startsWith("P") || !(period.endsWith("h") || period.endsWith("D")
|| period.endsWith("W") || period.endsWith("M") || period.endsWith("Y"))) {
return period;
}
String newPeriod = period.length() == 1 ? "1" + period : period;
if (newPeriod.endsWith("h")) {
newPeriod = "T" + newPeriod.replace("h", "H");
}
return "P" + newPeriod;
}
}

View File

@ -0,0 +1,107 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.core.ui.internal.chart;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAmount;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
/**
* @author Laurent Garnier - Initial contribution
*/
@NonNullByDefault
public class ChartServletPeriodParamTest {
@Test
public void convertToTemporalAmountFromNull() {
TemporalAmount period = ChartServlet.convertToTemporalAmount(null, Duration.ZERO);
assertEquals(0, period.get(ChronoUnit.SECONDS));
}
@Test
public void convertToTemporalAmountFromHours() {
TemporalAmount period = ChartServlet.convertToTemporalAmount("h", Duration.ZERO);
assertEquals(1 * 60 * 60, period.get(ChronoUnit.SECONDS));
period = ChartServlet.convertToTemporalAmount("12h", Duration.ZERO);
assertEquals(12 * 60 * 60, period.get(ChronoUnit.SECONDS));
}
@Test
public void convertToTemporalAmountFromDays() {
TemporalAmount period = ChartServlet.convertToTemporalAmount("D", Duration.ZERO);
assertEquals(1, period.get(ChronoUnit.DAYS));
assertEquals(0, period.get(ChronoUnit.MONTHS));
assertEquals(0, period.get(ChronoUnit.YEARS));
period = ChartServlet.convertToTemporalAmount("4D", Duration.ZERO);
assertEquals(4, period.get(ChronoUnit.DAYS));
assertEquals(0, period.get(ChronoUnit.MONTHS));
assertEquals(0, period.get(ChronoUnit.YEARS));
}
@Test
public void convertToTemporalAmountFromWeeks() {
TemporalAmount period = ChartServlet.convertToTemporalAmount("W", Duration.ZERO);
assertEquals(7, period.get(ChronoUnit.DAYS));
assertEquals(0, period.get(ChronoUnit.MONTHS));
assertEquals(0, period.get(ChronoUnit.YEARS));
period = ChartServlet.convertToTemporalAmount("2W", Duration.ZERO);
assertEquals(14, period.get(ChronoUnit.DAYS));
assertEquals(0, period.get(ChronoUnit.MONTHS));
assertEquals(0, period.get(ChronoUnit.YEARS));
}
@Test
public void convertToTemporalAmountFromMonths() {
TemporalAmount period = ChartServlet.convertToTemporalAmount("M", Duration.ZERO);
assertEquals(0, period.get(ChronoUnit.DAYS));
assertEquals(1, period.get(ChronoUnit.MONTHS));
assertEquals(0, period.get(ChronoUnit.YEARS));
period = ChartServlet.convertToTemporalAmount("3M", Duration.ZERO);
assertEquals(0, period.get(ChronoUnit.DAYS));
assertEquals(3, period.get(ChronoUnit.MONTHS));
assertEquals(0, period.get(ChronoUnit.YEARS));
}
@Test
public void convertToTemporalAmountFromYears() {
TemporalAmount period = ChartServlet.convertToTemporalAmount("Y", Duration.ZERO);
assertEquals(0, period.get(ChronoUnit.DAYS));
assertEquals(0, period.get(ChronoUnit.MONTHS));
assertEquals(1, period.get(ChronoUnit.YEARS));
period = ChartServlet.convertToTemporalAmount("2Y", Duration.ZERO);
assertEquals(0, period.get(ChronoUnit.DAYS));
assertEquals(0, period.get(ChronoUnit.MONTHS));
assertEquals(2, period.get(ChronoUnit.YEARS));
}
@Test
public void convertToTemporalAmountFromISO8601() {
TemporalAmount period = ChartServlet.convertToTemporalAmount("P2Y3M4D", Duration.ZERO);
assertEquals(4, period.get(ChronoUnit.DAYS));
assertEquals(3, period.get(ChronoUnit.MONTHS));
assertEquals(2, period.get(ChronoUnit.YEARS));
period = ChartServlet.convertToTemporalAmount("P1DT12H30M15S", Duration.ZERO);
assertEquals(36 * 60 * 60 + 30 * 60 + 15, period.get(ChronoUnit.SECONDS));
}
}