Repository: OpenAPITools/openapi-generator (language: python)

Issue:
[BUG][java] Object with uniqueItems array of string enums causes compile error
#### Bug Report Checklist

- [x] Have you provided a full/minimal spec to reproduce the issue?
- [x] Have you validated the input using an OpenAPI validator ([example](https://apidevtools.org/swagger-parser/online/))?
- [x] Have you [tested with the latest master](https://github.com/OpenAPITools/openapi-generator/wiki/FAQ#how-to-test-with-the-latest-master-of-openapi-generator) to confirm the issue still exists?
- [x] Have you searched for related issues/PRs?
- [x] What's the actual output vs expected output?
- [ ] [Optional] Sponsorship to speed up the bug fix or feature request ([example](https://github.com/OpenAPITools/openapi-generator/issues/6178))

<!--
Please follow the issue template below for bug reports.
Also please indicate in the issue title which language/library is concerned. Eg:  [BUG][JAVA] Bug generating foo with bar 
-->

##### Description

<!-- describe what is the question, suggestion or issue and why this is a problem for you. -->

When trying to generate a Java apache-httpclient client library, I ran into a compile error. The culprit is the following schema definition:
```json
"GetUsersRequestV1": {
  "type": "object",
  "properties": {
    "roles": {
      "uniqueItems": true,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "ROLE1",
          "ROLE2"
        ]
      }
    }
  }
}
```

This causes the generator to output the following code snippet which causes a type mismatch compiler error:
```java
// class GetUsersRequestV1

public Set<RolesEnum> getRoles() {
  return roles;
}

// ...

// In method "toUrlQueryString":

// add `roles` to the URL query string
if (getRoles() != null) {
  int i = 0;
  for (String _item : getRoles()) { // this line is the culprit
    try {
      joiner.add(String.format("%sroles%s%s=%s", prefix, suffix,
          "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix),
          URLEncoder.encode(String.valueOf(_item), "UTF-8").replaceAll("\\+", "%20")));
    } catch (UnsupportedEncodingException e) {
      // Should never happen, UTF-8 is always supported
      throw new RuntimeException(e);
    }
  }
  i++;
}
```

In the highlighted line `for (String _item : getRoles())`, it tries to assign the return value of getRoles (a set of RolesEnum values) to a String which causes the compilation to fail.

The correct contents of the line would be `for (RolesEnum _item : getRoles())`.

I managed to reproduce the issue with the following Java client generators:
* apache-httpclient
* native

##### openapi-generator version

<!-- which version of openapi-generator are you using, is it a regression? -->
Tested with the latest snapshot (7.10.0-SNAPSHOT on commit 008c1a42ef)

##### OpenAPI declaration file content or url

<!-- if it is a bug, a json or yaml that produces it.
If you post the code inline, please wrap it with
```yaml
(here your code)
```
(for YAML code) or
```json
(here your code)
```
(for JSON code), so it becomes more readable. If it is longer than about ten lines,
please create a Gist (https://gist.github.com) or upload it somewhere else and
link it here.
  -->
Minimal example:
```json
{
  "openapi": "3.0.1",
  "info": {
    "title": "Title",
    "description": "Title",
    "version": "1.0.0"
  },
  "servers": [],
  "paths": {},
  "components": {
    "schemas": {
      "GetUsersRequestV1": {
        "type": "object",
        "properties": {
          "roles": {
            "uniqueItems": true,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "ROLE1",
                "ROLE2"
              ]
            }
          }
        }
      }
    }
  }
}
```
Production use case: https://docs.clockify.me/openapi.json

##### Generation Details

<!-- 
    Prefer CLI steps, including the language, libraries and various options. 
    Providing config-based settings allows for simpler testing across CLI and plugins. 
    For examples, see https://github.com/OpenAPITools/openapi-generator/tree/master/bin/configs
-->

I use the following Maven plugin declaration:
```xml
<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>${openapi-generator.version}</version>
    <executions>
        <execution>
            <id>generate-server</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>./test.json</inputSpec>
                <apiPackage>${project.groupId}</apiPackage>
                <modelPackage>${project.groupId}.model</modelPackage>
                <generatorName>java</generatorName>
                <generateApiTests>false</generateApiTests>
                <generateModelTests>false</generateModelTests>
                <configOptions>
                    <library>apache-httpclient</library>
                    <useJakartaEe>true</useJakartaEe>
                    <hideGenerationTimestamp>true</hideGenerationTimestamp>
                    <sourceFolder>target/generated-sources</sourceFolder>
                </configOptions>
            </configuration>
        </execution>
    </executions>
</plugin>
```

##### Steps to reproduce

<!-- unambiguous set of steps to reproduce the bug.-->

* Set up a Maven project with the above Maven config and OpenAPI declaration.
* Execute `mvn clean verify`
* Check the contents of `target/generated-sources/<project groupId>/model/GetUsersRequestV1.java`
* Line 187 contains the relevant compiler error

##### Related issues/PRs

<!-- has a similar issue/PR been reported/opened before? Please do a search in https://github.com/openapitools/openapi-generator/issues?utf8=%E2%9C%93&q=is%3Aissue%20 -->
Haven't seen any

##### Suggest a fix

<!-- if you can't fix the bug yourself, perhaps you can point to what might be
  causing the problem (line of code or commit), or simply make a suggestion -->
I will try to look into this and provide a fix in form of a PR.
[BUG][java] Object with uniqueItems array of string enums causes compile error
#### Bug Report Checklist

- [x] Have you provided a full/minimal spec to reproduce the issue?
- [x] Have you validated the input using an OpenAPI validator ([example](https://apidevtools.org/swagger-parser/online/))?
- [x] Have you [tested with the latest master](https://github.com/OpenAPITools/openapi-generator/wiki/FAQ#how-to-test-with-the-latest-master-of-openapi-generator) to confirm the issue still exists?
- [x] Have you searched for related issues/PRs?
- [x] What's the actual output vs expected output?
- [ ] [Optional] Sponsorship to speed up the bug fix or feature request ([example](https://github.com/OpenAPITools/openapi-generator/issues/6178))

<!--
Please follow the issue template below for bug reports.
Also please indicate in the issue title which language/library is concerned. Eg:  [BUG][JAVA] Bug generating foo with bar 
-->

##### Description

<!-- describe what is the question, suggestion or issue and why this is a problem for you. -->

When trying to generate a Java apache-httpclient client library, I ran into a compile error. The culprit is the following schema definition:
```json
"GetUsersRequestV1": {
  "type": "object",
  "properties": {
    "roles": {
      "uniqueItems": true,
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "ROLE1",
          "ROLE2"
        ]
      }
    }
  }
}
```

This causes the generator to output the following code snippet which causes a type mismatch compiler error:
```java
// class GetUsersRequestV1

public Set<RolesEnum> getRoles() {
  return roles;
}

// ...

// In method "toUrlQueryString":

// add `roles` to the URL query string
if (getRoles() != null) {
  int i = 0;
  for (String _item : getRoles()) { // this line is the culprit
    try {
      joiner.add(String.format("%sroles%s%s=%s", prefix, suffix,
          "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix),
          URLEncoder.encode(String.valueOf(_item), "UTF-8").replaceAll("\\+", "%20")));
    } catch (UnsupportedEncodingException e) {
      // Should never happen, UTF-8 is always supported
      throw new RuntimeException(e);
    }
  }
  i++;
}
```

In the highlighted line `for (String _item : getRoles())`, it tries to assign the return value of getRoles (a set of RolesEnum values) to a String which causes the compilation to fail.

The correct contents of the line would be `for (RolesEnum _item : getRoles())`.

I managed to reproduce the issue with the following Java client generators:
* apache-httpclient
* native

##### openapi-generator version

<!-- which version of openapi-generator are you using, is it a regression? -->
Tested with the latest snapshot (7.10.0-SNAPSHOT on commit 008c1a42ef)

##### OpenAPI declaration file content or url

<!-- if it is a bug, a json or yaml that produces it.
If you post the code inline, please wrap it with
```yaml
(here your code)
```
(for YAML code) or
```json
(here your code)
```
(for JSON code), so it becomes more readable. If it is longer than about ten lines,
please create a Gist (https://gist.github.com) or upload it somewhere else and
link it here.
  -->
Minimal example:
```json
{
  "openapi": "3.0.1",
  "info": {
    "title": "Title",
    "description": "Title",
    "version": "1.0.0"
  },
  "servers": [],
  "paths": {},
  "components": {
    "schemas": {
      "GetUsersRequestV1": {
        "type": "object",
        "properties": {
          "roles": {
            "uniqueItems": true,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "ROLE1",
                "ROLE2"
              ]
            }
          }
        }
      }
    }
  }
}
```
Production use case: https://docs.clockify.me/openapi.json

##### Generation Details

<!-- 
    Prefer CLI steps, including the language, libraries and various options. 
    Providing config-based settings allows for simpler testing across CLI and plugins. 
    For examples, see https://github.com/OpenAPITools/openapi-generator/tree/master/bin/configs
-->

I use the following Maven plugin declaration:
```xml
<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>${openapi-generator.version}</version>
    <executions>
        <execution>
            <id>generate-server</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>./test.json</inputSpec>
                <apiPackage>${project.groupId}</apiPackage>
                <modelPackage>${project.groupId}.model</modelPackage>
                <generatorName>java</generatorName>
                <generateApiTests>false</generateApiTests>
                <generateModelTests>false</generateModelTests>
                <configOptions>
                    <library>apache-httpclient</library>
                    <useJakartaEe>true</useJakartaEe>
                    <hideGenerationTimestamp>true</hideGenerationTimestamp>
                    <sourceFolder>target/generated-sources</sourceFolder>
                </configOptions>
            </configuration>
        </execution>
    </executions>
</plugin>
```

##### Steps to reproduce

<!-- unambiguous set of steps to reproduce the bug.-->

* Set up a Maven project with the above Maven config and OpenAPI declaration.
* Execute `mvn clean verify`
* Check the contents of `target/generated-sources/<project groupId>/model/GetUsersRequestV1.java`
* Line 187 contains the relevant compiler error

##### Related issues/PRs

<!-- has a similar issue/PR been reported/opened before? Please do a search in https://github.com/openapitools/openapi-generator/issues?utf8=%E2%9C%93&q=is%3Aissue%20 -->
Haven't seen any

##### Suggest a fix

<!-- if you can't fix the bug yourself, perhaps you can point to what might be
  causing the problem (line of code or commit), or simply make a suggestion -->
I will try to look into this and provide a fix in form of a PR.


Discussion / hints:

Fix patch:
diff --git a/modules/openapi-generator/src/main/resources/Java/pojo.mustache b/modules/openapi-generator/src/main/resources/Java/pojo.mustache
index 0de3f814b8a7..09482dd66e66 100644
--- a/modules/openapi-generator/src/main/resources/Java/pojo.mustache
+++ b/modules/openapi-generator/src/main/resources/Java/pojo.mustache
@@ -395,7 +395,7 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens
     {{#uniqueItems}}
     if ({{getter}}() != null) {
       int i = 0;
-      for ({{{items.dataType}}} _item : {{getter}}()) {
+      for ({{{items.datatypeWithEnum}}} _item : {{getter}}()) {
         try {
           joiner.add(String.format("%s{{baseName}}%s%s=%s", prefix, suffix,
               "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix),


Test patch:
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/apachehttpclient/ApacheHttpClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/apachehttpclient/ApacheHttpClientCodegenTest.java
index 2ecf67b896ac..909e073e7da8 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/apachehttpclient/ApacheHttpClientCodegenTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/apachehttpclient/ApacheHttpClientCodegenTest.java
@@ -90,4 +90,28 @@ public void testApacheHttpClientExplodedQueryParamWithArrayProperty() throws IOE
             "localVarQueryParams.addAll(apiClient.parameterToPairs(\"multi\", \"values\", queryObject.getValues()))"
         );
     }
+
+    @Test
+    void testApacheHttpClientQueryParamHandlingUniqueItemsStringEnum() throws IOException {
+        // Arrange
+        var output = Files.createTempDirectory("test").toFile();
+        output.deleteOnExit();
+
+        var configurator = new CodegenConfigurator()
+                .setGeneratorName("java")
+                .setLibrary(JavaClientCodegen.APACHE)
+                .setInputSpec("src/test/resources/3_0/unique-items-string-enum.yaml")
+                .setOutputDir(output.getAbsolutePath().replace("\\", "/"));
+
+        final ClientOptInput clientOptInput = configurator.toClientOptInput();
+        DefaultGenerator generator = new DefaultGenerator();
+
+        // Act
+        var files = generator.opts(clientOptInput).generate();
+
+        // Assert
+        TestUtils.assertFileContains(Paths.get(output + "/src/main/java/org/openapitools/client/model/GetUsersRequestV1.java"),
+                "for (RolesEnum _item : getRoles()) {"
+        );
+    }
 }
diff --git a/modules/openapi-generator/src/test/resources/3_0/unique-items-string-enum.yaml b/modules/openapi-generator/src/test/resources/3_0/unique-items-string-enum.yaml
new file mode 100644
index 000000000000..e8572229f814
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_0/unique-items-string-enum.yaml
@@ -0,0 +1,20 @@
+openapi: 3.0.1
+info:
+  title: Sample API to test generation of schemas with uniqueItems arrays of enums
+  description: API description in Markdown.
+  version: 1.0.0
+servers: []
+paths: {}
+components:
+  schemas:
+    GetUsersRequestV1:
+      type: object
+      properties:
+        roles:
+          uniqueItems: true
+          type: array
+          items:
+            type: string
+            enum:
+              - ROLE1
+              - ROLE2