diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntity.java index 8bdb5c8b..a0574bce 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntity.java @@ -98,7 +98,15 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject { private Map resources = new HashMap<>(); @Transient - private PatchableMapWrapper resourcesWrapper; + private PatchableMapWrapper resourcesWrapper; + + public PatchableMapWrapper getResources() { + return PatchableMapWrapper.of(resourcesWrapper, (newWrapper) -> {resourcesWrapper = newWrapper; }, resources ); + } + + public void putResources(Map newResources) { + getResources().assign(newResources); + } public void setValidFrom(final LocalDate validFrom) { setValidity(toPostgresDateRange(validFrom, getValidTo())); @@ -116,20 +124,6 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject { return upperInclusiveFromPostgresDateRange(getValidity()); } - public PatchableMapWrapper getResources() { - if ( resourcesWrapper == null ) { - resourcesWrapper = new PatchableMapWrapper(resources); - } - return resourcesWrapper; - } - - public void putResources(Map entries) { - if ( resourcesWrapper == null ) { - resourcesWrapper = new PatchableMapWrapper(resources); - } - resourcesWrapper.assign(entries); - } - @Override public String toString() { return stringify.apply(this); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntity.java index 199e0e7b..462ccd2c 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntity.java @@ -105,20 +105,14 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject { private Map config = new HashMap<>(); @Transient - private PatchableMapWrapper configWrapper; + private PatchableMapWrapper configWrapper; - public PatchableMapWrapper getConfig() { - if ( configWrapper == null ) { - configWrapper = new PatchableMapWrapper(config); - } - return configWrapper; + public PatchableMapWrapper getConfig() { + return PatchableMapWrapper.of(configWrapper, (newWrapper) -> {configWrapper = newWrapper; }, config ); } - public void putConfig(Map entries) { - if ( configWrapper == null ) { - configWrapper = new PatchableMapWrapper(config); - } - configWrapper.assign(entries); + public void putConfig(Map newConfg) { + PatchableMapWrapper.of(configWrapper, (newWrapper) -> {configWrapper = newWrapper; }, config).assign(newConfg); } @Override diff --git a/src/main/java/net/hostsharing/hsadminng/mapper/PatchableMapWrapper.java b/src/main/java/net/hostsharing/hsadminng/mapper/PatchableMapWrapper.java index 678a68cd..a3d2687e 100644 --- a/src/main/java/net/hostsharing/hsadminng/mapper/PatchableMapWrapper.java +++ b/src/main/java/net/hostsharing/hsadminng/mapper/PatchableMapWrapper.java @@ -6,31 +6,41 @@ import jakarta.validation.constraints.NotNull; import java.util.Collection; import java.util.Map; import java.util.Set; +import java.util.function.Consumer; +import static java.util.Optional.ofNullable; import static java.util.stream.Collectors.joining; /** This class wraps another (usually persistent) map and * supports applying `PatchMap` as well as a toString method with stable entry order. */ -public class PatchableMapWrapper implements Map { +public class PatchableMapWrapper implements Map { - private final Map delegate; + private final Map delegate; - public PatchableMapWrapper(final Map map) { + private PatchableMapWrapper(final Map map) { delegate = map; } + public static PatchableMapWrapper of(final PatchableMapWrapper currentWrapper, final Consumer> setWrapper, final Map target) { + return ofNullable(currentWrapper).orElseGet(() -> { + final var newWrapper = new PatchableMapWrapper(target); + setWrapper.accept(newWrapper); + return newWrapper; + }); + } + @NotNull - public static ImmutablePair entry(final String key, final Object value) { + public static ImmutablePair entry(final String key, final E value) { return new ImmutablePair<>(key, value); } - public void assign(final Map entries) { + public void assign(final Map entries) { delegate.clear(); delegate.putAll(entries); } - public void patch(final Map patch) { + public void patch(final Map patch) { patch.forEach((key, value) -> { if (value == null) { remove(key); @@ -73,22 +83,22 @@ public class PatchableMapWrapper implements Map { } @Override - public Object get(final Object key) { + public T get(final Object key) { return delegate.get(key); } @Override - public Object put(final String key, final Object value) { + public T put(final String key, final T value) { return delegate.put(key, value); } @Override - public Object remove(final Object key) { + public T remove(final Object key) { return delegate.remove(key); } @Override - public void putAll(final Map m) { + public void putAll(final @NotNull Map m) { delegate.putAll(m); } @@ -103,12 +113,12 @@ public class PatchableMapWrapper implements Map { } @Override - public Collection values() { + public Collection values() { return delegate.values(); } @Override - public Set> entrySet() { + public Set> entrySet() { return delegate.entrySet(); } }