Skip to content

Commit ffa1dc3

Browse files
committed
#361 - Polishing.
Made implementation class package protected to not expose it. Avoid the use of Optional for hot code paths. Removed factory method as we only use the type internally anyway. Removed test customizations as the discoverer is now just leniently opting out if not ApplicationContext can be found. Original pull request: #1328.
1 parent c5f4bfa commit ffa1dc3

File tree

7 files changed

+44
-82
lines changed

7 files changed

+44
-82
lines changed

src/main/java/org/springframework/hateoas/server/mvc/PropertyResolvingMappingDiscoverer.java

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2020 the original author or authors.
2+
* Copyright 2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,32 +15,31 @@
1515
*/
1616
package org.springframework.hateoas.server.mvc;
1717

18-
import static java.util.Optional.ofNullable;
18+
import java.lang.reflect.Method;
19+
import java.util.Collection;
1920

20-
import org.springframework.core.env.PropertyResolver;
2121
import org.springframework.hateoas.server.core.MappingDiscoverer;
2222
import org.springframework.http.HttpMethod;
2323
import org.springframework.lang.Nullable;
24+
import org.springframework.util.Assert;
2425
import org.springframework.web.context.ContextLoader;
25-
26-
import java.lang.reflect.Method;
27-
import java.util.Collection;
26+
import org.springframework.web.context.WebApplicationContext;
2827

2928
/**
3029
* Property resolving adapter of {@link MappingDiscoverer}.
3130
*
3231
* @author Lars Michele
32+
* @author Oliver Drotbohm
3333
*/
34-
public class PropertyResolvingMappingDiscoverer implements MappingDiscoverer {
34+
class PropertyResolvingMappingDiscoverer implements MappingDiscoverer {
3535

3636
private final MappingDiscoverer delegate;
3737

38-
private PropertyResolvingMappingDiscoverer(MappingDiscoverer delegate) {
39-
this.delegate = delegate;
40-
}
38+
PropertyResolvingMappingDiscoverer(MappingDiscoverer delegate) {
4139

42-
public static PropertyResolvingMappingDiscoverer of(MappingDiscoverer delegate) {
43-
return new PropertyResolvingMappingDiscoverer(delegate);
40+
Assert.notNull(delegate, "Delegate MappingDiscoverer must not be null!");
41+
42+
this.delegate = delegate;
4443
}
4544

4645
/*
@@ -50,7 +49,7 @@ public static PropertyResolvingMappingDiscoverer of(MappingDiscoverer delegate)
5049
@Nullable
5150
@Override
5251
public String getMapping(Class<?> type) {
53-
return ofNullable(delegate.getMapping(type)).map(getPropertyResolver()::resolvePlaceholders).orElse(null);
52+
return resolveProperties(delegate.getMapping(type));
5453
}
5554

5655
/*
@@ -60,7 +59,7 @@ public String getMapping(Class<?> type) {
6059
@Nullable
6160
@Override
6261
public String getMapping(Method method) {
63-
return ofNullable(delegate.getMapping(method)).map(getPropertyResolver()::resolvePlaceholders).orElse(null);
62+
return resolveProperties(delegate.getMapping(method));
6463
}
6564

6665
/*
@@ -70,7 +69,7 @@ public String getMapping(Method method) {
7069
@Nullable
7170
@Override
7271
public String getMapping(Class<?> type, Method method) {
73-
return ofNullable(delegate.getMapping(type, method)).map(getPropertyResolver()::resolvePlaceholders).orElse(null);
72+
return resolveProperties(delegate.getMapping(type, method));
7473
}
7574

7675
/*
@@ -82,7 +81,17 @@ public Collection<HttpMethod> getRequestMethod(Class<?> type, Method method) {
8281
return delegate.getRequestMethod(type, method);
8382
}
8483

85-
private static PropertyResolver getPropertyResolver() {
86-
return ContextLoader.getCurrentWebApplicationContext().getEnvironment();
84+
@Nullable
85+
private static String resolveProperties(@Nullable String mapping) {
86+
87+
if (mapping == null) {
88+
return mapping;
89+
}
90+
91+
WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
92+
93+
return context == null //
94+
? mapping //
95+
: context.getEnvironment().resolvePlaceholders(mapping);
8796
}
8897
}

src/main/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
public class WebMvcLinkBuilder extends TemplateVariableAwareLinkBuilderSupport<WebMvcLinkBuilder> {
5454

5555
private static final MappingDiscoverer DISCOVERER = CachingMappingDiscoverer
56-
.of(PropertyResolvingMappingDiscoverer.of(new AnnotationMappingDiscoverer(RequestMapping.class)));
56+
.of(new PropertyResolvingMappingDiscoverer(new AnnotationMappingDiscoverer(RequestMapping.class)));
5757
private static final WebMvcLinkBuilderFactory FACTORY = new WebMvcLinkBuilderFactory();
5858
private static final CustomUriTemplateHandler HANDLER = new CustomUriTemplateHandler();
5959

src/test/java/org/springframework/hateoas/TestUtils.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import javax.servlet.http.HttpServletRequest;
2424

2525
import org.junit.jupiter.api.BeforeEach;
26-
import org.springframework.context.annotation.Configuration;
2726
import org.springframework.mock.web.MockFilterChain;
2827
import org.springframework.mock.web.MockHttpServletRequest;
2928
import org.springframework.mock.web.MockHttpServletResponse;
@@ -33,7 +32,7 @@
3332

3433
/**
3534
* Utility class to ease testing.
36-
*
35+
*
3736
* @author Oliver Gierke
3837
* @author Greg Turnquist
3938
*/
@@ -87,7 +86,4 @@ public static void assertNotEqualAndDifferentHashCode(Object left, Object right)
8786
assertThat(left.hashCode()).isNotEqualTo(right.hashCode());
8887
assertThat(left.toString()).isNotEqualTo(right.toString());
8988
}
90-
91-
@Configuration
92-
public static class Config {}
9389
}

src/test/java/org/springframework/hateoas/server/core/ControllerEntityLinksUnitTest.java

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import static java.util.Collections.*;
1919
import static org.assertj.core.api.Assertions.*;
20-
import static org.mockito.ArgumentMatchers.any;
20+
import static org.mockito.ArgumentMatchers.*;
2121
import static org.mockito.ArgumentMatchers.eq;
2222
import static org.mockito.Mockito.*;
2323
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
@@ -26,46 +26,30 @@
2626

2727
import java.util.Arrays;
2828

29-
import org.junit.jupiter.api.BeforeEach;
3029
import org.junit.jupiter.api.Test;
3130
import org.junit.jupiter.api.extension.ExtendWith;
3231
import org.mockito.Mock;
3332
import org.mockito.junit.jupiter.MockitoExtension;
34-
import org.springframework.beans.factory.annotation.Autowired;
3533
import org.springframework.hateoas.TestUtils;
3634
import org.springframework.hateoas.server.EntityLinks;
3735
import org.springframework.hateoas.server.ExposesResourceFor;
3836
import org.springframework.hateoas.server.LinkBuilder;
3937
import org.springframework.hateoas.server.LinkBuilderFactory;
4038
import org.springframework.hateoas.server.TypedEntityLinks;
4139
import org.springframework.hateoas.server.TypedEntityLinks.ExtendedTypedEntityLinks;
42-
import org.springframework.mock.web.MockServletContext;
4340
import org.springframework.stereotype.Controller;
44-
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
4541
import org.springframework.web.bind.annotation.RequestMapping;
46-
import org.springframework.web.context.ContextLoader;
47-
import org.springframework.web.context.WebApplicationContext;
4842

4943
/**
5044
* Unit tests for {@link ControllerEntityLinks}.
5145
*
5246
* @author Oliver Gierke
5347
*/
5448
@ExtendWith(MockitoExtension.class)
55-
@SpringJUnitWebConfig(classes = TestUtils.Config.class)
5649
class ControllerEntityLinksUnitTest extends TestUtils {
5750

5851
@Mock LinkBuilderFactory<LinkBuilder> linkBuilderFactory;
5952

60-
@Autowired
61-
WebApplicationContext context;
62-
63-
@BeforeEach
64-
void contextLoading() {
65-
ContextLoader contextLoader = new ContextLoader(context);
66-
contextLoader.initWebApplicationContext(new MockServletContext());
67-
}
68-
6953
@Test
7054
void rejectsUnannotatedController() {
7155

src/test/java/org/springframework/hateoas/server/mvc/PropertyResolvingMappingDiscovererUnitTest.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
2222
import org.junit.jupiter.api.BeforeEach;
2323
import org.junit.jupiter.api.Test;
2424
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.context.annotation.Configuration;
2526
import org.springframework.hateoas.TestUtils;
2627
import org.springframework.hateoas.server.core.AnnotationMappingDiscoverer;
2728
import org.springframework.mock.web.MockServletContext;
@@ -35,25 +36,25 @@
3536
* Unit tests for {@link PropertyResolvingMappingDiscoverer}.
3637
*
3738
* @author Lars Michele
39+
* @author Oliver Drotbohm
3840
*/
39-
@SpringJUnitWebConfig(classes = TestUtils.Config.class)
40-
@TestPropertySource(properties = {"test.parent=resolvedparent", "test.child=resolvedchild"})
41+
@SpringJUnitWebConfig(classes = PropertyResolvingMappingDiscovererUnitTest.Config.class)
42+
@TestPropertySource(properties = { "test.parent=resolvedparent", "test.child=resolvedchild" })
4143
class PropertyResolvingMappingDiscovererUnitTest extends TestUtils {
4244

43-
@Autowired
44-
WebApplicationContext context;
45+
@Autowired WebApplicationContext context;
4546

4647
@BeforeEach
4748
void contextLoading() {
48-
ContextLoader contextLoader = new ContextLoader(context);
49-
contextLoader.initWebApplicationContext(new MockServletContext());
49+
new ContextLoader(context).initWebApplicationContext(new MockServletContext());
5050
}
5151

5252
/**
5353
* @see #361
5454
*/
5555
@Test
5656
void resolvesVariablesInMappings() throws NoSuchMethodException {
57+
5758
Method method = ResolveMethodEndpointController.class.getMethod("method");
5859
AnnotationMappingDiscoverer annotationMappingDiscoverer = new AnnotationMappingDiscoverer(RequestMapping.class);
5960

@@ -62,10 +63,11 @@ void resolvesVariablesInMappings() throws NoSuchMethodException {
6263
assertThat(annotationMappingDiscoverer.getMapping(ResolveMethodEndpointController.class, method))
6364
.isEqualTo("/${test.parent}/${test.child}");
6465

65-
PropertyResolvingMappingDiscoverer propertyResolvingMappingDiscoverer = PropertyResolvingMappingDiscoverer
66-
.of(annotationMappingDiscoverer);
66+
PropertyResolvingMappingDiscoverer propertyResolvingMappingDiscoverer = new PropertyResolvingMappingDiscoverer(
67+
annotationMappingDiscoverer);
6768

68-
assertThat(propertyResolvingMappingDiscoverer.getMapping(ResolveEndpointController.class)).isEqualTo("/resolvedparent");
69+
assertThat(propertyResolvingMappingDiscoverer.getMapping(ResolveEndpointController.class))
70+
.isEqualTo("/resolvedparent");
6971
assertThat(propertyResolvingMappingDiscoverer.getMapping(method)).isEqualTo("/resolvedparent/resolvedchild");
7072
assertThat(propertyResolvingMappingDiscoverer.getMapping(ResolveMethodEndpointController.class, method))
7173
.isEqualTo("/resolvedparent/resolvedchild");
@@ -80,4 +82,7 @@ interface ResolveMethodEndpointController {
8082
@RequestMapping("/${test.child}")
8183
void method();
8284
}
85+
86+
@Configuration
87+
public static class Config {}
8388
}

src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderFactoryUnitTest.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525

2626
import org.joda.time.DateTime;
2727
import org.joda.time.format.ISODateTimeFormat;
28-
import org.junit.jupiter.api.BeforeEach;
2928
import org.junit.jupiter.api.Test;
30-
import org.springframework.beans.factory.annotation.Autowired;
3129
import org.springframework.core.MethodParameter;
3230
import org.springframework.format.annotation.DateTimeFormat;
3331
import org.springframework.format.annotation.DateTimeFormat.ISO;
@@ -38,15 +36,11 @@
3836
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilderUnitTest.PersonControllerImpl;
3937
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilderUnitTest.PersonsAddressesController;
4038
import org.springframework.http.HttpEntity;
41-
import org.springframework.mock.web.MockServletContext;
42-
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
4339
import org.springframework.util.LinkedMultiValueMap;
4440
import org.springframework.util.MultiValueMap;
4541
import org.springframework.web.bind.annotation.PathVariable;
4642
import org.springframework.web.bind.annotation.RequestMapping;
4743
import org.springframework.web.bind.annotation.RequestParam;
48-
import org.springframework.web.context.ContextLoader;
49-
import org.springframework.web.context.WebApplicationContext;
5044
import org.springframework.web.util.UriComponentsBuilder;
5145

5246
/**
@@ -57,18 +51,8 @@
5751
* @author Kamill Sokol
5852
* @author Ross Turner
5953
*/
60-
@SpringJUnitWebConfig(classes = TestUtils.Config.class)
6154
class WebMvcLinkBuilderFactoryUnitTest extends TestUtils {
6255

63-
@Autowired
64-
WebApplicationContext context;
65-
66-
@BeforeEach
67-
void contextLoading() {
68-
ContextLoader contextLoader = new ContextLoader(context);
69-
contextLoader.initWebApplicationContext(new MockServletContext());
70-
}
71-
7256
WebMvcLinkBuilderFactory factory = new WebMvcLinkBuilderFactory();
7357

7458
@Test

src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderUnitTest.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,21 @@
2323
import java.util.List;
2424
import java.util.Optional;
2525

26-
import org.junit.jupiter.api.BeforeEach;
2726
import org.junit.jupiter.api.Test;
28-
import org.springframework.beans.factory.annotation.Autowired;
2927
import org.springframework.hateoas.IanaLinkRelations;
3028
import org.springframework.hateoas.Link;
3129
import org.springframework.hateoas.TemplateVariable;
3230
import org.springframework.hateoas.TemplateVariable.VariableType;
3331
import org.springframework.hateoas.TestUtils;
3432
import org.springframework.http.HttpEntity;
3533
import org.springframework.http.ResponseEntity;
36-
import org.springframework.mock.web.MockServletContext;
37-
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
3834
import org.springframework.util.MultiValueMap;
3935
import org.springframework.web.bind.annotation.GetMapping;
4036
import org.springframework.web.bind.annotation.PathVariable;
4137
import org.springframework.web.bind.annotation.RequestBody;
4238
import org.springframework.web.bind.annotation.RequestMapping;
4339
import org.springframework.web.bind.annotation.RequestParam;
4440
import org.springframework.web.bind.annotation.RestController;
45-
import org.springframework.web.context.ContextLoader;
46-
import org.springframework.web.context.WebApplicationContext;
4741
import org.springframework.web.util.UriComponents;
4842
import org.springframework.web.util.UriComponentsBuilder;
4943

@@ -59,18 +53,8 @@
5953
* @author Oliver Trosien
6054
* @author Greg Turnquist
6155
*/
62-
@SpringJUnitWebConfig(classes = TestUtils.Config.class)
6356
class WebMvcLinkBuilderUnitTest extends TestUtils {
6457

65-
@Autowired
66-
WebApplicationContext context;
67-
68-
@BeforeEach
69-
void contextLoading() {
70-
ContextLoader contextLoader = new ContextLoader(context);
71-
contextLoader.initWebApplicationContext(new MockServletContext());
72-
}
73-
7458
@Test
7559
void createsLinkToControllerRoot() {
7660

0 commit comments

Comments
 (0)