Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public abstract class AbstractKotlinCodegen extends DefaultCodegenConfig {

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

private Set<String> instantiationLibraryFunction;



protected String artifactId;
protected String artifactVersion = "1.0.0";
protected String groupId = "io.swagger";
Expand Down Expand Up @@ -47,7 +53,7 @@ public AbstractKotlinCodegen() {
"kotlin.Boolean",
"kotlin.Char",
"kotlin.String",
"kotlin.Array",
"kotlin.Array",
"kotlin.collections.List",
"kotlin.collections.Map",
"kotlin.collections.Set"
Expand Down Expand Up @@ -136,6 +142,11 @@ public AbstractKotlinCodegen() {
"kotlin.collections.Map"
));

instantiationLibraryFunction = new HashSet<String>(Arrays.asList(
"arrayOf",
"mapOf"
));

typeMapping = new HashMap<String, String>();
typeMapping.put("string", "kotlin.String");
typeMapping.put("boolean", "kotlin.Boolean");
Expand Down Expand Up @@ -250,7 +261,7 @@ public void setEnumPropertyNaming(final String enumPropertyNamingType) {
}
throw new RuntimeException(sb.toString());
}
}
}

/**
* Output the type declaration of the property
Expand All @@ -270,8 +281,8 @@ public String getTypeDeclaration(Schema propertySchema) {
return null;
}
// Maps will be keyed only by primitive Kotlin string
return String.format("%s<kotlin.String, %s>", getSchemaType(propertySchema), getTypeDeclaration(inner));
}
return String.format("%s<kotlin.String, %s>", getSchemaType(propertySchema), getTypeDeclaration(inner));
}
return super.getTypeDeclaration(propertySchema);
}

Expand All @@ -287,8 +298,6 @@ public String getAlias(String name) {
public String getSchemaType(Schema schema) {
String schemaType = super.getSchemaType(schema);

schemaType = getAlias(schemaType);

// don't apply renaming on types from the typeMapping
if (typeMapping.containsKey(schemaType)) {
return toModelName(typeMapping.get(schemaType));
Expand All @@ -301,7 +310,7 @@ public String getSchemaType(Schema schema) {
} else {
return toModelName("kotlin.Any");
}
}
}
return toModelName(schemaType);
}

Expand Down Expand Up @@ -496,9 +505,9 @@ public String toModelName(final String name) {

@Override
public String toVarName(String name) {
return super.toVarName(sanitizeKotlinSpecificNames(name));
return super.toVarName(sanitizeKotlinSpecificNames(name));
}

/**
* Provides a strongly typed declaration for simple arrays of some type and arrays of arrays of some type.
*
Expand All @@ -515,7 +524,7 @@ private String getArrayTypeDeclaration(ArraySchema arraySchema) {
// TODO: We may want to differentiate here between generics and primitive arrays.
instantiationType.append("<").append(nestedType).append(">");
return instantiationType.toString();
}
}

/**
* Sanitize against Kotlin specific naming conventions, which may differ from those required by {@link DefaultCodegen#sanitizeName}.
Expand Down Expand Up @@ -566,7 +575,13 @@ protected boolean isReservedWord(String word) {
@Override
protected boolean needToImport(String type) {
// provides extra protection against improperly trying to import language primitives and java types
boolean imports = !type.startsWith("kotlin.") && !type.startsWith("java.") && !defaultIncludes.contains(type) && !languageSpecificPrimitives.contains(type);
boolean imports =
!type.startsWith("kotlin.") &&
!type.startsWith("java.") &&
!defaultIncludes.contains(type) &&
!languageSpecificPrimitives.contains(type) &&
!instantiationLibraryFunction.contains(type);

return imports;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.codegen.CodegenOperation;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.parameters.Parameter;

import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.SupportingFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -35,15 +38,15 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen {
private Boolean compressionFeatureEnabled = true;

// This is here to potentially warn the user when an option is not supoprted by the target framework.
private Map<String, List<String>> optionsSupportedPerFramework =
singletonMap(Constants.KTOR,
private Map<String, List<String>> optionsSupportedPerFramework =
singletonMap(Constants.KTOR,
Arrays.asList(
Constants.AUTOMATIC_HEAD_REQUESTS,
Constants.CONDITIONAL_HEADERS,
Constants.HSTS,
Constants.CORS,
Constants.COMPRESSION
));
));

/**
* Constructs an instance of `KotlinServerCodegen`.
Expand Down Expand Up @@ -128,9 +131,21 @@ public CodegenType getTag() {
return CodegenType.SERVER;
}

/**
* Handle typealias for schema of Array type
*/
@Override
public CodegenModel fromModel(String name, Schema schema, Map<String, Schema> allDefinitions) {
CodegenModel codegenModel = super.fromModel(name, schema, allDefinitions);

if (schema instanceof ArraySchema) {
codegenModel.dataType = getTypeDeclaration(schema);
}
return codegenModel;
}

@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Schema> schemas, OpenAPI openAPI) {

// Ensure that the parameter names in the path are valid kotlin names
// they need to match the names in the generated data class, this is required by ktor Location
String modifiedPath = path;
Expand Down Expand Up @@ -198,7 +213,6 @@ public void processOpts() {

String packageFolder = (sourceFolder + File.separator + packageName).replace(".", File.separator);
String resourcesFolder = "src/main/resources"; // not sure this can be user configurable.

Boolean generateApis = additionalProperties.containsKey(GENERATE_APIS) && (Boolean)additionalProperties.get(GENERATE_APIS);

supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
Expand All @@ -210,9 +224,9 @@ public void processOpts() {

supportingFiles.add(new SupportingFile("AppMain.kt.mustache", packageFolder, "AppMain.kt"));
supportingFiles.add(new SupportingFile("Configuration.kt.mustache", packageFolder, "Configuration.kt"));

if (generateApis) {
supportingFiles.add(new SupportingFile("Paths.kt.mustache", packageFolder, "Paths.kt"));
supportingFiles.add(new SupportingFile("Paths.kt.mustache", packageFolder, "Paths.kt"));
}

supportingFiles.add(new SupportingFile("application.conf.mustache", resourcesFolder, "application.conf"));
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/v2/kotlin-server/model.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import org.threeten.bp.LocalDateTime

{{#models}}
{{#model}}
{{#is this 'alias'}}typealias {{classname}} = {{dataType}}{{/is}}{{#isNot this 'alias'}}{{#is this 'enum'}}{{>enum_class}}{{/is}}{{#isNot this 'enum'}}{{>data_class}}{{/isNot}}{{/isNot}}
{{#is this 'alias'}}typealias {{classname}} = {{{dataType}}}{{/is}}{{#isNot this 'alias'}}{{#is this 'enum'}}{{>enum_class}}{{/is}}{{#isNot this 'enum'}}{{>data_class}}{{/isNot}}{{/isNot}}
{{/model}}
{{/models}}