Skip to content

Commit bed21e4

Browse files
committed
Merge pull request #2508 from wing328/php_enum
[PHP][C#] better enum support
2 parents 40815f5 + 2c41451 commit bed21e4

File tree

260 files changed

+6433
-2698
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

260 files changed

+6433
-2698
lines changed

bin/javascript-petstore.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ fi
2626

2727
# if you've executed sbt assembly previously it will use that instead.
2828
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
29-
ags="$@ generate -t modules/swagger-codegen/src/main/resources/Javascript -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l javascript -o samples/client/petstore/javascript"
29+
ags="$@ generate -t modules/swagger-codegen/src/main/resources/Javascript -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l javascript -o samples/client/petstore/javascript"
3030

3131
java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags

modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class CodegenModel {
2020
public List<CodegenProperty> requiredVars = new ArrayList<CodegenProperty>(); // a list of required properties
2121
public List<CodegenProperty> optionalVars = new ArrayList<CodegenProperty>(); // a list of optional properties
2222
public List<CodegenProperty> allVars;
23-
public List<String> allowableValues;
23+
public Map<String, Object> allowableValues;
2424

2525
// Sorted sets of required parameters.
2626
public Set<String> mandatory = new TreeSet<String>();

modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java

Lines changed: 163 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,161 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
133133
return objs;
134134
}
135135

136+
/**
137+
* post process enum defined in model's properties
138+
*
139+
* @param objs Map of models
140+
* @return maps of models with better enum support
141+
*/
142+
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
143+
List<Object> models = (List<Object>) objs.get("models");
144+
for (Object _mo : models) {
145+
Map<String, Object> mo = (Map<String, Object>) _mo;
146+
CodegenModel cm = (CodegenModel) mo.get("model");
147+
148+
// for enum model
149+
if (Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null) {
150+
Map<String, Object> allowableValues = cm.allowableValues;
151+
152+
List<Object> values = (List<Object>) allowableValues.get("values");
153+
List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
154+
String commonPrefix = findCommonPrefixOfVars(values);
155+
int truncateIdx = commonPrefix.length();
156+
for (Object value : values) {
157+
Map<String, String> enumVar = new HashMap<String, String>();
158+
String enumName;
159+
if (truncateIdx == 0) {
160+
enumName = value.toString();
161+
} else {
162+
enumName = value.toString().substring(truncateIdx);
163+
if ("".equals(enumName)) {
164+
enumName = value.toString();
165+
}
166+
}
167+
enumVar.put("name", toEnumVarName(enumName, cm.dataType));
168+
enumVar.put("value", toEnumValue(value.toString(), cm.dataType));
169+
enumVars.add(enumVar);
170+
}
171+
cm.allowableValues.put("enumVars", enumVars);
172+
}
173+
174+
// for enum model's properties
175+
for (CodegenProperty var : cm.vars) {
176+
Map<String, Object> allowableValues = var.allowableValues;
177+
178+
// handle ArrayProperty
179+
if (var.items != null) {
180+
allowableValues = var.items.allowableValues;
181+
}
182+
183+
if (allowableValues == null) {
184+
continue;
185+
}
186+
//List<String> values = (List<String>) allowableValues.get("values");
187+
List<Object> values = (List<Object>) allowableValues.get("values");
188+
if (values == null) {
189+
continue;
190+
}
191+
192+
// put "enumVars" map into `allowableValues", including `name` and `value`
193+
List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
194+
String commonPrefix = findCommonPrefixOfVars(values);
195+
int truncateIdx = commonPrefix.length();
196+
for (Object value : values) {
197+
Map<String, String> enumVar = new HashMap<String, String>();
198+
String enumName;
199+
if (truncateIdx == 0) {
200+
enumName = value.toString();
201+
} else {
202+
enumName = value.toString().substring(truncateIdx);
203+
if ("".equals(enumName)) {
204+
enumName = value.toString();
205+
}
206+
}
207+
enumVar.put("name", toEnumVarName(enumName, var.datatype));
208+
enumVar.put("value", toEnumValue(value.toString(), var.datatype));
209+
enumVars.add(enumVar);
210+
}
211+
allowableValues.put("enumVars", enumVars);
212+
// handle default value for enum, e.g. available => StatusEnum.AVAILABLE
213+
if (var.defaultValue != null) {
214+
String enumName = null;
215+
for (Map<String, String> enumVar : enumVars) {
216+
if (toEnumValue(var.defaultValue, var.datatype).equals(enumVar.get("value"))) {
217+
enumName = enumVar.get("name");
218+
break;
219+
}
220+
}
221+
if (enumName != null) {
222+
var.defaultValue = toEnumDefaultValue(enumName, var.datatypeWithEnum);
223+
}
224+
}
225+
}
226+
}
227+
return objs;
228+
}
229+
230+
/**
231+
* Returns the common prefix of variables for enum naming
232+
*
233+
* @param vars List of variable names
234+
* @return the common prefix for naming
235+
*/
236+
public String findCommonPrefixOfVars(List<Object> vars) {
237+
try {
238+
String[] listStr = vars.toArray(new String[vars.size()]);
239+
240+
String prefix = StringUtils.getCommonPrefix(listStr);
241+
// exclude trailing characters that should be part of a valid variable
242+
// e.g. ["status-on", "status-off"] => "status-" (not "status-o")
243+
return prefix.replaceAll("[a-zA-Z0-9]+\\z", "");
244+
} catch (ArrayStoreException e) {
245+
return "";
246+
}
247+
}
248+
249+
/**
250+
* Return the enum default value in the language specifed format
251+
*
252+
* @param value enum variable name
253+
* @param datatype data type
254+
* @return the default value for the enum
255+
*/
256+
public String toEnumDefaultValue(String value, String datatype) {
257+
return datatype + "." + value;
258+
}
259+
260+
/**
261+
* Return the enum value in the language specifed format
262+
* e.g. status becomes "status"
263+
*
264+
* @param value enum variable name
265+
* @param datatype data type
266+
* @return the sanitized value for enum
267+
*/
268+
public String toEnumValue(String value, String datatype) {
269+
if ("number".equalsIgnoreCase(datatype)) {
270+
return value;
271+
} else {
272+
return "\"" + escapeText(value) + "\"";
273+
}
274+
}
275+
276+
/**
277+
* Return the sanitized variable name for enum
278+
*
279+
* @param value enum variable name
280+
* @param datatype data type
281+
* @return the sanitized variable name for enum
282+
*/
283+
public String toEnumVarName(String value, String datatype) {
284+
String var = value.replaceAll("\\W+", "_").toUpperCase();
285+
if (var.matches("\\d.*")) {
286+
return "_" + var;
287+
} else {
288+
return var;
289+
}
290+
}
136291

137292
// override with any special post-processing
138293
@SuppressWarnings("static-method")
@@ -456,7 +611,7 @@ public String toParamName(String name) {
456611
/**
457612
* Return the Enum name (e.g. StatusEnum given 'status')
458613
*
459-
* @param property Codegen property object
614+
* @param property Codegen property
460615
* @return the Enum name
461616
*/
462617
@SuppressWarnings("static-method")
@@ -1012,7 +1167,9 @@ public CodegenModel fromModel(String name, Model model, Map<String, Model> allDe
10121167
ModelImpl impl = (ModelImpl) model;
10131168
if(impl.getEnum() != null && impl.getEnum().size() > 0) {
10141169
m.isEnum = true;
1015-
m.allowableValues = impl.getEnum();
1170+
// comment out below as allowableValues is not set in post processing model enum
1171+
m.allowableValues = new HashMap<String, Object>();
1172+
m.allowableValues.put("values", impl.getEnum());
10161173
Property p = PropertyBuilder.build(impl.getType(), impl.getFormat(), null);
10171174
m.dataType = getSwaggerType(p);
10181175
}
@@ -1144,7 +1301,8 @@ public CodegenProperty fromProperty(String name, Property p) {
11441301
}
11451302
}
11461303

1147-
if (p instanceof BaseIntegerProperty) {
1304+
// type is integer and without format
1305+
if (p instanceof BaseIntegerProperty && !(p instanceof IntegerProperty) && !(p instanceof LongProperty)) {
11481306
BaseIntegerProperty sp = (BaseIntegerProperty) p;
11491307
property.isInteger = true;
11501308
/*if (sp.getEnum() != null) {
@@ -1210,7 +1368,8 @@ public CodegenProperty fromProperty(String name, Property p) {
12101368
property.isByteArray = true;
12111369
}
12121370

1213-
if (p instanceof DecimalProperty) {
1371+
// type is number and without format
1372+
if (p instanceof DecimalProperty && !(p instanceof DoubleProperty) && !(p instanceof FloatProperty)) {
12141373
DecimalProperty sp = (DecimalProperty) p;
12151374
property.isFloat = true;
12161375
/*if (sp.getEnum() != null) {

modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,6 @@ public void processOpts() {
203203
}
204204
}
205205

206-
@Override
207-
public String toEnumName(CodegenProperty property) {
208-
return StringUtils.capitalize(property.name) + "Enum?";
209-
}
210-
211206
@Override
212207
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
213208
List<Object> models = (List<Object>) objs.get("models");
@@ -223,7 +218,8 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
223218
}
224219
}
225220
}
226-
return objs;
221+
// process enum in models
222+
return postProcessModelsEnum(objs);
227223
}
228224

229225
@Override
@@ -544,4 +540,54 @@ public void setPackageVersion(String packageVersion) {
544540
public void setSourceFolder(String sourceFolder) {
545541
this.sourceFolder = sourceFolder;
546542
}
543+
544+
545+
@Override
546+
public String toEnumVarName(String name, String datatype) {
547+
String enumName = sanitizeName(name);
548+
549+
enumName = enumName.replaceFirst("^_", "");
550+
enumName = enumName.replaceFirst("_$", "");
551+
552+
enumName = camelize(enumName) + "Enum";
553+
554+
LOGGER.info("toEnumVarName = " + enumName);
555+
556+
if (enumName.matches("\\d.*")) { // starts with number
557+
return "_" + enumName;
558+
} else {
559+
return enumName;
560+
}
561+
}
562+
563+
@Override
564+
public String toEnumName(CodegenProperty property) {
565+
return sanitizeName(camelize(property.name)) + "Enum";
566+
}
567+
568+
/*
569+
@Override
570+
public String toEnumName(CodegenProperty property) {
571+
String enumName = sanitizeName(property.name);
572+
if (!StringUtils.isEmpty(modelNamePrefix)) {
573+
enumName = modelNamePrefix + "_" + enumName;
574+
}
575+
576+
if (!StringUtils.isEmpty(modelNameSuffix)) {
577+
enumName = enumName + "_" + modelNameSuffix;
578+
}
579+
580+
// model name cannot use reserved keyword, e.g. return
581+
if (isReservedWord(enumName)) {
582+
LOGGER.warn(enumName + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + enumName));
583+
enumName = "model_" + enumName; // e.g. return => ModelReturn (after camelize)
584+
}
585+
586+
if (enumName.matches("\\d.*")) { // starts with number
587+
return "_" + enumName;
588+
} else {
589+
return enumName;
590+
}
591+
}
592+
*/
547593
}

modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractTypeScriptClientCodegen.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,4 +231,59 @@ public String getNameUsingModelPropertyNaming(String name) {
231231
}
232232

233233
}
234+
235+
@Override
236+
public String toEnumValue(String value, String datatype) {
237+
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
238+
return value;
239+
} else {
240+
return "\'" + escapeText(value) + "\'";
241+
}
242+
}
243+
244+
@Override
245+
public String toEnumDefaultValue(String value, String datatype) {
246+
return datatype + "_" + value;
247+
}
248+
249+
@Override
250+
public String toEnumVarName(String name, String datatype) {
251+
// number
252+
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
253+
String varName = new String(name);
254+
varName = varName.replaceAll("-", "MINUS_");
255+
varName = varName.replaceAll("\\+", "PLUS_");
256+
varName = varName.replaceAll("\\.", "_DOT_");
257+
return varName;
258+
}
259+
260+
// string
261+
String enumName = sanitizeName(underscore(name).toUpperCase());
262+
enumName = enumName.replaceFirst("^_", "");
263+
enumName = enumName.replaceFirst("_$", "");
264+
265+
if (enumName.matches("\\d.*")) { // starts with number
266+
return "_" + enumName;
267+
} else {
268+
return enumName;
269+
}
270+
}
271+
272+
@Override
273+
public String toEnumName(CodegenProperty property) {
274+
String enumName = toModelName(property.name) + "Enum";
275+
276+
if (enumName.matches("\\d.*")) { // starts with number
277+
return "_" + enumName;
278+
} else {
279+
return enumName;
280+
}
281+
}
282+
283+
@Override
284+
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
285+
// process enum in models
286+
return postProcessModelsEnum(objs);
287+
}
288+
234289
}

0 commit comments

Comments
 (0)