Adjust transformations to core changes (#13126)
Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
parent
8e16c411f0
commit
9f8c1772d2
|
@ -28,9 +28,9 @@ import org.eclipse.jdt.annotation.Nullable;
|
|||
import org.openhab.core.common.registry.RegistryChangeListener;
|
||||
import org.openhab.core.config.core.ConfigOptionProvider;
|
||||
import org.openhab.core.config.core.ParameterOption;
|
||||
import org.openhab.core.transform.TransformationConfiguration;
|
||||
import org.openhab.core.transform.TransformationConfigurationRegistry;
|
||||
import org.openhab.core.transform.Transformation;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
import org.openhab.core.transform.TransformationRegistry;
|
||||
import org.openhab.core.transform.TransformationService;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
@ -45,43 +45,41 @@ import org.slf4j.LoggerFactory;
|
|||
*
|
||||
* @author Kai Kreuzer - Initial contribution and API
|
||||
* @author Gaël L'hopital - Make it localizable
|
||||
* @author Jan N. Klug - Refactored to use {@link TransformationConfigurationRegistry}
|
||||
* @author Jan N. Klug - Refactored to use {@link TransformationRegistry}
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = { TransformationService.class, ConfigOptionProvider.class }, property = {
|
||||
"openhab.transform=MAP" })
|
||||
public class MapTransformationService
|
||||
implements TransformationService, ConfigOptionProvider, RegistryChangeListener<TransformationConfiguration> {
|
||||
implements TransformationService, ConfigOptionProvider, RegistryChangeListener<Transformation> {
|
||||
private final Logger logger = LoggerFactory.getLogger(MapTransformationService.class);
|
||||
|
||||
private static final String PROFILE_CONFIG_URI = "profile:transform:MAP";
|
||||
private static final String CONFIG_PARAM_FUNCTION = "function";
|
||||
private static final Set<String> SUPPORTED_CONFIGURATION_TYPES = Set.of("map");
|
||||
|
||||
private final TransformationConfigurationRegistry transformationConfigurationRegistry;
|
||||
private final TransformationRegistry transformationRegistry;
|
||||
private final Map<String, Properties> cachedTransformations = new ConcurrentHashMap<>();
|
||||
|
||||
@Activate
|
||||
public MapTransformationService(
|
||||
@Reference TransformationConfigurationRegistry transformationConfigurationRegistry) {
|
||||
this.transformationConfigurationRegistry = transformationConfigurationRegistry;
|
||||
transformationConfigurationRegistry.addRegistryChangeListener(this);
|
||||
public MapTransformationService(@Reference TransformationRegistry transformationRegistry) {
|
||||
this.transformationRegistry = transformationRegistry;
|
||||
transformationRegistry.addRegistryChangeListener(this);
|
||||
}
|
||||
|
||||
@Deactivate
|
||||
public void deactivate() {
|
||||
transformationConfigurationRegistry.removeRegistryChangeListener(this);
|
||||
transformationRegistry.removeRegistryChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String transform(String function, String source) throws TransformationException {
|
||||
// always get a configuration from the registry to account for changed system locale
|
||||
TransformationConfiguration transformationConfiguration = transformationConfigurationRegistry.get(function,
|
||||
null);
|
||||
Transformation transformation = transformationRegistry.get(function, null);
|
||||
|
||||
if (transformationConfiguration != null) {
|
||||
if (!cachedTransformations.containsKey(transformationConfiguration.getUID())) {
|
||||
importConfiguration(transformationConfiguration);
|
||||
if (transformation != null) {
|
||||
if (!cachedTransformations.containsKey(transformation.getUID())) {
|
||||
importConfiguration(transformation);
|
||||
}
|
||||
Properties properties = cachedTransformations.get(function);
|
||||
if (properties != null) {
|
||||
|
@ -106,7 +104,7 @@ public class MapTransformationService
|
|||
@Nullable Locale locale) {
|
||||
if (PROFILE_CONFIG_URI.equals(uri.toString())) {
|
||||
if (CONFIG_PARAM_FUNCTION.equals(param)) {
|
||||
return transformationConfigurationRegistry.getConfigurations(SUPPORTED_CONFIGURATION_TYPES).stream()
|
||||
return transformationRegistry.getTransformations(SUPPORTED_CONFIGURATION_TYPES).stream()
|
||||
.map(c -> new ParameterOption(c.getUID(), c.getLabel())).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -114,29 +112,34 @@ public class MapTransformationService
|
|||
}
|
||||
|
||||
@Override
|
||||
public void added(TransformationConfiguration element) {
|
||||
public void added(Transformation element) {
|
||||
// do nothing, configurations are added to cache if needed
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(TransformationConfiguration element) {
|
||||
public void removed(Transformation element) {
|
||||
cachedTransformations.remove(element.getUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updated(TransformationConfiguration oldElement, TransformationConfiguration element) {
|
||||
public void updated(Transformation oldElement, Transformation element) {
|
||||
if (cachedTransformations.remove(oldElement.getUID()) != null) {
|
||||
// import only if it was present before
|
||||
importConfiguration(element);
|
||||
}
|
||||
}
|
||||
|
||||
private void importConfiguration(@Nullable TransformationConfiguration configuration) {
|
||||
if (configuration != null) {
|
||||
private void importConfiguration(@Nullable Transformation transformation) {
|
||||
if (transformation != null) {
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
properties.load(new StringReader(configuration.getContent()));
|
||||
cachedTransformations.put(configuration.getUID(), properties);
|
||||
String function = transformation.getConfiguration().get(Transformation.FUNCTION);
|
||||
if (function == null || function.isBlank()) {
|
||||
logger.warn("Function not defined for transformation '{}'", transformation.getUID());
|
||||
return;
|
||||
}
|
||||
properties.load(new StringReader(function));
|
||||
cachedTransformations.put(transformation.getUID(), properties);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,13 +35,13 @@ import org.mockito.junit.jupiter.MockitoSettings;
|
|||
import org.mockito.quality.Strictness;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.openhab.core.test.java.JavaTest;
|
||||
import org.openhab.core.transform.TransformationConfiguration;
|
||||
import org.openhab.core.transform.TransformationConfigurationRegistry;
|
||||
import org.openhab.core.transform.Transformation;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
import org.openhab.core.transform.TransformationRegistry;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
* @author Jan N. Klug - Refactored to use {@link TransformationConfigurationRegistry}
|
||||
* @author Jan N. Klug - Refactored to use {@link TransformationRegistry}
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
|
@ -58,10 +58,10 @@ public class MapTransformationServiceTest extends JavaTest {
|
|||
private static final String SRC_FOLDER = "conf" + File.separator + "transform";
|
||||
|
||||
@Mock
|
||||
private @NonNullByDefault({}) TransformationConfigurationRegistry transformationConfigurationRegistry;
|
||||
private @NonNullByDefault({}) TransformationRegistry transformationRegistry;
|
||||
|
||||
private @NonNullByDefault({}) MapTransformationService processor;
|
||||
private final Map<String, TransformationConfiguration> configurationMap = new HashMap<>();
|
||||
private final Map<String, Transformation> configurationMap = new HashMap<>();
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws IOException {
|
||||
|
@ -70,20 +70,20 @@ public class MapTransformationServiceTest extends JavaTest {
|
|||
try {
|
||||
String content = new String(Files.readAllBytes(file), StandardCharsets.UTF_8);
|
||||
String uid = Path.of(SRC_FOLDER).relativize(file).toString();
|
||||
TransformationConfiguration transformationConfiguration = new TransformationConfiguration(uid, uid,
|
||||
"map", null, content);
|
||||
configurationMap.put(uid, transformationConfiguration);
|
||||
Transformation transformation = new Transformation(uid, uid, "map",
|
||||
Map.of(Transformation.FUNCTION, content));
|
||||
configurationMap.put(uid, transformation);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
});
|
||||
|
||||
Mockito.when(transformationConfigurationRegistry.get(anyString(), eq(null)))
|
||||
.thenAnswer((Answer<TransformationConfiguration>) invocation -> {
|
||||
Mockito.when(transformationRegistry.get(anyString(), eq(null)))
|
||||
.thenAnswer((Answer<Transformation>) invocation -> {
|
||||
Object[] args = invocation.getArguments();
|
||||
return configurationMap.get(args[0]);
|
||||
});
|
||||
|
||||
processor = new MapTransformationService(transformationConfigurationRegistry);
|
||||
processor = new MapTransformationService(transformationRegistry);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -109,49 +109,40 @@ public class MapTransformationServiceTest extends JavaTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void setTransformationConfigurationIsRemoved() throws TransformationException {
|
||||
public void setTransformationIsRemoved() throws TransformationException {
|
||||
assertEquals("zu", processor.transform(NON_DEFAULTED_TRANSFORMATION_DE, SOURCE_CLOSED));
|
||||
|
||||
TransformationConfiguration transformationConfiguration = configurationMap
|
||||
.remove(NON_DEFAULTED_TRANSFORMATION_DE);
|
||||
processor.removed(Objects.requireNonNull(transformationConfiguration));
|
||||
Transformation transformation = configurationMap.remove(NON_DEFAULTED_TRANSFORMATION_DE);
|
||||
processor.removed(Objects.requireNonNull(transformation));
|
||||
|
||||
assertThrows(TransformationException.class,
|
||||
() -> processor.transform(NON_DEFAULTED_TRANSFORMATION_DE, SOURCE_CLOSED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setTransformationConfigurationIsNotUpdatedIfOldElementMissing() throws TransformationException {
|
||||
public void setTransformationIsNotUpdatedIfOldElementMissing() throws TransformationException {
|
||||
// update configuration
|
||||
TransformationConfiguration transformationConfigurationDE = Objects
|
||||
.requireNonNull(configurationMap.get(NON_DEFAULTED_TRANSFORMATION_DE));
|
||||
TransformationConfiguration transformationConfigurationFR = Objects
|
||||
.requireNonNull(configurationMap.get(NON_DEFAULTED_TRANSFORMATION_FR));
|
||||
TransformationConfiguration transformationConfigurationModified = new TransformationConfiguration(
|
||||
transformationConfigurationDE.getUID(), transformationConfigurationDE.getLabel(),
|
||||
transformationConfigurationDE.getType(), transformationConfigurationDE.getLanguage(),
|
||||
transformationConfigurationFR.getContent());
|
||||
processor.updated(transformationConfigurationDE, transformationConfigurationModified);
|
||||
Transformation transformationDE = Objects.requireNonNull(configurationMap.get(NON_DEFAULTED_TRANSFORMATION_DE));
|
||||
Transformation transformationFR = Objects.requireNonNull(configurationMap.get(NON_DEFAULTED_TRANSFORMATION_FR));
|
||||
Transformation transformationModified = new Transformation(transformationDE.getUID(),
|
||||
transformationDE.getLabel(), transformationDE.getType(), transformationDE.getConfiguration());
|
||||
processor.updated(transformationDE, transformationModified);
|
||||
|
||||
// assert there is no modified cached version
|
||||
assertEquals("zu", processor.transform(NON_DEFAULTED_TRANSFORMATION_DE, SOURCE_CLOSED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setTransformationConfigurationIsUpdatedIfOldElementPresent() throws TransformationException {
|
||||
public void setTransformationIsUpdatedIfOldElementPresent() throws TransformationException {
|
||||
// ensure old transformation is cached
|
||||
processor.transform(NON_DEFAULTED_TRANSFORMATION_DE, SOURCE_CLOSED);
|
||||
|
||||
// update configuration
|
||||
TransformationConfiguration transformationConfigurationDE = Objects
|
||||
.requireNonNull(configurationMap.get(NON_DEFAULTED_TRANSFORMATION_DE));
|
||||
TransformationConfiguration transformationConfigurationFR = Objects
|
||||
.requireNonNull(configurationMap.get(NON_DEFAULTED_TRANSFORMATION_FR));
|
||||
TransformationConfiguration transformationConfigurationModified = new TransformationConfiguration(
|
||||
transformationConfigurationDE.getUID(), transformationConfigurationDE.getLabel(),
|
||||
transformationConfigurationDE.getType(), transformationConfigurationDE.getLanguage(),
|
||||
transformationConfigurationFR.getContent());
|
||||
processor.updated(transformationConfigurationDE, transformationConfigurationModified);
|
||||
Transformation transformationDE = Objects.requireNonNull(configurationMap.get(NON_DEFAULTED_TRANSFORMATION_DE));
|
||||
Transformation transformationFR = Objects.requireNonNull(configurationMap.get(NON_DEFAULTED_TRANSFORMATION_FR));
|
||||
Transformation transformationModified = new Transformation(transformationDE.getUID(),
|
||||
transformationDE.getLabel(), transformationDE.getType(), transformationFR.getConfiguration());
|
||||
processor.updated(transformationDE, transformationModified);
|
||||
|
||||
// ensure modified configuration is applied
|
||||
assertEquals("fermé", processor.transform(NON_DEFAULTED_TRANSFORMATION_DE, SOURCE_CLOSED));
|
||||
|
|
|
@ -37,9 +37,9 @@ import org.openhab.core.common.registry.RegistryChangeListener;
|
|||
import org.openhab.core.config.core.ConfigOptionProvider;
|
||||
import org.openhab.core.config.core.ParameterOption;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.transform.TransformationConfiguration;
|
||||
import org.openhab.core.transform.TransformationConfigurationRegistry;
|
||||
import org.openhab.core.transform.Transformation;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
import org.openhab.core.transform.TransformationRegistry;
|
||||
import org.openhab.core.transform.TransformationService;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
@ -59,7 +59,7 @@ import org.slf4j.LoggerFactory;
|
|||
"openhab.transform=SCALE" })
|
||||
@NonNullByDefault
|
||||
public class ScaleTransformationService
|
||||
implements TransformationService, ConfigOptionProvider, RegistryChangeListener<TransformationConfiguration> {
|
||||
implements TransformationService, ConfigOptionProvider, RegistryChangeListener<Transformation> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ScaleTransformationService.class);
|
||||
|
||||
|
@ -77,34 +77,33 @@ public class ScaleTransformationService
|
|||
|
||||
/** Inaccessible range used to store presentation format ]0..0[ */
|
||||
private static final Range FORMAT_RANGE = Range.range(BigDecimal.ZERO, false, BigDecimal.ZERO, false);
|
||||
private final TransformationConfigurationRegistry transformationConfigurationRegistry;
|
||||
private final TransformationRegistry transformationRegistry;
|
||||
|
||||
private final Map<String, Map<@Nullable Range, String>> cachedTransformations = new ConcurrentHashMap<>();
|
||||
|
||||
@Activate
|
||||
public ScaleTransformationService(
|
||||
@Reference TransformationConfigurationRegistry transformationConfigurationRegistry) {
|
||||
this.transformationConfigurationRegistry = transformationConfigurationRegistry;
|
||||
transformationConfigurationRegistry.addRegistryChangeListener(this);
|
||||
public ScaleTransformationService(@Reference TransformationRegistry transformationRegistry) {
|
||||
this.transformationRegistry = transformationRegistry;
|
||||
transformationRegistry.addRegistryChangeListener(this);
|
||||
}
|
||||
|
||||
@Deactivate
|
||||
public void deactivate() {
|
||||
transformationConfigurationRegistry.removeRegistryChangeListener(this);
|
||||
transformationRegistry.removeRegistryChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void added(TransformationConfiguration element) {
|
||||
public void added(Transformation element) {
|
||||
// do nothing, configurations are added to cache if needed
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(TransformationConfiguration element) {
|
||||
public void removed(Transformation element) {
|
||||
cachedTransformations.remove(element.getUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updated(TransformationConfiguration oldElement, TransformationConfiguration element) {
|
||||
public void updated(Transformation oldElement, Transformation element) {
|
||||
if (cachedTransformations.remove(oldElement.getUID()) != null) {
|
||||
// import only if it was present before
|
||||
importConfiguration(element);
|
||||
|
@ -144,12 +143,11 @@ public class ScaleTransformationService
|
|||
@Override
|
||||
public @Nullable String transform(String function, String source) throws TransformationException {
|
||||
// always get a configuration from the registry to account for changed system locale
|
||||
TransformationConfiguration transformationConfiguration = transformationConfigurationRegistry.get(function,
|
||||
null);
|
||||
Transformation transformation = transformationRegistry.get(function, null);
|
||||
|
||||
if (transformationConfiguration != null) {
|
||||
if (!cachedTransformations.containsKey(transformationConfiguration.getUID())) {
|
||||
importConfiguration(transformationConfiguration);
|
||||
if (transformation != null) {
|
||||
if (!cachedTransformations.containsKey(transformation.getUID())) {
|
||||
importConfiguration(transformation);
|
||||
}
|
||||
Map<@Nullable Range, String> data = cachedTransformations.get(function);
|
||||
|
||||
|
@ -196,13 +194,17 @@ public class ScaleTransformationService
|
|||
.orElseThrow(() -> new TransformationException("No matching range for '" + source + "'"));
|
||||
}
|
||||
|
||||
private void importConfiguration(@Nullable TransformationConfiguration configuration) {
|
||||
private void importConfiguration(@Nullable Transformation configuration) {
|
||||
if (configuration != null) {
|
||||
try {
|
||||
final Map<@Nullable Range, String> data = new LinkedHashMap<>();
|
||||
data.put(FORMAT_RANGE, FORMAT_LABEL);
|
||||
final OrderedProperties properties = new OrderedProperties();
|
||||
properties.load(new StringReader(configuration.getContent()));
|
||||
String function = configuration.getConfiguration().get(Transformation.FUNCTION);
|
||||
if (function == null) {
|
||||
return;
|
||||
}
|
||||
properties.load(new StringReader(function));
|
||||
|
||||
for (Object orderedKey : properties.orderedKeys()) {
|
||||
final String entry = (String) orderedKey;
|
||||
|
@ -244,7 +246,7 @@ public class ScaleTransformationService
|
|||
@Nullable Locale locale) {
|
||||
if (PROFILE_CONFIG_URI.equals(uri.toString())) {
|
||||
if (CONFIG_PARAM_FUNCTION.equals(param)) {
|
||||
return transformationConfigurationRegistry.getConfigurations(SUPPORTED_CONFIGURATION_TYPES).stream()
|
||||
return transformationRegistry.getTransformations(SUPPORTED_CONFIGURATION_TYPES).stream()
|
||||
.map(c -> new ParameterOption(c.getUID(), c.getLabel())).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,9 +37,9 @@ import org.mockito.junit.jupiter.MockitoSettings;
|
|||
import org.mockito.quality.Strictness;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.transform.TransformationConfiguration;
|
||||
import org.openhab.core.transform.TransformationConfigurationRegistry;
|
||||
import org.openhab.core.transform.Transformation;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
import org.openhab.core.transform.TransformationRegistry;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
|
@ -51,8 +51,8 @@ public class ScaleTransformServiceTest {
|
|||
private static final String SRC_FOLDER = "conf" + File.separator + "transform";
|
||||
|
||||
@Mock
|
||||
private @NonNullByDefault({}) TransformationConfigurationRegistry transformationConfigurationRegistry;
|
||||
private final Map<String, TransformationConfiguration> configurationMap = new HashMap<>();
|
||||
private @NonNullByDefault({}) TransformationRegistry transformationConfigurationRegistry;
|
||||
private final Map<String, Transformation> configurationMap = new HashMap<>();
|
||||
private @NonNullByDefault({}) ScaleTransformationService processor;
|
||||
|
||||
@BeforeEach
|
||||
|
@ -62,15 +62,15 @@ public class ScaleTransformServiceTest {
|
|||
try {
|
||||
String content = new String(Files.readAllBytes(file), StandardCharsets.UTF_8);
|
||||
String uid = Path.of(SRC_FOLDER).relativize(file).toString();
|
||||
TransformationConfiguration transformationConfiguration = new TransformationConfiguration(uid, uid,
|
||||
"scale", null, content);
|
||||
Transformation transformationConfiguration = new Transformation(uid, uid, "scale",
|
||||
Map.of(Transformation.FUNCTION, content));
|
||||
configurationMap.put(uid, transformationConfiguration);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
});
|
||||
|
||||
Mockito.when(transformationConfigurationRegistry.get(anyString(), eq(null)))
|
||||
.thenAnswer((Answer<TransformationConfiguration>) invocation -> {
|
||||
.thenAnswer((Answer<Transformation>) invocation -> {
|
||||
Object[] args = invocation.getArguments();
|
||||
return configurationMap.get(args[0]);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue