From b95982509118df82ca95bd64bc49f183109e7c96 Mon Sep 17 00:00:00 2001 From: "Irina.Chernushina" Date: Tue, 24 Oct 2017 16:55:35 +0200 Subject: [PATCH] json schema: do not keep schema virtual file(s) in static fields... ... of schema providers factories: different project-related user data (including project reference) could (and is actually) cached on this file objects, which leads to leaks --- .../extension/JsonSchemaFileProvider.java | 3 +++ .../JsonSchemaProjectSelfProviderFactory.java | 17 +++++++++++------ .../JsonSchemaUserDefinedProviderFactory.java | 5 +++++ .../jsonSchema/JsonSchemaTestProvider.java | 3 +++ .../src/META-INF/JsonPlugin.xml | 1 - 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaFileProvider.java b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaFileProvider.java index fd9475873c24..caa7d0726d88 100644 --- a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaFileProvider.java +++ b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaFileProvider.java @@ -3,6 +3,7 @@ package com.jetbrains.jsonSchema.extension; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public interface JsonSchemaFileProvider { boolean isAvailable(@NotNull VirtualFile file); @@ -10,7 +11,9 @@ public interface JsonSchemaFileProvider { @NotNull String getName(); + @Nullable VirtualFile getSchemaFile(); + @NotNull SchemaType getSchemaType(); } diff --git a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaProjectSelfProviderFactory.java b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaProjectSelfProviderFactory.java index 75b43e052412..b6755b37c3b7 100644 --- a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaProjectSelfProviderFactory.java +++ b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaProjectSelfProviderFactory.java @@ -20,6 +20,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.jetbrains.jsonSchema.ide.JsonSchemaService; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; @@ -29,8 +30,6 @@ import java.util.List; */ public class JsonSchemaProjectSelfProviderFactory implements JsonSchemaProviderFactory { public static final String SCHEMA_JSON_FILE_NAME = "schema.json"; - private final static VirtualFile SCHEMA_FILE = JsonSchemaProviderFactory.getResourceFile( - JsonSchemaProjectSelfProviderFactory.class, "/jsonSchema/schema.json"); @NotNull @Override @@ -40,10 +39,14 @@ public class JsonSchemaProjectSelfProviderFactory implements JsonSchemaProviderF private static class MyJsonSchemaFileProvider implements JsonSchemaFileProvider { public static final Pair KEY = Pair.create(SchemaType.schema, SchemaType.schema); - @NotNull - private final Project myProject; + @NotNull private final Project myProject; + @Nullable private final VirtualFile mySchemaFile; - private MyJsonSchemaFileProvider(@NotNull final Project project) {myProject = project;} + private MyJsonSchemaFileProvider(@NotNull final Project project) { + myProject = project; + // schema file can not be static here, because in schema's user data we cache project-scope objects (i.e. which can refer to project) + mySchemaFile = JsonSchemaProviderFactory.getResourceFile(JsonSchemaProjectSelfProviderFactory.class, "/jsonSchema/schema.json"); + } @Override public boolean isAvailable(@NotNull VirtualFile file) { @@ -56,11 +59,13 @@ public class JsonSchemaProjectSelfProviderFactory implements JsonSchemaProviderF return SCHEMA_JSON_FILE_NAME; } + @Nullable @Override public VirtualFile getSchemaFile() { - return SCHEMA_FILE; + return mySchemaFile; } + @NotNull @Override public SchemaType getSchemaType() { return SchemaType.schema; diff --git a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaUserDefinedProviderFactory.java b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaUserDefinedProviderFactory.java index c2817433fd9b..cf648e42821c 100644 --- a/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaUserDefinedProviderFactory.java +++ b/json/src/com/jetbrains/jsonSchema/extension/JsonSchemaUserDefinedProviderFactory.java @@ -9,6 +9,7 @@ import com.jetbrains.jsonSchema.JsonSchemaMappingsProjectConfiguration; import com.jetbrains.jsonSchema.UserDefinedJsonSchemaConfiguration; import com.jetbrains.jsonSchema.ide.JsonSchemaService; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.Collections; @@ -50,6 +51,7 @@ public class JsonSchemaUserDefinedProviderFactory implements JsonSchemaProviderF myPatterns = patterns; } + @Nullable @Override public VirtualFile getSchemaFile() { if (myVirtualFile != null && myVirtualFile.isValid()) return myVirtualFile; @@ -61,6 +63,7 @@ public class JsonSchemaUserDefinedProviderFactory implements JsonSchemaProviderF return myVirtualFile; } + @NotNull @Override public SchemaType getSchemaType() { return SchemaType.userSchema; @@ -74,6 +77,7 @@ public class JsonSchemaUserDefinedProviderFactory implements JsonSchemaProviderF @Override public boolean isAvailable(@NotNull VirtualFile file) { + //noinspection SimplifiableIfStatement if (myPatterns.isEmpty() || file.isDirectory() || !file.isValid() || getSchemaFile() == null || JsonSchemaService.Impl.get(myProject).isSchemaFile(file)) return false; return myPatterns.stream().anyMatch(processor -> processor.process(myProject, file)); @@ -87,6 +91,7 @@ public class JsonSchemaUserDefinedProviderFactory implements JsonSchemaProviderF MyProvider provider = (MyProvider)o; if (!myName.equals(provider.myName)) return false; + //noinspection RedundantIfStatement if (!FileUtil.filesEqual(myFile, provider.myFile)) return false; return true; diff --git a/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaTestProvider.java b/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaTestProvider.java index 0d6a2678a8de..3c63e9f69bb5 100644 --- a/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaTestProvider.java +++ b/json/tests/test/com/jetbrains/jsonSchema/JsonSchemaTestProvider.java @@ -7,6 +7,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.jetbrains.jsonSchema.extension.JsonSchemaFileProvider; import com.jetbrains.jsonSchema.extension.SchemaType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class JsonSchemaTestProvider implements JsonSchemaFileProvider { private final VirtualFile mySchemaFile; @@ -26,11 +27,13 @@ public class JsonSchemaTestProvider implements JsonSchemaFileProvider { return "test"; } + @Nullable @Override public VirtualFile getSchemaFile() { return mySchemaFile; } + @NotNull @Override public SchemaType getSchemaType() { return SchemaType.userSchema; diff --git a/platform/platform-resources/src/META-INF/JsonPlugin.xml b/platform/platform-resources/src/META-INF/JsonPlugin.xml index 50b1f8c48fd6..fc2309bba8a2 100644 --- a/platform/platform-resources/src/META-INF/JsonPlugin.xml +++ b/platform/platform-resources/src/META-INF/JsonPlugin.xml @@ -75,7 +75,6 @@ implementationClass="com.jetbrains.jsonSchema.impl.JsonSchemaDocumentationProvider"/> -