Skip to content

Commit af8bb82

Browse files
hararefrantuma
authored andcommitted
feat: introduce cache loaded extensions in OpenAPIDeserializer
1 parent 8d5b569 commit af8bb82

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java

-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ public void processSchema(Schema schema) {
4747
return;
4848
}
4949
if (openapi31) {
50-
// TODO use as singleton somewhere loaded as static used by both here and deserializer
5150
List<JsonSchemaParserExtension> jsonschemaExtensions = OpenAPIDeserializer.getJsonSchemaParserExtensions();
5251
for (JsonSchemaParserExtension jsonschemaExtension: jsonschemaExtensions) {
5352
if (jsonschemaExtension.resolveSchema(schema, cache, openAPI, openapi31)) {

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java

+34-8
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,17 @@ public class OpenAPIDeserializer {
264264
"(\\d{2}):(\\d{2})(\\.\\d+)?((Z)|([+-]\\d{2}:\\d{2}))$");
265265
private static final Pattern RFC3339_DATE_PATTERN = Pattern.compile("^(\\d{4})-(\\d{2})-(\\d{2})$");
266266
private static final String REFERENCE_SEPARATOR = "#/";
267+
268+
private static final int MAX_EXTENSION_ENTRIES = 20;
269+
270+
// Holds extensions to a given classloader. Implemented as a least-recently used cache
271+
private static final Map<ClassLoader, List<JsonSchemaParserExtension>> jsonSchemaParserExtensionMap = new LinkedHashMap<ClassLoader, List<JsonSchemaParserExtension>>() {
272+
@Override
273+
protected boolean removeEldestEntry(Map.Entry<ClassLoader, List<JsonSchemaParserExtension>> eldest) {
274+
return size() > MAX_EXTENSION_ENTRIES;
275+
}
276+
};
277+
267278
private Components components;
268279
private JsonNode rootNode;
269280
private Map<String, Object> rootMap;
@@ -3780,15 +3791,30 @@ public static List<JsonSchemaParserExtension> getJsonSchemaParserExtensions() {
37803791
return extensions;
37813792
}
37823793

3783-
protected static List<JsonSchemaParserExtension> getJsonSchemaParserExtensions(ClassLoader cl) {
3784-
final List<JsonSchemaParserExtension> extensions = new ArrayList<>();
3794+
/**
3795+
* Locates the extensions for given {@link ClassLoader} and stores them for performance reason in an in-memory
3796+
* (LRU) cache.
3797+
*
3798+
* @param cl the {@link ClassLoader} for which the extensions are located
3799+
* @return
3800+
*/
3801+
protected static List<JsonSchemaParserExtension> getJsonSchemaParserExtensions(ClassLoader cl) {
3802+
if (jsonSchemaParserExtensionMap.containsKey(cl)) {
3803+
return jsonSchemaParserExtensionMap.get(cl);
3804+
}
37853805

3786-
final ServiceLoader<JsonSchemaParserExtension> loader = ServiceLoader.load(JsonSchemaParserExtension.class, cl);
3787-
for (JsonSchemaParserExtension extension : loader) {
3788-
extensions.add(extension);
3789-
}
3790-
return extensions;
3791-
}
3806+
final List<JsonSchemaParserExtension> extensions = new ArrayList<>();
3807+
final ServiceLoader<JsonSchemaParserExtension> loader = ServiceLoader.load(JsonSchemaParserExtension.class, cl);
3808+
for (JsonSchemaParserExtension extension : loader) {
3809+
extensions.add(extension);
3810+
}
3811+
3812+
// don't cache null-Value classLoader (e.g. Bootstrap Classloader)
3813+
if (cl != null) {
3814+
jsonSchemaParserExtensionMap.put(cl, extensions);
3815+
}
3816+
return extensions;
3817+
}
37923818

37933819
public Schema getJsonSchema(JsonNode jsonNode, String location, ParseResult result) {
37943820
if (jsonNode == null) {

0 commit comments

Comments
 (0)