vojtechhabarta / typescript-generator

Generates TypeScript from Java - JSON declarations, REST service client

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

When overriding abstract JAX-RS methods with generics types, it causes duplicate function implementation in the generated output

jerryhowe opened this issue · comments

Problem Description:

When we extend an abstract class with generics in JAX-RS, and then override the abstract method in the concrete class, it causes the following error TS2393: Duplicate function implementation. in the generated output file.

Java

import javax.ejb.Stateless;
import javax.ws.*;

/* dto */
public class AccountDTO {
    private Long   id;
    private String accountNumber;
    private String accountName;
}

/* abstract class */
public abstract class AbstractCRUDResource<DTO>  {
    @POST
    @Path("")
    public DTO create(final DTO dto) {
        // implement some default behaviour...
        return null;
    }
    @PUT
    @Path("/{id}")
    public DTO update(final DTO dto, @PathParam("id") final Long id) {
        // implement some default behaviour...
        return null;
    }
}

/* concrete jax-rs class */
@Path("/data/account")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Stateless
public class AccountService
        extends AbstractCRUDResource<AccountDTO> {

    @POST
    @Path("")
    @Override
    public AccountDTO create(final AccountDTO dto) {
        // here we override the default behaviour from the abstract class
        return new AccountDTO();
    }

    @PUT
    @Path("/{id}")
    @Override
    public AccountDTO update(final AccountDTO dto, @PathParam("id") final Long id) {
        // here we override the default behaviour from the abstract class
        return new AccountDTO();
    }
}

Configuration

{
    "jsonLibrary" : "jackson2",
    "outputFileType" : "implementationFile",
    "classesFromAutomaticJaxrsApplication" : true,
    "generateJaxrsApplicationClient" : true,
    "outputFile" : "index.ts",
    "outputKind" : "module",
    "mapEnum" : "asEnum",
    "nonConstEnums" : true,
    "sortDeclarations" : true,
    "sortTypeDeclarations" : true,
    "noFileComment" : true,
    "noTslintDisable" : true,
    "noEslintDisable" : true
}

Output

    /**
     * HTTP POST /data/account
     * Java method: ch.nimbus.ee.j4us_app.ejb.service.ws.rest.data.AccountService.create
     */
    create$POST$data_account(arg0: AccountDTO): RestResponse<AccountDTO> {
        return this.httpClient.request({ method: "POST", url: uriEncoding`data/account`, data: arg0 });
    }

    /**
     * HTTP POST /data/account
     * Java method: ch.nimbus.ee.j4us_app.ejb.service.ws.rest.data.AccountService.create
     */
    create$POST$data_account(arg0: any): RestResponse<any> {
        return this.httpClient.request({ method: "POST", url: uriEncoding`data/account`, data: arg0 });
    }

    /**
     * HTTP PUT /data/account/{id}
     * Java method: ch.nimbus.ee.j4us_app.ejb.service.ws.rest.data.AccountService.update
     */
    update$PUT$data_account_id(id: number, arg0: AccountDTO): RestResponse<AccountDTO> {
        return this.httpClient.request({ method: "PUT", url: uriEncoding`data/account/${id}`, data: arg0 });
    }

    /**
     * HTTP PUT /data/account/{id}
     * Java method: ch.nimbus.ee.j4us_app.ejb.service.ws.rest.data.AccountService.update
     */
    update$PUT$data_account_id(id: number, arg0: any): RestResponse<any> {
        return this.httpClient.request({ method: "PUT", url: uriEncoding`data/account/${id}`, data: arg0 });
    }

Expected Behaviour:

Only the following should be generated:

    /**
     * HTTP POST /data/account
     * Java method: ch.nimbus.ee.j4us_app.ejb.service.ws.rest.data.AccountService.create
     */
    create$POST$data_account(arg0: AccountDTO): RestResponse<AccountDTO> {
        return this.httpClient.request({ method: "POST", url: uriEncoding`data/account`, data: arg0 });
    }

    /**
     * HTTP PUT /data/account/{id}
     * Java method: ch.nimbus.ee.j4us_app.ejb.service.ws.rest.data.AccountService.update
     */
    update$PUT$data_account_id(id: number, arg0: AccountDTO): RestResponse<AccountDTO> {
        return this.httpClient.request({ method: "PUT", url: uriEncoding`data/account/${id}`, data: arg0 });
    }

If I remove the overriden methods from the concrete class, then I get expected output. However in my scenario, I need to override the abstract method in certain use-cases. Is there a way I can do this without producing duplicate implementation in the generated typescript file?