From 593e62fa32334ce2aa5bbd9b38b7502df8e1fff8 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Thu, 27 Jun 2024 11:37:51 +0200 Subject: [PATCH] generic subclass return values for ValidatableProperty and subclasses --- .../HsBookingItemEntityValidator.java | 4 +- .../HsHostingAssetEntityValidator.java | 6 +-- .../HsUnixUserHostingAssetValidator.java | 2 +- .../hs/validation/BooleanProperty.java | 4 +- .../hs/validation/EnumerationProperty.java | 10 ++-- .../hs/validation/HsEntityValidator.java | 6 +-- .../hs/validation/IntegerProperty.java | 4 +- .../hs/validation/PasswordProperty.java | 7 +-- .../hs/validation/StringProperty.java | 22 ++++---- .../hs/validation/ValidatableProperty.java | 51 ++++++++++--------- .../validation/PasswordPropertyUnitTest.java | 2 +- 11 files changed, 62 insertions(+), 56 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/item/validators/HsBookingItemEntityValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/item/validators/HsBookingItemEntityValidator.java index 315de471..5cd0d71a 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/booking/item/validators/HsBookingItemEntityValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/item/validators/HsBookingItemEntityValidator.java @@ -16,7 +16,7 @@ import static java.util.Optional.ofNullable; public class HsBookingItemEntityValidator extends HsEntityValidator { - public HsBookingItemEntityValidator(final ValidatableProperty... properties) { + public HsBookingItemEntityValidator(final ValidatableProperty... properties) { super(properties); } @@ -54,7 +54,7 @@ public class HsBookingItemEntityValidator extends HsEntityValidator propDef) { + final ValidatableProperty propDef) { final var propName = propDef.propertyName(); final var propUnit = ofNullable(propDef.unit()).map(u -> " " + u).orElse(""); final var totalValue = ofNullable(bookingItem.getSubBookingItems()).orElse(emptyList()) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidator.java index 05bcee97..9f4a6e61 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidator.java @@ -24,7 +24,7 @@ import static java.util.Optional.ofNullable; public abstract class HsHostingAssetEntityValidator extends HsEntityValidator { - static final ValidatableProperty[] NO_EXTRA_PROPERTIES = new ValidatableProperty[0]; + static final ValidatableProperty[] NO_EXTRA_PROPERTIES = new ValidatableProperty[0]; private final HsHostingAssetEntityValidator.BookingItem bookingItemValidation; private final HsHostingAssetEntityValidator.ParentAsset parentAssetValidation; @@ -36,7 +36,7 @@ public abstract class HsHostingAssetEntityValidator extends HsEntityValidator... properties) { + final ValidatableProperty... properties) { super(properties); this.bookingItemValidation = bookingItemValidation; this.parentAssetValidation = parentAssetValidation; @@ -105,7 +105,7 @@ public abstract class HsHostingAssetEntityValidator extends HsEntityValidator propDef) { + final ValidatableProperty propDef) { final var propName = propDef.propertyName(); final var propUnit = ofNullable(propDef.unit()).map(u -> " " + u).orElse(""); final var totalValue = ofNullable(hostingAsset.getSubHostingAssets()).orElse(emptyList()) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java index 74e59965..5f86c86c 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java @@ -30,7 +30,7 @@ class HsUnixUserHostingAssetValidator extends HsHostingAssetEntityValidator { .withDefault("/bin/false"), stringProperty("homedir").readOnly().computedBy(HsUnixUserHostingAssetValidator::computeHomedir), stringProperty("totpKey").matchesRegEx("^0x([0-9A-Fa-f]{2})+$").minLength(20).maxLength(256).undisclosed().writeOnly().optional(), - passwordProperty("password").minLength(8).maxLength(40).writeOnly()); + passwordProperty("password").minLength(8).maxLength(40).hashedUsing("SHA-512").writeOnly()); } @Override diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/BooleanProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/BooleanProperty.java index 5f893d74..abe5f7b4 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/BooleanProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/BooleanProperty.java @@ -9,7 +9,7 @@ import java.util.Map; import java.util.Objects; @Setter -public class BooleanProperty extends ValidatableProperty { +public class BooleanProperty extends ValidatableProperty { private static final String[] KEY_ORDER = Array.join(ValidatableProperty.KEY_ORDER_HEAD, ValidatableProperty.KEY_ORDER_TAIL); @@ -23,7 +23,7 @@ public class BooleanProperty extends ValidatableProperty { return new BooleanProperty(propertyName); } - public ValidatableProperty falseIf(final String refPropertyName, final String refPropertyValue) { + public BooleanProperty falseIf(final String refPropertyName, final String refPropertyValue) { this.falseIf = new AbstractMap.SimpleImmutableEntry<>(refPropertyName, refPropertyValue); return this; } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/EnumerationProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/EnumerationProperty.java index 60af1b73..60e0f244 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/EnumerationProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/EnumerationProperty.java @@ -9,7 +9,7 @@ import java.util.List; import static java.util.Arrays.stream; @Setter -public class EnumerationProperty extends ValidatableProperty { +public class EnumerationProperty extends ValidatableProperty { private static final String[] KEY_ORDER = Array.join( ValidatableProperty.KEY_ORDER_HEAD, @@ -26,12 +26,12 @@ public class EnumerationProperty extends ValidatableProperty { return new EnumerationProperty(propertyName); } - public ValidatableProperty values(final String... values) { + public EnumerationProperty values(final String... values) { this.values = values; return this; } - public void deferredInit(final ValidatableProperty[] allProperties) { + public void deferredInit(final ValidatableProperty[] allProperties) { if (hasDeferredInit()) { if (this.values != null) { throw new IllegalStateException("property " + this + " already has values"); @@ -40,8 +40,8 @@ public class EnumerationProperty extends ValidatableProperty { } } - public ValidatableProperty valuesFromProperties(final String propertyNamePrefix) { - this.setDeferredInit( (ValidatableProperty[] allProperties) -> stream(allProperties) + public EnumerationProperty valuesFromProperties(final String propertyNamePrefix) { + this.setDeferredInit( (ValidatableProperty[] allProperties) -> stream(allProperties) .map(ValidatableProperty::propertyName) .filter(name -> name.startsWith(propertyNamePrefix)) .map(name -> name.substring(propertyNamePrefix.length())) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java index 5af7118d..b8c345e7 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java @@ -14,9 +14,9 @@ import static java.util.Collections.emptyList; // TODO.refa: rename to HsEntityProcessor, also subclasses public abstract class HsEntityValidator { - public final ValidatableProperty[] propertyValidators; + public final ValidatableProperty[] propertyValidators; - public HsEntityValidator(final ValidatableProperty... validators) { + public HsEntityValidator(final ValidatableProperty... validators) { propertyValidators = validators; stream(propertyValidators).forEach(p -> p.deferredInit(propertyValidators)); } @@ -68,7 +68,7 @@ public abstract class HsEntityValidator { .orElse(emptyList())); } - protected static Integer getIntegerValueWithDefault0(final ValidatableProperty prop, final Map propValues) { + protected static Integer getIntegerValueWithDefault0(final ValidatableProperty prop, final Map propValues) { final var value = prop.getValue(propValues); if (value instanceof Integer) { return (Integer) value; 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 f185c469..7021f9e1 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/IntegerProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/IntegerProperty.java @@ -7,7 +7,7 @@ import org.apache.commons.lang3.Validate; import java.util.List; @Setter -public class IntegerProperty extends ValidatableProperty { +public class IntegerProperty extends ValidatableProperty { private final static String[] KEY_ORDER = Array.join( ValidatableProperty.KEY_ORDER_HEAD, @@ -30,7 +30,7 @@ public class IntegerProperty extends ValidatableProperty { } @Override - public void deferredInit(final ValidatableProperty[] allProperties) { + public void deferredInit(final ValidatableProperty[] allProperties) { Validate.isTrue(min == null || minFrom == null, "min and minFrom are exclusive, but both are given"); Validate.isTrue(max == null || maxFrom == null, "max and maxFrom are exclusive, but both are given"); } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/PasswordProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/PasswordProperty.java index 92cafb9a..fba233d1 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/PasswordProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/PasswordProperty.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.stream.Stream; @Setter -public class PasswordProperty extends StringProperty { +public class PasswordProperty extends StringProperty { private PasswordProperty(final String propertyName) { super(propertyName); @@ -23,7 +23,9 @@ public class PasswordProperty extends StringProperty { validatePassword(result, propValue); } - // TODO.impl: only a SHA512 hash should be stored in the database, not the password itself + public PasswordProperty hashedUsing(final String hashAlgoritm) { + return self(); + } @Override protected String simpleTypeName() { @@ -60,6 +62,5 @@ public class PasswordProperty extends StringProperty { if (containsColon) { result.add(propertyName + "' must not contain colon (':')"); } - } } 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 d34e77a9..e6b184f0 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java @@ -8,7 +8,7 @@ import java.util.regex.Pattern; @Setter -public class StringProperty extends ValidatableProperty { +public class StringProperty

> extends ValidatableProperty { private static final String[] KEY_ORDER = Array.join( ValidatableProperty.KEY_ORDER_HEAD, @@ -24,23 +24,23 @@ public class StringProperty extends ValidatableProperty { super(String.class, propertyName, KEY_ORDER); } - public static StringProperty stringProperty(final String propertyName) { - return new StringProperty(propertyName); + public static StringProperty stringProperty(final String propertyName) { + return new StringProperty<>(propertyName); } - public StringProperty minLength(final int minLength) { + public P minLength(final int minLength) { this.minLength = minLength; - return this; + return self(); } - public StringProperty maxLength(final int maxLength) { + public P maxLength(final int maxLength) { this.maxLength = maxLength; - return this; + return self(); } - public StringProperty matchesRegEx(final String regExPattern) { + public P matchesRegEx(final String regExPattern) { this.matchesRegEx = Pattern.compile(regExPattern); - return this; + return self(); } /** @@ -48,9 +48,9 @@ public class StringProperty extends ValidatableProperty { * * @return this; */ - public StringProperty undisclosed() { + public P undisclosed() { this.undisclosed = true; - return this; + return self(); } @Override 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 b34eb8fa..76fc451e 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; @Getter @RequiredArgsConstructor -public abstract class ValidatableProperty { +public abstract class ValidatableProperty

, T> { protected static final String[] KEY_ORDER_HEAD = Array.of("propertyName"); protected static final String[] KEY_ORDER_TAIL = Array.of("required", "defaultValue", "readOnly", "writeOnly", "computed", "isTotalsValidator", "thresholdPercentage"); @@ -51,7 +51,7 @@ public abstract class ValidatableProperty { @Accessors(makeFinal = true, chain = true, fluent = false) private boolean writeOnly; - private Function[], T[]> deferredInit; + private Function[], T[]> deferredInit; private boolean isTotalsValidator = false; @JsonIgnore @@ -59,11 +59,16 @@ public abstract class ValidatableProperty { private Integer thresholdPercentage; // TODO.impl: move to IntegerProperty + public final P self() { + //noinspection unchecked + return (P) this; + } + public String unit() { return null; } - protected void setDeferredInit(final Function[], T[]> function) { +protected void setDeferredInit(final Function[], T[]> function) { this.deferredInit = function; } @@ -71,47 +76,47 @@ public abstract class ValidatableProperty { return deferredInit != null; } - public T[] doDeferredInit(final ValidatableProperty[] allProperties) { + public T[] doDeferredInit(final ValidatableProperty[] allProperties) { return deferredInit.apply(allProperties); } - public ValidatableProperty writeOnly() { + public P writeOnly() { this.writeOnly = true; optional(); - return this; + return self(); } - public ValidatableProperty readOnly() { + public P readOnly() { this.readOnly = true; optional(); - return this; + return self(); } - public ValidatableProperty required() { + public P required() { required = TRUE; - return this; + return self(); } - public ValidatableProperty optional() { + public ValidatableProperty optional() { required = FALSE; return this; } - public ValidatableProperty withDefault(final T value) { + public P withDefault(final T value) { defaultValue = value; required = FALSE; - return this; + return self(); } - public void deferredInit(final ValidatableProperty[] allProperties) { + public void deferredInit(final ValidatableProperty[] allProperties) { } - public ValidatableProperty asTotalLimit() { + public P asTotalLimit() { isTotalsValidator = true; - return this; + return self(); } - public ValidatableProperty asTotalLimitFor(final String propertyName, final String propertyValue) { + public P asTotalLimitFor(final String propertyName, final String propertyValue) { if (asTotalLimitValidators == null) { asTotalLimitValidators = new ArrayList<>(); } @@ -132,7 +137,7 @@ public abstract class ValidatableProperty { return emptyList(); }; asTotalLimitValidators.add((final HsBookingItemEntity entity) -> validator.apply(entity, (IntegerProperty)this, 1)); - return this; + return self(); } public String propertyName() { @@ -147,7 +152,7 @@ public abstract class ValidatableProperty { return thresholdPercentage; } - public ValidatableProperty eachComprising(final int factor, final TriFunction> validator) { + public ValidatableProperty eachComprising(final int factor, final TriFunction> validator) { if (asTotalLimitValidators == null) { asTotalLimitValidators = new ArrayList<>(); } @@ -155,9 +160,9 @@ public abstract class ValidatableProperty { return this; } - public ValidatableProperty withThreshold(final Integer percentage) { + public P withThreshold(final Integer percentage) { this.thresholdPercentage = percentage; - return this; + return self(); } public final List validate(final PropertiesProvider propsProvider) { @@ -250,10 +255,10 @@ public abstract class ValidatableProperty { .toList(); } - public ValidatableProperty computedBy(final Function compute) { + public P computedBy(final Function compute) { this.computedBy = compute; this.computed = true; - return this; + return self(); } public T compute(final E entity) { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/validation/PasswordPropertyUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/validation/PasswordPropertyUnitTest.java index 66da5f2d..24801e9c 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/validation/PasswordPropertyUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/validation/PasswordPropertyUnitTest.java @@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat; class PasswordPropertyUnitTest { - private final ValidatableProperty passwordProp = passwordProperty("password").minLength(8).maxLength(40).writeOnly(); + private final ValidatableProperty passwordProp = passwordProperty("password").minLength(8).maxLength(40).writeOnly(); private final List violations = new ArrayList<>(); @ParameterizedTest