diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
index d7a04d25312..ae2d2a6fc3d 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
@@ -761,6 +761,8 @@ public class DefaultCodegen implements CodegenConfig {
public String toVarName(String name) {
if (reservedWords.contains(name)) {
return escapeReservedWord(name);
+ } else if (((CharSequence) name).chars().anyMatch(character -> specialCharReplacements.keySet().contains( "" + ((char) character)))) {
+ return escapeSpecialCharacters(name, null, null);
} else {
return name;
}
@@ -777,6 +779,8 @@ public class DefaultCodegen implements CodegenConfig {
name = removeNonNameElementToCamelCase(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
if (reservedWords.contains(name)) {
return escapeReservedWord(name);
+ } else if (((CharSequence) name).chars().anyMatch(character -> specialCharReplacements.keySet().contains( "" + ((char) character)))) {
+ return escapeSpecialCharacters(name, null, null);
}
return name;
}
@@ -815,6 +819,32 @@ public class DefaultCodegen implements CodegenConfig {
throw new RuntimeException("reserved word " + name + " not allowed");
}
+ /**
+ * Return the name with escaped characters.
+ *
+ * @param name the name to be escaped
+ * @param charactersToAllow characters that are not escaped
+ * @param appdendixToReplacement String to append to replaced characters.
+ * @return the escaped word
+ *
+ * throws Runtime exception as word is not escaped properly.
+ */
+ public String escapeSpecialCharacters(String name, List charactersToAllow, String appdendixToReplacement) {
+ String result = (String) ((CharSequence) name).chars().mapToObj(c -> {
+ String character = "" + (char) c;
+ if (charactersToAllow != null && charactersToAllow.contains(character)) {
+ return character;
+ } else if (specialCharReplacements.containsKey(character)) {
+ return specialCharReplacements.get(character) + (appdendixToReplacement != null ? appdendixToReplacement: "");
+ } else {
+ return character;
+ }
+ }).reduce( (c1, c2) -> "" + c1 + c2).orElse(null);
+
+ if (result != null) return result;
+ throw new RuntimeException("Word '" + name + "' could not be escaped.");
+ }
+
/**
* Return the fully-qualified "Model" name for import
*
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java
index 85feab0ca1c..3f7d014a3ca 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java
@@ -574,6 +574,14 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
name = name.substring(0, 2).toLowerCase() + name.substring(2);
}
+ // If name contains special chars -> replace them.
+ if ((((CharSequence) name).chars().anyMatch(character -> specialCharReplacements.keySet().contains( "" + ((char) character))))) {
+ List allowedCharacters = new ArrayList<>();
+ allowedCharacters.add("_");
+ allowedCharacters.add("$");
+ name = escapeSpecialCharacters(name, allowedCharacters, "_");
+ }
+
// camelize (lower first character) the variable name
// pet_id => petId
name = camelize(name, true);
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaModelTest.java
index b54a8bf2ebb..54dc3b0cd63 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaModelTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaModelTest.java
@@ -242,6 +242,31 @@ public class JavaModelTest {
Assert.assertTrue(property.isContainer);
}
+ @Test(description = "convert a model with restriced characters")
+ public void restrictedCharactersPropertiesTest() {
+ final Schema schema = new Schema()
+ .description("a sample model")
+ .addProperties("@Some:restricted%characters#to!handle+", new BooleanSchema());
+ final DefaultCodegen codegen = new JavaClientCodegen();
+ final CodegenModel cm = codegen.fromModel("sample", schema, Collections.singletonMap("sample", schema));
+
+ Assert.assertEquals(cm.name, "sample");
+ Assert.assertEquals(cm.classname, "Sample");
+ Assert.assertEquals(cm.description, "a sample model");
+ Assert.assertEquals(cm.vars.size(), 1);
+
+ final CodegenProperty property = cm.vars.get(0);
+ Assert.assertEquals(property.baseName, "@Some:restricted%characters#to!handle+");
+ Assert.assertEquals(property.getter, "getAtSomeColonRestrictedPercentCharactersHashToExclamationHandlePlus");
+ Assert.assertEquals(property.setter, "setAtSomeColonRestrictedPercentCharactersHashToExclamationHandlePlus");
+ Assert.assertEquals(property.dataType, "Boolean");
+ Assert.assertEquals(property.name, "atSomeColonRestrictedPercentCharactersHashToExclamationHandlePlus");
+ Assert.assertEquals(property.defaultValue, "null");
+ Assert.assertEquals(property.baseType, "Boolean");
+ Assert.assertFalse(property.required);
+ Assert.assertTrue(property.isNotContainer);
+ }
+
@Test(description = "convert a model with complex properties")
public void complexPropertiesTest() {
final Schema schema = new Schema()