Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Kotlin][client] Support gson and moshi as serialization libraries #3734

Merged
merged 12 commits into from
Aug 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/openapi3/kotlin-client-petstore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ then
fi

export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -t modules/openapi-generator/src/main/resources/kotlin-client -g kotlin --artifact-id kotlin-petstore-client --additional-properties dateLibrary=java8 -o samples/openapi3/client/petstore/kotlin $@"
ags="generate -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -t modules/openapi-generator/src/main/resources/kotlin-client -g kotlin --artifact-id kotlin-petstore-client --additional-properties dateLibrary=java8 -o samples/openapi3/client/petstore/kotlin $@"

echo "Cleaning previously generated files if any from samples/openapi3/client/petstore/kotlin"
rm -rf samples/openapi3/client/petstore/kotlin
Expand Down
1 change: 1 addition & 0 deletions docs/generators/kotlin-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ sidebar_label: kotlin-server
|artifactId|Generated artifact id (name of jar).| |kotlin-server|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|serializationLibrary|What serialization library to use: 'moshi' (default), or 'gson'| |moshi|
|parcelizeModels|toggle "@Parcelize" for generated models| |null|
|library|library template (sub-template)|<dl><dt>**ktor**</dt><dd>ktor framework</dd><dl>|ktor|
|featureAutoHead|Automatically provide responses to HEAD requests for existing routes that have the GET verb defined.| |true|
Expand Down
1 change: 1 addition & 0 deletions docs/generators/kotlin-spring.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ sidebar_label: kotlin-spring
|artifactId|Generated artifact id (name of jar).| |openapi-spring|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|serializationLibrary|What serialization library to use: 'moshi' (default), or 'gson'| |moshi|
|parcelizeModels|toggle &quot;@Parcelize&quot; for generated models| |null|
|title|server title name or client service name| |OpenAPI Kotlin Spring|
|basePackage|base package (invokerPackage) for generated code| |org.openapitools|
Expand Down
1 change: 1 addition & 0 deletions docs/generators/kotlin.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ sidebar_label: kotlin
|artifactId|Generated artifact id (name of jar).| |kotlin-client|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|serializationLibrary|What serialization library to use: 'moshi' (default), or 'gson'| |moshi|
|parcelizeModels|toggle &quot;@Parcelize&quot; for generated models| |null|
|dateLibrary|Option. Date library to use|<dl><dt>**string**</dt><dd>String</dd><dt>**java8**</dt><dd>Java 8 native JSR310</dd><dt>**threetenbp**</dt><dd>Threetenbp</dd><dl>|java8|
|collectionType|Option. Collection type to use|<dl><dt>**array**</dt><dd>kotlin.Array</dd><dt>**list**</dt><dd>kotlin.collections.List</dd><dl>|array|
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case,
public static final String ENUM_PROPERTY_NAMING = "enumPropertyNaming";
public static final String ENUM_PROPERTY_NAMING_DESC = "Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'";

// Allow different language generators to offer an option of serialization library. Each language specific
// Codegen constants should define a description and provide proper input validation for the value of serializationLibrary
public static final String SERIALIZATION_LIBRARY = "serializationLibrary";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, once merged I will remove org.openapitools.codegen.languages.JavaClientCodegen.SERIALIZATION_LIBRARY and use that instead.


public static final String MODEL_NAME_PREFIX = "modelNamePrefix";
public static final String MODEL_NAME_PREFIX_DESC = "Prefix that will be prepended to all model names.";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
import static org.openapitools.codegen.utils.StringUtils.*;

public abstract class AbstractKotlinCodegen extends DefaultCodegen implements CodegenConfig {

public static final String SERIALIZATION_LIBRARY_DESC = "What serialization library to use: 'moshi' (default), or 'gson'";
public enum SERIALIZATION_LIBRARY_TYPE {moshi, gson}

private static final Logger LOGGER = LoggerFactory.getLogger(AbstractKotlinCodegen.class);

protected String artifactId;
Expand All @@ -51,6 +55,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
protected boolean parcelizeModels = false;

protected CodegenConstants.ENUM_PROPERTY_NAMING_TYPE enumPropertyNaming = CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.camelCase;
protected SERIALIZATION_LIBRARY_TYPE serializationLibrary = SERIALIZATION_LIBRARY_TYPE.moshi;

public AbstractKotlinCodegen() {
super();
Expand Down Expand Up @@ -205,6 +210,10 @@ public AbstractKotlinCodegen() {

CliOption enumPropertyNamingOpt = new CliOption(CodegenConstants.ENUM_PROPERTY_NAMING, CodegenConstants.ENUM_PROPERTY_NAMING_DESC);
cliOptions.add(enumPropertyNamingOpt.defaultValue(enumPropertyNaming.name()));

CliOption serializationLibraryOpt = new CliOption(CodegenConstants.SERIALIZATION_LIBRARY, SERIALIZATION_LIBRARY_DESC);
cliOptions.add(serializationLibraryOpt.defaultValue(serializationLibrary.name()));

cliOptions.add(new CliOption(CodegenConstants.PARCELIZE_MODELS, CodegenConstants.PARCELIZE_MODELS_DESC));
}

Expand Down Expand Up @@ -244,6 +253,10 @@ public CodegenConstants.ENUM_PROPERTY_NAMING_TYPE getEnumPropertyNaming() {
return this.enumPropertyNaming;
}

public SERIALIZATION_LIBRARY_TYPE getSerializationLibrary() {
return this.serializationLibrary;
}

/**
* Sets the naming convention for Kotlin enum properties
*
Expand All @@ -261,6 +274,24 @@ public void setEnumPropertyNaming(final String enumPropertyNamingType) {
}
}

/**
* Sets the serialization engine for Kotlin
*
* @param enumSerializationLibrary The string representation of the serialization library as defined by
* {@link org.openapitools.codegen.languages.AbstractKotlinCodegen.SERIALIZATION_LIBRARY_TYPE}
*/
public void setSerializationLibrary(final String enumSerializationLibrary) {
try {
this.serializationLibrary = SERIALIZATION_LIBRARY_TYPE.valueOf(enumSerializationLibrary);
} catch (IllegalArgumentException ex) {
StringBuilder sb = new StringBuilder(enumSerializationLibrary + " is an invalid enum property naming option. Please choose from:");
for (SERIALIZATION_LIBRARY_TYPE t : SERIALIZATION_LIBRARY_TYPE.values()) {
sb.append("\n ").append(t.name());
}
throw new RuntimeException(sb.toString());
}
}

/**
* returns the swagger type for the property
*
Expand Down Expand Up @@ -330,6 +361,14 @@ public void processOpts() {
setEnumPropertyNaming((String) additionalProperties.get(CodegenConstants.ENUM_PROPERTY_NAMING));
}

if (additionalProperties.containsKey(CodegenConstants.SERIALIZATION_LIBRARY)) {
setSerializationLibrary((String) additionalProperties.get(CodegenConstants.SERIALIZATION_LIBRARY));
additionalProperties.put(this.serializationLibrary.name(), true);
}
else {
additionalProperties.put(this.serializationLibrary.name(), true);
}

if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ dependencies {
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
compile "com.squareup.moshi:moshi-kotlin:1.8.0"
compile "com.squareup.moshi:moshi-adapters:1.8.0"
{{#gson}}
implementation "com.google.code.gson:gson:2.8.5"
{{/gson}}
compile "com.squareup.okhttp3:okhttp:4.0.1"
{{#threetenbp}}
compile "org.threeten:threetenbp:1.3.8"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{{#gson}}
import com.google.gson.annotations.SerializedName
{{/gson}}
{{#moshi}}
import com.squareup.moshi.Json
{{/moshi}}
{{#parcelizeModels}}
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
Expand All @@ -19,17 +24,22 @@ data class {{classname}} (
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
{{/-last}}{{/optionalVars}}
){{#parcelizeModels}} : Parcelable{{/parcelizeModels}} {
){{#parcelizeModels}} : Parcelable{{/parcelizeModels}}
{{#hasEnums}}{{#vars}}{{#isEnum}}
{
/**
* {{{description}}}
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
*/
enum class {{{nameInCamelCase}}}(val value: {{#isListContainer}}{{{ nestedType }}}{{/isListContainer}}{{^isListContainer}}{{{dataType}}}{{/isListContainer}}){
{{#allowableValues}}{{#enumVars}}
@Json(name = {{{value}}})
{{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
{{#moshi}}
@Json(name = {{{value}}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
{{/moshi}}
{{#gson}}
@SerializedName(value={{{value}}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
{{/gson}}
{{/enumVars}}{{/allowableValues}}
}
{{/isEnum}}{{/vars}}{{/hasEnums}}
}
{{/isEnum}}{{/vars}}{{/hasEnums}}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{{#description}}
/* {{{description}}} */
{{/description}}
{{#moshi}}
@Json(name = "{{{baseName}}}")
{{/moshi}}
{{#gson}}
@SerializedName("{{name}}")
{{/gson}}
val {{{name}}}: {{#isEnum}}{{#isListContainer}}{{#isList}}kotlin.collections.List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{classname}}.{{{nameInCamelCase}}}>{{/isListContainer}}{{^isListContainer}}{{classname}}.{{{nameInCamelCase}}}{{/isListContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{{#description}}
/* {{{description}}} */
{{/description}}
{{#moshi}}
@Json(name = "{{{baseName}}}")
{{/moshi}}
{{#gson}}
@SerializedName("{{name}}")
{{/gson}}
val {{{name}}}: {{#isEnum}}{{#isListContainer}}{{#isList}}kotlin.collections.List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{classname}}.{{{nameInCamelCase}}}>{{/isListContainer}}{{^isListContainer}}{{classname}}.{{{nameInCamelCase}}}{{/isListContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{{#gson}}
import com.google.gson.annotations.SerializedName
{{/gson}}
{{#moshi}}
import com.squareup.moshi.Json
{{/moshi}}

/**
* {{{description}}}
Expand All @@ -7,7 +12,12 @@ import com.squareup.moshi.Json
enum class {{classname}}(val value: {{{dataType}}}){

{{#allowableValues}}{{#enumVars}}
{{#moshi}}
@Json(name = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}})
{{/moshi}}
{{#gson}}
@SerializedName(value = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}})
{{/gson}}
{{#isListContainer}}
{{#isList}}
{{&name}}(listOf({{{value}}})){{^-last}},{{/-last}}{{#-last}};{{/-last}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ data class ApiResponse (
val type: kotlin.String? = null,
@Json(name = "message")
val message: kotlin.String? = null
) {
)

}

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ data class Category (
val id: kotlin.Long? = null,
@Json(name = "name")
val name: kotlin.String? = null
) {
)

}

Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,22 @@ data class Order (
val status: Order.Status? = null,
@Json(name = "complete")
val complete: kotlin.Boolean? = null
) {
)

{
/**
* Order Status
* Values: placed,approved,delivered
*/
enum class Status(val value: kotlin.String){

@Json(name = "placed")
placed("placed"),
@Json(name = "placed") placed("placed"),

@Json(name = "approved")
approved("approved"),
@Json(name = "approved") approved("approved"),

@Json(name = "delivered")
delivered("delivered");
@Json(name = "delivered") delivered("delivered");

}

}


Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,22 @@ data class Pet (
/* pet status in the store */
@Json(name = "status")
val status: Pet.Status? = null
) {
)

{
/**
* pet status in the store
* Values: available,pending,sold
*/
enum class Status(val value: kotlin.String){

@Json(name = "available")
available("available"),
@Json(name = "available") available("available"),

@Json(name = "pending")
pending("pending"),
@Json(name = "pending") pending("pending"),

@Json(name = "sold")
sold("sold");
@Json(name = "sold") sold("sold");

}

}


Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ data class Tag (
val id: kotlin.Long? = null,
@Json(name = "name")
val name: kotlin.String? = null
) {
)

}

Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ data class User (
/* User Status */
@Json(name = "userStatus")
val userStatus: kotlin.Int? = null
) {
)

}

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ data class ApiResponse (
val type: kotlin.String? = null,
@Json(name = "message")
val message: kotlin.String? = null
) {
)

}

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ data class Category (
val id: kotlin.Long? = null,
@Json(name = "name")
val name: kotlin.String? = null
) {
)

}

Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,22 @@ data class Order (
val status: Order.Status? = null,
@Json(name = "complete")
val complete: kotlin.Boolean? = null
) {
)

{
/**
* Order Status
* Values: placed,approved,delivered
*/
enum class Status(val value: kotlin.String){

@Json(name = "placed")
placed("placed"),
@Json(name = "placed") placed("placed"),

@Json(name = "approved")
approved("approved"),
@Json(name = "approved") approved("approved"),

@Json(name = "delivered")
delivered("delivered");
@Json(name = "delivered") delivered("delivered");

}

}


Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,22 @@ data class Pet (
/* pet status in the store */
@Json(name = "status")
val status: Pet.Status? = null
) {
)

{
/**
* pet status in the store
* Values: available,pending,sold
*/
enum class Status(val value: kotlin.String){

@Json(name = "available")
available("available"),
@Json(name = "available") available("available"),

@Json(name = "pending")
pending("pending"),
@Json(name = "pending") pending("pending"),

@Json(name = "sold")
sold("sold");
@Json(name = "sold") sold("sold");

}

}


Loading