diff --git a/src/main/java/org/springframework/hateoas/AffordanceModel.java b/src/main/java/org/springframework/hateoas/AffordanceModel.java index 51d305490..7e91901b3 100644 --- a/src/main/java/org/springframework/hateoas/AffordanceModel.java +++ b/src/main/java/org/springframework/hateoas/AffordanceModel.java @@ -147,13 +147,35 @@ public PayloadMetadata getOutput() { * @return will never be {@literal null}. * @since 1.3 */ - public List createProperties(BiFunction creator) { + public List createProperties(PropertyCreator creator) { + PropertyCreationContext context = new PropertyCreationContext(getLink()); return input.stream() // - .map(it -> creator.apply(input, it)) // + .map(it -> creator.apply(input, it, context)) // .collect(Collectors.toList()); } + @FunctionalInterface + public interface PropertyCreator { + T apply(InputPayloadMetadata payload, PropertyMetadata metadata, PropertyCreationContext context); + } + + public static final class PropertyCreationContext { + + private final Link link; + + private PropertyCreationContext(Link link) { + this.link = link; + } + + /** + * {@link Link} for the URI of the resource. + */ + public Link link() { + return link; + } + } + /* * (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsConfiguration.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsConfiguration.java index 49c0aabc4..3f6df37ec 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsConfiguration.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsConfiguration.java @@ -21,10 +21,12 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; import org.springframework.core.ResolvableType; +import org.springframework.hateoas.AffordanceModel; import org.springframework.hateoas.AffordanceModel.PropertyMetadata; import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.mediatype.hal.HalConfiguration; @@ -165,7 +167,7 @@ public HalFormsConfiguration customize(ObjectMapper mapper) { * @return */ public HalFormsConfiguration withOptions(Class type, String property, - Function creator) { + BiFunction creator) { return new HalFormsConfiguration(halConfiguration, patterns, options.withOptions(type, property, creator), objectMapperCustomizer, mediaTypes); diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptionsFactory.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptionsFactory.java index 095971442..349e6388d 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptionsFactory.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsOptionsFactory.java @@ -17,10 +17,12 @@ import java.util.HashMap; import java.util.Map; +import java.util.function.BiFunction; import java.util.function.Function; import org.springframework.hateoas.AffordanceModel.PayloadMetadata; import org.springframework.hateoas.AffordanceModel.PropertyMetadata; +import org.springframework.hateoas.AffordanceModel.PropertyCreationContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -34,7 +36,7 @@ */ class HalFormsOptionsFactory { - private final Map, Map>> options; + private final Map, Map>> options; /** * Creates a new, empty {@link HalFormsOptionsFactory}. @@ -48,7 +50,7 @@ public HalFormsOptionsFactory() { * * @param options must not be {@literal null}. */ - private HalFormsOptionsFactory(Map, Map>> options) { + private HalFormsOptionsFactory(Map, Map>> options) { this.options = options; } @@ -64,13 +66,13 @@ private HalFormsOptionsFactory(Map, Map type, String property, - Function creator) { + BiFunction creator) { Assert.notNull(type, "Type must not be null!"); Assert.hasText(property, "Property must not be null or empty!"); Assert.notNull(creator, "Creator function must not be null!"); - Map, Map>> options = new HashMap<>(this.options); + Map, Map>> options = new HashMap<>(this.options); options.compute(type, (it, map) -> { @@ -95,7 +97,7 @@ HalFormsOptionsFactory withOptions(Class type, String property, * @return */ @Nullable - HalFormsOptions getOptions(PayloadMetadata payload, PropertyMetadata property) { + HalFormsOptions getOptions(PayloadMetadata payload, PropertyMetadata property, PropertyCreationContext context) { Assert.notNull(payload, "Payload metadata must not be null!"); Assert.notNull(property, "Property metadata must not be null!"); @@ -103,14 +105,14 @@ HalFormsOptions getOptions(PayloadMetadata payload, PropertyMetadata property) { Class type = payload.getType(); String name = property.getName(); - Map> map = options.get(type); + Map> map = options.get(type); if (map == null) { return null; } - Function function = map.get(name); + BiFunction function = map.get(name); - return function == null ? null : function.apply(property); + return function == null ? null : function.apply(property, context); } } diff --git a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsPropertyFactory.java b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsPropertyFactory.java index 210f06024..a907fea52 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsPropertyFactory.java +++ b/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsPropertyFactory.java @@ -80,10 +80,10 @@ public List createProperties(HalFormsAffordanceModel model) { HalFormsOptionsFactory optionsFactory = configuration.getOptionsFactory(); - return model.createProperties((payload, metadata) -> { + return model.createProperties((payload, metadata, context) -> { String inputType = metadata.getInputType(); - HalFormsOptions options = optionsFactory.getOptions(payload, metadata); + HalFormsOptions options = optionsFactory.getOptions(payload, metadata, context); HalFormsProperty property = new HalFormsProperty() .withName(metadata.getName()) diff --git a/src/test/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplateBuilderUnitTest.java b/src/test/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplateBuilderUnitTest.java index 9cd2cccd3..0dadac4af 100644 --- a/src/test/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplateBuilderUnitTest.java +++ b/src/test/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsTemplateBuilderUnitTest.java @@ -182,7 +182,7 @@ void rendersInlineOptions() { List values = Arrays.asList("1234123412341234", "4321432143214321"); HalFormsConfiguration configuration = new HalFormsConfiguration() // - .withOptions(PatternExample.class, "number", metadata -> HalFormsOptions.inline(values)); + .withOptions(PatternExample.class, "number", (metadata, context) -> HalFormsOptions.inline(values)); RepresentationModel models = new RepresentationModel<>( Affordances.of(Link.of("/example", LinkRelation.of("create"))) // @@ -209,7 +209,7 @@ void propagatesSelectedValueToProperty() { HalFormsConfiguration configuration = new HalFormsConfiguration() // .withOptions(PatternExample.class, "number", - metadata -> HalFormsOptions.inline(values).withSelectedValue(selected)); + (metadata, context) -> HalFormsOptions.inline(values).withSelectedValue(selected)); RepresentationModel models = new RepresentationModel<>( Affordances.of(Link.of("/example", LinkRelation.of("create"))) //