Issue 4416 (Assist escapeReservedWord with custom mappings) (#4480)

* Preliminary implementation for issue-4416

* Updated README.md with  reserved-words-mappings  parameter.
This commit is contained in:
Alex Nolasco 2017-01-09 05:22:25 -05:00 committed by wing328
parent 81b5b78fc2
commit 26ead9b58f
41 changed files with 214 additions and 64 deletions

View File

@ -289,6 +289,10 @@ OPTIONS
the format of swaggerType=generatedType,swaggerType=generatedType.
For example: array=List,map=Map,string=String
--reserved-words-mappings <import mappings>
specifies how a reserved name should be escaped to. Otherwise, the
default _<name> is used. For example id=identifier
-v, --verbose
verbose mode

View File

@ -117,7 +117,11 @@ public class Generate implements Runnable {
@Option(name = {"--http-user-agent"}, title = "http user agent", description = CodegenConstants.HTTP_USER_AGENT_DESC)
private String httpUserAgent;
@Option(name = {"--reserved-words-mappings"}, title = "import mappings",
description = "specifies how a reserved name should be escaped to. Otherwise, the default _<name> is used. For example id=identifier")
private String reservedWordsMappings;
@Override
public void run() {
@ -217,7 +221,7 @@ public class Generate implements Runnable {
applyTypeMappingsKvp(typeMappings, configurator);
applyAdditionalPropertiesKvp(additionalProperties, configurator);
applyLanguageSpecificPrimitivesCsv(languageSpecificPrimitives, configurator);
applyReservedWordsMappingsKvp(reservedWordsMappings, configurator);
final ClientOptInput clientOptInput = configurator.toClientOptInput();
new DefaultGenerator().opts(clientOptInput).generate();

View File

@ -21,6 +21,7 @@ import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyImportMapp
import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyInstantiationTypesKvp;
import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyLanguageSpecificPrimitivesCsv;
import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyTypeMappingsKvp;
import static io.swagger.codegen.config.CodegenConfiguratorUtils.applyReservedWordsMappingsKvp;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import java.io.File;
@ -284,6 +285,10 @@ public class CodeGenMojo extends AbstractMojo {
if(configOptions.containsKey("additional-properties")) {
applyAdditionalPropertiesKvp(configOptions.get("additional-properties").toString(), configurator);
}
if(configOptions.containsKey("reserved-words-mappings")) {
applyReservedWordsMappingsKvp(configOptions.get("reserved-words-mappings").toString(), configurator);
}
}
if (environmentVariables != null) {

View File

@ -14,7 +14,7 @@ import com.samskivert.mustache.Mustache.Compiler;
public interface CodegenConfig {
CodegenType getTag();
String getName();
String getHelp();
@ -118,6 +118,8 @@ public interface CodegenConfig {
Map<String, String> modelDocTemplateFiles();
Set<String> languageSpecificPrimitives();
Map<String, String> reservedWordsMappings();
void preprocessSwagger(Swagger swagger);
@ -197,4 +199,5 @@ public interface CodegenConfig {
String getHttpUserAgent();
String getCommonTemplateDir();
}

View File

@ -92,6 +92,7 @@ public class DefaultCodegen {
protected Map<String, String> modelTestTemplateFiles = new HashMap<String, String>();
protected Map<String, String> apiDocTemplateFiles = new HashMap<String, String>();
protected Map<String, String> modelDocTemplateFiles = new HashMap<String, String>();
protected Map<String, String> reservedWordsMappings = new HashMap<String, String>();
protected String templateDir;
protected String embeddedTemplateDir;
protected String commonTemplateDir = "_common";
@ -468,6 +469,10 @@ public class DefaultCodegen {
public Map<String, String> modelDocTemplateFiles() {
return modelDocTemplateFiles;
}
public Map<String, String> reservedWordsMappings() {
return reservedWordsMappings;
}
public Map<String, String> apiTestTemplateFiles() {
return apiTestTemplateFiles;

View File

@ -60,6 +60,8 @@ public class CodegenConfigurator {
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
private Map<String, String> importMappings = new HashMap<String, String>();
private Set<String> languageSpecificPrimitives = new HashSet<String>();
private Map<String, String> reservedWordMappings = new HashMap<String, String>();
private String gitUserId="GIT_USER_ID";
private String gitRepoId="GIT_REPO_ID";
private String releaseNote="Minor update";
@ -263,7 +265,7 @@ public class CodegenConfigurator {
this.additionalProperties = additionalProperties;
return this;
}
public CodegenConfigurator addAdditionalProperty(String key, Object value) {
this.additionalProperties.put(key, value);
return this;
@ -341,7 +343,21 @@ public class CodegenConfigurator {
this.httpUserAgent= httpUserAgent;
return this;
}
public Map<String, String> getReservedWordsMappings() {
return reservedWordMappings;
}
public CodegenConfigurator setReservedWordsMappings(Map<String, String> reservedWordsMappings) {
this.reservedWordMappings = reservedWordsMappings;
return this;
}
public CodegenConfigurator addAdditionalReservedWordMapping(String key, String value) {
this.reservedWordMappings.put(key, value);
return this;
}
public ClientOptInput toClientOptInput() {
Validate.notEmpty(lang, "language must be specified");
@ -360,7 +376,8 @@ public class CodegenConfigurator {
config.typeMapping().putAll(typeMappings);
config.importMapping().putAll(importMappings);
config.languageSpecificPrimitives().addAll(languageSpecificPrimitives);
config.reservedWordsMappings().putAll(reservedWordMappings);
checkAndSetAdditionalProperty(apiPackage, CodegenConstants.API_PACKAGE);
checkAndSetAdditionalProperty(modelPackage, CodegenConstants.MODEL_PACKAGE);
checkAndSetAdditionalProperty(invokerPackage, CodegenConstants.INVOKER_PACKAGE);

View File

@ -58,6 +58,13 @@ public final class CodegenConfiguratorUtils {
}
}
public static void applyReservedWordsMappingsKvp(String reservedWordMappings, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(reservedWordMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addAdditionalReservedWordMapping(entry.getKey(), entry.getValue());
}
}
private static Set<String> createSetFromCsvList(String csvProperty) {
final List<String> values = OptionUtils.splitCommaSeparatedList(csvProperty);
return new HashSet<String>(values);
@ -74,4 +81,6 @@ public final class CodegenConfiguratorUtils {
return result;
}
}

View File

@ -401,10 +401,13 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
}
return name;
}
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -328,7 +328,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -251,8 +251,11 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
.replaceAll(regLastPathSeparator+ "$", "");
}
@Override
public String escapeReservedWord(String name) {
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -67,7 +67,10 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -114,10 +114,13 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
return CodegenType.CLIENT;
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String apiFileFolder() {

View File

@ -154,6 +154,9 @@ public class AkkaScalaClientCodegen extends AbstractScalaCodegen implements Code
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "`" + name + "`";
}

View File

@ -119,7 +119,10 @@ public class AndroidClientCodegen extends DefaultCodegen implements CodegenConfi
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -170,7 +170,10 @@ public class CsharpDotNet2ClientCodegen extends DefaultCodegen implements Codege
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -174,7 +174,10 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -182,8 +182,11 @@ public class ErlangServerCodegen extends DefaultCodegen implements CodegenConfig
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return name + "_"; // add an underscore to the name
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**

View File

@ -177,8 +177,11 @@ public class FlashClientCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
return name + "_";
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override

View File

@ -236,10 +236,13 @@ public class FlaskConnexionCodegen extends DefaultCodegen implements CodegenConf
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name
}
/**
* Location to write api files. You can use the apiPackage() as defined when the class is
* instantiated

View File

@ -180,9 +180,10 @@ public class GoClientCodegen extends DefaultCodegen implements CodegenConfig {
// - XName
// - X_Name
// ... or maybe a suffix?
// - Name_ ... think this will work.
// FIXME: This should also really be a customizable option
// - Name_ ... think this will work.
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return camelize(name) + '_';
}

View File

@ -204,6 +204,9 @@ public class GoServerCodegen extends DefaultCodegen implements CodegenConfig {
*/
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name
}

View File

@ -154,8 +154,11 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return name + "_";
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
public String firstLetterToUpper(String word) {

View File

@ -119,10 +119,13 @@ public class JMeterCodegen extends DefaultCodegen implements CodegenConfig {
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**
* Location to write model files. You can use the modelPackage() as defined when the class is

View File

@ -313,7 +313,10 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -102,7 +102,10 @@ public class JavascriptClosureAngularClientCodegen extends DefaultCodegen implem
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -147,13 +147,16 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
* those terms here. This logic is only called if a variable matches the reseved words
* those terms here. This logic is only called if a variable matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**

View File

@ -538,8 +538,17 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
return toVarName(name);
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
* those terms here. This logic is only called if a variable matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -161,7 +161,10 @@ public class PerlClientCodegen extends DefaultCodegen implements CodegenConfig {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -307,7 +307,10 @@ public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -251,7 +251,10 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -198,8 +198,11 @@ public class Qt5CPPGenerator extends DefaultCodegen implements CodegenConfig {
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
/**

View File

@ -186,7 +186,10 @@ public class Rails5ServerCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -330,7 +330,10 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -107,10 +107,13 @@ public class SilexServerCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String apiFileFolder() {
return (outputFolder + "/" + apiPackage()).replace('/', File.separatorChar);

View File

@ -104,7 +104,10 @@ public class SinatraServerCodegen extends DefaultCodegen implements CodegenConfi
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -118,7 +118,10 @@ public class SlimFrameworkServerCodegen extends DefaultCodegen implements Codege
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -77,7 +77,10 @@ public class StaticDocCodegen extends DefaultCodegen implements CodegenConfig {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -235,10 +235,13 @@ public class Swift3Codegen extends DefaultCodegen implements CodegenConfig {
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name
}
@Override
public String modelFileFolder() {
return outputFolder + File.separator + sourceFolder + modelPackage().replace('.', File.separatorChar);

View File

@ -232,11 +232,14 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
protected boolean isReservedWord(String word) {
return word != null && reservedWords.contains(word); //don't lowercase as super does
}
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name; // add an underscore to the name
}
@Override
public String modelFileFolder() {

View File

@ -261,7 +261,10 @@ public class TizenClientCodegen extends DefaultCodegen implements CodegenConfig
}
@Override
public String escapeReservedWord(String name) {
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}

View File

@ -1,9 +1,10 @@
package io.swagger.codegen.utils;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import joptsimple.internal.Strings;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
@ -22,10 +23,10 @@ public class OptionUtils {
results.add(pair);
}
}
//Strings.isNullOrEmpty(input)
return results;
}
public static List<String> splitCommaSeparatedList(String input) {
List<String> results = new ArrayList<String>();
@ -39,5 +40,4 @@ public class OptionUtils {
return results;
}
}