2929import org .apache .commons .logging .LogFactory ;
3030
3131import org .springframework .beans .factory .BeanClassLoaderAware ;
32+ import org .springframework .core .ResolvableType ;
33+ import org .springframework .integration .mapping .support .JsonHeaders ;
3234import org .springframework .lang .Nullable ;
3335import org .springframework .messaging .MessageChannel ;
3436import org .springframework .messaging .MessageHeaders ;
@@ -67,8 +69,8 @@ public abstract class AbstractHeaderMapper<T> implements RequestReplyHeaderMappe
6769 */
6870 public static final String NON_STANDARD_HEADER_NAME_PATTERN = "NON_STANDARD_HEADERS" ;
6971
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 );
7274
7375 protected final Log logger = LogFactory .getLog (getClass ()); // NOSONAR final
7476
@@ -155,7 +157,7 @@ protected HeaderMatcher createDefaultHeaderMatcher(String standardHeaderPrefix,
155157 * @return a header mapper that match if any of the specified patters match
156158 */
157159 protected HeaderMatcher createHeaderMatcher (Collection <String > patterns ) {
158- List <HeaderMatcher > matchers = new ArrayList <HeaderMatcher >();
160+ List <HeaderMatcher > matchers = new ArrayList <>();
159161 for (String pattern : patterns ) {
160162 if (STANDARD_REQUEST_HEADER_NAME_PATTERN .equals (pattern )) {
161163 matchers .add (new ContentBasedHeaderMatcher (true , this .requestHeaderNames ));
@@ -190,40 +192,38 @@ else if (pattern.startsWith("\\!")) {
190192
191193 @ Override
192194 public void fromHeadersToRequest (MessageHeaders headers , T target ) {
193- this . fromHeaders (headers , target , this .requestHeaderMatcher );
195+ fromHeaders (headers , target , this .requestHeaderMatcher );
194196 }
195197
196198 @ Override
197199 public void fromHeadersToReply (MessageHeaders headers , T target ) {
198- this . fromHeaders (headers , target , this .replyHeaderMatcher );
200+ fromHeaders (headers , target , this .replyHeaderMatcher );
199201 }
200202
201203 @ Override
202204 public Map <String , Object > toHeadersFromRequest (T source ) {
203- return this . toHeaders (source , this .requestHeaderMatcher );
205+ return toHeaders (source , this .requestHeaderMatcher );
204206 }
205207
206208 @ Override
207209 public Map <String , Object > toHeadersFromReply (T source ) {
208- return this . toHeaders (source , this .replyHeaderMatcher );
210+ return toHeaders (source , this .replyHeaderMatcher );
209211 }
210212
211213 private void fromHeaders (MessageHeaders headers , T target , HeaderMatcher headerMatcher ) {
212214 try {
213- Map <String , Object > subset = new HashMap <String , Object >();
215+ Map <String , Object > subset = new HashMap <>();
214216 for (Map .Entry <String , Object > entry : headers .entrySet ()) {
215217 String headerName = entry .getKey ();
216- if (this . shouldMapHeader (headerName , headerMatcher )) {
218+ if (shouldMapHeader (headerName , headerMatcher )) {
217219 subset .put (headerName , entry .getValue ());
218220 }
219221 }
220- this . populateStandardHeaders (headers , subset , target );
221- this . populateUserDefinedHeaders (subset , target );
222+ populateStandardHeaders (headers , subset , target );
223+ populateUserDefinedHeaders (subset , target );
222224 }
223225 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 );
227227 }
228228 }
229229
@@ -234,8 +234,8 @@ private void populateUserDefinedHeaders(Map<String, Object> headers, T target) {
234234 if (value != null && !isMessageChannel (headerName , value )) {
235235 try {
236236 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 );
239239 }
240240 }
241241 catch (Exception e ) {
@@ -262,21 +262,30 @@ private boolean isMessageChannel(String headerName, Object headerValue) {
262262 * a {@link org.springframework.messaging.Message}.
263263 */
264264 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 <>();
266266 Map <String , Object > standardHeaders = extractStandardHeaders (source );
267- this . copyHeaders (standardHeaders , headers , headerMatcher );
267+ copyHeaders (standardHeaders , headers , headerMatcher );
268268 Map <String , Object > userDefinedHeaders = extractUserDefinedHeaders (source );
269- this . copyHeaders (userDefinedHeaders , headers , headerMatcher );
269+ copyHeaders (userDefinedHeaders , headers , headerMatcher );
270270 return headers ;
271271 }
272272
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 ) {
274274 if (!CollectionUtils .isEmpty (source )) {
275275 for (Map .Entry <String , Object > entry : source .entrySet ()) {
276276 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+ }
280289 }
281290 }
282291 catch (Exception e ) {
@@ -289,6 +298,20 @@ private <V> void copyHeaders(Map<String, Object> source, Map<String, Object> tar
289298 }
290299 }
291300
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+
292315 private boolean shouldMapHeader (String headerName , HeaderMatcher headerMatcher ) {
293316 return !(!StringUtils .hasText (headerName ) || getTransientHeaderNames ().contains (headerName ))
294317 && headerMatcher .matchHeader (headerName );
@@ -303,8 +326,8 @@ protected <V> V getHeaderIfAvailable(Map<String, Object> headers, String name, C
303326 }
304327 if (!type .isAssignableFrom (value .getClass ())) {
305328 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 () + "]" );
308331 }
309332 return null ;
310333 }
@@ -380,6 +403,7 @@ protected void populateStandardHeaders(@Nullable Map<String, Object> allHeaders,
380403 * Strategy interface to determine if a given header name matches.
381404 * @since 4.1
382405 */
406+ @ FunctionalInterface
383407 public interface HeaderMatcher {
384408
385409 /**
@@ -393,7 +417,9 @@ public interface HeaderMatcher {
393417 * Return true if this match should be explicitly excluded from the mapping.
394418 * @return true if negated.
395419 */
396- boolean isNegated ();
420+ default boolean isNegated () {
421+ return false ;
422+ }
397423
398424 }
399425
@@ -440,11 +466,6 @@ private boolean containsIgnoreCase(String name) {
440466 return false ;
441467 }
442468
443- @ Override
444- public boolean isNegated () {
445- return false ;
446- }
447-
448469 }
449470
450471 /**
@@ -457,7 +478,7 @@ protected static class PatternBasedHeaderMatcher implements HeaderMatcher {
457478
458479 private static final Log logger = LogFactory .getLog (HeaderMatcher .class );
459480
460- private final Collection <String > patterns = new ArrayList <String >();
481+ private final Collection <String > patterns = new ArrayList <>();
461482
462483 public PatternBasedHeaderMatcher (Collection <String > patterns ) {
463484 Assert .notNull (patterns , "Patterns must no be null" );
@@ -482,11 +503,6 @@ public boolean matchHeader(String headerName) {
482503 return false ;
483504 }
484505
485- @ Override
486- public boolean isNegated () {
487- return false ;
488- }
489-
490506 }
491507
492508 /**
@@ -566,11 +582,6 @@ public boolean matchHeader(String headerName) {
566582 return result ;
567583 }
568584
569- @ Override
570- public boolean isNegated () {
571- return false ;
572- }
573-
574585 }
575586
576587 /**
@@ -608,11 +619,6 @@ public boolean matchHeader(String headerName) {
608619 return false ;
609620 }
610621
611- @ Override
612- public boolean isNegated () {
613- return false ;
614- }
615-
616622 }
617623
618624}
0 commit comments