Repository: springdoc/springdoc-openapi (java)

Issue:
Type-use annotations are not picked up when used in defining parameters
I have a use case in which I am using type-use annotations for parameters.
Take following example:

```java
    @PostMapping("euroMillions")
    public ResponseEntity<String> euroMillions(@Parameter(description = "the numbers")
                                               @RequestParam @Size(min = 5, max = 5) List<@Max(50) @Min(1) Integer> numbers,
                                               @Parameter(description = "the stars")
                                               @RequestParam @Size(min = 2, max = 2) List<@Max(12) @Min(1) Integer> stars) {
        return ResponseEntity.ok("ok");
    }
```

I am expecting to see the `@Max` and `@Min` translated to maximum and minimum properties in the Openapi-definition, but instead it translates to:

```json
        "parameters": [
          {
            "name": "numbers",
            "in": "query",
            "description": "the numbers",
            "required": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int32",
>>>> maximum and minimum properties are missing
              },
              "maxItems": 5,
              "minItems": 5
            }
          },
          {
            "name": "stars",
            "in": "query",
            "description": "the stars",
            "required": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int32",
>>>> maximum and minimum properties are missing
              },
              "maxItems": 2,
              "minItems": 2
            }
          }
        ]
```

If I move away from the parameters and make a RequestBody like so:

```java
    @PostMapping("euroMillions2")
    public ResponseEntity<String> euroMillions2(@RequestBody LotteryTicket lotteryTicket) {
        return ResponseEntity.ok("ok");
    }
```
```java
public class LotteryTicket {

    @Size(min = 5, max = 5)
    private List<@Max(50) @Min(1) Integer> numbers;
    
    @Size(min = 2, max = 2) 
    private List<@Max(12) @Min(1) Integer> stars;
}
```
The definition is correctly processed and the minimum and maximum properties are set for the lotteryTicket-schema:
```json
  "components": {
    "schemas": {
      "LotteryTicket": {
        "type": "object",
        "properties": {
          "numbers": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32",
              "maximum": 50,
              "minimum": 1
            },
            "maxItems": 5,
            "minItems": 5
          },
          "stars": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32",
              "maximum": 12,
              "minimum": 1
            },
            "maxItems": 2,
            "minItems": 2
          }
        }
      }
    }
  }
```

I tested this on the latest snapshot-version of springdoc: 2.8.9-SNAPSHOT


Pull request:
feat: type-use for method parameters
Closes #3000 

Patch:
diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java
index df1d7a0e3..466f67c57 100644
--- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java
+++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java
@@ -617,9 +617,18 @@ public abstract class AbstractRequestService {
 		if (annotations != null) {
 			Schema<?> schema = parameter.getSchema();
 			SchemaUtils.applyValidationsToSchema(schema, annotations);
-			if (schema instanceof ArraySchema && isParameterObject && methodParameter instanceof DelegatingMethodParameter mp) {
-				Field field = mp.getField();
-				if (field != null && field.getAnnotatedType() instanceof AnnotatedParameterizedType paramType) {
+			if (schema instanceof ArraySchema && methodParameter instanceof DelegatingMethodParameter mp) {
+				java.lang.reflect.AnnotatedType annotatedType = null;
+				if (isParameterObject) {
+					Field field = mp.getField();
+					if (field != null) {
+						annotatedType = field.getAnnotatedType();
+					}
+				} else {
+					java.lang.reflect.Parameter param = mp.getParameter();
+					annotatedType = param.getAnnotatedType();
+				}
+				if (annotatedType instanceof AnnotatedParameterizedType paramType) {
 					java.lang.reflect.AnnotatedType[] typeArgs = paramType.getAnnotatedActualTypeArguments();
 					for (java.lang.reflect.AnnotatedType typeArg : typeArgs) {
 						List<Annotation> genericAnnotations = Arrays.stream(typeArg.getAnnotations()).toList();


Test patch:
diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app19/SpringDocApp19Test.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app19/SpringDocApp19Test.kt
new file mode 100644
index 000000000..aa1aa2085
--- /dev/null
+++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app19/SpringDocApp19Test.kt
@@ -0,0 +1,57 @@
+/*
+ *
+ *  * Copyright 2019-2020 the original author or authors.
+ *  *
+ *  * 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
+ *  *
+ *  *      https://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 test.org.springdoc.api.v31.app19
+
+import io.swagger.v3.oas.annotations.Parameter
+import jakarta.validation.constraints.Max
+import jakarta.validation.constraints.Min
+import jakarta.validation.constraints.Size
+import org.springframework.boot.autoconfigure.SpringBootApplication
+import org.springframework.http.ResponseEntity
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RequestParam
+import org.springframework.web.bind.annotation.RestController
+import test.org.springdoc.api.v31.AbstractKotlinSpringDocMVCTest
+
+
+class SpringDocApp19Test : AbstractKotlinSpringDocMVCTest() {
+    @SpringBootApplication
+    class DemoApplication
+}
+
+@RestController
+@RequestMapping
+class HelloController {
+
+    @PostMapping("euroMillions")
+    fun euroMillions(
+        @Parameter(description = "the numbers")
+        @RequestParam
+        @Size(min = 5, max = 5)
+        numbers: List<@Max(50) @Min(1) Int>,
+
+        @Parameter(description = "the stars")
+        @RequestParam
+        @Size(min = 2, max = 2)
+        stars: List<@Max(12) @Min(1) Int>
+    ): ResponseEntity<String> {
+        return ResponseEntity.ok("ok")
+    }
+}
\ No newline at end of file
diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app19.json b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app19.json
new file mode 100644
index 000000000..3b6d85058
--- /dev/null
+++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app19.json
@@ -0,0 +1,72 @@
+{
+  "openapi": "3.1.0",
+  "info": {
+    "title": "OpenAPI definition",
+    "version": "v0"
+  },
+  "servers": [
+    {
+      "url": "http://localhost",
+      "description": "Generated server url"
+    }
+  ],
+  "paths": {
+    "/euroMillions": {
+      "post": {
+        "tags": [
+          "hello-controller"
+        ],
+        "operationId": "euroMillions",
+        "parameters": [
+          {
+            "name": "numbers",
+            "in": "query",
+            "description": "the numbers",
+            "required": true,
+            "schema": {
+              "type": "array",
+              "items": {
+                "type": "integer",
+                "format": "int32",
+                "maximum": 50,
+                "minimum": 1
+              },
+              "maxItems": 5,
+              "minItems": 5
+            }
+          },
+          {
+            "name": "stars",
+            "in": "query",
+            "description": "the stars",
+            "required": true,
+            "schema": {
+              "type": "array",
+              "items": {
+                "type": "integer",
+                "format": "int32",
+                "maximum": 12,
+                "minimum": 1
+              },
+              "maxItems": 2,
+              "minItems": 2
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "type": "string"
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  },
+  "components": {}
+}