Skip to content

Enum inside array breaks generated code [JavaJAXRSServerCodegen/DefaultCodegen] #3450

@fiore-adrian

Description

@fiore-adrian
Description

When using and array of an enum type the generated model in java doesn't compile.

Swagger-codegen version

v2.2.0

Swagger declaration file example
swagger: '2.0'
info:
  title: Enum Test
  description: Test enum inside array
  version: "1.0.0"
host: localhost:8080
schemes:
  - http
  - https
consumes:
  - "application/json"
produces:
  - "application/json"

paths:
  /boxes:
    get:
      responses:
        200:
          schema:
            type: array
            items:
              $ref: "#/definitions/box"

definitions:
  box:
    properties:
      id:
        type: string
      arrayprop:
        type: array
        items:
          type: string
          enum:
          - A
          - B
          - C
BoxModel.java generated class
public class BoxModel  {

        //...

        public enum java.util.List<ArraypropEnum> {


                private String value;

                java.util.List<ArraypropEnum>(String value) {
                        this.value = value;
                }

                @Override
                @com.fasterxml.jackson.annotation.JsonValue
                public String toString() {
                        return value;
                }
        }


        public enum ArraypropEnum {
                A("A"),
                B("B"),
                C("C");

                private String value;

                ArraypropEnum(String value) {
                        this.value = value;
                }

                @Override
                @com.fasterxml.jackson.annotation.JsonValue
                public String toString() {
                        return value;
                }
        }

        protected java.util.List<ArraypropEnum> arrayprop = new java.util.ArrayList<ArraypropEnum>();

        //...
}

Error detected

The list is not an enum. This class must not exists:

 public enum java.util.List<ArraypropEnum> {
    // ...
}
Suggested fix

In DefaultCodegen.updatePropertyForArray

    /**
     * Update property for array(list) container
     * @param property Codegen property
     * @param innerProperty Codegen inner property of map or list
     */
    protected void updatePropertyForArray(CodegenProperty property, CodegenProperty innerProperty) {
        if (innerProperty == null) {
            LOGGER.warn("skipping invalid array property " + Json.pretty(property));
        } else {
            if (!languageSpecificPrimitives.contains(innerProperty.baseType)) {
                property.complexType = innerProperty.baseType;
            } else {
                property.isPrimitiveType = true;
            }
            property.items = innerProperty;
            // inner item is Enum
            if (isPropertyInnerMostEnum(property)) {
                property.isEnum = true;
                // update datatypeWithEnum and default value for array
                // e.g. List<string> => List<StatusEnum>
                updateDataTypeWithEnumForArray(property);

            }
        }
    }

I eliminated the property.isEnum = true; inside the condicion if (isPropertyInnerMostEnum(property))
The modified method must be:

    /**
     * Update property for array(list) container
     * @param property Codegen property
     * @param innerProperty Codegen inner property of map or list
     */
    protected void updatePropertyForArray(CodegenProperty property, CodegenProperty innerProperty) {
        if (innerProperty == null) {
            LOGGER.warn("skipping invalid array property " + Json.pretty(property));
        } else {
            if (!languageSpecificPrimitives.contains(innerProperty.baseType)) {
                property.complexType = innerProperty.baseType;
            } else {
                property.isPrimitiveType = true;
            }
            property.items = innerProperty;
            // inner item is Enum
            if (isPropertyInnerMostEnum(property)) {
                // update datatypeWithEnum and default value for array
                // e.g. List<string> => List<StatusEnum>
                updateDataTypeWithEnumForArray(property);

            }
        }
    }

I think that this line set the list as an enum (thing that we do not want).
With this change the generated class doesn't have the extra "enum list" that it's wrong.
I'm not sure if this is the right solution and if this affects other cases.

Thanks!
Regards,

Adrian

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions