15
15
*/
16
16
package org .springframework .hateoas .mediatype .hal ;
17
17
18
+ import java .util .ArrayList ;
19
+ import java .util .Collections ;
18
20
import java .util .LinkedHashMap ;
21
+ import java .util .List ;
19
22
import java .util .Map ;
20
23
import java .util .Map .Entry ;
21
24
import java .util .function .Consumer ;
22
25
23
26
import org .springframework .hateoas .Link ;
24
27
import org .springframework .hateoas .LinkRelation ;
28
+ import org .springframework .hateoas .MediaTypes ;
29
+ import org .springframework .http .MediaType ;
25
30
import org .springframework .util .AntPathMatcher ;
26
31
import org .springframework .util .Assert ;
27
32
import org .springframework .util .PathMatcher ;
@@ -45,6 +50,7 @@ public class HalConfiguration {
45
50
private final RenderSingleLinks renderSingleLinks ;
46
51
private final Map <String , RenderSingleLinks > singleLinksPerPattern ;
47
52
private final Consumer <ObjectMapper > objectMapperCustomizer ;
53
+ private final List <MediaType > mediaTypes ;
48
54
49
55
/**
50
56
* Configures whether the Jackson property naming strategy is applied to link relations and within {@code _embedded}
@@ -62,22 +68,26 @@ public class HalConfiguration {
62
68
* Creates a new default {@link HalConfiguration} rendering single links as immediate sub-document.
63
69
*/
64
70
public HalConfiguration () {
65
- this (RenderSingleLinks .AS_SINGLE , new LinkedHashMap <>(), true , true , __ -> {});
71
+
72
+ this (RenderSingleLinks .AS_SINGLE , new LinkedHashMap <>(), true , true , __ -> {},
73
+ Collections .singletonList (MediaTypes .HAL_JSON ));
66
74
}
67
75
68
76
private HalConfiguration (RenderSingleLinks renderSingleLinks , Map <String , RenderSingleLinks > singleLinksPerPattern ,
69
77
boolean applyPropertyNamingStrategy , boolean enforceEmbeddedCollections ,
70
- Consumer <ObjectMapper > objectMapperCustomizer ) {
78
+ Consumer <ObjectMapper > objectMapperCustomizer , List < MediaType > mediaTypes ) {
71
79
72
80
Assert .notNull (renderSingleLinks , "RenderSingleLinks must not be null!" );
73
81
Assert .notNull (singleLinksPerPattern , "Single links per pattern map must not be null!" );
74
82
Assert .notNull (objectMapperCustomizer , "ObjectMapper customizer must not be null!" );
83
+ Assert .notNull (mediaTypes , "MediaTypes must not be null!" );
75
84
76
85
this .renderSingleLinks = renderSingleLinks ;
77
86
this .singleLinksPerPattern = singleLinksPerPattern ;
78
87
this .applyPropertyNamingStrategy = applyPropertyNamingStrategy ;
79
88
this .enforceEmbeddedCollections = enforceEmbeddedCollections ;
80
89
this .objectMapperCustomizer = objectMapperCustomizer ;
90
+ this .mediaTypes = mediaTypes ;
81
91
}
82
92
83
93
/**
@@ -144,7 +154,7 @@ public HalConfiguration withRenderSingleLinks(RenderSingleLinks renderSingleLink
144
154
return this .renderSingleLinks == renderSingleLinks //
145
155
? this //
146
156
: new HalConfiguration (renderSingleLinks , singleLinksPerPattern , applyPropertyNamingStrategy ,
147
- enforceEmbeddedCollections , objectMapperCustomizer );
157
+ enforceEmbeddedCollections , objectMapperCustomizer , mediaTypes );
148
158
}
149
159
150
160
/**
@@ -160,7 +170,7 @@ private HalConfiguration withSingleLinksPerPattern(Map<String, RenderSingleLinks
160
170
return this .singleLinksPerPattern == singleLinksPerPattern //
161
171
? this //
162
172
: new HalConfiguration (renderSingleLinks , singleLinksPerPattern , applyPropertyNamingStrategy ,
163
- enforceEmbeddedCollections , objectMapperCustomizer );
173
+ enforceEmbeddedCollections , objectMapperCustomizer , mediaTypes );
164
174
}
165
175
166
176
/**
@@ -175,7 +185,7 @@ public HalConfiguration withApplyPropertyNamingStrategy(boolean applyPropertyNam
175
185
return this .applyPropertyNamingStrategy == applyPropertyNamingStrategy //
176
186
? this //
177
187
: new HalConfiguration (renderSingleLinks , singleLinksPerPattern , applyPropertyNamingStrategy ,
178
- enforceEmbeddedCollections , objectMapperCustomizer );
188
+ enforceEmbeddedCollections , objectMapperCustomizer , mediaTypes );
179
189
}
180
190
181
191
/**
@@ -190,15 +200,46 @@ public HalConfiguration withEnforceEmbeddedCollections(boolean enforceEmbeddedCo
190
200
return this .enforceEmbeddedCollections == enforceEmbeddedCollections //
191
201
? this //
192
202
: new HalConfiguration (renderSingleLinks , singleLinksPerPattern , applyPropertyNamingStrategy ,
193
- enforceEmbeddedCollections , objectMapperCustomizer );
203
+ enforceEmbeddedCollections , objectMapperCustomizer , mediaTypes );
194
204
}
195
205
206
+ /**
207
+ * Configures an {@link ObjectMapper} customizer to tweak the instance after it has been pre-configured with all HAL
208
+ * specific setup.
209
+ *
210
+ * @param objectMapperCustomizer must not be {@literal null}.
211
+ * @return will never be {@literal null}.
212
+ */
196
213
public HalConfiguration withObjectMapperCustomizer (Consumer <ObjectMapper > objectMapperCustomizer ) {
197
214
198
215
return this .objectMapperCustomizer == objectMapperCustomizer //
199
216
? this //
200
217
: new HalConfiguration (renderSingleLinks , singleLinksPerPattern , applyPropertyNamingStrategy ,
201
- enforceEmbeddedCollections , objectMapperCustomizer );
218
+ enforceEmbeddedCollections , objectMapperCustomizer , mediaTypes );
219
+ }
220
+
221
+ /**
222
+ * Registers additional media types that are supposed to be aliases to {@link MediaTypes#HAL_JSON}. Registered
223
+ * {@link MediaType}s will be preferred over the default one, i.e. they'll be listed first in client's accept headers
224
+ * etc.
225
+ *
226
+ * @param mediaType must not be {@literal null}.
227
+ * @return will never be {@literal null}.
228
+ * @since 1.3
229
+ */
230
+ public HalConfiguration withMediaType (MediaType mediaType ) {
231
+
232
+ Assert .notNull (mediaType , "MediaType must not be null!" );
233
+
234
+ if (mediaTypes .contains (mediaType )) {
235
+ return this ;
236
+ }
237
+
238
+ List <MediaType > newMediaTypes = new ArrayList <>(mediaTypes );
239
+ newMediaTypes .add (mediaTypes .size () - 1 , mediaType );
240
+
241
+ return new HalConfiguration (renderSingleLinks , singleLinksPerPattern , applyPropertyNamingStrategy ,
242
+ enforceEmbeddedCollections , objectMapperCustomizer , newMediaTypes );
202
243
}
203
244
204
245
public RenderSingleLinks getRenderSingleLinks () {
@@ -220,6 +261,10 @@ public HalConfiguration customize(ObjectMapper mapper) {
220
261
return this ;
221
262
}
222
263
264
+ List <MediaType > getMediaTypes () {
265
+ return mediaTypes ;
266
+ }
267
+
223
268
/**
224
269
* Configuration option how to render single links of a given {@link LinkRelation}.
225
270
*
0 commit comments