#1098 - Institute checks for client-only setups.
Gather client- and server-side settings into one "stack". Move all logic of checking this into the enum itself.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.hateoas.config.WebMvcHateoasConfiguration.HypermediaWebMvcConfigurer;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Spring MVC HATEOAS Configuration
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Configuration
|
||||
class RestTemplateHateoasConfiguration {
|
||||
|
||||
@Bean
|
||||
static HypermediaRestTemplateBeanPostProcessor hypermediaRestTemplateBeanPostProcessor(
|
||||
ObjectProvider<HypermediaWebMvcConfigurer> configurer) {
|
||||
return new HypermediaRestTemplateBeanPostProcessor(configurer);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to register hypermedia support with {@link RestTemplate} instances found in the
|
||||
* application context.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class HypermediaRestTemplateBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final ObjectProvider<HypermediaWebMvcConfigurer> configurer;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (!RestTemplate.class.isInstance(bean)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
configurer.getObject().extendMessageConverters(((RestTemplate) bean).getMessageConverters());
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.config;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Spring WebFlux HATEOAS configuration.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @since 1.0 TODO: Inspect ApplicationContext -> WebApplicationContext -> WebMVC
|
||||
*/
|
||||
@Configuration
|
||||
class WebClientHateoasConfiguration {
|
||||
|
||||
@Bean
|
||||
WebClientConfigurer webClientConfigurer(ObjectProvider<ObjectMapper> mapper,
|
||||
List<HypermediaMappingInformation> hypermediaTypes) {
|
||||
return new WebClientConfigurer(mapper.getIfAvailable(ObjectMapper::new), hypermediaTypes);
|
||||
}
|
||||
|
||||
@Bean
|
||||
static HypermediaWebClientBeanPostProcessor webClientBeanPostProcessor(
|
||||
ObjectProvider<WebClientConfigurer> configurer) {
|
||||
return new HypermediaWebClientBeanPostProcessor(configurer);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to register the proper handlers in {@link WebClient} instances found in the application
|
||||
* context.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @since 1.0
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class HypermediaWebClientBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final ObjectProvider<WebClientConfigurer> configurer;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (bean instanceof WebClient) {
|
||||
return this.configurer.getObject().registerHypermediaTypes((WebClient) bean);
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,20 +19,16 @@ import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.web.filter.reactive.ServerWebExchangeContextFilter;
|
||||
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@@ -45,18 +41,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@Configuration
|
||||
class WebFluxHateoasConfiguration {
|
||||
|
||||
@Bean
|
||||
WebClientConfigurer webClientConfigurer(ObjectProvider<ObjectMapper> mapper,
|
||||
List<HypermediaMappingInformation> hypermediaTypes) {
|
||||
return new WebClientConfigurer(mapper.getIfAvailable(ObjectMapper::new), hypermediaTypes);
|
||||
}
|
||||
|
||||
@Bean
|
||||
static HypermediaWebClientBeanPostProcessor webClientBeanPostProcessor(
|
||||
ObjectProvider<WebClientConfigurer> configurer) {
|
||||
return new HypermediaWebClientBeanPostProcessor(configurer);
|
||||
}
|
||||
|
||||
@Bean
|
||||
HypermediaWebFluxConfigurer hypermediaWebFluxConfigurer(ObjectProvider<ObjectMapper> mapper,
|
||||
List<HypermediaMappingInformation> hypermediaTypes) {
|
||||
@@ -70,34 +54,6 @@ class WebFluxHateoasConfiguration {
|
||||
return new ServerWebExchangeContextFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to register the proper handlers in {@link WebClient} instances found in the application
|
||||
* context.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @since 1.0
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class HypermediaWebClientBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final ObjectProvider<WebClientConfigurer> configurer;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (bean instanceof WebClient) {
|
||||
return this.configurer.getObject().registerHypermediaTypes((WebClient) bean);
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link WebFluxConfigurer} to register hypermedia-aware {@link org.springframework.core.codec.Encoder}s and
|
||||
* {@link org.springframework.core.codec.Decoder}s that will render hypermedia for WebFlux controllers.
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.springframework.hateoas.server.mvc.UriComponentsContributor;
|
||||
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilderFactory;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
@@ -73,12 +72,6 @@ class WebMvcHateoasConfiguration {
|
||||
return new HypermediaRepresentationModelBeanProcessorPostProcessor(invoker);
|
||||
}
|
||||
|
||||
@Bean
|
||||
static HypermediaRestTemplateBeanPostProcessor restTemplateBeanPostProcessor(
|
||||
ObjectProvider<HypermediaWebMvcConfigurer> configurer) {
|
||||
return new HypermediaRestTemplateBeanPostProcessor(configurer);
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebMvcLinkBuilderFactory webMvcLinkBuilderFactory(ObjectProvider<UriComponentsContributor> contributors) {
|
||||
|
||||
@@ -146,34 +139,4 @@ class WebMvcHateoasConfiguration {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to register hypermedia support with {@link RestTemplate} instances found in the
|
||||
* application context.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
static class HypermediaRestTemplateBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
private final ObjectProvider<HypermediaWebMvcConfigurer> configurer;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (!RestTemplate.class.isInstance(bean)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
configurer.getObject().extendMessageConverters(((RestTemplate) bean).getMessageConverters());
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
package org.springframework.hateoas.config;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
@@ -33,18 +31,6 @@ class WebStackImportSelector implements ImportSelector {
|
||||
|
||||
private static final String WEB_STACK_MISSING = "At least one web stack has to be selected in @EnableHypermediaSupport on %s!";
|
||||
|
||||
static Map<WebStack, String> CONFIGS;
|
||||
|
||||
static {
|
||||
|
||||
Map<WebStack, String> configs = new HashMap<>();
|
||||
|
||||
configs.put(WebStack.WEBMVC, "org.springframework.hateoas.config.WebMvcHateoasConfiguration");
|
||||
configs.put(WebStack.WEBFLUX, "org.springframework.hateoas.config.WebFluxHateoasConfiguration");
|
||||
|
||||
CONFIGS = Collections.unmodifiableMap(configs);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.annotation.ImportSelector#selectImports(org.springframework.core.type.AnnotationMetadata)
|
||||
@@ -67,8 +53,7 @@ class WebStackImportSelector implements ImportSelector {
|
||||
}
|
||||
|
||||
return Arrays.stream(stacks) //
|
||||
.filter(WebStack::isAvailable) //
|
||||
.map(CONFIGS::get) //
|
||||
.flatMap(webStack -> webStack.getAvailableConfigurations().stream()) //
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.hateoas.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -24,23 +27,61 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public enum WebStack {
|
||||
|
||||
WEBMVC("org.springframework.web.servlet.DispatcherServlet"),
|
||||
WEBMVC("org.springframework.web.servlet.DispatcherServlet", //
|
||||
"org.springframework.hateoas.config.WebMvcHateoasConfiguration", //
|
||||
"org.springframework.web.client.RestTemplate", //
|
||||
"org.springframework.hateoas.config.RestTemplateHateoasConfiguration"),
|
||||
|
||||
WEBFLUX("org.springframework.web.reactive.DispatcherHandler");
|
||||
WEBFLUX("org.springframework.web.reactive.DispatcherHandler", //
|
||||
"org.springframework.hateoas.config.WebFluxHateoasConfiguration", //
|
||||
"org.springframework.web.reactive.function.client.WebClient", //
|
||||
"org.springframework.hateoas.config.WebClientHateoasConfiguration");
|
||||
|
||||
private final boolean isAvailable;
|
||||
private final boolean isServerAvailable;
|
||||
private final String serverConfiguration;
|
||||
|
||||
private final boolean isClientAvailable;
|
||||
private final String clientConfiguration;
|
||||
|
||||
/**
|
||||
* Initialize the {@link #isAvailable} based upon a defined signature class.
|
||||
*/
|
||||
WebStack(String signatureClass) {
|
||||
this.isAvailable = ClassUtils.isPresent(signatureClass, null);
|
||||
WebStack(String serverAvailableClazz, String serverConfigurationClazz, String clientAvailableClazz,
|
||||
String clientConfigurationClazz) {
|
||||
|
||||
this.isServerAvailable = ClassUtils.isPresent(serverAvailableClazz, null);
|
||||
this.serverConfiguration = serverConfigurationClazz;
|
||||
|
||||
this.isClientAvailable = ClassUtils.isPresent(clientAvailableClazz, null);
|
||||
this.clientConfiguration = clientConfigurationClazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on what client/server components are on the classpath, return what configuration classes should be
|
||||
* registered.
|
||||
*/
|
||||
public List<String> getAvailableConfigurations() {
|
||||
|
||||
List<String> configurations = new ArrayList<>();
|
||||
|
||||
if (this.isServerAvailable) {
|
||||
configurations.add(this.serverConfiguration);
|
||||
}
|
||||
|
||||
if (this.isClientAvailable) {
|
||||
configurations.add(this.clientConfiguration);
|
||||
}
|
||||
|
||||
return configurations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this web stack on the classpath?
|
||||
*
|
||||
* @deprecated Will be removed in 1.2 in light of {@link #getAvailableConfigurations()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isAvailable() {
|
||||
return this.isAvailable;
|
||||
return this.isServerAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user