Skip to content

Commit

Permalink
Extend support to ISO8601 format for sitemap chart period parameter (o…
Browse files Browse the repository at this point in the history
…penhab#3863)

* Extend support to ISO8601 format for sitemap chart period parameter

Signed-off-by: Laurent Garnier <[email protected]>
  • Loading branch information
lolodomo authored Nov 24, 2023
1 parent ae117f6 commit f71ebfb
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -69,6 +69,7 @@
*
* @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")
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -233,7 +224,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res) throws Ser
}

// 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;

Expand Down Expand Up @@ -359,4 +350,37 @@ public void init(@Nullable ServletConfig config) throws ServletException {
@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;
}
}
Original file line number Diff line number Diff line change
@@ -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));
}
}

0 comments on commit f71ebfb

Please sign in to comment.