Skip to content

Commit

Permalink
Merge pull request #920 from denvitaharen/feature/add-equals-hashcode…
Browse files Browse the repository at this point in the history
…-client

Added so equals and hashcode is generated in models.
  • Loading branch information
fjtirado authored Dec 23, 2024
2 parents ff0130e + 5121a39 commit 6553a9e
Show file tree
Hide file tree
Showing 14 changed files with 533 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ public enum ConfigName {
GENERATE_APIS("generate-apis"),
GENERATE_MODELS("generate-models"),
BEAN_VALIDATION("use-bean-validation"),
SERIALIZABLE_MODEL("serializable-model");
SERIALIZABLE_MODEL("serializable-model"),
EQUALS_HASHCODE("equals-hashcode");

private final String name;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,11 @@ public class CommonItemConfig {
*/
@ConfigItem(name = "generate-models")
public Optional<Boolean> generateModels;

/**
* Enable the generation of equals and hashcode in models. If you set this to {@code false}, the models
* will not have equals and hashcode.
*/
@ConfigItem(name = "equals-hashcode")
public Optional<Boolean> equalsHashcode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,9 @@ protected void generate(OpenApiGeneratorOptions options) {
getValues(smallRyeConfig, openApiFilePath, CodegenConfig.ConfigName.SERIALIZABLE_MODEL, Boolean.class)
.ifPresent(generator::withSerialiableModel);

getValues(smallRyeConfig, openApiFilePath, CodegenConfig.ConfigName.EQUALS_HASHCODE, Boolean.class)
.ifPresent(generator::withEqualsHashcode);

getValues(smallRyeConfig, openApiFilePath, CodegenConfig.ConfigName.NORMALIZER, String.class, String.class)
.ifPresent(generator::withOpenApiNormalizer);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ private void setDefaults() {
this.configurator.addAdditionalProperty("use-field-name-in-part-filename", FALSE);
this.configurator.addAdditionalProperty("verbose", FALSE);
this.configurator.addAdditionalProperty(CodegenConstants.SERIALIZABLE_MODEL, FALSE);
this.configurator.addAdditionalProperty("equals-hashcode", TRUE);
}

/**
Expand Down Expand Up @@ -202,6 +203,11 @@ public OpenApiClientGeneratorWrapper withSerialiableModel(final Boolean serialia
return this;
}

public OpenApiClientGeneratorWrapper withEqualsHashcode(final Boolean equalsHashcode) {
this.configurator.addAdditionalProperty("equals-hashcode", equalsHashcode);
return this;
}

/**
* Sets the global 'additionalModelTypeAnnotations' setting. If not set this setting will default to empty.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,64 @@ public class {m.classname} {#if m.parent}extends {m.parent}{/if}{#if serializabl
return sb.toString();
}

{#if equals-hashcode}
{#if m.vars.size > 0}
/**
* Compares this object to the specified object. The result is
* \{@code true\} if and only if the argument is not
* \{@code null\} and is a \{@code {m.classname}\} object that
* contains the same values as this object.
*
* @param obj the object to compare with.
* @return \{@code true\} if the objects are the same;
* \{@code false\} otherwise.
**/
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;

{m.classname} model = ({m.classname}) obj;

{#if m.vars.size == 1}
return java.util.Objects.equals({m.vars.0.name}, model.{m.vars.0.name});
{#else}
{#for v in m.vars}
{#if v_isFirst}
return java.util.Objects.equals({v.name}, model.{v.name}) &&
{#else if v_isLast}
java.util.Objects.equals({v.name}, model.{v.name});
{#else}
java.util.Objects.equals({v.name}, model.{v.name}) &&
{/if}
{/for}
{/if}
}

/**
* Returns a hash code for a \{@code {m.classname}\}.
*
* @return a hash code value for a \{@code {m.classname}\}.
**/
@Override
public int hashCode() {
{#if m.vars.size == 1}
return java.util.Objects.hash({m.vars.0.name});
{#else}
{#for v in m.vars}
{#if v_isFirst}
return java.util.Objects.hash({v.name},
{#else if v_isLast}
{v.name});
{#else}
{v.name},
{/if}
{/for}
{/if}
}
{/if}
{/if}

/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
Expand Down
93 changes: 93 additions & 0 deletions client/integration-tests/equals-hashcode/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-openapi-generator-integration-tests</artifactId>
<groupId>io.quarkiverse.openapi.generator</groupId>
<version>3.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-openapi-generator-it-equals-hashcode</artifactId>
<name>Quarkus - Openapi Generator - Integration Tests - Client - Equals hashcode</name>
<description>Example project for general usage</description>

<dependencies>
<dependency>
<groupId>io.quarkiverse.openapi.generator</groupId>
<artifactId>quarkus-openapi-generator</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native-image</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${native.surefire.skip}</skipTests>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>
${project.build.directory}/${project.build.finalName}-runner
</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager
</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
{
"openapi": "3.0.2",
"info": {
"title": "Animals - OpenAPI 3.0",
"version": "1.0.5"
},
"servers": [
{
"url": "/api/v3"
}
],
"tags": [
{
"name": "primate",
"description": "Everything about Primates"
}
],
"paths": {
"/primate/{id}": {
"get": {
"tags": [
"primate"
],
"summary": "Find primate by ID",
"description": "Returns a single primate",
"operationId": "getPrimateById",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of primate to return",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Primate"
}
}
}
},
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Primate not found"
}
}
}
}
},
"components": {
"schemas": {
"Animal": {
"type": "object",
"properties": {
"born": {
"type": "string",
"description": "Dated Base extension.",
"format": "date-time"
},
"deceased": {
"type": "string",
"description": "Dated Base extension.",
"format": "date-time"
}
},
"xml": {
"name": "animal"
}
},
"Mammal": {
"type": "object",
"allOf": [ {
"$ref": "#/components/schemas/Animal"
} ],
"properties": {
"gender": {
"type": "string",
"enum": [
"female",
"male"
]
}
},
"xml": {
"name": "mammal"
}
},
"Primate": {
"required": [
"name"
],
"type": "object",
"allOf": [
{
"$ref": "#/components/schemas/Mammal"
}
],
"properties": {
"id": {
"type": "integer",
"format": "int64",
"example": 10
},
"name": {
"type": "string",
"example": "jane doe"
}
},
"xml": {
"name": "primate"
}
}
}
}
}
Loading

0 comments on commit 6553a9e

Please sign in to comment.