fix: prevent ClassCastException when handling options of (issue #4468) (#4495)

* issue 4468 fix: prevent ClassCastException when handling options of type boolean

*  #4468 fix: remove duplicate code
This commit is contained in:
Jan
2019-11-17 01:59:25 +01:00
committed by William Cheng
parent a1a9e70fe4
commit 5181ddcbb0
10 changed files with 243 additions and 33 deletions

View File

@@ -139,6 +139,7 @@ script:
- mvn clean compile -f modules/openapi-generator-maven-plugin/examples/java-client.xml
- mvn clean compile -f modules/openapi-generator-maven-plugin/examples/multi-module/pom.xml
- mvn clean compile -f modules/openapi-generator-maven-plugin/examples/kotlin.xml
- mvn clean compile -f modules/openapi-generator-maven-plugin/examples/spring.xml
# test gradle plugin
- (cd modules/openapi-generator-gradle-plugin/samples/local-spec && ./gradlew buildGoSdk)
- (cd modules/openapi-generator-gradle-plugin/samples/local-spec && ./gradlew openApiGenerate)

View File

@@ -27,7 +27,7 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate --artifact-id springboot -t modules/openapi-generator/src/main/resources/JavaSpring -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g spring -o samples/server/petstore/springboot --additional-properties hideGenerationTimestamp=true $@"
ags="generate --artifact-id springboot -t modules/openapi-generator/src/main/resources/JavaSpring -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g spring -o samples/server/petstore/springboot --additional-properties hideGenerationTimestamp=true,snapshotVersion=true $@"
echo "Removing files and folders under samples/server/petstore/springboot/src/main"
rm -rf samples/server/petstore/springboot/src/main

View File

@@ -0,0 +1,126 @@
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.openapitools</groupId>
<artifactId>sample-project</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>sample-project</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
</parent>
<build>
<plugins>
<!-- activate the plugin -->
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>4.2.1-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
<id>spring-server</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!-- specify the swagger yaml -->
<inputSpec>${project.basedir}/swagger.yaml</inputSpec>
<!-- target to generate java client code -->
<generatorName>spring</generatorName>
<!-- hint: if you want to generate java server code, e.g. based on Spring Boot,
you can use the following target: <generatorName>spring</generatorName> -->
<!-- pass any necessary config options -->
<configOptions>
<serializableModel>true</serializableModel>
<snapshotVersion>true</snapshotVersion>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<proc>none</proc>
</configuration>
</plugin>
</plugins>
<pluginManagement>
</pluginManagement>
</build>
<pluginRepositories>
<pluginRepository>
<id>sonatype-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<!-- dependencies are needed for the client being generated -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations-version}</version>
</dependency>
<!-- You can find the dependencies for the library configuation you chose by looking in JavaClientCodegen.
Then find the corresponding dependency on Maven Central, and set the versions in the property section below -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringFox dependencies -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
</dependencies>
<properties>
<swagger-annotations-version>1.5.8</swagger-annotations-version>
<spring-boot-starter-web.version>2.2.1.RELEASE</spring-boot-starter-web.version>
<springfox-version>2.8.0</springfox-version>
</properties>
</project>

View File

@@ -4401,14 +4401,9 @@ public class DefaultCodegen implements CodegenConfig {
* @return property value as boolean
*/
public boolean convertPropertyToBooleanAndWriteBack(String propertyKey) {
boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) {
booleanValue = convertPropertyToBoolean(propertyKey);
// write back as boolean
writePropertyBack(propertyKey, booleanValue);
}
return booleanValue;
boolean result = convertPropertyToBoolean(propertyKey);
writePropertyBack(propertyKey, result);
return result;
}
/**
@@ -4432,12 +4427,14 @@ public class DefaultCodegen implements CodegenConfig {
}
public boolean convertPropertyToBoolean(String propertyKey) {
boolean booleanValue = false;
if (additionalProperties.containsKey(propertyKey)) {
booleanValue = Boolean.valueOf(additionalProperties.get(propertyKey).toString());
final Object booleanValue = additionalProperties.get(propertyKey);
Boolean result = Boolean.FALSE;
if (booleanValue instanceof Boolean) {
result = (Boolean) booleanValue;
} else if (booleanValue instanceof String) {
result = Boolean.parseBoolean((String) booleanValue);
}
return booleanValue;
return result;
}
public void writePropertyBack(String propertyKey, boolean value) {

View File

@@ -1055,8 +1055,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
}
if (additionalProperties.containsKey(CodegenConstants.SNAPSHOT_VERSION)) {
Boolean useSnapshotVersion = Boolean.valueOf((String) additionalProperties.get(CodegenConstants.SNAPSHOT_VERSION));
if (useSnapshotVersion) {
if (convertPropertyToBooleanAndWriteBack(CodegenConstants.SNAPSHOT_VERSION)) {
this.setArtifactVersion(this.buildSnapshotVersion(this.getArtifactVersion()));
}
}

View File

@@ -434,19 +434,19 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
}
if (additionalProperties.containsKey(CodegenConstants.SERIALIZABLE_MODEL)) {
this.setSerializableModel(getBooleanOption(CodegenConstants.SERIALIZABLE_MODEL));
this.setSerializableModel(convertPropertyToBooleanAndWriteBack(CodegenConstants.SERIALIZABLE_MODEL));
} else {
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, serializableModel);
}
if (additionalProperties.containsKey(CodegenConstants.PARCELIZE_MODELS)) {
this.setParcelizeModels(getBooleanOption(CodegenConstants.PARCELIZE_MODELS));
this.setParcelizeModels(convertPropertyToBooleanAndWriteBack(CodegenConstants.PARCELIZE_MODELS));
} else {
additionalProperties.put(CodegenConstants.PARCELIZE_MODELS, parcelizeModels);
}
if (additionalProperties.containsKey(CodegenConstants.NON_PUBLIC_API)) {
this.setNonPublicApi(getBooleanOption(CodegenConstants.NON_PUBLIC_API));
this.setNonPublicApi(convertPropertyToBooleanAndWriteBack(CodegenConstants.NON_PUBLIC_API));
} else {
additionalProperties.put(CodegenConstants.NON_PUBLIC_API, nonPublicApi);
}
@@ -458,18 +458,6 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
additionalProperties.put("modelDocPath", modelDocPath);
}
private boolean getBooleanOption(String key) {
final Object booleanValue = additionalProperties.get(key);
Boolean result = Boolean.FALSE;
if (booleanValue instanceof Boolean) {
result = (Boolean) booleanValue;
} else if (booleanValue instanceof String) {
result = Boolean.parseBoolean((String) booleanValue);
}
additionalProperties.put(key, result);
return result;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}

View File

@@ -1030,5 +1030,50 @@ public class DefaultCodegenTest {
CodegenParameter parameter = codegenParameter("/set_should_explode");
assertTrue(parameter.isExplode);
}
@Test
public void testConvertPropertyToBooleanAndWriteBack_Boolean_true() {
final DefaultCodegen codegen = new DefaultCodegen();
Map<String, Object> additionalProperties = codegen.additionalProperties();
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, true);
boolean result = codegen.convertPropertyToBooleanAndWriteBack(CodegenConstants.SERIALIZABLE_MODEL);
Assert.assertTrue(result);
}
@Test
public void testConvertPropertyToBooleanAndWriteBack_Boolean_false() {
final DefaultCodegen codegen = new DefaultCodegen();
Map<String, Object> additionalProperties = codegen.additionalProperties();
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, false);
boolean result = codegen.convertPropertyToBooleanAndWriteBack(CodegenConstants.SERIALIZABLE_MODEL);
Assert.assertFalse(result);
}
@Test
public void testConvertPropertyToBooleanAndWriteBack_String_true() {
final DefaultCodegen codegen = new DefaultCodegen();
Map<String, Object> additionalProperties = codegen.additionalProperties();
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, "true");
boolean result = codegen.convertPropertyToBooleanAndWriteBack(CodegenConstants.SERIALIZABLE_MODEL);
Assert.assertTrue(result);
}
@Test
public void testConvertPropertyToBooleanAndWriteBack_String_false() {
final DefaultCodegen codegen = new DefaultCodegen();
Map<String, Object> additionalProperties = codegen.additionalProperties();
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, "false");
boolean result = codegen.convertPropertyToBooleanAndWriteBack(CodegenConstants.SERIALIZABLE_MODEL);
Assert.assertFalse(result);
}
@Test
public void testConvertPropertyToBooleanAndWriteBack_String_blibb() {
final DefaultCodegen codegen = new DefaultCodegen();
Map<String, Object> additionalProperties = codegen.additionalProperties();
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, "blibb");
boolean result = codegen.convertPropertyToBooleanAndWriteBack(CodegenConstants.SERIALIZABLE_MODEL);
Assert.assertFalse(result);
}
}
}

View File

@@ -372,6 +372,60 @@ public class AbstractJavaCodegenTest {
Assert.assertEquals(defaultValue, "Object");
}
@Test
public void processOptsBooleanTrueFromString() {
final P_AbstractJavaCodegen codegen = new P_AbstractJavaCodegen();
final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml");
codegen.additionalProperties().put(CodegenConstants.SNAPSHOT_VERSION, "true");
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue((boolean) codegen.additionalProperties().get(CodegenConstants.SNAPSHOT_VERSION));
}
@Test
public void processOptsBooleanTrueFromBoolean() {
final P_AbstractJavaCodegen codegen = new P_AbstractJavaCodegen();
final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml");
codegen.additionalProperties().put(CodegenConstants.SNAPSHOT_VERSION, true);
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue((boolean) codegen.additionalProperties().get(CodegenConstants.SNAPSHOT_VERSION));
}
@Test
public void processOptsBooleanFalseFromString() {
final P_AbstractJavaCodegen codegen = new P_AbstractJavaCodegen();
final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml");
codegen.additionalProperties().put(CodegenConstants.SNAPSHOT_VERSION, "false");
codegen.preprocessOpenAPI(openAPI);
Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SNAPSHOT_VERSION));
}
@Test
public void processOptsBooleanFalseFromBoolean() {
final P_AbstractJavaCodegen codegen = new P_AbstractJavaCodegen();
final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml");
codegen.additionalProperties().put(CodegenConstants.SNAPSHOT_VERSION, false);
codegen.preprocessOpenAPI(openAPI);
Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SNAPSHOT_VERSION));
}
@Test
public void processOptsBooleanFalseFromGarbage() {
final P_AbstractJavaCodegen codegen = new P_AbstractJavaCodegen();
final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml");
codegen.additionalProperties().put(CodegenConstants.SNAPSHOT_VERSION, "blibb");
codegen.preprocessOpenAPI(openAPI);
Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SNAPSHOT_VERSION));
}
@Test
public void processOptsBooleanFalseFromNumeric() {
final P_AbstractJavaCodegen codegen = new P_AbstractJavaCodegen();
final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/petstore.yaml");
codegen.additionalProperties().put(CodegenConstants.SNAPSHOT_VERSION, 42L);
codegen.preprocessOpenAPI(openAPI);
Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SNAPSHOT_VERSION));
}
private static Schema<?> createObjectSchemaWithMinItems() {
return new ObjectSchema()
.addProperties("id", new IntegerSchema().format("int32"))

View File

@@ -1 +1 @@
4.1.3-SNAPSHOT
4.2.1-SNAPSHOT

View File

@@ -4,7 +4,7 @@
<artifactId>springboot</artifactId>
<packaging>jar</packaging>
<name>springboot</name>
<version>1.0.0</version>
<version>1.0.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>