Support channel transformations with parentheses (#4352)

* Support channel transformations with parentheses

Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
jimtng
2024-08-18 17:05:32 +02:00
committed by GitHub
parent 0e1883bdae
commit bb2a2d10dc
2 changed files with 107 additions and 9 deletions
@@ -15,6 +15,8 @@ package org.openhab.core.thing.binding.generic;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.transform.TransformationException;
@@ -61,18 +63,27 @@ public class ChannelTransformation {
}
private static class TransformationStep {
private static final List<Pattern> TRANSFORMATION_PATTERNS = List.of( //
Pattern.compile("(?<service>[a-zA-Z0-9]+)\\s*\\((?<function>.*)\\)$"), //
Pattern.compile("(?<service>[a-zA-Z0-9]+)\\s*:(?<function>.*)") //
);
private final Logger logger = LoggerFactory.getLogger(TransformationStep.class);
private final String serviceName;
private final String function;
public TransformationStep(String pattern) throws IllegalArgumentException {
int index = pattern.indexOf(":");
if (index == -1) {
throw new IllegalArgumentException(
"The transformation pattern must consist of the type and the pattern separated by a colon");
pattern = pattern.trim();
for (Pattern p : TRANSFORMATION_PATTERNS) {
Matcher matcher = p.matcher(pattern);
if (matcher.matches()) {
this.serviceName = matcher.group("service").trim().toUpperCase();
this.function = matcher.group("function").trim();
return;
}
}
this.serviceName = pattern.substring(0, index).toUpperCase().trim();
this.function = pattern.substring(index + 1).trim();
throw new IllegalArgumentException(
"The transformation pattern must be in the syntax of TYPE:PATTERN or TYPE(PATTERN)");
}
public Optional<String> apply(String value) {
@@ -52,6 +52,11 @@ public class ChannelTransformationTest {
private static final String T2_INPUT = T1_RESULT;
private static final String T2_RESULT = "T2Result";
private static final String T3_NAME = T2_NAME;
private static final String T3_PATTERN = "a()b()))";
private static final String T3_INPUT = T2_INPUT;
private static final String T3_RESULT = T2_RESULT;
private @Mock @NonNullByDefault({}) TransformationService transformationService1Mock;
private @Mock @NonNullByDefault({}) TransformationService transformationService2Mock;
@@ -69,6 +74,8 @@ public class ChannelTransformationTest {
.thenAnswer(answer -> T2_RESULT);
Mockito.when(transformationService2Mock.transform(eq(T2_PATTERN), eq(T2_INPUT)))
.thenAnswer(answer -> T2_RESULT);
Mockito.when(transformationService2Mock.transform(eq(T3_PATTERN), eq(T3_INPUT)))
.thenAnswer(answer -> T3_RESULT);
Mockito.when(serviceRef1Mock.getProperty(any())).thenReturn("TRANSFORM1");
Mockito.when(serviceRef2Mock.getProperty(any())).thenReturn("TRANSFORM2");
@@ -97,7 +104,7 @@ public class ChannelTransformationTest {
}
@Test
public void testSingleTransformation() {
public void testSingleTransformationWithColon() {
String pattern = T1_NAME + ":" + T1_PATTERN;
ChannelTransformation transformation = new ChannelTransformation(pattern);
@@ -106,6 +113,26 @@ public class ChannelTransformationTest {
assertEquals(T1_RESULT, result);
}
@Test
public void testSingleTransformationWithParens() {
String pattern = T1_NAME + "(" + T1_PATTERN + ")";
ChannelTransformation transformation = new ChannelTransformation(pattern);
String result = transformation.apply(T1_INPUT).orElse(null);
assertEquals(T1_RESULT, result);
}
@Test
public void testParensTransformationWithNestedParensInPattern() {
String pattern = T3_NAME + "(" + T3_PATTERN + ")";
ChannelTransformation transformation = new ChannelTransformation(pattern);
String result = transformation.apply(T3_INPUT).orElse(null);
assertEquals(T3_RESULT, result);
}
@Test
public void testInvalidFirstTransformation() {
String pattern = T1_NAME + "X:" + T1_PATTERN + "" + T2_NAME + ":" + T2_PATTERN;
@@ -127,7 +154,7 @@ public class ChannelTransformationTest {
}
@Test
public void testDoubleTransformationWithoutSpaces() {
public void testColonDoubleTransformationWithoutSpaces() {
String pattern = T1_NAME + ":" + T1_PATTERN + "" + T2_NAME + ":" + T2_PATTERN;
ChannelTransformation transformation = new ChannelTransformation(pattern);
@@ -137,7 +164,37 @@ public class ChannelTransformationTest {
}
@Test
public void testDoubleTransformationWithSpaces() {
public void testParensDoubleTransformationWithoutSpaces() {
String pattern = T1_NAME + "(" + T1_PATTERN + ")∩" + T2_NAME + "(" + T2_PATTERN + ")";
ChannelTransformation transformation = new ChannelTransformation(pattern);
String result = transformation.apply(T1_INPUT).orElse(null);
assertEquals(T2_RESULT, result);
}
@Test
public void testMixedDoubleTransformationWithoutSpaces1() {
String pattern = T1_NAME + ":" + T1_PATTERN + "" + T2_NAME + "(" + T2_PATTERN + ")";
ChannelTransformation transformation = new ChannelTransformation(pattern);
String result = transformation.apply(T1_INPUT).orElse(null);
assertEquals(T2_RESULT, result);
}
@Test
public void testMixedDoubleTransformationWithoutSpaces2() {
String pattern = T1_NAME + "(" + T1_PATTERN + ")∩" + T2_NAME + ":" + T2_PATTERN;
ChannelTransformation transformation = new ChannelTransformation(pattern);
String result = transformation.apply(T1_INPUT).orElse(null);
assertEquals(T2_RESULT, result);
}
@Test
public void testColonDoubleTransformationWithSpaces() {
String pattern = " " + T1_NAME + " : " + T1_PATTERN + "" + T2_NAME + " : " + T2_PATTERN + " ";
ChannelTransformation transformation = new ChannelTransformation(pattern);
@@ -145,4 +202,34 @@ public class ChannelTransformationTest {
assertEquals(T2_RESULT, result);
}
@Test
public void testParensDoubleTransformationWithSpaces() {
String pattern = " " + T1_NAME + " ( " + T1_PATTERN + " ) ∩ " + T2_NAME + " ( " + T2_PATTERN + " ) ";
ChannelTransformation transformation = new ChannelTransformation(pattern);
String result = transformation.apply(T1_INPUT).orElse(null);
assertEquals(T2_RESULT, result);
}
@Test
public void testMixedDoubleTransformationWithSpaces1() {
String pattern = " " + T1_NAME + " : " + T1_PATTERN + "" + T2_NAME + " ( " + T2_PATTERN + " ) ";
ChannelTransformation transformation = new ChannelTransformation(pattern);
String result = transformation.apply(T1_INPUT).orElse(null);
assertEquals(T2_RESULT, result);
}
@Test
public void testMixedDoubleTransformationWithSpaces2() {
String pattern = " " + T1_NAME + " ( " + T1_PATTERN + " ) ∩ " + T2_NAME + " : " + T2_PATTERN + " ";
ChannelTransformation transformation = new ChannelTransformation(pattern);
String result = transformation.apply(T1_INPUT).orElse(null);
assertEquals(T2_RESULT, result);
}
}