From 32a8321c0e64d6a96a3526e9d21a71c419e4700e Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 26 Jun 2024 16:29:13 +0200 Subject: [PATCH] proper properties descriptions --- .../hs/validation/IntegerProperty.java | 2 +- .../hs/validation/StringProperty.java | 13 +++++---- .../hs/validation/ValidatableProperty.java | 28 ++++++++++++------- ...UnixUserHostingAssetValidatorUnitTest.java | 21 ++++++++++++++ 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/IntegerProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/IntegerProperty.java index 37a011d4..f185c469 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/IntegerProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/IntegerProperty.java @@ -11,7 +11,7 @@ public class IntegerProperty extends ValidatableProperty { private final static String[] KEY_ORDER = Array.join( ValidatableProperty.KEY_ORDER_HEAD, - Array.of("unit", "min", "max", "step"), + Array.of("unit", "min", "minFrom", "max", "maxFrom", "step"), ValidatableProperty.KEY_ORDER_TAIL); private String unit; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java index 805f3d0b..616ff26c 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java @@ -12,9 +12,10 @@ public class StringProperty extends ValidatableProperty { private static final String[] KEY_ORDER = Array.join( ValidatableProperty.KEY_ORDER_HEAD, - Array.of("values"), - ValidatableProperty.KEY_ORDER_TAIL); - private Pattern regExPattern; + Array.of("matchesRegEx", "minLength", "maxLength"), + ValidatableProperty.KEY_ORDER_TAIL, + Array.of("hidden")); + private Pattern matchesRegEx; private Integer minLength; private Integer maxLength; private boolean hidden; @@ -38,7 +39,7 @@ public class StringProperty extends ValidatableProperty { } public StringProperty matchesRegEx(final String regExPattern) { - this.regExPattern = Pattern.compile(regExPattern); + this.matchesRegEx = Pattern.compile(regExPattern); return this; } @@ -55,8 +56,8 @@ public class StringProperty extends ValidatableProperty { if (maxLength != null && propValue.length()>maxLength) { result.add(propertyName + "' length is expected to be at max " + maxLength + " but length of " + display(propValue) + " is " + propValue.length()); } - if (regExPattern != null && !regExPattern.matcher(propValue).matches()) { - result.add(propertyName + "' is expected to be match " + regExPattern + " but " + display(propValue) + " does not match"); + if (matchesRegEx != null && !matchesRegEx.matcher(propValue).matches()) { + result.add(propertyName + "' is expected to be match " + matchesRegEx + " but " + display(propValue) + " does not match"); } if (readOnly && propValue != null) { result.add(propertyName + "' is readonly but given as " + display(propValue)); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java index c65f9325..259bff9d 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java @@ -25,7 +25,7 @@ import static java.util.Optional.ofNullable; public abstract class ValidatableProperty { protected static final String[] KEY_ORDER_HEAD = Array.of("propertyName"); - protected static final String[] KEY_ORDER_TAIL = Array.of("required", "defaultValue", "isTotalsValidator", "thresholdPercentage"); + protected static final String[] KEY_ORDER_TAIL = Array.of("required", "defaultValue", "readOnly", "writeOnly", "computed", "isTotalsValidator", "thresholdPercentage"); final Class type; final String propertyName; @@ -33,6 +33,7 @@ public abstract class ValidatableProperty { private Boolean required; private T defaultValue; protected Function computedBy; + protected boolean computed; // used in descriptor, because computedBy cannot be rendered to a text string protected boolean readOnly; protected boolean writeOnly; @@ -177,26 +178,32 @@ public abstract class ValidatableProperty { // Add entries according to the given order for (String key : keyOrder) { final Optional propValue = getPropertyValue(key); - propValue.ifPresent(o -> sortedMap.put(key, o)); + propValue.filter(ValidatableProperty::isToBeRendered).ifPresent(o -> sortedMap.put(key, o)); } return sortedMap; } + private static boolean isToBeRendered(final Object v) { + return !(v instanceof Boolean b) || b; + } + @SneakyThrows private Optional getPropertyValue(final String key) { + return getPropertyValue(getClass(), key); + } + + @SneakyThrows + private Optional getPropertyValue(final Class clazz, final String key) { try { - final var field = getClass().getDeclaredField(key); + final var field = clazz.getDeclaredField(key); field.setAccessible(true); return Optional.ofNullable(arrayToList(field.get(this))); - } catch (final NoSuchFieldException e1) { - try { - final var field = getClass().getSuperclass().getDeclaredField(key); - field.setAccessible(true); - return Optional.ofNullable(arrayToList(field.get(this))); - } catch (final NoSuchFieldException e2) { - return Optional.empty(); + } catch (final NoSuchFieldException exc) { + if (clazz.getSuperclass() != null) { + return getPropertyValue(clazz.getSuperclass(), key); } + throw exc; } } @@ -220,6 +227,7 @@ public abstract class ValidatableProperty { public ValidatableProperty computedBy(final Function compute) { this.computedBy = compute; + this.computed = true; return this; } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidatorUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidatorUnitTest.java index 15f2de6c..c8b818f3 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidatorUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidatorUnitTest.java @@ -107,4 +107,25 @@ class HsUnixUserHostingAssetValidatorUnitTest { assertThat(result).containsExactly( "'identifier' expected to match '^abc00$|^abc00-[a-z0-9]+$', but is 'xyz99-temp'"); } + + @Test + void describesItsProperties() { + // given + final var validator = HsHostingAssetEntityValidatorRegistry.forType(UNIX_USER); + + // when + final var props = validator.properties(); + + // then + assertThat(props).extracting(Object::toString).containsExactlyInAnyOrder( + "{type=integer, propertyName=SSD hard quota, unit=GB, maxFrom=SSD}", + "{type=integer, propertyName=SSD soft quota, unit=GB, maxFrom=SSD hard quota}", + "{type=integer, propertyName=HDD hard quota, unit=GB, maxFrom=HDD}", + "{type=integer, propertyName=HDD soft quota, unit=GB, maxFrom=HDD hard quota}", + "{type=enumeration, propertyName=shell, values=[/bin/false, /bin/bash, /bin/csh, /bin/dash, /usr/bin/tcsh, /usr/bin/zsh, /usr/bin/passwd], defaultValue=/bin/false}", + "{type=string, propertyName=homedir, readOnly=true, computed=true}", + "{type=string, propertyName=totpKey, matchesRegEx=^0x([0-9A-Fa-f]{2})+$, minLength=20, maxLength=256, writeOnly=true, hidden=true}", + "{type=password, propertyName=password, minLength=8, maxLength=40, writeOnly=true, hidden=true}" + ); + } }