package org.gbif.ws.server.processor;

import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.ServletRequest;
import org.gbif.api.annotation.ParamName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;

/** ServletRequestDataBinder which supports fields renaming using {@link ParamName} */
public class ParamNameDataBinder extends ExtendedServletRequestDataBinder {

  private static final Logger LOG = LoggerFactory.getLogger(ParamNameDataBinder.class);

  private final Map<String, String> paramMappings;
  private final Map<String, String> methodMappings;

  public ParamNameDataBinder(
      Object target,
      String objectName,
      Map<String, String> paramMappings,
      Map<String, String> methodMappings) {
    super(target, objectName);
    this.paramMappings = paramMappings;
    this.methodMappings = methodMappings;
  }

  /**
   * Using a mapping which was created by {@link ParamNameProcessor} this method binds actual values
   * to the parameters.
   */
  @Override
  protected void addBindValues(
      MutablePropertyValues mutablePropertyValues, ServletRequest request) {
    super.addBindValues(mutablePropertyValues, request);
    for (Map.Entry<String, String> entry : paramMappings.entrySet()) {
      String paramName = entry.getKey();
      String fieldName = entry.getValue();
      if (mutablePropertyValues.contains(paramName)) {
        mutablePropertyValues.add(
            fieldName, mutablePropertyValues.getPropertyValue(paramName).getValue());
      }
    }

    for (Map.Entry<String, String> entry : methodMappings.entrySet()) {
      String paramName = entry.getKey();
      String methodName = entry.getValue();
      if (mutablePropertyValues.contains(paramName)) {
        try {
          final Method declaredMethod =
              getTarget().getClass().getDeclaredMethod(methodName, String.class);
          declaredMethod.invoke(
              getTarget(), mutablePropertyValues.getPropertyValue(paramName).getValue());
        } catch (Exception e) {
          LOG.error("There was a problem to invoke a method {}", methodName);
        }
      }
    }
  }
}

@@ -462,16 +462,54 @@
 ame%7D */%0A
+@SuppressWarnings(%22NullableProblems%22)%0A
 public c
@@ -2177,24 +2177,88 @@
 etValue());%0A
+          mutablePropertyValues.removePropertyValue(paramName);%0A
         %7D ca

Remove parameters from list in order to prevent unexpected binding