Skip to content

Commit

Permalink
Enhanced parsing of date & time
Browse files Browse the repository at this point in the history
Allow locale-based date time strings

Signed-off-by: Thomas Calmant <thomas.calmant@kentyou.com>
  • Loading branch information
tcalmant committed Feb 7, 2024
1 parent 2112602 commit acd03ae
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*********************************************************************
* Copyright (c) 2024 Kentyou.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Thomas Calmant (Kentyou) - initial implementation
**********************************************************************/
package org.eclipse.sensinact.gateway.southbound.device.factory;

import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Utility methods to find a locale
*/
public class LocaleUtils {

private static final Logger logger = LoggerFactory.getLogger(LocaleUtils.class);

/**
* Try to find the locale from the given string.
*
* The string can be a language code, a language code and a country code or a
* language code, a country code and a variant.
* Parts are separated by an underscore character, for example: <code>fr_FR</code>
*
* @param strLocale Locale string
* @return
*/
public static Locale fromString(final String strLocale) {
if (strLocale == null || strLocale.isBlank()) {
return null;
}

final String[] parts = strLocale.split("_");
switch (parts.length) {
case 1:
return new Locale(parts[0]);

case 2:
return new Locale(parts[0], parts[1]);

case 3:
return new Locale(parts[0], parts[1], parts[2]);

default:
// Invalid locale string
logger.warn("Unhandled number locale {}", strLocale);
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,12 @@
import java.util.stream.Stream;

import org.eclipse.sensinact.gateway.southbound.device.factory.dto.DeviceMappingOptionsDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public enum ValueType {
/**
* Represent available types
*/
AS_IS("any", null, null),
STRING("string", (v, o) -> String.valueOf(v), String.class),
CHAR("char", (v, o) -> {
AS_IS("any", null, null), STRING("string", (v, o) -> String.valueOf(v), String.class), CHAR("char", (v, o) -> {
if (v instanceof Character) {
return (Character) v;
} else if (v instanceof CharSequence) {
Expand All @@ -55,8 +51,7 @@ public enum ValueType {
} else {
return null;
}
}, Character.class),
BOOLEAN("boolean", (v, o) -> {
}, Character.class), BOOLEAN("boolean", (v, o) -> {
if (v instanceof Boolean) {
return (Boolean) v;
} else if (v instanceof Number) {
Expand All @@ -66,32 +61,25 @@ public enum ValueType {
} else {
return null;
}
}, Boolean.class),
BYTE("byte", (v, o) -> {
}, Boolean.class), BYTE("byte", (v, o) -> {
final Number parsed = parseNumber(v, true, o);
return parsed != null ? parsed.byteValue() : null;
}, Byte.class),
SHORT("short", (v, o) -> {
}, Byte.class), SHORT("short", (v, o) -> {
final Number parsed = parseNumber(v, true, o);
return parsed != null ? parsed.shortValue() : null;
}, Short.class),
INT("int", (v, o) -> {
}, Short.class), INT("int", (v, o) -> {
final Number parsed = parseNumber(v, true, o);
return parsed != null ? parsed.intValue() : null;
}, Integer.class),
LONG("long", (v, o) -> {
}, Integer.class), LONG("long", (v, o) -> {
final Number parsed = parseNumber(v, true, o);
return parsed != null ? parsed.longValue() : null;
}, Long.class),
FLOAT("float", (v, o) -> {
}, Long.class), FLOAT("float", (v, o) -> {
final Number parsed = parseNumber(v, false, o);
return parsed != null ? parsed.floatValue() : null;
}, Float.class),
DOUBLE("double", (v, o) -> {
}, Float.class), DOUBLE("double", (v, o) -> {
final Number parsed = parseNumber(v, false, o);
return parsed != null ? parsed.doubleValue() : null;
}, Double.class),
ANY_ARRAY("any[]", (v, o) -> asList(v, o, AS_IS), List.class),
}, Double.class), ANY_ARRAY("any[]", (v, o) -> asList(v, o, AS_IS), List.class),
STRING_ARRAY("string[]", (v, o) -> asList(v, o, STRING), List.class),
CHAR_ARRAY("char[]", (v, o) -> asList(v, o, CHAR), List.class),
BOOLEAN_ARRAY("boolean[]", (v, o) -> asList(v, o, BOOLEAN), List.class),
Expand All @@ -102,8 +90,6 @@ public enum ValueType {
FLOAT_ARRAY("float[]", (v, o) -> asList(v, o, FLOAT), List.class),
DOUBLE_ARRAY("double[]", (v, o) -> asList(v, o, DOUBLE), List.class);

private static final Logger logger = LoggerFactory.getLogger(ValueType.class);

/**
* String representation
*/
Expand All @@ -126,28 +112,8 @@ public enum ValueType {
* @return The number format for the given locale or null
*/
private static NumberFormat getNumberFormat(final DeviceMappingOptionsDTO options, boolean integers) {
final String strLocale = options.numbersLocale;
if (strLocale == null || strLocale.isBlank()) {
return null;
}

final String[] parts = strLocale.split("_");
final Locale locale;
switch (parts.length) {
case 1:
locale = new Locale(parts[0]);
break;

case 2:
locale = new Locale(parts[0], parts[1]);
break;

case 3:
locale = new Locale(parts[0], parts[1], parts[2]);
break;

default:
logger.warn("Unhandled number locale {}", strLocale);
final Locale locale = LocaleUtils.fromString(options.numbersLocale);
if (locale == null) {
return null;
}

Expand Down Expand Up @@ -220,7 +186,8 @@ private static Number parseNumber(final Object value, final boolean expectIntege
* @param converter Function to convert any input to the value type
* @param javaClass Java class represented by the value type
*/
<T> ValueType(final String strRepr, final BiFunction<Object, DeviceMappingOptionsDTO, T> converter, final Class<T> javaClass) {
<T> ValueType(final String strRepr, final BiFunction<Object, DeviceMappingOptionsDTO, T> converter,
final Class<T> javaClass) {
this.repr = strRepr;
this.converter = converter;
this.javaClass = javaClass != null ? javaClass : Object.class;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ public class DeviceMappingOptionsDTO {
@JsonProperty("format.datetime")
public String formatDateTime;

@JsonProperty("format.datetime.locale")
public String formatDateTimeLocale;

@JsonProperty("format.date.style")
public String formatDateStyle;

@JsonProperty("format.time.style")
public String formatTimeStyle;

@JsonProperty("datetime.timezone")
public String dateTimezone;

Expand Down
Loading

0 comments on commit acd03ae

Please sign in to comment.