View Javadoc
1   /*
2    * Copyright 2002-2013 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.messaging.handler.annotation.support;
18  
19  import java.lang.reflect.Method;
20  import java.util.Map;
21  
22  import org.springframework.core.MethodParameter;
23  import org.springframework.messaging.Message;
24  import org.springframework.messaging.MessageHeaders;
25  import org.springframework.messaging.handler.annotation.Header;
26  import org.springframework.messaging.handler.annotation.Headers;
27  import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
28  import org.springframework.messaging.support.MessageHeaderAccessor;
29  import org.springframework.util.Assert;
30  import org.springframework.util.ReflectionUtils;
31  
32  /**
33   * Resolves the following method parameters:
34   * <ul>
35   * <li>Parameters assignable to {@link Map} annotated with {@link Header @Headers}
36   * <li>Parameters of type {@link MessageHeaders}
37   * <li>Parameters assignable to {@link MessageHeaderAccessor}
38   * </ul>
39   *
40   * @author Rossen Stoyanchev
41   * @since 4.0
42   */
43  public class HeadersMethodArgumentResolver implements HandlerMethodArgumentResolver {
44  
45  	@Override
46  	public boolean supportsParameter(MethodParameter parameter) {
47  		Class<?> paramType = parameter.getParameterType();
48  		return ((parameter.hasParameterAnnotation(Headers.class) && Map.class.isAssignableFrom(paramType)) ||
49  				MessageHeaders.class.equals(paramType) ||
50  				MessageHeaderAccessor.class.isAssignableFrom(paramType));
51  	}
52  
53  	@Override
54  	public Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception {
55  
56  		Class<?> paramType = parameter.getParameterType();
57  
58  		if (Map.class.isAssignableFrom(paramType)) {
59  			return message.getHeaders();
60  		}
61  		else if (MessageHeaderAccessor.class.equals(paramType)) {
62  			MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class);
63  			return (accessor != null ? accessor : new MessageHeaderAccessor(message));
64  		}
65  		else if (MessageHeaderAccessor.class.isAssignableFrom(paramType)) {
66  			MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class);
67  			if (accessor != null && paramType.isAssignableFrom(accessor.getClass())) {
68  				return accessor;
69  			}
70  			else {
71  				Method method = ReflectionUtils.findMethod(paramType, "wrap", Message.class);
72  				Assert.notNull(method, "Cannot create accessor of type " + paramType + " for message " +  message);
73  				return ReflectionUtils.invokeMethod(method, null, message);
74  			}
75  		}
76  		else {
77  			throw new IllegalStateException(
78  					"Unexpected method parameter type " + paramType + "in method " + parameter.getMethod() + ". "
79  					+ "@Headers method arguments must be assignable to java.util.Map.");
80  		}
81  	}
82  
83  }