Skip to content

Commit

Permalink
#1060 - When EnableHypermediaSupport has an empty list, enable all.
Browse files Browse the repository at this point in the history
Default it to being empty. Existing code, `@EnableHypermediaSupport(types = HAL)` will still operate as expected. But simply using the annotation with no arguments will activate ALL types.

Related issues: #1015.
Related pull request: #1065.
  • Loading branch information
gregturn committed Apr 9, 2020
1 parent 023e999 commit 7a22171
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 12 deletions.
Expand Up @@ -44,11 +44,12 @@
public @interface EnableHypermediaSupport {

/**
* The hypermedia type to be supported.
* The hypermedia type to be supported. By default, it is empty, thus activating all available
* {@link MediaTypeConfigurationProvider}s.
*
* @return
*/
HypermediaType[] type();
HypermediaType[] type() default {};

/**
* Configures which {@link WebStack}s we're supposed to enable support for. By default we're activating it for all
Expand Down
Expand Up @@ -62,7 +62,7 @@ public String[] selectImports(AnnotationMetadata metadata) {

Map<String, Object> attributes = metadata.getAnnotationAttributes(EnableHypermediaSupport.class.getName());

List<MediaType> types = attributes == null //
List<MediaType> mediaTypes = attributes == null //
? Collections.emptyList() //
: Arrays.stream((HypermediaType[]) attributes.get("type")) //
.flatMap(it -> it.getMediaTypes().stream()) //
Expand All @@ -71,9 +71,9 @@ public String[] selectImports(AnnotationMetadata metadata) {
List<MediaTypeConfigurationProvider> configurationProviders = SpringFactoriesLoader.loadFactories(
MediaTypeConfigurationProvider.class, HypermediaConfigurationImportSelector.class.getClassLoader());

// Filter the ones supporting the given media types
// Filter the ones supporting the given media types, or let them all through if none declared.
Stream<String> imports = configurationProviders.stream() //
.filter(it -> it.supportsAny(types)) //
.filter(it -> mediaTypes.isEmpty() || it.supportsAny(mediaTypes)) //
.map(MediaTypeConfigurationProvider::getConfiguration) //
.map(Class::getName);

Expand Down
Expand Up @@ -106,16 +106,32 @@ void includesWebTestHateoasConfigurationIfWebTestClientIsOnTheClasspath() {
@Test // #1252
void doesNotIncludeWebTestHateoasConfigurationIfWebTestClientIsNotOnTheClasspath() {

HidingClassLoader delegate = HidingClassLoader.hide(WebTestClientConfigurer.class);
ShadowingClassLoader loader = new ShadowingClassLoader(delegate);
loader.excludePackage("org.springframework");
HidingClassLoader delegate = HidingClassLoader.hide(WebTestClientConfigurer.class);
ShadowingClassLoader loader = new ShadowingClassLoader(delegate);
loader.excludePackage("org.springframework");

withContext(HalConfig.class, context -> {
withContext(HalConfig.class, context -> {

assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
.isThrownBy(() -> context.getBean(WebTestHateoasConfiguration.class));

}, loader);
}

assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
.isThrownBy(() -> context.getBean(WebTestHateoasConfiguration.class));
@Test // #1060
void testEmptyHypermediaTypes() {

withContext(NoConfig.class, context -> {

Map<String, LinkDiscoverer> linkDiscoverers = context.getBeansOfType(LinkDiscoverer.class);

}, loader);
assertThat(linkDiscoverers.values()).extracting("class") //
.containsExactlyInAnyOrder( //
HalLinkDiscoverer.class, //
HalFormsLinkDiscoverer.class, //
UberLinkDiscoverer.class, //
CollectionJsonLinkDiscoverer.class);
});
}

@EnableHypermediaSupport(type = HAL)
Expand All @@ -137,4 +153,9 @@ static class HalAndHalFormsConfig {
static class AllConfig {

}

@EnableHypermediaSupport(type = { })
static class NoConfig {

}
}
@@ -0,0 +1,38 @@
/*
* 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.support;

import java.util.Collection;

import org.springframework.hateoas.config.HypermediaMappingInformation;
import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
import org.springframework.http.MediaType;

/**
* @author Greg Turnquist
*/
public class CustomHypermediaConfigurationProvider implements MediaTypeConfigurationProvider {

@Override
public Class<? extends HypermediaMappingInformation> getConfiguration() {
return CustomHypermediaType.class;
}

@Override
public boolean supportsAny(Collection<MediaType> mediaTypes) {
return mediaTypes.stream().anyMatch(mediaType -> mediaType.isCompatibleWith(CustomHypermediaType.FRODO_MEDIATYPE));
}
}
2 changes: 2 additions & 0 deletions src/test/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
org.springframework.hateoas.config.MediaTypeConfigurationProvider=\
org.springframework.hateoas.support.CustomHypermediaConfigurationProvider

0 comments on commit 7a22171

Please sign in to comment.