Skip to content

Commit e646f7f

Browse files
committed
Merge branch '3.0.0' of https://github.com/endrec/swagger-codegen into endrec-3.0.0
# Conflicts: # modules/swagger-codegen/src/main/java/io/swagger/codegen/utils/ModelUtils.java
2 parents 33cb42b + 77ef153 commit e646f7f

File tree

1 file changed

+243
-0
lines changed
  • modules/swagger-codegen/src/main/java/io/swagger/codegen/utils

1 file changed

+243
-0
lines changed
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
package io.swagger.codegen.utils;
2+
3+
import io.swagger.codegen.CodegenModel;
4+
import io.swagger.codegen.CodegenProperty;
5+
import io.swagger.v3.oas.models.Operation;
6+
import io.swagger.v3.oas.models.PathItem;
7+
import org.apache.commons.lang3.StringEscapeUtils;
8+
import org.apache.commons.lang3.StringUtils;
9+
10+
import java.util.ArrayList;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.Objects;
15+
import java.util.stream.Collectors;
16+
import java.util.stream.Stream;
17+
18+
import static io.swagger.codegen.CodegenConstants.IS_ENUM_EXT_NAME;
19+
import static io.swagger.codegen.languages.helpers.ExtensionHelper.getBooleanValue;
20+
21+
public class ModelUtils {
22+
/**
23+
* Searches for the model by name in the map of models and returns it
24+
*
25+
* @param name Name of the model
26+
* @param models Map of models
27+
* @return model
28+
*/
29+
public static CodegenModel getModelByName(final String name, final Map<String, Object> models) {
30+
final Object data = models.get(name);
31+
if (data instanceof Map) {
32+
final Map<?, ?> dataMap = (Map<?, ?>) data;
33+
final Object dataModels = dataMap.get("models");
34+
if (dataModels instanceof List) {
35+
final List<?> dataModelsList = (List<?>) dataModels;
36+
for (final Object entry : dataModelsList) {
37+
if (entry instanceof Map) {
38+
final Map<?, ?> entryMap = (Map<?, ?>) entry;
39+
final Object model = entryMap.get("model");
40+
if (model instanceof CodegenModel) {
41+
return (CodegenModel) model;
42+
}
43+
}
44+
}
45+
}
46+
}
47+
return null;
48+
}
49+
50+
public static Operation[] createOperationArray (PathItem pathItem) {
51+
return Stream.of(
52+
pathItem.getGet(),
53+
pathItem.getPost(),
54+
pathItem.getDelete(),
55+
pathItem.getHead(),
56+
pathItem.getPut(),
57+
pathItem.getPatch(),
58+
pathItem.getOptions()
59+
)
60+
.filter(Objects::nonNull)
61+
.collect(Collectors.toSet())
62+
.toArray(new Operation[]{});
63+
}
64+
65+
public static void processCodegenModels(Map<String, CodegenModel> allModels) {
66+
// Fix up all parent and interface CodegenModel references.
67+
for (CodegenModel codegenModel : allModels.values()) {
68+
if (codegenModel.getParent() != null) {
69+
codegenModel.setParentModel(allModels.get(codegenModel.getParent()));
70+
}
71+
if (codegenModel.getInterfaces() == null || codegenModel.getInterfaces().isEmpty()) {
72+
continue;
73+
}
74+
codegenModel.setInterfaceModels(new ArrayList<CodegenModel>(codegenModel.getInterfaces().size()));
75+
for (String intf : codegenModel.getInterfaces()) {
76+
CodegenModel intfModel = allModels.get(intf);
77+
if (intfModel != null) {
78+
codegenModel.getInterfaceModels().add(intfModel);
79+
}
80+
}
81+
}
82+
// Let parent know about all its children
83+
for (String name : allModels.keySet()) {
84+
CodegenModel codegenModel = allModels.get(name);
85+
CodegenModel parent = allModels.get(codegenModel.getParent());
86+
// if a discriminator exists on the parent, don't add this child to the inheritance heirarchy
87+
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
88+
while (parent != null) {
89+
if (parent.getChildren() == null) {
90+
parent.setChildren(new ArrayList<CodegenModel>());
91+
}
92+
parent.getChildren().add(codegenModel);
93+
if (parent.getDiscriminator() == null) {
94+
parent = allModels.get(parent.parent);
95+
} else {
96+
parent = null;
97+
}
98+
}
99+
}
100+
}
101+
102+
public static void processModelEnums(Map<String, Object> objs) {
103+
List<Object> models = (List<Object>) objs.get("models");
104+
for (Object _mo : models) {
105+
Map<String, Object> mo = (Map<String, Object>) _mo;
106+
CodegenModel cm = (CodegenModel) mo.get("model");
107+
108+
// for enum model
109+
boolean isEnum = getBooleanValue(cm, IS_ENUM_EXT_NAME);
110+
if (Boolean.TRUE.equals(isEnum) && cm.allowableValues != null) {
111+
Map<String, Object> allowableValues = cm.allowableValues;
112+
List<Object> values = (List<Object>) allowableValues.get("values");
113+
List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
114+
String commonPrefix = findCommonPrefixOfVars(values);
115+
int truncateIdx = commonPrefix.length();
116+
for (Object value : values) {
117+
Map<String, String> enumVar = new HashMap<String, String>();
118+
String enumName;
119+
if (truncateIdx == 0) {
120+
enumName = value.toString();
121+
} else {
122+
enumName = value.toString().substring(truncateIdx);
123+
if ("".equals(enumName)) {
124+
enumName = value.toString();
125+
}
126+
}
127+
enumVar.put("name", toEnumVarName(enumName));
128+
enumVar.put("value", toEnumValue(value.toString(), cm.dataType));
129+
enumVars.add(enumVar);
130+
}
131+
cm.allowableValues.put("enumVars", enumVars);
132+
}
133+
134+
// update codegen property enum with proper naming convention
135+
// and handling of numbers, special characters
136+
for (CodegenProperty var : cm.vars) {
137+
updateCodegenPropertyEnum(var);
138+
}
139+
}
140+
}
141+
142+
/**
143+
* Returns the common prefix of variables for enum naming
144+
*
145+
* @param vars List of variable names
146+
* @return the common prefix for naming
147+
*/
148+
public static String findCommonPrefixOfVars(List<Object> vars) {
149+
try {
150+
String[] listStr = vars.toArray(new String[vars.size()]);
151+
String prefix = StringUtils.getCommonPrefix(listStr);
152+
// exclude trailing characters that should be part of a valid variable
153+
// e.g. ["status-on", "status-off"] => "status-" (not "status-o")
154+
return prefix.replaceAll("[a-zA-Z0-9]+\\z", "");
155+
} catch (ArrayStoreException e) {
156+
return "";
157+
}
158+
}
159+
160+
/**
161+
* Update codegen property's enum by adding "enumVars" (with name and value)
162+
*
163+
* @param var list of CodegenProperty
164+
*/
165+
public static void updateCodegenPropertyEnum(CodegenProperty var) {
166+
Map<String, Object> allowableValues = var.allowableValues;
167+
168+
// handle ArrayProperty
169+
if (var.items != null) {
170+
allowableValues = var.items.allowableValues;
171+
}
172+
173+
if (allowableValues == null) {
174+
return;
175+
}
176+
177+
List<Object> values = (List<Object>) allowableValues.get("values");
178+
if (values == null) {
179+
return;
180+
}
181+
182+
// put "enumVars" map into `allowableValues", including `name` and `value`
183+
List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
184+
String commonPrefix = findCommonPrefixOfVars(values);
185+
int truncateIdx = commonPrefix.length();
186+
for (Object value : values) {
187+
Map<String, String> enumVar = new HashMap<String, String>();
188+
String enumName;
189+
if (truncateIdx == 0) {
190+
enumName = value.toString();
191+
} else {
192+
enumName = value.toString().substring(truncateIdx);
193+
if ("".equals(enumName)) {
194+
enumName = value.toString();
195+
}
196+
}
197+
enumVar.put("name", toEnumVarName(enumName));
198+
enumVar.put("value", toEnumValue(value.toString(), var.datatype));
199+
enumVars.add(enumVar);
200+
}
201+
allowableValues.put("enumVars", enumVars);
202+
203+
// handle default value for enum, e.g. available => StatusEnum.AVAILABLE
204+
if (var.defaultValue != null) {
205+
String enumName = null;
206+
for (Map<String, String> enumVar : enumVars) {
207+
if (toEnumValue(var.defaultValue, var.datatype).equals(enumVar.get("value"))) {
208+
enumName = enumVar.get("name");
209+
break;
210+
}
211+
}
212+
if (enumName != null) {
213+
var.defaultValue = String.format("%s.%s", enumName, var.datatypeWithEnum);
214+
}
215+
}
216+
}
217+
218+
public static String toEnumVarName(String value) {
219+
if (value.length() == 0) {
220+
return "EMPTY";
221+
}
222+
String var = value.replaceAll("\\W+", "_").toUpperCase();
223+
if (var.matches("\\d.*")) {
224+
return "_" + var;
225+
} else {
226+
return var;
227+
}
228+
}
229+
230+
private static String toEnumValue(String value, String datatype) {
231+
if ("number".equalsIgnoreCase(datatype)) {
232+
return value;
233+
} else {
234+
value = StringEscapeUtils.unescapeJava(
235+
StringEscapeUtils.escapeJava(value)
236+
.replace("\\/", "/"))
237+
.replaceAll("[\\t\\n\\r]"," ")
238+
.replace("\\", "\\\\")
239+
.replace("\"", "\\\"");
240+
return String.format("\"%s\"", value);
241+
}
242+
}
243+
}

0 commit comments

Comments
 (0)