@@ -122,6 +122,7 @@ object SpringModelUtils {
122122 private val requestMappingClassId = ClassId (" org.springframework.web.bind.annotation.RequestMapping" )
123123 private val pathVariableClassId = ClassId (" org.springframework.web.bind.annotation.PathVariable" )
124124 private val requestBodyClassId = ClassId (" org.springframework.web.bind.annotation.RequestBody" )
125+ private val requestParamClassId = ClassId (" org.springframework.web.bind.annotation.RequestParam" )
125126 private val uriComponentsBuilderClassId = ClassId (" org.springframework.web.util.UriComponentsBuilder" )
126127 private val mediaTypeClassId = ClassId (" org.springframework.http.MediaType" )
127128 private val mockHttpServletResponseClassId = ClassId (" org.springframework.mock.web.MockHttpServletResponse" )
@@ -283,15 +284,17 @@ object SpringModelUtils {
283284 @Suppress(" UNCHECKED_CAST" )
284285 val classRequestMappingAnnotation: Annotation ? =
285286 methodId.classId.jClass.getAnnotation(requestMappingClassId.jClass as Class <out Annotation >)
286- val cassRequestPath = classRequestMappingAnnotation?.let { getRequestPathOrNull(it) }.orEmpty()
287+ val classRequestPath = classRequestMappingAnnotation?.let { getRequestPathOrNull(it) }.orEmpty()
287288
288- val requestPath = cassRequestPath + (getRequestPathOrNull(requestMappingAnnotation) ? : return null )
289+ val requestPath = classRequestPath + (getRequestPathOrNull(requestMappingAnnotation) ? : return null )
289290
290291 val pathVariablesModel = createPathVariablesModel(methodId, arguments, idGenerator)
291292
292- val urlTemplateModel = createUrlTemplateModel(pathVariablesModel, requestPath , idGenerator)
293+ val requestParamsModel = createRequestParamsModel(methodId, arguments , idGenerator)
293294
294- val requestBuilderModel = UtAssembleModel (
295+ val urlTemplateModel = createUrlTemplateModel(pathVariablesModel, requestParamsModel, requestPath, idGenerator)
296+
297+ var requestBuilderModel = UtAssembleModel (
295298 id = idGenerator(),
296299 classId = mockHttpServletRequestBuilderClassId,
297300 modelName = " requestBuilder" ,
@@ -405,16 +408,7 @@ object SpringModelUtils {
405408 arguments : List <UtModel >,
406409 idGenerator : () -> Int
407410 ): UtAssembleModel {
408- val pathVariables = mutableMapOf<String , UtModel >()
409-
410- methodId.method.parameters.zip(arguments).forEach { (param, arg) ->
411- @Suppress(" UNCHECKED_CAST" ) val pathVariableAnnotation =
412- param.getAnnotation(pathVariableClassId.jClass as Class <out Annotation >) ? : return @forEach
413- val name = (pathVariableClassId.jClass.getMethod(" name" ).invoke(pathVariableAnnotation) as ? String ).orEmpty()
414- .ifEmpty { pathVariableClassId.jClass.getMethod(" value" ).invoke(pathVariableAnnotation) as ? String }.orEmpty()
415- .ifEmpty { param.name }
416- pathVariables[name] = arg
417- }
411+ val pathVariables = collectArgumentsWithAnnotationModels(methodId, pathVariableClassId, arguments)
418412
419413 // TODO filter out `null` and `Optional.empty()` values of `arg`
420414 return UtAssembleModel (
@@ -442,15 +436,73 @@ object SpringModelUtils {
442436 )
443437 }
444438
439+ private fun createRequestParamsModel (
440+ methodId : MethodId ,
441+ arguments : List <UtModel >,
442+ idGenerator : () -> Int
443+ ): List < Pair <UtPrimitiveModel , UtAssembleModel > > {
444+ val requestParams = collectArgumentsWithAnnotationModels(methodId, requestParamClassId, arguments)
445+
446+ // TODO filter out `null` and `Optional.empty()` values of `arg`
447+ return requestParams.map { (name, value) ->
448+ Pair (UtPrimitiveModel (name),
449+ UtAssembleModel (
450+ id = idGenerator(),
451+ classId = listClassId,
452+ modelName = " queryParams" ,
453+ instantiationCall = UtExecutableCallModel (
454+ instance = null ,
455+ executable = constructorId(java.util.ArrayList ::class .id),
456+ params = emptyList()
457+ ),
458+ modificationsChainProvider = {
459+ listOf (
460+ UtExecutableCallModel (
461+ instance = this ,
462+ executable = methodId(
463+ classId = listClassId,
464+ name = " add" ,
465+ returnType = booleanClassId,
466+ arguments = arrayOf(Object ::class .id),
467+ ),
468+ params = listOf (value)
469+ )
470+ )
471+ }
472+ )
473+ )
474+ }
475+ }
476+
477+ private fun collectArgumentsWithAnnotationModels (
478+ methodId : MethodId ,
479+ annotationClassId : ClassId ,
480+ arguments : List <UtModel >
481+ ): MutableMap <String , UtModel > {
482+ val argumentsModels = mutableMapOf<String , UtModel >()
483+
484+ methodId.method.parameters.zip(arguments).forEach { (param, arg) ->
485+ @Suppress(" UNCHECKED_CAST" ) val paramAnnotation =
486+ param.getAnnotation(annotationClassId.jClass as Class <out Annotation >) ? : return @forEach
487+ val name = (annotationClassId.jClass.getMethod(" name" ).invoke(paramAnnotation) as ? String ).orEmpty()
488+ .ifEmpty { annotationClassId.jClass.getMethod(" value" ).invoke(paramAnnotation) as ? String }.orEmpty()
489+ .ifEmpty { param.name }
490+ argumentsModels[name] = arg
491+ }
492+
493+ return argumentsModels
494+ }
495+
445496 private fun createUrlTemplateModel (
446497 pathVariablesModel : UtAssembleModel ,
498+ requestParamModel : List <Pair <UtPrimitiveModel , UtAssembleModel >>,
447499 requestPath : String ,
448500 idGenerator : () -> Int
449501 ): UtModel {
450502 val requestPathModel = UtPrimitiveModel (requestPath)
451- return if (pathVariablesModel.modificationsChain.isEmpty()) requestPathModel
503+ return if (pathVariablesModel.modificationsChain.isEmpty() && requestParamModel.isEmpty() ) requestPathModel
452504 else {
453- val uriBuilderFromPath = UtAssembleModel (
505+ var uriBuilderFromPath = UtAssembleModel (
454506 id = idGenerator(),
455507 classId = uriComponentsBuilderClassId,
456508 modelName = " uriBuilderFromPath" ,
@@ -465,27 +517,49 @@ object SpringModelUtils {
465517 params = listOf (requestPathModel),
466518 )
467519 )
468- val uriBuilderWithPathVariables = UtAssembleModel (
469- id = idGenerator(),
470- classId = uriComponentsBuilderClassId,
471- modelName = " uriBuilderWithPathVariables" ,
472- instantiationCall = UtExecutableCallModel (
473- instance = uriBuilderFromPath,
474- executable = MethodId (
475- classId = uriComponentsBuilderClassId,
476- name = " uriVariables" ,
477- parameters = listOf (Map ::class .java.id),
478- returnType = uriComponentsBuilderClassId
479- ),
480- params = listOf (pathVariablesModel),
520+
521+ if (pathVariablesModel.modificationsChain.isNotEmpty()) {
522+ uriBuilderFromPath = UtAssembleModel (
523+ id = idGenerator(),
524+ classId = uriComponentsBuilderClassId,
525+ modelName = " uriBuilderWithPathVariables" ,
526+ instantiationCall = UtExecutableCallModel (
527+ instance = uriBuilderFromPath,
528+ executable = MethodId (
529+ classId = uriComponentsBuilderClassId,
530+ name = " uriVariables" ,
531+ parameters = listOf (Map ::class .java.id),
532+ returnType = uriComponentsBuilderClassId
533+ ),
534+ params = listOf (pathVariablesModel),
535+ )
481536 )
482- )
483- UtAssembleModel (
537+ }
538+
539+ requestParamModel.forEach { (name, value) ->
540+ uriBuilderFromPath = UtAssembleModel (
541+ id = idGenerator(),
542+ classId = uriComponentsBuilderClassId,
543+ modelName = " uriBuilderWithRequestParam" ,
544+ instantiationCall = UtExecutableCallModel (
545+ instance = uriBuilderFromPath,
546+ executable = MethodId (
547+ classId = uriComponentsBuilderClassId,
548+ name = " queryParam" ,
549+ parameters = listOf (stringClassId, collectionClassId),
550+ returnType = uriComponentsBuilderClassId
551+ ),
552+ params = listOf (name, value),
553+ )
554+ )
555+ }
556+
557+ return UtAssembleModel (
484558 id = idGenerator(),
485559 classId = stringClassId,
486560 modelName = " uriString" ,
487561 instantiationCall = UtExecutableCallModel (
488- instance = uriBuilderWithPathVariables ,
562+ instance = uriBuilderFromPath ,
489563 executable = MethodId (
490564 classId = uriComponentsBuilderClassId,
491565 name = " toUriString" ,
0 commit comments