#832 - Tweaked setup of HalFormsConfiguration and HalConfiguration.
HalFormsConfiguration now delegates to a HalConfiguration and the configuration will favor a user registered instance of the former over an instance of the latter or even fall back to default instances in case none of that is defined in the ApplicationContext. This allows seamless pickup of HalConfiguration for HAL FORMS but also explicit opt-out if not desired.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
* Copyright 2017-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,52 +15,26 @@
|
||||
*/
|
||||
package org.springframework.hateoas.mediatype.hal.forms;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Wither;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.mediatype.hal.HalConfiguration;
|
||||
|
||||
/**
|
||||
* HAL-FORMS specific configuration extension of {@link HalConfiguration}.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
class HalFormsConfiguration {
|
||||
@RequiredArgsConstructor
|
||||
public class HalFormsConfiguration {
|
||||
|
||||
private @Wither @Getter RenderSingleLinks renderSingleLinks = RenderSingleLinks.AS_SINGLE;
|
||||
|
||||
public enum RenderSingleLinks {
|
||||
|
||||
/**
|
||||
* A single {@link Link} is rendered as a JSON object.
|
||||
*/
|
||||
AS_SINGLE,
|
||||
|
||||
/**
|
||||
* A single {@link Link} is rendered as a JSON Array.
|
||||
*/
|
||||
AS_ARRAY
|
||||
}
|
||||
private final @Getter HalConfiguration halConfiguration;
|
||||
|
||||
/**
|
||||
* Translate a {@link HalFormsConfiguration} into a {@link HalConfiguration}.
|
||||
*
|
||||
* @return
|
||||
* Creates a new {@link HalFormsConfiguration} backed by a default {@link HalConfiguration}.
|
||||
*/
|
||||
public HalConfiguration toHalConfiguration() {
|
||||
|
||||
if (this.getRenderSingleLinks() == RenderSingleLinks.AS_SINGLE) {
|
||||
return new HalConfiguration().withRenderSingleLinks(HalConfiguration.RenderSingleLinks.AS_SINGLE);
|
||||
}
|
||||
|
||||
if (this.getRenderSingleLinks() == RenderSingleLinks.AS_ARRAY) {
|
||||
return new HalConfiguration().withRenderSingleLinks(HalConfiguration.RenderSingleLinks.AS_ARRAY);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Don't know how to translate " + this);
|
||||
public HalFormsConfiguration() {
|
||||
this.halConfiguration = new HalConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.hateoas.client.LinkDiscoverer;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.hateoas.config.HypermediaMappingInformation;
|
||||
import org.springframework.hateoas.mediatype.hal.CurieProvider;
|
||||
import org.springframework.hateoas.mediatype.hal.HalConfiguration;
|
||||
import org.springframework.hateoas.server.core.DelegatingLinkRelationProvider;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
@@ -46,6 +47,7 @@ class HalFormsMediaTypeConfiguration implements HypermediaMappingInformation {
|
||||
private final DelegatingLinkRelationProvider relProvider;
|
||||
private final ObjectProvider<CurieProvider> curieProvider;
|
||||
private final ObjectProvider<HalFormsConfiguration> halFormsConfiguration;
|
||||
private final ObjectProvider<HalConfiguration> halConfiguration;
|
||||
private final MessageSourceAccessor messageSourceAccessor;
|
||||
|
||||
@Bean
|
||||
@@ -69,13 +71,14 @@ class HalFormsMediaTypeConfiguration implements HypermediaMappingInformation {
|
||||
@Override
|
||||
public ObjectMapper configureObjectMapper(ObjectMapper mapper) {
|
||||
|
||||
HalFormsConfiguration configuration = halFormsConfiguration
|
||||
.getIfAvailable(() -> new HalFormsConfiguration(halConfiguration.getIfAvailable(HalConfiguration::new)));
|
||||
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
mapper.registerModule(new Jackson2HalFormsModule());
|
||||
mapper.setHandlerInstantiator(new Jackson2HalFormsModule.HalFormsHandlerInstantiator(relProvider,
|
||||
curieProvider.getIfAvailable(() -> CurieProvider.NONE), messageSourceAccessor, true,
|
||||
halFormsConfiguration.getIfAvailable(HalFormsConfiguration::new)));
|
||||
curieProvider.getIfAvailable(() -> CurieProvider.NONE), messageSourceAccessor, true, configuration));
|
||||
|
||||
return mapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ class Jackson2HalFormsModule extends SimpleModule {
|
||||
super("hal-forms-module", new Version(1, 0, 0, null, "org.springframework.hateoas", "spring-hateoas"));
|
||||
|
||||
setMixInAnnotation(Link.class, LinkMixin.class);
|
||||
setMixInAnnotation(Links.class, LinksMixin.class);
|
||||
setMixInAnnotation(RepresentationModel.class, RepresentationModelMixin.class);
|
||||
setMixInAnnotation(EntityModel.class, EntityModelMixin.class);
|
||||
setMixInAnnotation(CollectionModel.class, CollectionModelMixin.class);
|
||||
@@ -89,6 +90,9 @@ class Jackson2HalFormsModule extends SimpleModule {
|
||||
setMixInAnnotation(MediaType.class, MediaTypeMixin.class);
|
||||
}
|
||||
|
||||
@JsonSerialize(using = HalLinkListSerializer.class)
|
||||
abstract class LinksMixin {}
|
||||
|
||||
@JsonSerialize(using = HalFormsResourceSerializer.class)
|
||||
abstract class EntityModelMixin<T> extends EntityModel<T> {}
|
||||
|
||||
@@ -156,17 +160,16 @@ class Jackson2HalFormsModule extends SimpleModule {
|
||||
private final Map<Class<?>, Object> serializers = new HashMap<>();
|
||||
|
||||
public HalFormsHandlerInstantiator(LinkRelationProvider resolver, CurieProvider curieProvider,
|
||||
MessageSourceAccessor accessor, boolean enforceEmbeddedCollections,
|
||||
HalFormsConfiguration halFormsConfiguration) {
|
||||
MessageSourceAccessor accessor, boolean enforceEmbeddedCollections, HalFormsConfiguration configuration) {
|
||||
|
||||
super(resolver, curieProvider, accessor, enforceEmbeddedCollections, halFormsConfiguration.toHalConfiguration());
|
||||
super(resolver, curieProvider, accessor, enforceEmbeddedCollections, configuration.getHalConfiguration());
|
||||
|
||||
EmbeddedMapper mapper = new EmbeddedMapper(resolver, curieProvider, enforceEmbeddedCollections);
|
||||
|
||||
this.serializers.put(HalFormsResourceSerializer.class, new HalFormsResourceSerializer(accessor));
|
||||
this.serializers.put(HalFormsResourcesSerializer.class, new HalFormsResourcesSerializer(accessor, mapper));
|
||||
this.serializers.put(HalLinkListSerializer.class,
|
||||
new HalLinkListSerializer(curieProvider, mapper, accessor, halFormsConfiguration.toHalConfiguration()));
|
||||
new HalLinkListSerializer(curieProvider, mapper, accessor, configuration.getHalConfiguration()));
|
||||
}
|
||||
|
||||
public HalFormsHandlerInstantiator(LinkRelationProvider relProvider, CurieProvider curieProvider,
|
||||
|
||||
Reference in New Issue
Block a user