All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy