001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 *     http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package org.gbif.ws.server.processor;
015
016import org.gbif.api.annotation.ParamName;
017
018import java.lang.reflect.Method;
019import java.util.Map;
020
021import javax.servlet.ServletRequest;
022
023import org.slf4j.Logger;
024import org.slf4j.LoggerFactory;
025import org.springframework.beans.MutablePropertyValues;
026import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;
027
028/** ServletRequestDataBinder which supports fields renaming using {@link ParamName} */
029@SuppressWarnings("NullableProblems")
030public class ParamNameDataBinder extends ExtendedServletRequestDataBinder {
031
032  private static final Logger LOG = LoggerFactory.getLogger(ParamNameDataBinder.class);
033
034  private final Map<String, String> paramMappings;
035  private final Map<String, String> methodMappings;
036
037  public ParamNameDataBinder(
038      Object target,
039      String objectName,
040      Map<String, String> paramMappings,
041      Map<String, String> methodMappings) {
042    super(target, objectName);
043    this.paramMappings = paramMappings;
044    this.methodMappings = methodMappings;
045  }
046
047  /**
048   * Using a mapping which was created by {@link ParamNameProcessor} this method binds actual values
049   * to the parameters.
050   */
051  @Override
052  protected void addBindValues(
053      MutablePropertyValues mutablePropertyValues, ServletRequest request) {
054    super.addBindValues(mutablePropertyValues, request);
055    for (Map.Entry<String, String> entry : paramMappings.entrySet()) {
056      String paramName = entry.getKey();
057      String fieldName = entry.getValue();
058      if (mutablePropertyValues.contains(paramName)) {
059        mutablePropertyValues.add(
060            fieldName, mutablePropertyValues.getPropertyValue(paramName).getValue());
061      }
062    }
063
064    for (Map.Entry<String, String> entry : methodMappings.entrySet()) {
065      String paramName = entry.getKey();
066      String methodName = entry.getValue();
067      if (mutablePropertyValues.contains(paramName)) {
068        try {
069          final Method declaredMethod =
070              getTarget().getClass().getDeclaredMethod(methodName, String.class);
071          declaredMethod.invoke(
072              getTarget(), mutablePropertyValues.getPropertyValue(paramName).getValue());
073          mutablePropertyValues.removePropertyValue(paramName);
074        } catch (Exception e) {
075          LOG.error("There was a problem to invoke a method {}", methodName);
076        }
077      }
078    }
079  }
080}