Skip to content

fix(java): generate correct enum constructor when string format is uri#16929

Merged
wing328 merged 1 commit intoOpenAPITools:masterfrom
hhomar:enum-with-uri-format
Nov 7, 2023
Merged

fix(java): generate correct enum constructor when string format is uri#16929
wing328 merged 1 commit intoOpenAPITools:masterfrom
hhomar:enum-with-uri-format

Conversation

@hhomar
Copy link
Contributor

@hhomar hhomar commented Oct 28, 2023

Using the following spec:

openapi: 3.0.0
info:
  title: Sample API
  description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
  version: 0.1.9
servers:
  - url: http://api.example.com/v1
    description: Optional server description, e.g. Main (production) server
paths:
  /users:
    post:
      summary: Creates a user.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                dataSchema:
                  type: string
                  format: uri
                  default: https://example.com/v1/schema.json
                  enum:
                    - https://example.com/v1/schema.json
                    - https://example.com/v2/schema.json

      responses: 
        '201':
          description: Created

The generated DataSchemaEnum is:

public enum DataSchemaEnum {
    COM_V1_SCHEMA_JSON("https://example.com/v1/schema.json"), 
    COM_V2_SCHEMA_JSON("https://example.com/v2/schema.json");
                                                                                      
    private URI value;                                                                
                                                                                      
    DataSchemaEnum(URI value) {
      this.value = value;
    }
}

private DataSchemaEnum dataSchema = URI.create("https://example.com/v1/schema.json");

Causing the following compilation errors:

[ERROR] incompatible types: java.lang.String cannot be converted to java.net.URI
[ERROR] incompatible types: java.net.URI cannot be converted to org.openapitools.client.model.UsersPostRequest.DataSchemaEnum

With the fix applied:

public enum DataSchemaEnum {
    COM_V1_SCHEMA_JSON(URI.create("https://example.com/v1/schema.json"),
    COM_V2_SCHEMA_JSON(URI.create("https://example.com/v2/schema.json");

    private URI value;                                                                
                                                                                      
    DataSchemaEnum(URI value) {
      this.value = value;
    }
}

private DataSchemaEnum dataSchema = DataSchemaEnum.COM_V1_SCHEMA_JSON;

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package 
    ./bin/generate-samples.sh ./bin/configs/*.yaml
    ./bin/utils/export_docs_generators.sh
    
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    For Windows users, please run the script in Git BASH.
  • File the PR against the correct branch: master (upcoming 7.1.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@bbdouglas (2017/07) @sreeshas (2017/08) @jfiala (2017/08) @lukoyanov (2017/09) @cbornet (2017/09) @jeff9finger (2018/01) @karismann (2019/03) @Zomzog (2019/04) @lwlee2608 (2019/10) @martin-mfg (2023/08)

@wing328
Copy link
Member

wing328 commented Oct 30, 2023

I did a test with the spec you provided but got the following errors:

[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /private/tmp/enum/src/main/java/org/openapitools/client/model/UsersPostRequest.java:[91,18] error: no suitable method found for value(URI)
    method JsonWriter.value(String) is not applicable
      (argument mismatch; URI cannot be converted to String)
    method JsonWriter.value(boolean) is not applicable
      (argument mismatch; URI cannot be converted to boolean)
    method JsonWriter.value(Boolean) is not applicable
      (argument mismatch; URI cannot be converted to Boolean)
    method JsonWriter.value(float) is not applicable
      (argument mismatch; URI cannot be converted to float)
    method JsonWriter.value(double) is not applicable
      (argument mismatch; URI cannot be converted to double)
    method JsonWriter.value(long) is not applicable
      (argument mismatch; URI cannot be converted to long)
    method JsonWriter.value(Number) is not applicable
      (argument mismatch; URI cannot be converted to Number)
[ERROR] /private/tmp/enum/src/main/java/org/openapitools/client/model/UsersPostRequest.java:[96,31] error: cannot find symbol
  symbol:   method nextURI()
  location: variable jsonReader of type JsonReader
[INFO] 2 errors 

Did you get the same issue in your environment?

command: java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i /tmp/a.yaml -o /tmp/enum/

@hhomar
Copy link
Contributor Author

hhomar commented Nov 4, 2023

Hi

I was testing with:

java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java --library resttemplate -i /tmp/a.yaml -o /tmp/enum

Sorry, I wasn't aware that the enum model was generated differently depending on the library. I guess this should have gone to the Java Spring team.

I've dug into it a bit and found the issue in the Java/modelEnum.mustache and Java/modelInnerEnum.mustache templates. I've updated the templates to check for isUri and now they generate the correct code:

public static class Adapter extends TypeAdapter<DataSchemaEnum> {
    @Override
    public void write(final JsonWriter jsonWriter, final DataSchemaEnum enumeration) throws IOException {
      jsonWriter.value(enumeration.getValue().toASCIIString());
    }

    @Override
    public DataSchemaEnum read(final JsonReader jsonReader) throws IOException {
      URI value = URI.create(jsonReader.nextString());
      return DataSchemaEnum.fromValue(value);
    }
  }

The modelEnum template update was a bit trickier as the isUri check was returning false. I had to add some additional code to the CodegenModel to check if the format is set as URI. I followed the same code as isUuid, but noticed a comment in DefaultCodeGen about UUID being a rare use case and may be removed in future DefaultCodegen.java#L3016, so I don't know if this change is the best approach.

There'ss also a native/modelEnum.mustache template, but it looks like the serialization library is fixed to Jackson JavaClientCodegen.java#L633, so the incorrect code can never be generated.

I've made all these changes on a separate branch (along with some tests). I'm not sure whether to pull those changes into this PR or raise as a separate PR?

@wing328
Copy link
Member

wing328 commented Nov 7, 2023

confirmed this fix the issue in resttemplate

I've made all these changes on a separate branch (along with some tests). I'm not sure whether to pull those changes into this PR or raise as a separate PR?

yes please

@wing328 wing328 merged commit ba85461 into OpenAPITools:master Nov 7, 2023
@hhomar hhomar deleted the enum-with-uri-format branch November 12, 2023 10:17
@hhomar hhomar mentioned this pull request Nov 18, 2023
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments