From f9ea413ea8bc1a846a1ae3025a2ac060a5e8e80e Mon Sep 17 00:00:00 2001 From: Konrad Windszus Date: Thu, 28 Mar 2024 12:58:23 +0100 Subject: [PATCH] Grant access to StringEscapeUtils.escapeXml10 and StringUtils.capitalize This closes #690 This closes #710 Co-authored-by: Beatrice Peptenaru --- .../configreader/YamlMacroElEvaluator.java | 10 +++- .../YamlMacroElEvaluatorTest.java | 46 +++++++++++++++++++ docs/AdvancedFeatures.md | 2 + 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 accesscontroltool-bundle/src/test/java/biz/netcentric/cq/tools/actool/configreader/YamlMacroElEvaluatorTest.java diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlMacroElEvaluator.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlMacroElEvaluator.java index a0edee6a..c45edd4b 100644 --- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlMacroElEvaluator.java +++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/configreader/YamlMacroElEvaluator.java @@ -30,6 +30,7 @@ import jakarta.el.VariableMapper; import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.apache.el.ExpressionFactoryImpl; @@ -119,6 +120,7 @@ public ElFunctionMapper() { StringUtils.class.getMethod("upperCase", new Class[] { String.class }), StringUtils.class.getMethod("lowerCase", new Class[] { String.class }), + StringUtils.class.getMethod("capitalize", new Class[] { String.class }), StringUtils.class.getMethod("substringAfter", new Class[] { String.class, String.class }), StringUtils.class.getMethod("substringBefore", new Class[] { String.class, String.class }), StringUtils.class.getMethod("substringAfterLast", new Class[] { String.class, String.class }), @@ -134,7 +136,8 @@ public ElFunctionMapper() { YamlMacroElEvaluator.ElFunctionMapper.class.getMethod("containsAllItems", new Class[] { List.class, List.class }), YamlMacroElEvaluator.ElFunctionMapper.class.getMethod("containsAnyItem", new Class[] { List.class, List.class }), YamlMacroElEvaluator.ElFunctionMapper.class.getMethod("keys", new Class[] { Map.class }), - YamlMacroElEvaluator.ElFunctionMapper.class.getMethod("values", new Class[] { Map.class }) + YamlMacroElEvaluator.ElFunctionMapper.class.getMethod("values", new Class[] { Map.class }), + YamlMacroElEvaluator.ElFunctionMapper.class.getMethod("escapeXml", new Class[] { String.class }) }; for (Method method : exportedMethods) { functionMap.put(method.getName(), method); @@ -171,6 +174,11 @@ public static List keys(Map map) { public static List values(Map map) { return new ArrayList<>(map.values()); } + + public static String escapeXml(String input) { + // DocView is XML 1.0 + return StringEscapeUtils.escapeXml10(input); + } } class ElVariableMapper extends VariableMapper { diff --git a/accesscontroltool-bundle/src/test/java/biz/netcentric/cq/tools/actool/configreader/YamlMacroElEvaluatorTest.java b/accesscontroltool-bundle/src/test/java/biz/netcentric/cq/tools/actool/configreader/YamlMacroElEvaluatorTest.java new file mode 100644 index 00000000..f2f822ab --- /dev/null +++ b/accesscontroltool-bundle/src/test/java/biz/netcentric/cq/tools/actool/configreader/YamlMacroElEvaluatorTest.java @@ -0,0 +1,46 @@ +package biz.netcentric.cq.tools.actool.configreader; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import jakarta.el.ELException; + +class YamlMacroElEvaluatorTest { + private YamlMacroElEvaluator elEvaluator; + + @BeforeEach + public void setUp() { + elEvaluator = new YamlMacroElEvaluator(); + } + + @Test + void testFunctions() { + assertEquals("bread&butter", evaluateSimpleExpression("escapeXml(\"bread&butter\")")); + assertEquals("Test", evaluateSimpleExpression("capitalize(\"test\")")); + assertEquals("item1,item2", evaluateSimpleExpression("join(var1, \",\")", Collections.singletonMap("var1", new Object[] {"item1", "item2"}))); + } + + @Test + void testNonExistingFunction() { + assertThrows(ELException.class, () -> evaluateSimpleExpression("invalid(\"test\")")); + } + + @Test + void testSyntaxErrpr() { + assertThrows(ELException.class, () -> evaluateSimpleExpression("invalid(\"test\"")); + } + + private Object evaluateSimpleExpression(String expression) { + return evaluateSimpleExpression(expression, Collections.emptyMap()); + } + + private Object evaluateSimpleExpression(String expression, Map variables) { + return elEvaluator.evaluateEl("${" + expression + "}", Object.class, variables); + } +} diff --git a/docs/AdvancedFeatures.md b/docs/AdvancedFeatures.md index 9d141d27..41260302 100644 --- a/docs/AdvancedFeatures.md +++ b/docs/AdvancedFeatures.md @@ -14,6 +14,7 @@ Function Signature | Description `subarray(String array, startIndexInclusive,endIndexExclusive)`| [`ArrayUtils.subarray(...)`](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/ArrayUtils.html#subarray-T:A-int-int-) `upperCase(String str)`|[`StringUtils.upperCase(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringUtils.html#upperCase(java.lang.String)) `lowerCase(String str)`|[`StringUtils.lowerCase(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringUtils.html#lowerCase(java.lang.String)) +`capitalize(String str)`|[`StringUtils.capitalize(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringUtils.html#capitalize(java.lang.String)) `replace(String text, String searchString, String replacement)`|[`StringUtils.replace(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringUtils.html#replace(java.lang.String,%20java.lang.String,%20java.lang.String)) `substringAfter(String str, String separator)`|[`StringUtils.substringAfter(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringUtils.html#substringAfter(java.lang.String,%20java.lang.String)) `substringBefore(String str, String separator)`|[`StringUtils.substringBefore(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringUtils.html#substringBefore(java.lang.String,%20java.lang.String)) @@ -24,6 +25,7 @@ Function Signature | Description `startsWith(String str, String prefix)`| [`StringUtils.startsWith(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringUtils.html#startsWith(java.lang.CharSequence,%20java.lang.CharSequence)) `length(String string)`| [`StringUtils.length(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringUtils.html#length(java.lang.CharSequence)) `defaultIfEmpty(String str, String default)` | [`StringUtils.defaultIfEmpty(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringUtils.html#defaultIfEmpty(T,%20T)) +`escapeXml(String str)` | [`StringEscapeUtils.escapeXml10(...)`](https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/StringEscapeUtils.html#escapeXml10(java.lang.String)), useful for escaping values within `initialContent` which uses [enhanced JCR DocView syntax (an XML 1.0 language)](https://jackrabbit.apache.org/filevault/docview.html). `containsItem(List list, String item)`| Returns `true` if the item is contained in the given list. `containsAnyItem(List list, List items)`| Returns `true` if any of the items is contained in the given list. `containsAllItems(List list, List items)`| Returns `true` if all of the items are contained in the given list (independent of their order).