21
21
import java .util .Map ;
22
22
23
23
import org .springframework .beans .BeansException ;
24
+ import org .springframework .beans .factory .BeanFactory ;
25
+ import org .springframework .beans .factory .BeanFactoryAware ;
24
26
import org .springframework .beans .factory .config .BeanDefinition ;
25
27
import org .springframework .beans .factory .config .BeanDefinitionHolder ;
26
28
import org .springframework .beans .factory .config .BeanPostProcessor ;
27
29
import org .springframework .beans .factory .support .AbstractBeanDefinition ;
30
+ import org .springframework .beans .factory .support .BeanDefinitionBuilder ;
28
31
import org .springframework .beans .factory .support .BeanDefinitionRegistry ;
29
32
import org .springframework .beans .factory .support .RootBeanDefinition ;
30
33
import org .springframework .context .ApplicationContext ;
31
34
import org .springframework .context .annotation .ImportBeanDefinitionRegistrar ;
32
35
import org .springframework .core .type .AnnotationMetadata ;
33
36
import org .springframework .hateoas .EntityLinks ;
34
37
import org .springframework .hateoas .LinkDiscoverer ;
38
+ import org .springframework .hateoas .RelProvider ;
35
39
import org .springframework .hateoas .config .EnableHypermediaSupport .HypermediaType ;
40
+ import org .springframework .hateoas .core .AnnotationRelProvider ;
36
41
import org .springframework .hateoas .core .DefaultLinkDiscoverer ;
42
+ import org .springframework .hateoas .core .DefaultRelProvider ;
43
+ import org .springframework .hateoas .core .DelegatingRelProvider ;
37
44
import org .springframework .hateoas .hal .HalLinkDiscoverer ;
38
45
import org .springframework .hateoas .hal .Jackson1HalModule ;
39
46
import org .springframework .hateoas .hal .Jackson2HalModule ;
40
47
import org .springframework .http .converter .HttpMessageConverter ;
41
48
import org .springframework .http .converter .json .MappingJackson2HttpMessageConverter ;
42
49
import org .springframework .http .converter .json .MappingJacksonHttpMessageConverter ;
50
+ import org .springframework .plugin .core .PluginRegistry ;
51
+ import org .springframework .plugin .core .support .PluginRegistryFactoryBean ;
43
52
import org .springframework .util .ClassUtils ;
44
53
import org .springframework .web .servlet .mvc .annotation .AnnotationMethodHandlerAdapter ;
45
54
import org .springframework .web .servlet .mvc .method .annotation .RequestMappingHandlerAdapter ;
56
65
class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
57
66
58
67
private static final String LINK_DISCOVERER_BEAN_NAME = "_linkDiscoverer" ;
68
+ private static final String DELEGATING_REL_PROVIDER_BEAN_NAME = "_relProvider" ;
59
69
60
70
private static final boolean JACKSON1_PRESENT = ClassUtils .isPresent ("org.codehaus.jackson.map.ObjectMapper" , null );
61
71
private static final boolean JACKSON2_PRESENT = ClassUtils .isPresent ("com.fasterxml.jackson.databind.ObjectMapper" ,
62
72
null );
63
73
private static final boolean JSONPATH_PRESENT = ClassUtils .isPresent ("com.jayway.jsonpath.JsonPath" , null );
64
74
75
+ private final ImportBeanDefinitionRegistrar linkBuilderBeanDefinitionRegistrar = new LinkBuilderBeanDefinitionRegistrar ();
76
+
65
77
/*
66
78
* (non-Javadoc)
67
79
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
68
80
*/
69
81
@ Override
70
82
public void registerBeanDefinitions (AnnotationMetadata importingClassMetadata , BeanDefinitionRegistry registry ) {
71
83
72
- new LinkBuilderBeanDefinitionRegistrar () .registerBeanDefinitions (importingClassMetadata , registry );
84
+ linkBuilderBeanDefinitionRegistrar .registerBeanDefinitions (importingClassMetadata , registry );
73
85
74
86
Map <String , Object > attributes = importingClassMetadata .getAnnotationAttributes (EnableHypermediaSupport .class
75
87
.getName ());
@@ -90,6 +102,38 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
90
102
registerWithGeneratedName (new RootBeanDefinition (Jackson1ModuleRegisteringBeanPostProcessor .class ), registry );
91
103
}
92
104
}
105
+
106
+ registerRelProviderPluginRegistryAndDelegate (registry );
107
+ }
108
+
109
+ /**
110
+ * Registers bean definitions for a {@link PluginRegistry} to capture {@link RelProvider} instances. Wraps the
111
+ * registry into a {@link DelegatingRelProvider} bean definition backed by the registry.
112
+ *
113
+ * @param registry
114
+ */
115
+ private static void registerRelProviderPluginRegistryAndDelegate (BeanDefinitionRegistry registry ) {
116
+
117
+ RootBeanDefinition defaultRelProviderBeanDefinition = new RootBeanDefinition (DefaultRelProvider .class );
118
+ registry .registerBeanDefinition ("defaultRelProvider" , defaultRelProviderBeanDefinition );
119
+
120
+ RootBeanDefinition annotationRelProviderBeanDefinition = new RootBeanDefinition (AnnotationRelProvider .class );
121
+ registry .registerBeanDefinition ("annotationRelProvider" , annotationRelProviderBeanDefinition );
122
+
123
+ BeanDefinitionBuilder registryFactoryBeanBuilder = BeanDefinitionBuilder
124
+ .rootBeanDefinition (PluginRegistryFactoryBean .class );
125
+ registryFactoryBeanBuilder .addPropertyValue ("type" , RelProvider .class );
126
+ registryFactoryBeanBuilder .addPropertyValue ("exclusions" , DelegatingRelProvider .class );
127
+
128
+ AbstractBeanDefinition registryBeanDefinition = registryFactoryBeanBuilder .getBeanDefinition ();
129
+ registry .registerBeanDefinition ("relProviderPluginRegistry" , registryBeanDefinition );
130
+
131
+ BeanDefinitionBuilder delegateBuilder = BeanDefinitionBuilder .rootBeanDefinition (DelegatingRelProvider .class );
132
+ delegateBuilder .addConstructorArgValue (registryBeanDefinition );
133
+
134
+ AbstractBeanDefinition beanDefinition = delegateBuilder .getBeanDefinition ();
135
+ beanDefinition .setPrimary (true );
136
+ registry .registerBeanDefinition (DELEGATING_REL_PROVIDER_BEAN_NAME , beanDefinition );
93
137
}
94
138
95
139
/**
@@ -121,7 +165,17 @@ private AbstractBeanDefinition getLinkDiscovererBeanDefinition(HypermediaType ty
121
165
*
122
166
* @author Oliver Gierke
123
167
*/
124
- private static class Jackson2ModuleRegisteringBeanPostProcessor implements BeanPostProcessor {
168
+ private static class Jackson2ModuleRegisteringBeanPostProcessor implements BeanPostProcessor , BeanFactoryAware {
169
+
170
+ private BeanFactory factory ;
171
+
172
+ /* (non-Javadoc)
173
+ * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
174
+ */
175
+ @ Override
176
+ public void setBeanFactory (BeanFactory beanFactory ) throws BeansException {
177
+ this .factory = beanFactory ;
178
+ }
125
179
126
180
/*
127
181
* (non-Javadoc)
@@ -164,7 +218,12 @@ private void registerModule(List<HttpMessageConverter<?>> converters) {
164
218
}
165
219
166
220
private void registerModule (Object objectMapper ) {
167
- ((ObjectMapper ) objectMapper ).registerModule (new Jackson2HalModule (null ));
221
+
222
+ RelProvider provider = factory .getBean (DELEGATING_REL_PROVIDER_BEAN_NAME , RelProvider .class );
223
+
224
+ ObjectMapper mapper = (ObjectMapper ) objectMapper ;
225
+ mapper .registerModule (new Jackson2HalModule ());
226
+ mapper .setHandlerInstantiator (new Jackson2HalModule .HalHandlerInstantiator (provider ));
168
227
}
169
228
}
170
229
@@ -174,7 +233,18 @@ private void registerModule(Object objectMapper) {
174
233
*
175
234
* @author Oliver Gierke
176
235
*/
177
- private static class Jackson1ModuleRegisteringBeanPostProcessor implements BeanPostProcessor {
236
+ private static class Jackson1ModuleRegisteringBeanPostProcessor implements BeanPostProcessor , BeanFactoryAware {
237
+
238
+ private BeanFactory beanFactory ;
239
+
240
+ /*
241
+ * (non-Javadoc)
242
+ * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
243
+ */
244
+ @ Override
245
+ public void setBeanFactory (BeanFactory beanFactory ) throws BeansException {
246
+ this .beanFactory = beanFactory ;
247
+ }
178
248
179
249
/*
180
250
* (non-Javadoc)
@@ -216,8 +286,13 @@ private void registerModule(List<HttpMessageConverter<?>> converters) {
216
286
}
217
287
}
218
288
219
- private void registerModule (Object mapper ) {
220
- ((org .codehaus .jackson .map .ObjectMapper ) mapper ).registerModule (new Jackson1HalModule (null ));
289
+ private void registerModule (Object objectMapper ) {
290
+
291
+ RelProvider relProvider = beanFactory .getBean (DELEGATING_REL_PROVIDER_BEAN_NAME , RelProvider .class );
292
+
293
+ org .codehaus .jackson .map .ObjectMapper mapper = (org .codehaus .jackson .map .ObjectMapper ) objectMapper ;
294
+ mapper .registerModule (new Jackson1HalModule ());
295
+ mapper .setHandlerInstantiator (new Jackson1HalModule .HalHandlerInstantiator (relProvider ));
221
296
}
222
297
}
223
298
}
0 commit comments