From 288df9375e098544c8871e6def7a704eb8519f4d Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 14 Apr 2016 18:19:35 +0200 Subject: [PATCH] json schema, refactor code that when searching definitions we go to definitions registry with absolute path only once (break the recursive call) --- .../impl/JsonSchemaExportedDefinitions.java | 7 +-- .../jsonSchema/impl/JsonSchemaReader.java | 46 ++++++++++++------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaExportedDefinitions.java b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaExportedDefinitions.java index 742898d3ec9a..2fbf3e10bcce 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaExportedDefinitions.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaExportedDefinitions.java @@ -57,15 +57,16 @@ public class JsonSchemaExportedDefinitions { } public JsonSchemaObject findDefinition(@NotNull VirtualFile requestingSchemaKey, @NotNull final String url, - @NotNull final String relativePart, - @NotNull final JsonSchemaObject rootObject) { + @NotNull final String relativePart) { synchronized (myLock) { ensureInitialized(); final VirtualFile key = myId2Key.get(url); if (key != null) myCrossDependencies.putValue(key, requestingSchemaKey); final Map map = myMap.get(url); if (map != null) { - return JsonSchemaReader.findDefinition(key, relativePart, rootObject, map, null); + final JsonSchemaObject found = map.get(relativePart); + if (found != null) return found; + //return JsonSchemaReader.findRelativeDefinition(relativePart, rootObject); } } return null; diff --git a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReader.java b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReader.java index d13010ee184a..b6c441ede44e 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReader.java +++ b/json/src/com/jetbrains/jsonSchema/impl/JsonSchemaReader.java @@ -43,7 +43,7 @@ public class JsonSchemaReader { adapter.readSomeProperty(in, name, object); } - processReferences(object, adapter.getAllObjects(), adapter.getIds(), definitions); + processReferences(object, adapter.getAllObjects(), definitions); final ArrayList withoutDefinitions = new ArrayList(adapter.getAllObjects()); removeDefinitions(object, withoutDefinitions); return object; @@ -123,20 +123,18 @@ public class JsonSchemaReader { private void processReferences(JsonSchemaObject root, Set objects, - Map ids, @Nullable JsonSchemaExportedDefinitions definitions) { final ArrayDeque queue = new ArrayDeque(); queue.addAll(objects); int control = 10000; while (!queue.isEmpty()) { - // todo graph algorithm?? if (--control == 0) throw new RuntimeException("cyclic definitions search"); final JsonSchemaObject current = queue.removeFirst(); if ("#".equals(current.getRef())) continue; if (current.getRef() != null) { - final JsonSchemaObject definition = findDefinition(myKey, current.getRef(), root, ids, definitions); + final JsonSchemaObject definition = findDefinition(myKey, current.getRef(), root, definitions); if (definition == null) { if (definitions == null) { // just skip current item @@ -160,27 +158,41 @@ public class JsonSchemaReader { } } - @Nullable - public static JsonSchemaObject findDefinition(@Nullable VirtualFile key, - @NotNull String ref, - @NotNull final JsonSchemaObject root, - @NotNull final Map ids, - @Nullable JsonSchemaExportedDefinitions definitions) { - if ("#".equals(ref)) { - return root; - } - final JsonSchemaObject found = ids.get(ref); - if (found != null) return found; + private static JsonSchemaObject findAbsoluteDefinition(@Nullable VirtualFile key, + @NotNull String ref, + @Nullable JsonSchemaExportedDefinitions definitions) { if (!ref.startsWith("#/")) { int idx = ref.indexOf("#/"); if (idx == -1) throw new RuntimeException("Non-relative or erroneous reference: " + ref); if (definitions == null || key == null) return null; final String url = ref.substring(0, idx); final String relative = ref.substring(idx); - return definitions.findDefinition(key, url, relative, root); + return definitions.findDefinition(key, url, relative); } - ref = ref.substring(2); + return null; + } + @Nullable + private static JsonSchemaObject findDefinition(@Nullable VirtualFile key, + @NotNull String ref, + @NotNull final JsonSchemaObject root, + @Nullable JsonSchemaExportedDefinitions definitions) { + if ("#".equals(ref)) { + return root; + } + if (!ref.startsWith("#/")) { + return findAbsoluteDefinition(key, ref, definitions); + } + return findRelativeDefinition(ref, root); + } + + @NotNull + public static JsonSchemaObject findRelativeDefinition(@NotNull String ref, @NotNull JsonSchemaObject root) { + if ("#".equals(ref)) { + return root; + } + if (!ref.startsWith("#/")) throw new RuntimeException("Non-relative or erroneous reference: " + ref); + ref = ref.substring(2); final String[] parts = ref.split("/"); JsonSchemaObject current = root; for (int i = 0; i < parts.length; i++) {