org.springframework.web.method.annotation.DimensionArgumentResolver Maven / Gradle / Ivy
package org.springframework.web.method.annotation;
import java.awt.Dimension;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.MethodParameter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
public class DimensionArgumentResolver implements HandlerMethodArgumentResolver {
private static final String DEFAULT_PREFIX = "";
private static final String DEFAULT_QUALIFIER_DELIMITER = "_";
private static final String DEFAULT_WIDTH_PARAMETER = "w";
private static final String DEFAULT_HEIGHT_PARAMETER = "h";
private static final String DEFAULT_ALL_PARAMETER = "all";
static final Dimension DEFAULT_DIMENSION = new Dimension(0, 0);
private Dimension fallbackDimension = DEFAULT_DIMENSION;
private String prefix = DEFAULT_PREFIX;
private String qualifierDelimiter = DEFAULT_QUALIFIER_DELIMITER;
private String widthParameterName = DEFAULT_WIDTH_PARAMETER;
private String heightParameterName = DEFAULT_HEIGHT_PARAMETER;
private String allParameterName = DEFAULT_ALL_PARAMETER;
@Override
public boolean supportsParameter(MethodParameter parameter) {
return Dimension.class.isAssignableFrom(parameter.getParameterType());
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
assertDimensionUniqueness(parameter);
Dimension defaultOrFallback = getDefaultFromAnnotationOrFallback(parameter);
String widthString = webRequest.getParameter(getParameterNameToUse(this.widthParameterName, parameter));
String heightString = webRequest.getParameter(getParameterNameToUse(this.heightParameterName, parameter));
boolean widthAndHeightGiven = StringUtils.hasText(widthString) && StringUtils.hasText(heightString);
if (!widthAndHeightGiven && defaultOrFallback == null) {
return null;
}
String allString = webRequest.getParameter(getParameterNameToUse(this.allParameterName, parameter));
if (allString != null) {
return null;
}
int width = StringUtils.hasText(widthString) ? parse(widthString) : defaultOrFallback.width;
int height = StringUtils.hasText(heightString) ? parse(heightString) : defaultOrFallback.height;
return new Dimension(width, height);
}
protected String getParameterNameToUse(String source, MethodParameter parameter) {
StringBuilder builder = new StringBuilder(this.prefix);
if (parameter != null && parameter.hasParameterAnnotation(Qualifier.class)) {
builder.append(parameter.getParameterAnnotation(Qualifier.class).value());
builder.append(this.qualifierDelimiter);
}
return builder.append(source).toString();
}
private Dimension getDefaultFromAnnotationOrFallback(MethodParameter methodParameter) {
if (methodParameter.hasParameterAnnotation(DimensionDefault.class)) {
return getDefaultDimensionRequestFrom(methodParameter);
}
return this.fallbackDimension;
}
private static Dimension getDefaultDimensionRequestFrom(MethodParameter parameter) {
DimensionDefault defaults = parameter.getParameterAnnotation(DimensionDefault.class);
Integer width = defaults.width();
Integer height = defaults.height();
if (width < 1 || height < 1) {
return null;
}
return new Dimension(width, height);
}
private int parse(String parameter) {
try {
return Integer.parseInt(parameter);
}
catch (NumberFormatException e) {
return 0;
}
}
public void setWidthParameterName(String widthParameterName) {
Assert.hasText(widthParameterName, "Width parameter name must not be null or empty!");
this.widthParameterName = widthParameterName;
}
public void setHeightParameterName(String heightParameterName) {
Assert.hasText(heightParameterName, "Height parameter name must not be null or empty!");
this.heightParameterName = heightParameterName;
}
public void setAllParameterName(String allParameterName) {
Assert.hasText(allParameterName, "All parameter name must not be null or empty!");
this.allParameterName = allParameterName;
}
public void setPrefix(String prefix) {
this.prefix = prefix == null ? DEFAULT_PREFIX : prefix;
}
public void setQualifierDelimiter(String qualifierDelimiter) {
this.qualifierDelimiter = qualifierDelimiter == null ? DEFAULT_QUALIFIER_DELIMITER : qualifierDelimiter;
}
public void setFallbackDimension(Dimension fallbackDimension) {
this.fallbackDimension = fallbackDimension;
}
public boolean isFallbackDimension(Dimension dimension) {
return this.fallbackDimension.equals(dimension);
}
public static void assertDimensionUniqueness(MethodParameter parameter) {
Method method = parameter.getMethod();
if (containsMoreThanOneDimensionParameter(method)) {
Annotation[][] annotations = method.getParameterAnnotations();
assertQualifiersFor(method.getParameterTypes(), annotations);
}
}
private static boolean containsMoreThanOneDimensionParameter(Method method) {
boolean pageableFound = false;
for (Class type : method.getParameterTypes()) {
if (pageableFound && type.equals(Dimension.class)) {
return true;
}
if (type.equals(Dimension.class)) {
pageableFound = true;
}
}
return false;
}
public static void assertQualifiersFor(Class[] parameterTypes, Annotation[][] annotations) {
Set values = new HashSet();
for (int i = 0; i < annotations.length; i++) {
if (Dimension.class.equals(parameterTypes[i])) {
Qualifier qualifier = findAnnotation(annotations[i]);
if (null == qualifier) {
throw new IllegalStateException("Ambiguous Dimension arguments in handler method. If you use multiple parameters of type Dimension you need to qualify them with @Qualifier");
}
if (values.contains(qualifier.value())) {
throw new IllegalStateException("Values of the user Qualifiers must be unique!");
}
values.add(qualifier.value());
}
}
}
public static Qualifier findAnnotation(Annotation[] annotations) {
for (Annotation annotation : annotations) {
if (annotation instanceof Qualifier) {
return (Qualifier) annotation;
}
}
return null;
}
}