29
29
import org .apache .commons .logging .LogFactory ;
30
30
31
31
import org .springframework .beans .factory .BeanClassLoaderAware ;
32
+ import org .springframework .core .ResolvableType ;
33
+ import org .springframework .integration .mapping .support .JsonHeaders ;
32
34
import org .springframework .lang .Nullable ;
33
35
import org .springframework .messaging .MessageChannel ;
34
36
import org .springframework .messaging .MessageHeaders ;
@@ -67,8 +69,8 @@ public abstract class AbstractHeaderMapper<T> implements RequestReplyHeaderMappe
67
69
*/
68
70
public static final String NON_STANDARD_HEADER_NAME_PATTERN = "NON_STANDARD_HEADERS" ;
69
71
70
- private static final Collection <String > TRANSIENT_HEADER_NAMES = Arrays . asList (
71
- MessageHeaders .ID , MessageHeaders .TIMESTAMP );
72
+ private static final Collection <String > TRANSIENT_HEADER_NAMES =
73
+ Arrays . asList ( MessageHeaders .ID , MessageHeaders .TIMESTAMP );
72
74
73
75
protected final Log logger = LogFactory .getLog (getClass ()); // NOSONAR final
74
76
@@ -155,7 +157,7 @@ protected HeaderMatcher createDefaultHeaderMatcher(String standardHeaderPrefix,
155
157
* @return a header mapper that match if any of the specified patters match
156
158
*/
157
159
protected HeaderMatcher createHeaderMatcher (Collection <String > patterns ) {
158
- List <HeaderMatcher > matchers = new ArrayList <HeaderMatcher >();
160
+ List <HeaderMatcher > matchers = new ArrayList <>();
159
161
for (String pattern : patterns ) {
160
162
if (STANDARD_REQUEST_HEADER_NAME_PATTERN .equals (pattern )) {
161
163
matchers .add (new ContentBasedHeaderMatcher (true , this .requestHeaderNames ));
@@ -190,40 +192,38 @@ else if (pattern.startsWith("\\!")) {
190
192
191
193
@ Override
192
194
public void fromHeadersToRequest (MessageHeaders headers , T target ) {
193
- this . fromHeaders (headers , target , this .requestHeaderMatcher );
195
+ fromHeaders (headers , target , this .requestHeaderMatcher );
194
196
}
195
197
196
198
@ Override
197
199
public void fromHeadersToReply (MessageHeaders headers , T target ) {
198
- this . fromHeaders (headers , target , this .replyHeaderMatcher );
200
+ fromHeaders (headers , target , this .replyHeaderMatcher );
199
201
}
200
202
201
203
@ Override
202
204
public Map <String , Object > toHeadersFromRequest (T source ) {
203
- return this . toHeaders (source , this .requestHeaderMatcher );
205
+ return toHeaders (source , this .requestHeaderMatcher );
204
206
}
205
207
206
208
@ Override
207
209
public Map <String , Object > toHeadersFromReply (T source ) {
208
- return this . toHeaders (source , this .replyHeaderMatcher );
210
+ return toHeaders (source , this .replyHeaderMatcher );
209
211
}
210
212
211
213
private void fromHeaders (MessageHeaders headers , T target , HeaderMatcher headerMatcher ) {
212
214
try {
213
- Map <String , Object > subset = new HashMap <String , Object >();
215
+ Map <String , Object > subset = new HashMap <>();
214
216
for (Map .Entry <String , Object > entry : headers .entrySet ()) {
215
217
String headerName = entry .getKey ();
216
- if (this . shouldMapHeader (headerName , headerMatcher )) {
218
+ if (shouldMapHeader (headerName , headerMatcher )) {
217
219
subset .put (headerName , entry .getValue ());
218
220
}
219
221
}
220
- this . populateStandardHeaders (headers , subset , target );
221
- this . populateUserDefinedHeaders (subset , target );
222
+ populateStandardHeaders (headers , subset , target );
223
+ populateUserDefinedHeaders (subset , target );
222
224
}
223
225
catch (Exception e ) {
224
- if (this .logger .isWarnEnabled ()) {
225
- this .logger .warn ("error occurred while mapping from MessageHeaders" , e );
226
- }
226
+ this .logger .warn ("error occurred while mapping from MessageHeaders" , e );
227
227
}
228
228
}
229
229
@@ -234,8 +234,8 @@ private void populateUserDefinedHeaders(Map<String, Object> headers, T target) {
234
234
if (value != null && !isMessageChannel (headerName , value )) {
235
235
try {
236
236
if (!headerName .startsWith (this .standardHeaderPrefix )) {
237
- String key = this . createTargetPropertyName (headerName , true );
238
- this . populateUserDefinedHeader (key , value , target );
237
+ String key = createTargetPropertyName (headerName , true );
238
+ populateUserDefinedHeader (key , value , target );
239
239
}
240
240
}
241
241
catch (Exception e ) {
@@ -262,21 +262,30 @@ private boolean isMessageChannel(String headerName, Object headerValue) {
262
262
* a {@link org.springframework.messaging.Message}.
263
263
*/
264
264
private Map <String , Object > toHeaders (T source , HeaderMatcher headerMatcher ) {
265
- Map <String , Object > headers = new HashMap <String , Object >();
265
+ Map <String , Object > headers = new HashMap <>();
266
266
Map <String , Object > standardHeaders = extractStandardHeaders (source );
267
- this . copyHeaders (standardHeaders , headers , headerMatcher );
267
+ copyHeaders (standardHeaders , headers , headerMatcher );
268
268
Map <String , Object > userDefinedHeaders = extractUserDefinedHeaders (source );
269
- this . copyHeaders (userDefinedHeaders , headers , headerMatcher );
269
+ copyHeaders (userDefinedHeaders , headers , headerMatcher );
270
270
return headers ;
271
271
}
272
272
273
- private < V > void copyHeaders (Map <String , Object > source , Map <String , Object > target , HeaderMatcher headerMatcher ) {
273
+ private void copyHeaders (Map <String , Object > source , Map <String , Object > target , HeaderMatcher headerMatcher ) {
274
274
if (!CollectionUtils .isEmpty (source )) {
275
275
for (Map .Entry <String , Object > entry : source .entrySet ()) {
276
276
try {
277
- String headerName = this .createTargetPropertyName (entry .getKey (), false );
278
- if (this .shouldMapHeader (headerName , headerMatcher )) {
279
- target .put (headerName , entry .getValue ());
277
+ String headerName = createTargetPropertyName (entry .getKey (), false );
278
+ if (shouldMapHeader (headerName , headerMatcher )) {
279
+ Object value = entry .getValue ();
280
+ target .put (headerName , value );
281
+ if (JsonHeaders .TYPE_ID .equals (headerName ) && value != null ) {
282
+ ResolvableType resolvableType =
283
+ createJsonResolvableTypHeaderInAny (value , source .get (JsonHeaders .CONTENT_TYPE_ID ),
284
+ source .get (JsonHeaders .KEY_TYPE_ID ));
285
+ if (resolvableType != null ) {
286
+ target .put (JsonHeaders .RESOLVABLE_TYPE , resolvableType );
287
+ }
288
+ }
280
289
}
281
290
}
282
291
catch (Exception e ) {
@@ -289,6 +298,20 @@ private <V> void copyHeaders(Map<String, Object> source, Map<String, Object> tar
289
298
}
290
299
}
291
300
301
+ @ Nullable
302
+ private ResolvableType createJsonResolvableTypHeaderInAny (Object typeId , @ Nullable Object contentId ,
303
+ @ Nullable Object keyId ) {
304
+
305
+ try {
306
+ return JsonHeaders .buildResolvableType (getClassLoader (), typeId ,
307
+ contentId , keyId );
308
+ }
309
+ catch (Exception e ) {
310
+ this .logger .warn ("Cannot build a ResolvableType from 'json__TypeId__' header" , e );
311
+ }
312
+ return null ;
313
+ }
314
+
292
315
private boolean shouldMapHeader (String headerName , HeaderMatcher headerMatcher ) {
293
316
return !(!StringUtils .hasText (headerName ) || getTransientHeaderNames ().contains (headerName ))
294
317
&& headerMatcher .matchHeader (headerName );
@@ -303,8 +326,8 @@ protected <V> V getHeaderIfAvailable(Map<String, Object> headers, String name, C
303
326
}
304
327
if (!type .isAssignableFrom (value .getClass ())) {
305
328
if (this .logger .isWarnEnabled ()) {
306
- this .logger .warn ("skipping header '" + name + "' since it is not of expected type [" + type + "], it is [ " +
307
- value .getClass () + "]" );
329
+ this .logger .warn ("skipping header '" + name + "' since it is not of expected type [" + type + "], " +
330
+ "it is [" + value .getClass () + "]" );
308
331
}
309
332
return null ;
310
333
}
@@ -380,6 +403,7 @@ protected void populateStandardHeaders(@Nullable Map<String, Object> allHeaders,
380
403
* Strategy interface to determine if a given header name matches.
381
404
* @since 4.1
382
405
*/
406
+ @ FunctionalInterface
383
407
public interface HeaderMatcher {
384
408
385
409
/**
@@ -393,7 +417,9 @@ public interface HeaderMatcher {
393
417
* Return true if this match should be explicitly excluded from the mapping.
394
418
* @return true if negated.
395
419
*/
396
- boolean isNegated ();
420
+ default boolean isNegated () {
421
+ return false ;
422
+ }
397
423
398
424
}
399
425
@@ -440,11 +466,6 @@ private boolean containsIgnoreCase(String name) {
440
466
return false ;
441
467
}
442
468
443
- @ Override
444
- public boolean isNegated () {
445
- return false ;
446
- }
447
-
448
469
}
449
470
450
471
/**
@@ -457,7 +478,7 @@ protected static class PatternBasedHeaderMatcher implements HeaderMatcher {
457
478
458
479
private static final Log logger = LogFactory .getLog (HeaderMatcher .class );
459
480
460
- private final Collection <String > patterns = new ArrayList <String >();
481
+ private final Collection <String > patterns = new ArrayList <>();
461
482
462
483
public PatternBasedHeaderMatcher (Collection <String > patterns ) {
463
484
Assert .notNull (patterns , "Patterns must no be null" );
@@ -482,11 +503,6 @@ public boolean matchHeader(String headerName) {
482
503
return false ;
483
504
}
484
505
485
- @ Override
486
- public boolean isNegated () {
487
- return false ;
488
- }
489
-
490
506
}
491
507
492
508
/**
@@ -566,11 +582,6 @@ public boolean matchHeader(String headerName) {
566
582
return result ;
567
583
}
568
584
569
- @ Override
570
- public boolean isNegated () {
571
- return false ;
572
- }
573
-
574
585
}
575
586
576
587
/**
@@ -608,11 +619,6 @@ public boolean matchHeader(String headerName) {
608
619
return false ;
609
620
}
610
621
611
- @ Override
612
- public boolean isNegated () {
613
- return false ;
614
- }
615
-
616
622
}
617
623
618
624
}
0 commit comments