18
18
import static org .springframework .hateoas .mvc .ForwardedHeader .*;
19
19
20
20
import lombok .RequiredArgsConstructor ;
21
- import lombok .experimental .Delegate ;
22
21
23
22
import java .lang .reflect .Method ;
24
23
import java .net .URI ;
39
38
import org .springframework .hateoas .core .DummyInvocationUtils .MethodInvocation ;
40
39
import org .springframework .hateoas .core .LinkBuilderSupport ;
41
40
import org .springframework .hateoas .core .MappingDiscoverer ;
41
+ import org .springframework .http .HttpMethod ;
42
42
import org .springframework .http .MediaType ;
43
43
import org .springframework .plugin .core .OrderAwarePluginRegistry ;
44
44
import org .springframework .plugin .core .PluginRegistry ;
63
63
* @author Kevin Conaway
64
64
* @author Andrew Naydyonock
65
65
* @author Oliver Trosien
66
+ * @author Josh Ghiloni
66
67
* @author Greg Turnquist
67
68
*/
68
69
public class ControllerLinkBuilder extends LinkBuilderSupport <ControllerLinkBuilder > {
@@ -82,6 +83,8 @@ public class ControllerLinkBuilder extends LinkBuilderSupport<ControllerLinkBuil
82
83
.create (factories );
83
84
}
84
85
86
+ private static MappingDiscoverer delegateDiscovererOverride = null ;
87
+
85
88
private final TemplateVariables variables ;
86
89
87
90
/**
@@ -102,17 +105,26 @@ public class ControllerLinkBuilder extends LinkBuilderSupport<ControllerLinkBuil
102
105
* @param uriComponents must not be {@literal null}.
103
106
*/
104
107
ControllerLinkBuilder (UriComponents uriComponents ) {
105
- this (uriComponents , TemplateVariables .NONE , null );
108
+ this (uriComponents , TemplateVariables .NONE , null , null );
106
109
}
107
110
108
- ControllerLinkBuilder (UriComponents uriComponents , TemplateVariables variables , MethodInvocation invocation ) {
111
+ ControllerLinkBuilder (UriComponents uriComponents , TemplateVariables variables , MethodInvocation invocation , MappingDiscoverer discoverer ) {
109
112
110
113
super (uriComponents );
111
114
112
115
this .variables = variables ;
116
+ ControllerLinkBuilder .delegateDiscovererOverride = discoverer ;
113
117
this .addAffordances (findAffordances (invocation , uriComponents ));
114
118
}
115
119
120
+ public static void setDelegateDiscoverer (MappingDiscoverer delegateDiscovererOverride ) {
121
+ ControllerLinkBuilder .delegateDiscovererOverride = delegateDiscovererOverride ;
122
+ }
123
+
124
+ public static void clearDelegateDiscoverer () {
125
+ ControllerLinkBuilder .delegateDiscovererOverride = null ;
126
+ }
127
+
116
128
/**
117
129
* Creates a new {@link ControllerLinkBuilder} with a base of the mapping annotated to the given controller class.
118
130
*
@@ -249,7 +261,7 @@ public static <T> T methodOn(Class<T> controller, Object... parameters) {
249
261
return DummyInvocationUtils .methodOn (controller , parameters );
250
262
}
251
263
252
- /*
264
+ /*
253
265
* (non-Javadoc)
254
266
* @see org.springframework.hateoas.UriComponentsLinkBuilder#getThis()
255
267
*/
@@ -368,14 +380,65 @@ private static Collection<Affordance> findAffordances(MethodInvocation invocatio
368
380
@ RequiredArgsConstructor
369
381
private static class CachingAnnotationMappingDiscoverer implements MappingDiscoverer {
370
382
371
- private final @ Delegate AnnotationMappingDiscoverer delegate ;
383
+ private final AnnotationMappingDiscoverer delegate ;
372
384
private final Map <String , UriTemplate > templates = new ConcurrentReferenceHashMap <>();
373
385
386
+ /**
387
+ * If {@link ControllerLinkBuilder} has a static {@link MappingDiscoverer}, use it instead of the delegate.
388
+ * @return
389
+ */
390
+ private MappingDiscoverer getDelegate () {
391
+ return (delegateDiscovererOverride != null ) ? delegateDiscovererOverride : this .delegate ;
392
+ }
393
+
374
394
public UriTemplate getMappingAsUriTemplate (Class <?> type , Method method ) {
375
395
376
- String mapping = delegate .getMapping (type , method );
396
+ String mapping = getDelegate () .getMapping (type , method );
377
397
return templates .computeIfAbsent (mapping , UriTemplate ::new );
378
398
}
399
+
400
+ /**
401
+ * Returns the mapping associated with the given type.
402
+ *
403
+ * @param type must not be {@literal null}.
404
+ * @return the type-level mapping or {@literal null} in case none is present.
405
+ */
406
+ @ Override
407
+ public String getMapping (Class <?> type ) {
408
+ return getDelegate ().getMapping (type );
409
+ }
410
+
411
+ /**
412
+ * Returns the mapping associated with the given {@link Method}. This will include the type-level mapping.
413
+ *
414
+ * @param method must not be {@literal null}.
415
+ * @return the method mapping including the type-level one or {@literal null} if neither of them present.
416
+ */
417
+ @ Override
418
+ public String getMapping (Method method ) {
419
+ return getDelegate ().getMapping (method );
420
+ }
421
+
422
+ /**
423
+ * Returns the mapping for the given {@link Method} invoked on the given type. This can be used to calculate the
424
+ * mapping for a super type method being invoked on a sub-type with a type mapping.
425
+ *
426
+ * @param type must not be {@literal null}.
427
+ * @param method must not be {@literal null}.
428
+ * @return the method mapping including the type-level one or {@literal null} if neither of them present.
429
+ */
430
+ @ Override
431
+ public String getMapping (Class <?> type , Method method ) {
432
+ return getDelegate ().getMapping (type , method );
433
+ }
434
+
435
+ /**
436
+ * Returns the {@link HttpMethod} invoked on the given type and {@link Method}.
437
+ */
438
+ @ Override
439
+ public Collection <HttpMethod > getRequestMethod (Class <?> type , Method method ) {
440
+ return getDelegate ().getRequestMethod (type , method );
441
+ }
379
442
}
380
443
381
444
private static class CustomUriTemplateHandler extends DefaultUriTemplateHandler {
@@ -402,4 +465,4 @@ public UriComponents expandAndEncode(UriComponentsBuilder builder, Object[] uriV
402
465
return super .expandAndEncode (builder , uriVariables );
403
466
}
404
467
}
405
- }
468
+ }
0 commit comments