Compare commits

...

2 Commits

Author SHA1 Message Date
Michael Hoennig
6318497294 still a bit hacky, but now working generically 2024-06-25 17:50:54 +02:00
Michael Hoennig
680b67f162 still hacked, but now cleaning up the resource object, not the entity 2024-06-25 17:37:52 +02:00
5 changed files with 47 additions and 30 deletions

View File

@ -23,6 +23,7 @@ import java.util.List;
import java.util.UUID;
import java.util.function.BiConsumer;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidatorRegistry.cleanup;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidatorRegistry.validated;
@RestController
@ -71,7 +72,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final var entityToSave = mapper.map(body, HsHostingAssetEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var saved = saveAndValidate(entityToSave);
final var saved = validated(assetRepo.save(entityToSave));
final var uri =
MvcUriComponentsBuilder.fromController(getClass())
@ -126,8 +127,8 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
new HsHostingAssetEntityPatcher(em, current).apply(body);
final var saved = saveAndValidate(current);
final var mapped = mapper.map(saved, HsHostingAssetResource.class);
final var saved = validated(assetRepo.save(current));
final var mapped = mapper.map(saved, HsHostingAssetResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(mapped);
}
@ -145,11 +146,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
}
};
HsHostingAssetEntity saveAndValidate(final HsHostingAssetEntity entity) {
final var saved = assetRepo.save(entity);
// FIXME: this is hacky, better remove the properties from the mapped resource object
em.flush();
em.detach(saved); // validated(...) is going to remove writeOnly properties
return validated(saved);
}
final BiConsumer<HsHostingAssetEntity, HsHostingAssetResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
cleanup(entity, resource);
};
}

View File

@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import net.hostsharing.hsadminng.errors.MultiValidationException;
@ -41,12 +42,7 @@ public class HsHostingAssetEntityValidatorRegistry {
public static List<String> doValidate(final HsHostingAssetEntity hostingAsset) {
final var validator = HsHostingAssetEntityValidatorRegistry.forType(hostingAsset.getType());
final var validated = validator.validate(hostingAsset);
//validator.cleanup()
hostingAsset.getConfig().remove("password"); // FIXME
hostingAsset.getConfig().remove("totpKey"); // FIXME
return validated;
return validator.validate(hostingAsset);
}
public static HsHostingAssetEntity validated(final HsHostingAssetEntity entityToSave) {
@ -54,4 +50,18 @@ public class HsHostingAssetEntityValidatorRegistry {
return entityToSave;
}
public static void cleanup(final HsHostingAssetEntity entity, final HsHostingAssetResource resource) {
final var validator = HsHostingAssetEntityValidatorRegistry.forType(entity.getType());
final var config = validator.cleanup(asMap(resource));
resource.setConfig(config);
}
@SuppressWarnings("unchecked")
private static Map<String, Object> asMap(final HsHostingAssetResource resource) {
if (resource.getConfig() instanceof Map map) {
return map;
}
throw new IllegalArgumentException("expected a Map, but got a " + resource.getConfig().getClass());
}
}

View File

@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.validation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
@ -86,4 +87,10 @@ public abstract class HsEntityValidator<E> {
}
throw new IllegalArgumentException("Integer value (or null) expected, but got " + value);
}
public Map<String, Object> cleanup(final Map<String, Object> config) {
final var copy = new HashMap<>(config);
stream(propertyValidators).filter(p -> p.writeOnly).forEach(p -> copy.remove(p.propertyName));
return copy;
}
}

View File

@ -17,8 +17,6 @@ public class StringProperty extends ValidatableProperty<String> {
private Pattern regExPattern;
private Integer minLength;
private Integer maxLength;
private boolean writeOnly;
private boolean readOnly;
private boolean hidden;
protected StringProperty(final String propertyName) {
@ -49,18 +47,6 @@ public class StringProperty extends ValidatableProperty<String> {
return this;
}
public StringProperty writeOnly() {
this.writeOnly = true;
super.optional();
return this;
}
public StringProperty readOnly() {
this.readOnly = true;
super.optional();
return this;
}
@Override
protected void validate(final List<String> result, final String propValue, final PropertiesProvider propProvider) {
if (minLength != null && propValue.length()<minLength) {

View File

@ -32,6 +32,9 @@ public abstract class ValidatableProperty<T> {
private final String[] keyOrder;
private Boolean required;
private T defaultValue;
protected boolean readOnly;
protected boolean writeOnly;
protected Function<ValidatableProperty<?>[], T[]> deferredInit;
private boolean isTotalsValidator = false;
@JsonIgnore
@ -43,6 +46,20 @@ public abstract class ValidatableProperty<T> {
return null;
}
public ValidatableProperty<T> writeOnly() {
this.writeOnly = true;
optional();
return this;
}
public ValidatableProperty<T> readOnly() {
this.readOnly = true;
optional();
return this;
}
public ValidatableProperty<T> required() {
required = TRUE;
return this;