package org.jsondoc.springmvc.scanner.builder; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.LinkedHashSet; import java.util.Set; import org.jsondoc.core.annotation.ApiQueryParam; import org.jsondoc.core.pojo.ApiParamDoc; import org.jsondoc.core.util.JSONDocType; import org.jsondoc.core.util.JSONDocTypeBuilder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ValueConstants; public class SpringQueryParamBuilder { /** * From Spring's documentation: Supported at the type level as well as at * the method level! When used at the type level, all method-level mappings * inherit this parameter restriction * * @param method * @param controller * @return */ public static Set<ApiParamDoc> buildQueryParams(Method method) { Set<ApiParamDoc> apiParamDocs = new LinkedHashSet<ApiParamDoc>(); Class<?> controller = method.getDeclaringClass(); if (controller.isAnnotationPresent(RequestMapping.class)) { RequestMapping requestMapping = controller.getAnnotation(RequestMapping.class); if (requestMapping.params().length > 0) { for (String param : requestMapping.params()) { String[] splitParam = param.split("="); if (splitParam.length > 1) { apiParamDocs.add(new ApiParamDoc(splitParam[0], "", JSONDocTypeBuilder.build(new JSONDocType(), String.class, null), "true", new String[] { splitParam[1] }, null, null)); } else { apiParamDocs.add(new ApiParamDoc(param, "", JSONDocTypeBuilder.build(new JSONDocType(), String.class, null), "true", new String[] {}, null, null)); } } } } if (method.isAnnotationPresent(RequestMapping.class)) { RequestMapping requestMapping = method.getAnnotation(RequestMapping.class); if (requestMapping.params().length > 0) { for (String param : requestMapping.params()) { String[] splitParam = param.split("="); if (splitParam.length > 1) { apiParamDocs.add(new ApiParamDoc(splitParam[0], "", JSONDocTypeBuilder.build(new JSONDocType(), String.class, null), "true", new String[] { splitParam[1] }, null, null)); } else { apiParamDocs.add(new ApiParamDoc(param, "", JSONDocTypeBuilder.build(new JSONDocType(), String.class, null), "true", new String[] {}, null, null)); } } } } Annotation[][] parametersAnnotations = method.getParameterAnnotations(); for (int i = 0; i < parametersAnnotations.length; i++) { RequestParam requestParam = null; ModelAttribute modelAttribute = null; ApiQueryParam apiQueryParam = null; ApiParamDoc apiParamDoc = null; for (Annotation annotation : parametersAnnotations[i]) { if (annotation instanceof RequestParam) { requestParam = (RequestParam) annotation; } if(annotation instanceof ModelAttribute) { modelAttribute = (ModelAttribute) annotation; } if (annotation instanceof ApiQueryParam) { apiQueryParam = (ApiQueryParam) annotation; } if (requestParam != null) { apiParamDoc = new ApiParamDoc(requestParam.value(), "", JSONDocTypeBuilder.build(new JSONDocType(), method.getParameterTypes()[i], method.getGenericParameterTypes()[i]), String.valueOf(requestParam.required()), new String[] {}, null, requestParam.defaultValue().equals(ValueConstants.DEFAULT_NONE) ? "" : requestParam.defaultValue()); mergeApiQueryParamDoc(apiQueryParam, apiParamDoc); } if(modelAttribute != null) { apiParamDoc = new ApiParamDoc(modelAttribute.value(), "", JSONDocTypeBuilder.build(new JSONDocType(), method.getParameterTypes()[i], method.getGenericParameterTypes()[i]), "false", new String[] {}, null, null); mergeApiQueryParamDoc(apiQueryParam, apiParamDoc); } } if(apiParamDoc != null) { apiParamDocs.add(apiParamDoc); } } return apiParamDocs; } /** * Available properties that can be overridden: name, description, required, * allowedvalues, format, defaultvalue. Name is overridden only if it's empty * in the apiParamDoc argument. Description, format and allowedvalues are * copied in any case Default value and required are not overridden: in any * case they are coming from the default values of @RequestParam * * @param apiQueryParam * @param apiParamDoc */ private static void mergeApiQueryParamDoc(ApiQueryParam apiQueryParam, ApiParamDoc apiParamDoc) { if (apiQueryParam != null) { if (apiParamDoc.getName().trim().isEmpty()) { apiParamDoc.setName(apiQueryParam.name()); } apiParamDoc.setDescription(apiQueryParam.description()); apiParamDoc.setAllowedvalues(apiQueryParam.allowedvalues()); apiParamDoc.setFormat(apiQueryParam.format()); } } }