Skip to content

Commit

Permalink
Merge pull request #2508 from wing328/php_enum
Browse files Browse the repository at this point in the history
[PHP][C#] better enum support
  • Loading branch information
wing328 committed May 3, 2016
2 parents 40815f5 + 2c41451 commit bed21e4
Show file tree
Hide file tree
Showing 260 changed files with 6,433 additions and 2,698 deletions.
2 changes: 1 addition & 1 deletion bin/javascript-petstore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ fi

# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
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"
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"

java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class CodegenModel {
public List<CodegenProperty> requiredVars = new ArrayList<CodegenProperty>(); // a list of required properties
public List<CodegenProperty> optionalVars = new ArrayList<CodegenProperty>(); // a list of optional properties
public List<CodegenProperty> allVars;
public List<String> allowableValues;
public Map<String, Object> allowableValues;

// Sorted sets of required parameters.
public Set<String> mandatory = new TreeSet<String>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,161 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
return objs;
}

/**
* post process enum defined in model's properties
*
* @param objs Map of models
* @return maps of models with better enum support
*/
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");

// for enum model
if (Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null) {
Map<String, Object> allowableValues = cm.allowableValues;

List<Object> values = (List<Object>) allowableValues.get("values");
List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
String commonPrefix = findCommonPrefixOfVars(values);
int truncateIdx = commonPrefix.length();
for (Object value : values) {
Map<String, String> enumVar = new HashMap<String, String>();
String enumName;
if (truncateIdx == 0) {
enumName = value.toString();
} else {
enumName = value.toString().substring(truncateIdx);
if ("".equals(enumName)) {
enumName = value.toString();
}
}
enumVar.put("name", toEnumVarName(enumName, cm.dataType));
enumVar.put("value", toEnumValue(value.toString(), cm.dataType));
enumVars.add(enumVar);
}
cm.allowableValues.put("enumVars", enumVars);
}

// for enum model's properties
for (CodegenProperty var : cm.vars) {
Map<String, Object> allowableValues = var.allowableValues;

// handle ArrayProperty
if (var.items != null) {
allowableValues = var.items.allowableValues;
}

if (allowableValues == null) {
continue;
}
//List<String> values = (List<String>) allowableValues.get("values");
List<Object> values = (List<Object>) allowableValues.get("values");
if (values == null) {
continue;
}

// put "enumVars" map into `allowableValues", including `name` and `value`
List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
String commonPrefix = findCommonPrefixOfVars(values);
int truncateIdx = commonPrefix.length();
for (Object value : values) {
Map<String, String> enumVar = new HashMap<String, String>();
String enumName;
if (truncateIdx == 0) {
enumName = value.toString();
} else {
enumName = value.toString().substring(truncateIdx);
if ("".equals(enumName)) {
enumName = value.toString();
}
}
enumVar.put("name", toEnumVarName(enumName, var.datatype));
enumVar.put("value", toEnumValue(value.toString(), var.datatype));
enumVars.add(enumVar);
}
allowableValues.put("enumVars", enumVars);
// handle default value for enum, e.g. available => StatusEnum.AVAILABLE
if (var.defaultValue != null) {
String enumName = null;
for (Map<String, String> enumVar : enumVars) {
if (toEnumValue(var.defaultValue, var.datatype).equals(enumVar.get("value"))) {
enumName = enumVar.get("name");
break;
}
}
if (enumName != null) {
var.defaultValue = toEnumDefaultValue(enumName, var.datatypeWithEnum);
}
}
}
}
return objs;
}

/**
* Returns the common prefix of variables for enum naming
*
* @param vars List of variable names
* @return the common prefix for naming
*/
public String findCommonPrefixOfVars(List<Object> vars) {
try {
String[] listStr = vars.toArray(new String[vars.size()]);

String prefix = StringUtils.getCommonPrefix(listStr);
// exclude trailing characters that should be part of a valid variable
// e.g. ["status-on", "status-off"] => "status-" (not "status-o")
return prefix.replaceAll("[a-zA-Z0-9]+\\z", "");
} catch (ArrayStoreException e) {
return "";
}
}

/**
* Return the enum default value in the language specifed format
*
* @param value enum variable name
* @param datatype data type
* @return the default value for the enum
*/
public String toEnumDefaultValue(String value, String datatype) {
return datatype + "." + value;
}

/**
* Return the enum value in the language specifed format
* e.g. status becomes "status"
*
* @param value enum variable name
* @param datatype data type
* @return the sanitized value for enum
*/
public String toEnumValue(String value, String datatype) {
if ("number".equalsIgnoreCase(datatype)) {
return value;
} else {
return "\"" + escapeText(value) + "\"";
}
}

/**
* Return the sanitized variable name for enum
*
* @param value enum variable name
* @param datatype data type
* @return the sanitized variable name for enum
*/
public String toEnumVarName(String value, String datatype) {
String var = value.replaceAll("\\W+", "_").toUpperCase();
if (var.matches("\\d.*")) {
return "_" + var;
} else {
return var;
}
}

// override with any special post-processing
@SuppressWarnings("static-method")
Expand Down Expand Up @@ -456,7 +611,7 @@ public String toParamName(String name) {
/**
* Return the Enum name (e.g. StatusEnum given 'status')
*
* @param property Codegen property object
* @param property Codegen property
* @return the Enum name
*/
@SuppressWarnings("static-method")
Expand Down Expand Up @@ -1012,7 +1167,9 @@ public CodegenModel fromModel(String name, Model model, Map<String, Model> allDe
ModelImpl impl = (ModelImpl) model;
if(impl.getEnum() != null && impl.getEnum().size() > 0) {
m.isEnum = true;
m.allowableValues = impl.getEnum();
// comment out below as allowableValues is not set in post processing model enum
m.allowableValues = new HashMap<String, Object>();
m.allowableValues.put("values", impl.getEnum());
Property p = PropertyBuilder.build(impl.getType(), impl.getFormat(), null);
m.dataType = getSwaggerType(p);
}
Expand Down Expand Up @@ -1144,7 +1301,8 @@ public CodegenProperty fromProperty(String name, Property p) {
}
}

if (p instanceof BaseIntegerProperty) {
// type is integer and without format
if (p instanceof BaseIntegerProperty && !(p instanceof IntegerProperty) && !(p instanceof LongProperty)) {
BaseIntegerProperty sp = (BaseIntegerProperty) p;
property.isInteger = true;
/*if (sp.getEnum() != null) {
Expand Down Expand Up @@ -1210,7 +1368,8 @@ public CodegenProperty fromProperty(String name, Property p) {
property.isByteArray = true;
}

if (p instanceof DecimalProperty) {
// type is number and without format
if (p instanceof DecimalProperty && !(p instanceof DoubleProperty) && !(p instanceof FloatProperty)) {
DecimalProperty sp = (DecimalProperty) p;
property.isFloat = true;
/*if (sp.getEnum() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,6 @@ public void processOpts() {
}
}

@Override
public String toEnumName(CodegenProperty property) {
return StringUtils.capitalize(property.name) + "Enum?";
}

@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
Expand All @@ -223,7 +218,8 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
}
}
}
return objs;
// process enum in models
return postProcessModelsEnum(objs);
}

@Override
Expand Down Expand Up @@ -544,4 +540,54 @@ public void setPackageVersion(String packageVersion) {
public void setSourceFolder(String sourceFolder) {
this.sourceFolder = sourceFolder;
}


@Override
public String toEnumVarName(String name, String datatype) {
String enumName = sanitizeName(name);

enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");

enumName = camelize(enumName) + "Enum";

LOGGER.info("toEnumVarName = " + enumName);

if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
}
}

@Override
public String toEnumName(CodegenProperty property) {
return sanitizeName(camelize(property.name)) + "Enum";
}

/*
@Override
public String toEnumName(CodegenProperty property) {
String enumName = sanitizeName(property.name);
if (!StringUtils.isEmpty(modelNamePrefix)) {
enumName = modelNamePrefix + "_" + enumName;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
enumName = enumName + "_" + modelNameSuffix;
}
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(enumName)) {
LOGGER.warn(enumName + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + enumName));
enumName = "model_" + enumName; // e.g. return => ModelReturn (after camelize)
}
if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
}
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,59 @@ public String getNameUsingModelPropertyNaming(String name) {
}

}

@Override
public String toEnumValue(String value, String datatype) {
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
return value;
} else {
return "\'" + escapeText(value) + "\'";
}
}

@Override
public String toEnumDefaultValue(String value, String datatype) {
return datatype + "_" + value;
}

@Override
public String toEnumVarName(String name, String datatype) {
// number
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
String varName = new String(name);
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
return varName;
}

// string
String enumName = sanitizeName(underscore(name).toUpperCase());
enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");

if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
}
}

@Override
public String toEnumName(CodegenProperty property) {
String enumName = toModelName(property.name) + "Enum";

if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
}
}

@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// process enum in models
return postProcessModelsEnum(objs);
}

}
Loading

0 comments on commit bed21e4

Please sign in to comment.