/**
  * Is this action input parameter required.
  *
  * @return true if required
  */
 public boolean isRequired() {
   boolean ret;
   if (isRequestBody()) {
     ret = requestBody.required();
   } else if (isRequestParam()) {
     ret = !(isDefined(requestParam.defaultValue()) || !requestParam.required());
   } else if (isRequestHeader()) {
     ret = !(isDefined(requestHeader.defaultValue()) || !requestHeader.required());
   } else {
     ret = true;
   }
   return ret;
 }
 /**
  * Determines default value of request param or request header, if available.
  *
  * @return value or null
  */
 public String getDefaultValue() {
   String ret;
   if (isRequestParam()) {
     ret = isDefined(requestParam.defaultValue()) ? requestParam.defaultValue() : null;
   } else if (isRequestHeader()) {
     ret =
         !(ValueConstants.DEFAULT_NONE.equals(requestHeader.defaultValue()))
             ? requestHeader.defaultValue()
             : null;
   } else {
     ret = null;
   }
   return ret;
 }
  @SuppressWarnings("unchecked")
  private Object[] resolveHandlerArguments(
      Method handlerMethod,
      Object handler,
      NativeWebRequest webRequest,
      ExtendedModelMap implicitModel)
      throws Exception {

    Class[] paramTypes = handlerMethod.getParameterTypes();
    Object[] args = new Object[paramTypes.length];

    for (int i = 0; i < args.length; i++) {
      MethodParameter methodParam = new MethodParameter(handlerMethod, i);
      methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
      GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());
      String paramName = null;
      String headerName = null;
      boolean requestBodyFound = false;
      String cookieName = null;
      String pathVarName = null;
      String attrName = null;
      boolean required = false;
      String defaultValue = null;
      boolean validate = false;
      int found = 0;
      Annotation[] paramAnns = methodParam.getParameterAnnotations();

      for (Annotation paramAnn : paramAnns) {
        if (RequestParam.class.isInstance(paramAnn)) {
          RequestParam requestParam = (RequestParam) paramAnn;
          paramName = requestParam.value();
          required = requestParam.required();
          defaultValue = requestParam.defaultValue();
          found++;
        } else if (RequestHeader.class.isInstance(paramAnn)) {
          RequestHeader requestHeader = (RequestHeader) paramAnn;
          headerName = requestHeader.value();
          required = requestHeader.required();
          defaultValue = requestHeader.defaultValue();
          found++;
        } else if (RequestBody.class.isInstance(paramAnn)) {
          requestBodyFound = true;
          found++;
        } else if (CookieValue.class.isInstance(paramAnn)) {
          CookieValue cookieValue = (CookieValue) paramAnn;
          cookieName = cookieValue.value();
          required = cookieValue.required();
          defaultValue = cookieValue.defaultValue();
          found++;
        } else if (PathVariable.class.isInstance(paramAnn)) {
          PathVariable pathVar = (PathVariable) paramAnn;
          pathVarName = pathVar.value();
          found++;
        } else if (ModelAttribute.class.isInstance(paramAnn)) {
          ModelAttribute attr = (ModelAttribute) paramAnn;
          attrName = attr.value();
          found++;
        } else if (Value.class.isInstance(paramAnn)) {
          defaultValue = ((Value) paramAnn).value();
        } else if ("Valid".equals(paramAnn.annotationType().getSimpleName())) {
          validate = true;
        }
      }

      if (found > 1) {
        throw new IllegalStateException(
            "Handler parameter annotations are exclusive choices - "
                + "do not specify more than one such annotation on the same parameter: "
                + handlerMethod);
      }

      if (found == 0) {
        Object argValue = resolveCommonArgument(methodParam, webRequest);
        if (argValue != WebArgumentResolver.UNRESOLVED) {
          args[i] = argValue;
        } else if (defaultValue != null) {
          args[i] = resolveDefaultValue(defaultValue);
        } else {
          Class paramType = methodParam.getParameterType();
          if (Model.class.isAssignableFrom(paramType) || Map.class.isAssignableFrom(paramType)) {
            args[i] = implicitModel;
          } else if (SessionStatus.class.isAssignableFrom(paramType)) {
            args[i] = this.sessionStatus;
          } else if (Errors.class.isAssignableFrom(paramType)) {
            throw new IllegalStateException(
                "Errors/BindingResult argument declared "
                    + "without preceding model attribute. Check your handler method signature!");
          } else if (BeanUtils.isSimpleProperty(paramType)) {
            paramName = "";
          } else {
            attrName = "";
          }
        }
      }

      if (paramName != null) {
        args[i] =
            resolveRequestParam(
                paramName, required, defaultValue, methodParam, webRequest, handler);
      } else if (headerName != null) {
        args[i] =
            resolveRequestHeader(
                headerName, required, defaultValue, methodParam, webRequest, handler);
      } else if (requestBodyFound) {
        args[i] = resolveRequestBody(methodParam, webRequest, handler);
      } else if (cookieName != null) {
        args[i] =
            resolveCookieValue(
                cookieName, required, defaultValue, methodParam, webRequest, handler);
      } else if (pathVarName != null) {
        args[i] = resolvePathVariable(pathVarName, methodParam, webRequest, handler);
      } else if (attrName != null) {
        WebDataBinder binder =
            resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);
        boolean assignBindingResult =
            (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));
        if (binder.getTarget() != null) {
          doBind(binder, webRequest, validate, !assignBindingResult);
        }
        args[i] = binder.getTarget();
        if (assignBindingResult) {
          args[i + 1] = binder.getBindingResult();
          i++;
        }
        implicitModel.putAll(binder.getBindingResult().getModel());
      }
    }

    return args;
  }
 @Override
 public String getRequestHeaderName() {
   return isRequestHeader() ? requestHeader.value() : null;
 }