Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faulty Transformation of Element with Type Boolean + Enum #10546

Closed
keil opened this issue Nov 4, 2020 · 2 comments · Fixed by #10563
Closed

Faulty Transformation of Element with Type Boolean + Enum #10546

keil opened this issue Nov 4, 2020 · 2 comments · Fixed by #10563

Comments

@keil
Copy link

keil commented Nov 4, 2020

Description

We are using an API defining a Boolean-like-element build upon an enum containing boolean values true and false. The element is defined as follows:

  Boolean:
    type: boolean
    description: True or False indicator
    enum:
      - true
      - false

In general, true and false are interpreted as the boolean values true and false. However, the code-generated generates the following code fragment:

public enum ModelBoolean {
  
  TRUE("true"),
  
  FALSE("false");

  private Boolean value;

  ModelBoolean(Boolean value) {
    this.value = value;
  }

  @JsonValue
  public Boolean getValue() {
    return value;
  }

  @Override
  public String toString() {
    return String.valueOf(value);
  }


  @JsonCreator
  public static ModelBoolean fromValue(String text) {
    for (ModelBoolean b : ModelBoolean.values()) {
      if (String.valueOf(b.value).equals(text)) {
        return b;
      }
    }
    return null;
  }
}

Here, true and false are interpreted as string values, whereas the constructor of ModelBoolean requests a Boolean value. In short, this is not a valid Java code.

Note: A similar result appears when using JavaScript as the target language.

Swagger-codegen version

Version 2.4.17 (swagger-codegen-maven-plugin) or SwaggerHub

Swagger declaration file content or url
swagger: '2.0'
info:
  description: Demo
  version: 1.0.0
  title: Demo for Boolean-element Bug
schemes:
  - https
consumes:
  - application/json
produces:
  - application/json
paths:
  /users:
    get:
      summary: Returns a list of users.
      description: Optional extended description in Markdown.
      produces:
        - application/json
      responses:
        200:
          description: OK
definitions:
  Boolean:
    type: boolean
    description: True or False indicator
    enum:
      - true
      - false
Command line used for generation
Steps to reproduce
  • Use swagger codegen (for example SwaggerHub) to generate Java code.
Related issues/PRs
Suggest a fix/enhancement
@keil
Copy link
Author

keil commented Nov 5, 2020

In addition:

A similar problem exists when using the number data type.

  Number:
    type: number
    description: numbers
    enum:
      - 0
      - 1
      - 2
      - 3

The Number element results in the following Java code.

public enum Number {
  
  _0("0"),
  
  _1("1"),
  
  _2("2"),
  
  _3("3");

  private BigDecimal value;

  Number(BigDecimal value) {
    this.value = value;
  }

  public BigDecimal getValue() {
    return value;
  }

  @Override
  public String toString() {
    return String.valueOf(value);
  }

  public static Number fromValue(String text) {
    for (Number b : Number.values()) {
      if (String.valueOf(b.value).equals(text)) {
        return b;
      }
    }
    return null;
  }

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

    @Override
    public Number read(final JsonReader jsonReader) throws IOException {
      BigDecimal value = jsonReader.nextBigDecimal();
      return Number.fromValue(String.valueOf(value));
    }
  }
}

Again, this is not a valid Java code. The number values are interpreted as string values, whereas the constructor request a value of type BigDecimal.

And, a similar picture is when using the integer data type.

Integer:
   type: integer
   description: integers
   enum:
     - 0
     - 1
     - 2
     - 3
public enum Integer {
  
  NUMBER_0(0),
  
  NUMBER_1(1),
  
  NUMBER_2(2),
  
  NUMBER_3(3);

  private Integer value;

  Integer(Integer value) {
    this.value = value;
  }

  public Integer getValue() {
    return value;
  }

  @Override
  public String toString() {
    return String.valueOf(value);
  }

  public static Integer fromValue(String text) {
    for (Integer b : Integer.values()) {
      if (String.valueOf(b.value).equals(text)) {
        return b;
      }
    }
    return null;
  }

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

    @Override
    public Integer read(final JsonReader jsonReader) throws IOException {
      Integer value = jsonReader.nextInteger();
      return Integer.fromValue(String.valueOf(value));
    }
  }
}

Here, int and Integer are not compatible. Moreover, the method call jsonWriter.value(enumeration.getValue()) is not applicatble vor values of type Integer, only for int values.

@keil
Copy link
Author

keil commented Jan 11, 2021

Unfortunately, the provided fix does not solve the problem! The generated Java code still looks as follows:

/**
 * True or False indicator
 */
@JsonAdapter(ModelBoolean.Adapter.class)
public enum ModelBoolean {
  
  TRUE("true"),
  
  FALSE("false");

  private Boolean value;

  ModelBoolean(Boolean value) {
    this.value = value;
  }

  public Boolean getValue() {
    return value;
  }

  @Override
  public String toString() {
    return String.valueOf(value);
  }

  public static ModelBoolean fromValue(String text) {
    for (ModelBoolean b : ModelBoolean.values()) {
      if (String.valueOf(b.value).equals(text)) {
        return b;
      }
    }
    return null;
  }

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

    @Override
    public ModelBoolean read(final JsonReader jsonReader) throws IOException {
      Boolean value = jsonReader.nextBoolean();
      return ModelBoolean.fromValue(String.valueOf(value));
    }
  }
}

This is not a valid Java code. The constructor requires a value of type Boolean ModelBoolean(Boolean value), but is called with values of type String TRUE("true").

Tested with Swagegr Codegen Version 2.4.18 and version 3.0.24. Both sould include the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant