Skip to content

Commit b8223dd

Browse files
committed
add basic implementation and unit test
1 parent 9432aaf commit b8223dd

7 files changed

Lines changed: 350 additions & 110 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
package org.openapitools.codegen;
1919

20+
import com.fasterxml.jackson.core.type.TypeReference;
21+
import com.fasterxml.jackson.databind.ObjectMapper;
2022
import com.github.benmanes.caffeine.cache.Cache;
2123
import com.github.benmanes.caffeine.cache.Caffeine;
2224
import com.github.benmanes.caffeine.cache.Ticker;
@@ -69,6 +71,10 @@
6971
import org.openapitools.codegen.utils.ExamplesUtils;
7072
import org.openapitools.codegen.utils.ModelUtils;
7173
import org.openapitools.codegen.utils.OneOfImplementorAdditionalData;
74+
import org.openapitools.codegen.validations.oas.ModelVendorExtensionAdd;
75+
import org.openapitools.codegen.validations.oas.ModelVendorExtensionRemove;
76+
import org.openapitools.codegen.validations.oas.OperationVendorExtensionAdd;
77+
import org.openapitools.codegen.validations.oas.OperationVendorExtensionRemove;
7278
import org.slf4j.Logger;
7379
import org.slf4j.LoggerFactory;
7480

@@ -101,6 +107,29 @@ public class DefaultCodegen implements CodegenConfig {
101107

102108
public static FeatureSet DefaultFeatureSet;
103109

110+
private final ObjectMapper mapper = new ObjectMapper();
111+
112+
public static final String MODEL_VENDOR_EXTENSION_REMOVE = "modelVendorExtensionRemove";
113+
public static final String MODEL_VENDOR_EXTENSION_ADD = "modelVendorExtensionAdd";
114+
public static final String OPERATION_VENDOR_EXTENSION_REMOVE = "operationVendorExtensionRemove";
115+
public static final String OPERATION_VENDOR_EXTENSION_ADD = "operationVendorExtensionAdd";
116+
117+
@Getter
118+
@Setter
119+
private Map<String, ModelVendorExtensionRemove> modelVendorExtensionRemove = new HashMap<>();
120+
121+
@Getter
122+
@Setter
123+
private Map<String, ModelVendorExtensionAdd> modelVendorExtensionAdd = new HashMap<>();
124+
125+
@Getter
126+
@Setter
127+
private Map<String, OperationVendorExtensionRemove> operationVendorExtensionRemove = new HashMap<>();
128+
129+
@Getter
130+
@Setter
131+
private Map<String, OperationVendorExtensionAdd> operationVendorExtensionAdd = new HashMap<>();
132+
104133
// A cache of sanitized words. The sanitizeName() method is invoked many times with the same
105134
// arguments, this cache is used to optimized performance.
106135
private static final Cache<SanitizeNameOptions, String> sanitizedNameCache;
@@ -430,6 +459,28 @@ public void processOpts() {
430459
parseDefaultToEmptyContainer((String) additionalProperties.get(DEFAULT_TO_EMPTY_CONTAINER));
431460
defaultToEmptyContainer = true;
432461
}
462+
463+
if(additionalProperties.containsKey(MODEL_VENDOR_EXTENSION_REMOVE)) {
464+
setModelVendorExtensionRemove(
465+
mapper.convertValue(additionalProperties.get(MODEL_VENDOR_EXTENSION_REMOVE), new TypeReference<Map<String, ModelVendorExtensionRemove>>() {})
466+
);
467+
}
468+
if(additionalProperties.containsKey(OPERATION_VENDOR_EXTENSION_REMOVE)) {
469+
setOperationVendorExtensionRemove(
470+
mapper.convertValue(additionalProperties.get(OPERATION_VENDOR_EXTENSION_REMOVE), new TypeReference<Map<String, OperationVendorExtensionRemove>>() {})
471+
);
472+
}
473+
474+
if(additionalProperties.containsKey(MODEL_VENDOR_EXTENSION_ADD)) {
475+
setModelVendorExtensionAdd(
476+
mapper.convertValue(additionalProperties.get(MODEL_VENDOR_EXTENSION_ADD), new TypeReference<>() {})
477+
);
478+
}
479+
if(additionalProperties.containsKey(OPERATION_VENDOR_EXTENSION_ADD)) {
480+
setOperationVendorExtensionAdd(
481+
mapper.convertValue(additionalProperties.get(OPERATION_VENDOR_EXTENSION_ADD), new TypeReference<>() {})
482+
);
483+
}
433484
}
434485

435486
/***
@@ -1136,6 +1187,97 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
11361187
@Override
11371188
@SuppressWarnings("unused")
11381189
public void processOpenAPI(OpenAPI openAPI) {
1190+
LinkedHashMap<String, Operation> operationsByOperationId = openAPI.getPaths().entrySet().stream()
1191+
.flatMap(path -> path.getValue().readOperations().stream())
1192+
.collect(Collectors.toMap(Operation::getOperationId, Function.identity(), (existing, replacement) -> existing, LinkedHashMap::new));
1193+
Map<String, Schema> modelsByName = openAPI.getComponents().getSchemas();
1194+
1195+
// Remove model vendor extensions
1196+
modelVendorExtensionRemove.forEach((name, ext) -> {
1197+
if (modelsByName.containsKey(name)) {
1198+
Schema schema = modelsByName.get(name);
1199+
if (schema.getExtensions() != null) {
1200+
ext.getClazz().forEach(schema.getExtensions()::remove);
1201+
}
1202+
ext.getFields().forEach((fieldName, fieldExtensionsToRemove) -> {
1203+
Map<String, Schema> props = schema.getProperties();
1204+
if (props != null && props.get(fieldName) != null && props.get(fieldName).getExtensions() != null) {
1205+
Map fieldExtensions = props.get(fieldName).getExtensions();
1206+
fieldExtensionsToRemove.forEach(fieldExtensions::remove);
1207+
}
1208+
});
1209+
}
1210+
});
1211+
1212+
// Add model vendor extensions
1213+
modelVendorExtensionAdd.forEach((name, ext) -> {
1214+
if (modelsByName.containsKey(name)) {
1215+
var schema = modelsByName.get(name);
1216+
// retrieve the extensions map or initialize
1217+
Map<String, Object> classExt = Objects.requireNonNullElse((Map<String, Object>) schema.getExtensions(), new HashMap<>());
1218+
ext.getClazz().forEach((extName, extVals) -> mergeExtensions(classExt, extName, extVals));
1219+
// put the modified map back
1220+
schema.setExtensions(classExt);
1221+
var props = schema.getProperties();
1222+
if (props != null) {
1223+
ext.getFields().forEach((fieldName, fieldExts) -> {
1224+
if (props.containsKey(fieldName)) {
1225+
Schema fieldSchema = (Schema) props.get(fieldName);
1226+
// retrieve the extensions map or initialize
1227+
Map<String, Object> fieldExt = Objects.requireNonNullElse((Map<String, Object>) fieldSchema.getExtensions(), new HashMap<>());
1228+
fieldExts.forEach((extName, extVals) -> mergeExtensions(fieldExt, extName, extVals));
1229+
// put the modified map back
1230+
fieldSchema.setExtensions(fieldExt);
1231+
}
1232+
});
1233+
}
1234+
}
1235+
});
1236+
1237+
// Remove operation vendor extensions
1238+
operationVendorExtensionRemove.forEach((opId, ext) -> {
1239+
if (operationsByOperationId.containsKey(opId)) {
1240+
var op = operationsByOperationId.get(opId);
1241+
if (op.getExtensions() != null) {
1242+
ext.getMethod().forEach(op.getExtensions()::remove);
1243+
}
1244+
ext.getParams().forEach((paramName, paramExtensionsToRemove) -> {
1245+
var params = op.getParameters().stream().collect(Collectors.toMap(Parameter::getName, Function.identity()));
1246+
if (params.containsKey(paramName) && params.get(paramName).getExtensions() != null) {
1247+
var paramsExtensions = params.get(paramName).getExtensions();
1248+
paramExtensionsToRemove.forEach(paramsExtensions::remove);
1249+
}
1250+
});
1251+
}
1252+
});
1253+
1254+
// Add operation vendor extensions
1255+
operationVendorExtensionAdd.forEach((opId, ext) -> {
1256+
if (operationsByOperationId.containsKey(opId)) {
1257+
var op = operationsByOperationId.get(opId);
1258+
// retrieve the extensions map or initialize
1259+
Map<String, Object> operationExtensions = Objects.requireNonNullElse(op.getExtensions(), new HashMap<>());
1260+
ext.getMethod().forEach((extName, extVals) -> mergeExtensions(operationExtensions, extName, extVals));
1261+
// put the modified map back
1262+
op.setExtensions(operationExtensions);
1263+
var params = op.getParameters().stream().collect(Collectors.toMap(Parameter::getName, Function.identity()));
1264+
ext.getParameters().forEach((paramName, paramExts) -> {
1265+
if (params.containsKey(paramName)) {
1266+
Parameter parameter = params.get(paramName);
1267+
// retrieve the extensions map or initialize
1268+
Map<String, Object> paramExt = Objects.requireNonNullElse(parameter.getExtensions(), new HashMap<>());
1269+
paramExts.forEach((extName, extVals) -> mergeExtensions(paramExt, extName, extVals));
1270+
// put the modified map back
1271+
parameter.setExtensions(paramExt);
1272+
}
1273+
});
1274+
}
1275+
});
1276+
}
1277+
1278+
private void mergeExtensions(Map<String, Object> extensionsMap, String name, List<String> values) {
1279+
var existing = getObjectAsStringList(extensionsMap.get(name));
1280+
extensionsMap.put(name, Stream.concat(existing.stream(), values.stream()).collect(Collectors.toList()));
11391281
}
11401282

11411283
// override with any special handling of the JMustache compiler
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.openapitools.codegen.validations.oas;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Map;
9+
10+
public class ModelVendorExtensionAdd {
11+
12+
@Getter
13+
@Setter
14+
private Map<String, List<String>> clazz = new HashMap<>();
15+
16+
@Getter
17+
@Setter
18+
private Map<String, Map<String, List<String>>> fields;
19+
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.openapitools.codegen.validations.oas;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
7+
import java.util.ArrayList;
8+
import java.util.HashMap;
9+
import java.util.List;
10+
import java.util.Map;
11+
12+
public class ModelVendorExtensionRemove {
13+
14+
@Getter
15+
@Setter
16+
@JsonProperty("class")
17+
private List<String> clazz = new ArrayList<>();
18+
19+
@Getter
20+
@Setter
21+
private Map<String, List<String>> fields = new HashMap<>();
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.openapitools.codegen.validations.oas;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Map;
9+
10+
public class OperationVendorExtensionAdd {
11+
12+
@Getter
13+
@Setter
14+
private Map<String, List<String>> method = new HashMap<>();
15+
16+
@Getter
17+
@Setter
18+
private Map<String, Map<String, List<String>>> parameters = new HashMap<>();
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.openapitools.codegen.validations.oas;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
import java.util.ArrayList;
7+
import java.util.HashMap;
8+
import java.util.List;
9+
import java.util.Map;
10+
11+
public class OperationVendorExtensionRemove {
12+
13+
@Getter
14+
@Setter
15+
private List<String> method = new ArrayList<>();
16+
17+
@Getter
18+
@Setter
19+
private Map<String, List<String>> params = new HashMap<>();
20+
}

modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinSpringServerCodegenTest.java

Lines changed: 0 additions & 108 deletions
This file was deleted.

0 commit comments

Comments
 (0)