Skip to content

Commit 7f853ed

Browse files
authored
Merge pull request #176 from rbiersbach/scala_akka_http_server
Scala akka http server improvements
2 parents d16f30d + 4d6cff2 commit 7f853ed

35 files changed

+3543
-0
lines changed
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
package io.swagger.codegen.v3.generators.scala;
2+
3+
import java.io.File;
4+
import java.util.Arrays;
5+
import java.util.Iterator;
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
import com.samskivert.mustache.Escapers;
10+
import com.samskivert.mustache.Mustache;
11+
import io.swagger.codegen.v3.CliOption;
12+
import io.swagger.codegen.v3.CodegenConstants;
13+
import io.swagger.codegen.v3.generators.DefaultCodegenConfig;
14+
import io.swagger.codegen.v3.templates.MustacheTemplateEngine;
15+
import io.swagger.codegen.v3.templates.TemplateEngine;
16+
import io.swagger.v3.oas.models.media.ArraySchema;
17+
import io.swagger.v3.oas.models.media.MapSchema;
18+
import io.swagger.v3.oas.models.media.Schema;
19+
import org.apache.commons.lang3.StringUtils;
20+
21+
public abstract class AbstractScalaCodegen extends DefaultCodegenConfig {
22+
23+
protected String modelPropertyNaming = "camelCase";
24+
protected String sourceFolder = "src/main/scala";
25+
26+
public AbstractScalaCodegen() {
27+
super();
28+
29+
languageSpecificPrimitives.addAll(Arrays.asList(
30+
"String",
31+
"boolean",
32+
"Boolean",
33+
"Double",
34+
"Int",
35+
"Long",
36+
"Float",
37+
"Object",
38+
"Any",
39+
"List",
40+
"Seq",
41+
"Map",
42+
"Array"));
43+
44+
reservedWords.addAll(Arrays.asList(
45+
"abstract",
46+
"case",
47+
"catch",
48+
"class",
49+
"def",
50+
"do",
51+
"else",
52+
"extends",
53+
"false",
54+
"final",
55+
"finally",
56+
"for",
57+
"forSome",
58+
"if",
59+
"implicit",
60+
"import",
61+
"lazy",
62+
"match",
63+
"new",
64+
"null",
65+
"object",
66+
"override",
67+
"package",
68+
"private",
69+
"protected",
70+
"return",
71+
"sealed",
72+
"super",
73+
"this",
74+
"throw",
75+
"trait",
76+
"try",
77+
"true",
78+
"type",
79+
"val",
80+
"var",
81+
"while",
82+
"with",
83+
"yield"
84+
));
85+
86+
typeMapping.put("int", "Int");
87+
typeMapping.put("integer", "Int");
88+
89+
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
90+
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
91+
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC));
92+
}
93+
94+
@Override
95+
public void processOpts() {
96+
super.processOpts();
97+
98+
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
99+
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
100+
}
101+
}
102+
103+
public void setSourceFolder(String sourceFolder) {
104+
this.sourceFolder = sourceFolder;
105+
}
106+
107+
public String getSourceFolder() {
108+
return sourceFolder;
109+
}
110+
111+
@Override
112+
public String escapeReservedWord(String name) {
113+
if (this.reservedWordsMappings().containsKey(name)) {
114+
return this.reservedWordsMappings().get(name);
115+
}
116+
// Reserved words will be further escaped at the mustache compiler level.
117+
// Scala escaping done here (via `, without compiler escaping) would otherwise be HTML encoded.
118+
return "`" + name + "`";
119+
}
120+
121+
@Override
122+
public Mustache.Compiler processCompiler(Mustache.Compiler compiler) {
123+
Mustache.Escaper SCALA = new Mustache.Escaper() {
124+
@Override public String escape (String text) {
125+
// Fix included as suggested by akkie in #6393
126+
// The given text is a reserved word which is escaped by enclosing it with grave accents. If we would
127+
// escape that with the default Mustache `HTML` escaper, then the escaper would also escape our grave
128+
// accents. So we remove the grave accents before the escaping and add it back after the escaping.
129+
if (text.startsWith("`") && text.endsWith("`")) {
130+
String unescaped = text.substring(1, text.length() - 1);
131+
return "`" + Escapers.HTML.escape(unescaped) + "`";
132+
}
133+
134+
// All none reserved words will be escaped with the default Mustache `HTML` escaper
135+
return Escapers.HTML.escape(text);
136+
}
137+
};
138+
139+
return compiler.withEscaper(SCALA);
140+
}
141+
142+
@Override
143+
public String apiFileFolder() {
144+
return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar);
145+
}
146+
147+
@Override
148+
public String modelFileFolder() {
149+
return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar);
150+
}
151+
152+
@Override
153+
public String getTypeDeclaration(Schema propertySchema) {
154+
if (propertySchema instanceof ArraySchema) {
155+
Schema inner = ((ArraySchema) propertySchema).getItems();
156+
return String.format("%s[%s]", getSchemaType(propertySchema), getTypeDeclaration(inner));
157+
} else if (propertySchema instanceof MapSchema && hasSchemaProperties(propertySchema)) {
158+
Schema inner = (Schema) propertySchema.getAdditionalProperties();
159+
return String.format("%s[String, %s]", getSchemaType(propertySchema), getTypeDeclaration(inner));
160+
}
161+
return super.getTypeDeclaration(propertySchema);
162+
}
163+
164+
@Override
165+
public String getSchemaType(Schema propertySchema) {
166+
String swaggerType = super.getSchemaType(propertySchema);
167+
String type = null;
168+
if (typeMapping.containsKey(swaggerType)) {
169+
type = typeMapping.get(swaggerType);
170+
if (languageSpecificPrimitives.contains(type))
171+
return (type);
172+
} else
173+
type = swaggerType;
174+
return type;
175+
}
176+
177+
@Override
178+
public String toInstantiationType(Schema schemaProperty) {
179+
if (schemaProperty instanceof MapSchema && hasSchemaProperties(schemaProperty)) {
180+
String inner = getSchemaType((Schema) schemaProperty.getAdditionalProperties());
181+
return String.format("%s[%s]", instantiationTypes.get("map"), inner);
182+
} else if (schemaProperty instanceof ArraySchema) {
183+
ArraySchema arraySchema = (ArraySchema) schemaProperty;
184+
String inner = getSchemaType(arraySchema.getItems());
185+
return String.format("%s[%s]", instantiationTypes.get("array"), inner);
186+
} else {
187+
return null;
188+
}
189+
}
190+
191+
@Override
192+
public String toDefaultValue(Schema propertySchema) {
193+
if (propertySchema instanceof MapSchema && hasSchemaProperties(propertySchema)) {
194+
String inner = getSchemaType((Schema) propertySchema.getAdditionalProperties());
195+
return String.format("new HashMap[String, %s]()", inner);
196+
} else if(propertySchema instanceof ArraySchema) {
197+
ArraySchema arraySchema = (ArraySchema) propertySchema;
198+
String inner = getSchemaType(arraySchema.getItems());
199+
return String.format("new ListBuffer[%s]()", inner);
200+
} else {
201+
return "null";
202+
}
203+
}
204+
205+
@Override
206+
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
207+
// remove model imports to avoid warnings for importing class in the same package in Scala
208+
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
209+
final String prefix = modelPackage() + ".";
210+
Iterator<Map<String, String>> iterator = imports.iterator();
211+
while (iterator.hasNext()) {
212+
String _import = iterator.next().get("import");
213+
if (_import.startsWith(prefix)) iterator.remove();
214+
}
215+
return objs;
216+
}
217+
218+
@Override
219+
public String toModelFilename(String name) {
220+
// should be the same as the model name
221+
return toModelName(name);
222+
}
223+
224+
@Override
225+
public String escapeUnsafeCharacters(String input) {
226+
return input.replace("*/", "*_/").replace("/*", "/_*");
227+
}
228+
229+
@Override
230+
public TemplateEngine getTemplateEngine() {
231+
return new MustacheTemplateEngine(this);
232+
}
233+
234+
protected String formatIdentifier(String name, boolean capitalized) {
235+
String identifier = camelize(sanitizeName(name), true);
236+
if (capitalized) {
237+
identifier = StringUtils.capitalize(identifier);
238+
}
239+
if (identifier.matches("[a-zA-Z_$][\\w_$]+") && !isReservedWord(identifier)) {
240+
return identifier;
241+
}
242+
return escapeReservedWord(identifier);
243+
}
244+
245+
protected String stripPackageName(String input) {
246+
if (StringUtils.isEmpty(input) || input.lastIndexOf(".") < 0)
247+
return input;
248+
249+
int lastIndexOfDot = input.lastIndexOf(".");
250+
return input.substring(lastIndexOfDot + 1);
251+
}
252+
}

0 commit comments

Comments
 (0)