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

com.ifengxue.http.proxy.Resolver Maven / Gradle / Ivy

/*
 * Copyright 2019 https://www.ifengxue.com
 *
 * 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
 *
 *     http://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 com.ifengxue.http.proxy;

import com.ifengxue.http.annotation.Body;
import com.ifengxue.http.annotation.BodyType;
import com.ifengxue.http.annotation.Expensive;
import com.ifengxue.http.annotation.Header;
import com.ifengxue.http.annotation.Param;
import com.ifengxue.http.annotation.ParamHeader;
import com.ifengxue.http.annotation.QueryMap;
import com.ifengxue.http.annotation.QueryParam;
import com.ifengxue.http.codec.Codec;
import com.ifengxue.http.codec.CodecFactory;
import com.ifengxue.http.codec.JsonCodec;
import com.ifengxue.http.codec.XmlCodec;
import com.ifengxue.http.collection.MultiMap;
import com.ifengxue.http.collection.MultiValueMap;
import com.ifengxue.http.contract.Callback;
import com.ifengxue.http.contract.CallbackHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

class Resolver {

  /**
   * 解析参数
   */
  static MultiMap resolveParameters(Map uriVariables) {
    if (uriVariables == null) {
      return new MultiValueMap<>();
    }
    MultiMap parameterMap = new MultiValueMap<>(uriVariables.size());
    parameterMap.putAll(uriVariables);
    return parameterMap;
  }

  /**
   * 解析参数
   */
  static MultiMap resolveParameters(Method method, Object[] args, BodyType bodyType) {
    if (args == null || args.length == 0) {
      return new MultiValueMap<>();
    }
    Parameter[] parameters = method.getParameters();
    MultiMap parameterMap = new MultiValueMap<>(parameters.length);
    for (int i = 0; i < parameters.length; i++) {
      Parameter parameter = parameters[i];
      // skip body annotation
      if (parameter.isAnnotationPresent(Body.class)) {
        continue;
      }
      // skip callback type
      if (Callback.class.isAssignableFrom(parameter.getType())) {
        continue;
      }
      // skip not param type param
      if ((parameter.isAnnotationPresent(Header.class) || parameter.isAnnotationPresent(ParamHeader.class))
          && !parameter.isAnnotationPresent(Param.class)
          && !parameter.isAnnotationPresent(QueryParam.class)
          && !parameter.isAnnotationPresent(QueryMap.class)) {
        continue;
      }
      if (parameter.isAnnotationPresent(Expensive.class) || parameter.isAnnotationPresent(QueryMap.class)) {
        if (parameter.isAnnotationPresent(QueryMap.class)) {
          if (!(args[i] instanceof Map)) {
            throw new IllegalArgumentException("@QueryMap must annotated on Map type parameter.");
          }
        }
        Codec codec = CodecFactory.findCodec(JsonCodec.class);
        if (bodyType == BodyType.APPLICATION_XML) {
          codec = CodecFactory.findCodec(XmlCodec.class);
        }
        codec.decode(args[i]).forEach((key, value) -> parameterMap
            .put(key, Optional.ofNullable(value).orElse(null)));
      } else if (parameter.isAnnotationPresent(QueryParam.class)) {
        QueryParam queryParam = parameter.getAnnotation(QueryParam.class);
        parameterMap.put(queryParam.name(), args[i]);
      } else {
        Param param = parameter.getAnnotation(Param.class);
        String parameterName = Optional.ofNullable(param).map(Param::value)
            .orElse(parameter.getName());
        parameterMap.put(parameterName, args[i]);
      }
    }
    return parameterMap;
  }

  /**
   * 解析请求头
   */
  static Map resolveHeaders(Method method) {
    Map headerMap = new HashMap<>();
    for (Header header : method.getDeclaringClass().getAnnotationsByType(Header.class)) {
      headerMap.put(header.name(), header.value());
    }
    for (Header header : method.getAnnotationsByType(Header.class)) {
      headerMap.put(header.name(), header.value());
    }
    return headerMap;
  }

  /**
   * 解析参数中的请求头
   */
  static Map resolveParamHeaders(Method method, Object[] args) {
    if (args == null) {
      return Collections.emptyMap();
    }
    Parameter[] parameters = method.getParameters();
    Map headerMap = new HashMap<>(args.length);
    for (int i = 0; i < parameters.length; i++) {
      Parameter parameter = parameters[i];
      if (!parameter.isAnnotationPresent(ParamHeader.class)) {
        continue;
      }
      ParamHeader header = parameter.getAnnotation(ParamHeader.class);
      headerMap.put(header.name(), String.valueOf(args[i]));
    }
    return headerMap;
  }

  /**
   * 解析参数中的查询参数名称
   */
  static Set resolveQueryParameterNames(Method method, Object[] args) {
    Set names = Collections.emptySet();
    for (int i = 0; i < method.getParameters().length; i++) {
      Parameter parameter = method.getParameters()[i];
      if (parameter.isAnnotationPresent(QueryParam.class)) {
        if (names.isEmpty()) {
          names = new LinkedHashSet<>();
        }
        QueryParam queryParam = parameter.getAnnotation(QueryParam.class);
        names.add(queryParam.name());
      } else if (parameter.isAnnotationPresent(QueryMap.class)) {
        if (names.isEmpty()) {
          names = new LinkedHashSet<>();
        }
        if (args[i] != null) {
          for (Object name : ((Map) args[i]).keySet()) {
            names.add(name.toString());
          }
        }
      }
    }
    return names;
  }

  /**
   * 解析请求body
   */
  public static Object resolveBody(Method method, Object[] args) {
    if (args == null) {
      return null;
    }
    Parameter[] parameters = method.getParameters();
    int bodyIndex = -1;
    for (int i = 0; i < parameters.length; i++) {
      Parameter parameter = parameters[i];
      if (parameter.isAnnotationPresent(Body.class)) {
        if (bodyIndex >= 0) {
          throw new IllegalArgumentException(method.getName() + " contains more than one @Body");
        }
        bodyIndex = i;
      }
    }
    return bodyIndex >= 0 ? args[bodyIndex] : null;
  }

  /**
   * 查找callback
   */
  public static CallbackHandler findCallbackHandler(Method method, Object[] args) {
    if (args == null || args.length == 0) {
      return null;
    }
    Parameter[] parameters = method.getParameters();
    int callbackIndex = -1;
    for (int i = 0; i < parameters.length; i++) {
      Parameter parameter = parameters[i];
      if (Callback.class.isAssignableFrom(parameter.getType())) {
        if (callbackIndex >= 0) {
          throw new IllegalArgumentException(method.getName() + " contains more than one Callback parameter");
        }
        callbackIndex = i;
      }
    }
    if (callbackIndex >= 0 && args[callbackIndex] == null) {
      throw new IllegalArgumentException("Callback can not be null");
    }
    return callbackIndex >= 0 ? new CallbackHandler((Callback) args[callbackIndex], parameters[callbackIndex])
        : null;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy