001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.messaging.handler.annotation.reactive; 018 019import java.util.Map; 020 021import org.springframework.core.MethodParameter; 022import org.springframework.core.convert.ConversionService; 023import org.springframework.lang.Nullable; 024import org.springframework.messaging.Message; 025import org.springframework.messaging.MessageHandlingException; 026import org.springframework.messaging.MessageHeaders; 027import org.springframework.messaging.handler.annotation.DestinationVariable; 028import org.springframework.messaging.handler.annotation.ValueConstants; 029import org.springframework.util.Assert; 030 031/** 032 * Resolve for {@link DestinationVariable @DestinationVariable} method parameters. 033 * 034 * @author Rossen Stoyanchev 035 * @since 5.2 036 */ 037public class DestinationVariableMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver { 038 039 /** The name of the header used to for template variables. */ 040 public static final String DESTINATION_TEMPLATE_VARIABLES_HEADER = 041 DestinationVariableMethodArgumentResolver.class.getSimpleName() + ".templateVariables"; 042 043 044 public DestinationVariableMethodArgumentResolver(ConversionService conversionService) { 045 super(conversionService, null); 046 } 047 048 049 @Override 050 public boolean supportsParameter(MethodParameter parameter) { 051 return parameter.hasParameterAnnotation(DestinationVariable.class); 052 } 053 054 @Override 055 protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) { 056 DestinationVariable annot = parameter.getParameterAnnotation(DestinationVariable.class); 057 Assert.state(annot != null, "No DestinationVariable annotation"); 058 return new DestinationVariableNamedValueInfo(annot); 059 } 060 061 @Override 062 @Nullable 063 @SuppressWarnings("unchecked") 064 protected Object resolveArgumentInternal(MethodParameter parameter, Message<?> message, String name) { 065 MessageHeaders headers = message.getHeaders(); 066 Map<String, String> vars = (Map<String, String>) headers.get(DESTINATION_TEMPLATE_VARIABLES_HEADER); 067 return vars != null ? vars.get(name) : null; 068 } 069 070 @Override 071 protected void handleMissingValue(String name, MethodParameter parameter, Message<?> message) { 072 throw new MessageHandlingException(message, "Missing path template variable '" + name + "' " + 073 "for method parameter type [" + parameter.getParameterType() + "]"); 074 } 075 076 077 private static final class DestinationVariableNamedValueInfo extends NamedValueInfo { 078 079 private DestinationVariableNamedValueInfo(DestinationVariable annotation) { 080 super(annotation.value(), true, ValueConstants.DEFAULT_NONE); 081 } 082 } 083 084}