Skip to content

[JAXRS-CXF] Invalid generation for reusable Enum definition #4160

@DarrenC

Description

@DarrenC
Description

When using enums defined outside of objects (so they can be reusable in multiple objects), the jaxrs-cxf codegen is not generating valid class files.
The same enum definition works correctly when defined within another object or when generating with other server stub types such as jaxrs or spring boot for example.

Swagger-codegen version

Latest - 2.2.2-SNAPSHOT

Swagger declaration file content or url

The swagger spec I'm using is based on the petstore example at - http://petstore.swagger.io/v2/swagger.json

I've added the statusExternal property with a $ref to the enum definition

definitions:
  Order:
    type: "object"
    properties:
      ...
      status:
        type: "string"
        description: "Order Status"
        enum:
        - "placed"
        - "approved"
        - "delivered"
      statusExternal:
        $ref: '#/definitions/StatusExt'  
...
  StatusExt:
        type: "string"
        enum:
        - "placed"
        - "approved"
        - "delivered"

The JaxRS-CXF generation correctly creates the status enum within the Order.java file but the StatusExt.java file is junk

Here's the Order class showing a valid StatusEnum

@XmlRootElement(name="Order")
public class Order  {

@XmlType(name="StatusEnum")
@XmlEnum(String.class)
public enum StatusEnum {

    @XmlEnumValue("placed") PLACED(String.valueOf("placed")), @XmlEnumValue("approved") APPROVED(String.valueOf("approved")), @XmlEnumValue("delivered") DELIVERED(String.valueOf("delivered"));

    private String value;

    StatusEnum (String v) {
        value = v;
    }

    public String value() {
        return value;
    }

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

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


  @XmlElement(name="status")
  @ApiModelProperty(example = "null", value = "Order Status")
  private StatusEnum status = null;

  @XmlElement(name="statusExternal")
  @ApiModelProperty(example = "null", value = "")
  private StatusExt statusExternal = null;
...

And here's the StatusExt class which is missing the type name for the enum and the String type in various places

package io.swagger.model;

@XmlType(name="")
@XmlEnum(.class)
public enum  {

    @XmlEnumValue("placed") PLACED(.valueOf("placed")), @XmlEnumValue("approved") APPROVED(.valueOf("approved")), @XmlEnumValue("delivered") DELIVERED(.valueOf("delivered"));


    private  value;

     ( v) {
        value = v;
    }

    public String value() {
        return value;
    }

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

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

If some other server generator is used such as Spring-boot, the StatusExt class is generated correctly

/**
 * Gets or Sets StatusExt
 */
public enum StatusExt {
  
  PLACED("placed"),
  
  APPROVED("approved"),
  
  DELIVERED("delivered");

  private String value;

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

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

  @JsonCreator
  public static StatusExt fromValue(String text) {
    for (StatusExt b : StatusExt.values()) {
      if (String.valueOf(b.value).equals(text)) {
        return b;
      }
    }
    return null;
  }
}
Command line used for generation
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate   \
-i testspec/swagger.yaml   \
-l jaxrs-cxf  \
-o testsamples/server/petstore/java-jaxrs-cxf

Steps to reproduce
  • Modify the petstore 2.0 sample yaml file to include a reusable enum definition
  • Launch the generation of a server stub for JAXRS-CXF using the command line above
  • Check the \src\gen\java\io\swagger\model\StatusExt.java file
  • See that it is not a valid java class declaration and that the enum declarations are missing the "String" type.
Related issues

There have been some fixes around the JAXRS-CXF enum generation recently but seem to deal just with the enums defined within another object definition.

Suggest a Fix

The issue comes from the JAX-RS CXF mustache template for generating the enum. It would seem to be missing some of the extra code in the same template in other languages for handling both cases.
(https://github.com/swagger-api/swagger-codegen/blob/master/modules/swagger-codegen/src/main/resources/JavaJaxRS/cxf/enumClass.mustache)

There is no variable for the classname when compared to the SpringBoot or JAX-RS templates for the enum generation. The datatypeWithEnum value is not set when running the code-gen for an reusable enum definition and so the resulting enum class is not valid.

CXF enumClass.mustache

public enum {{datatypeWithEnum}} {

JAX-RS enumClass.mustache

public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {

Can someone confirm that my analysis above is correct and is it okay for me to work on a possible pull request with a fix?

Cheers
Darren

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions