/*
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.method.support;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.lang.Nullable;
import org.springframework.web.util.UriComponentsBuilder;
A UriComponentsContributor
containing a list of other contributors to delegate and also encapsulating a specific ConversionService
to use for formatting method argument values to Strings. Author: Rossen Stoyanchev, Juergen Hoeller Since: 4.0
/**
* A {@link UriComponentsContributor} containing a list of other contributors
* to delegate and also encapsulating a specific {@link ConversionService} to
* use for formatting method argument values to Strings.
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @since 4.0
*/
public class CompositeUriComponentsContributor implements UriComponentsContributor {
private final List<Object> contributors;
private final ConversionService conversionService;
Create an instance from a collection of UriComponentsContributors
or HandlerMethodArgumentResolvers
. Since both of these tend to be implemented by the same class, the most convenient option is to obtain the configured HandlerMethodArgumentResolvers
in RequestMappingHandlerAdapter
and provide that to this constructor. Params: - contributors – a collection of
UriComponentsContributor
or HandlerMethodArgumentResolvers
.
/**
* Create an instance from a collection of {@link UriComponentsContributor UriComponentsContributors} or
* {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}. Since both of these tend to be implemented
* by the same class, the most convenient option is to obtain the configured
* {@code HandlerMethodArgumentResolvers} in {@code RequestMappingHandlerAdapter}
* and provide that to this constructor.
* @param contributors a collection of {@link UriComponentsContributor}
* or {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
*/
public CompositeUriComponentsContributor(UriComponentsContributor... contributors) {
this.contributors = Arrays.asList((Object[]) contributors);
this.conversionService = new DefaultFormattingConversionService();
}
Create an instance from a collection of UriComponentsContributors
or HandlerMethodArgumentResolvers
. Since both of these tend to be implemented by the same class, the most convenient option is to obtain the configured HandlerMethodArgumentResolvers
in RequestMappingHandlerAdapter
and provide that to this constructor. Params: - contributors – a collection of
UriComponentsContributor
or HandlerMethodArgumentResolvers
.
/**
* Create an instance from a collection of {@link UriComponentsContributor UriComponentsContributors} or
* {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}. Since both of these tend to be implemented
* by the same class, the most convenient option is to obtain the configured
* {@code HandlerMethodArgumentResolvers} in {@code RequestMappingHandlerAdapter}
* and provide that to this constructor.
* @param contributors a collection of {@link UriComponentsContributor}
* or {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
*/
public CompositeUriComponentsContributor(Collection<?> contributors) {
this(contributors, null);
}
Create an instance from a collection of UriComponentsContributors
or HandlerMethodArgumentResolvers
. Since both of these tend to be implemented by the same class, the most convenient option is to obtain the configured HandlerMethodArgumentResolvers
in the RequestMappingHandlerAdapter
and provide that to this constructor. If the ConversionService
argument is null
, DefaultFormattingConversionService
will be used by default.
Params: - contributors – a collection of
UriComponentsContributor
or HandlerMethodArgumentResolvers
. - cs – a ConversionService to use when method argument values
need to be formatted as Strings before being added to the URI
/**
* Create an instance from a collection of {@link UriComponentsContributor UriComponentsContributors} or
* {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}. Since both of these tend to be implemented
* by the same class, the most convenient option is to obtain the configured
* {@code HandlerMethodArgumentResolvers} in the {@code RequestMappingHandlerAdapter}
* and provide that to this constructor.
* <p>If the {@link ConversionService} argument is {@code null},
* {@link org.springframework.format.support.DefaultFormattingConversionService}
* will be used by default.
* @param contributors a collection of {@link UriComponentsContributor}
* or {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
* @param cs a ConversionService to use when method argument values
* need to be formatted as Strings before being added to the URI
*/
public CompositeUriComponentsContributor(@Nullable Collection<?> contributors, @Nullable ConversionService cs) {
this.contributors = (contributors != null ? new ArrayList<>(contributors) : Collections.emptyList());
this.conversionService = (cs != null ? cs : new DefaultFormattingConversionService());
}
public boolean hasContributors() {
return this.contributors.isEmpty();
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
for (Object contributor : this.contributors) {
if (contributor instanceof UriComponentsContributor) {
if (((UriComponentsContributor) contributor).supportsParameter(parameter)) {
return true;
}
}
else if (contributor instanceof HandlerMethodArgumentResolver) {
if (((HandlerMethodArgumentResolver) contributor).supportsParameter(parameter)) {
return false;
}
}
}
return false;
}
@Override
public void contributeMethodArgument(MethodParameter parameter, Object value,
UriComponentsBuilder builder, Map<String, Object> uriVariables, ConversionService conversionService) {
for (Object contributor : this.contributors) {
if (contributor instanceof UriComponentsContributor) {
UriComponentsContributor ucc = (UriComponentsContributor) contributor;
if (ucc.supportsParameter(parameter)) {
ucc.contributeMethodArgument(parameter, value, builder, uriVariables, conversionService);
break;
}
}
else if (contributor instanceof HandlerMethodArgumentResolver) {
if (((HandlerMethodArgumentResolver) contributor).supportsParameter(parameter)) {
break;
}
}
}
}
An overloaded method that uses the ConversionService created at construction.
/**
* An overloaded method that uses the ConversionService created at construction.
*/
public void contributeMethodArgument(MethodParameter parameter, Object value, UriComponentsBuilder builder,
Map<String, Object> uriVariables) {
this.contributeMethodArgument(parameter, value, builder, uriVariables, this.conversionService);
}
}