/**
  * @param name
  * @return
  * @throws Exception
  */
 @RequestMapping(value = "/greeting2", method = RequestMethod.GET)
 @ResponseBody
 public String greeting2(
     @RequestParam(value = "name", required = false, defaultValue = "World") String name)
     throws Exception {
   GroovyScriptEngine engine = new GroovyScriptEngine("src\\main\\groovy");
   Class aClass = engine.loadScriptByName("hello/Greeter.groovy");
   IGreeter greeter = (IGreeter) aClass.newInstance();
   return greeter.sayHello();
 }
 private boolean isAnnotationPresent(
     Annotation[] annotations, Class<? extends Annotation> annotationClass) {
   for (Annotation annotation : annotations) {
     if (annotationClass.isInstance(annotation)) {
       return true;
     }
   }
   return false;
 }
 /**
  * Allows convenient access to multiple call values in case that this input parameter is an array
  * or collection. Make sure to check {@link #isArrayOrCollection()} before calling this method.
  *
  * @return call values
  * @throws UnsupportedOperationException if this input parameter is not an array or collection
  */
 public Object[] getCallValues() {
   Object[] callValues;
   if (!isArrayOrCollection()) {
     throw new UnsupportedOperationException("parameter is not an array or collection");
   }
   Object callValue = getCallValue();
   if (callValue == null) {
     callValues = new Object[0];
   } else {
     Class<?> parameterType = getParameterType();
     if (parameterType.isArray()) {
       callValues = (Object[]) callValue;
     } else {
       callValues = ((Collection<?>) callValue).toArray();
     }
   }
   return callValues;
 }
  private String getValue(Annotation[] annotations, Class<? extends Annotation> annotationClass) {
    for (Annotation annotation : annotations) {
      if (annotationClass.isInstance(annotation)) {
        Method valueMethod = ReflectionUtils.findMethod(annotationClass, "value");
        if (valueMethod != null) {
          return (String) ReflectionUtils.invokeMethod(valueMethod, annotation);
        } else {
          return null;
        }
      }
    }

    return null;
  }
  @Override
  public RestMethodMetadata parse(Class<?> clientClass, Method method) {
    RestMethodMetadata metadata = new RestMethodMetadata();

    RequestMapping classMapping = clientClass.getAnnotation(RequestMapping.class);
    RequestMapping methodMapping = method.getAnnotation(RequestMapping.class);

    metadata.setCommonPath(getPath(classMapping));
    metadata.setAdditionalPath(getPath(methodMapping));
    metadata.setHttpMethod(getHttpMethod(classMapping, methodMapping));
    metadata.setResponseClass(getResponseType(method));
    metadata.setMethodReturnType(method.getReturnType());
    metadata.setRequestHeaderParameters(getParametersWithAnnotation(method, RequestHeader.class));
    metadata.setUriVarParameters(getParametersWithAnnotation(method, PathVariable.class));
    metadata.setQueryParameters(getParametersWithAnnotation(method, RequestParam.class));
    metadata.setRequestParameter(getRequestParameter(method));

    return metadata;
  }
  private Object[] getPossibleValues(
      MethodParameter methodParameter, AnnotatedParameters actionDescriptor) {
    try {
      Class<?> parameterType = methodParameter.getNestedParameterType();
      Object[] possibleValues;
      Class<?> nested;
      if (Enum[].class.isAssignableFrom(parameterType)) {
        possibleValues = parameterType.getComponentType().getEnumConstants();
      } else if (Enum.class.isAssignableFrom(parameterType)) {
        possibleValues = parameterType.getEnumConstants();
      } else if (Collection.class.isAssignableFrom(parameterType)
          && Enum.class.isAssignableFrom(
              nested = TypeDescriptor.nested(methodParameter, 1).getType())) {
        possibleValues = nested.getEnumConstants();
      } else {
        Select select = methodParameter.getParameterAnnotation(Select.class);
        if (select != null) {
          Class<? extends Options> optionsClass = select.options();
          Options options = optionsClass.newInstance();
          // collect call values to pass to options.get
          List<Object> from = new ArrayList<Object>();
          for (String paramName : select.args()) {
            AnnotatedParameter parameterValue = actionDescriptor.getAnnotatedParameter(paramName);
            if (parameterValue != null) {
              from.add(parameterValue.getCallValue());
            }
          }

          Object[] args = from.toArray();
          possibleValues = options.get(select.value(), args);
        } else {
          possibleValues = new Object[0];
        }
      }
      return possibleValues;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }