WEB-35463 Add a checkbox to prefer remote JSON schemas over bundled schemas

This commit is contained in:
Anton Lobov
2018-10-25 13:48:45 +02:00
parent 7ca728717e
commit d67ca3e728
3 changed files with 53 additions and 15 deletions
@@ -23,11 +23,13 @@ public class JsonSchemaCatalogConfigurable implements Configurable {
@NotNull private final Project myProject;
private final JBCheckBox myCatalogCheckBox;
private final JBCheckBox myRemoteCheckBox;
private final JBCheckBox myPreferRemoteCheckBox;
public JsonSchemaCatalogConfigurable(@NotNull final Project project) {
myProject = project;
myCatalogCheckBox = new JBCheckBox("Use schemastore.org JSON Schema catalog");
myRemoteCheckBox = new JBCheckBox("Allow downloading JSON Schemas from remote sources");
myPreferRemoteCheckBox = new JBCheckBox("Always download the most recent version of schemas");
}
@Nullable
@@ -40,16 +42,23 @@ public class JsonSchemaCatalogConfigurable implements Configurable {
myRemoteCheckBox.addChangeListener(c -> {
boolean selected = myRemoteCheckBox.isSelected();
myCatalogCheckBox.setEnabled(selected);
myPreferRemoteCheckBox.setEnabled(selected);
if (!selected) {
myCatalogCheckBox.setSelected(false);
myPreferRemoteCheckBox.setSelected(false);
}
});
builder.addComponent(myCatalogCheckBox);
builder.addComponent(
createComment("Schemas will be downloaded and assigned using the <a href=\"http://schemastore.org/json/\">SchemaStore API</a>"));
addWithComment(builder, myCatalogCheckBox,
"Schemas will be downloaded and assigned using the <a href=\"http://schemastore.org/json/\">SchemaStore API</a>");
addWithComment(builder, myPreferRemoteCheckBox,
"Schemas will always be downloaded from the SchemaStore, even if some of them are bundled with the IDE");
return wrap(builder.getPanel());
}
private static void addWithComment(FormBuilder builder, JBCheckBox box, String s) {
builder.addComponent(new ComponentPanelBuilder(box).withComment(s).createPanel());
}
@SuppressWarnings("SameParameterValue")
@NotNull
private static JLabel createComment(@NotNull String comment) {
@@ -72,9 +81,12 @@ public class JsonSchemaCatalogConfigurable implements Configurable {
@Override
public void reset() {
JsonSchemaCatalogProjectConfiguration.MyState state = JsonSchemaCatalogProjectConfiguration.getInstance(myProject).getState();
myRemoteCheckBox.setSelected(state == null || state.myIsRemoteActivityEnabled);
myCatalogCheckBox.setEnabled(state == null || state.myIsRemoteActivityEnabled);
final boolean remoteEnabled = state == null || state.myIsRemoteActivityEnabled;
myRemoteCheckBox.setSelected(remoteEnabled);
myCatalogCheckBox.setEnabled(remoteEnabled);
myPreferRemoteCheckBox.setEnabled(remoteEnabled);
myCatalogCheckBox.setSelected(state == null || state.myIsCatalogEnabled);
myPreferRemoteCheckBox.setSelected(state == null || state.myIsPreferRemoteSchemas);
}
@Override
@@ -82,13 +94,15 @@ public class JsonSchemaCatalogConfigurable implements Configurable {
JsonSchemaCatalogProjectConfiguration.MyState state = JsonSchemaCatalogProjectConfiguration.getInstance(myProject).getState();
return state == null
|| state.myIsCatalogEnabled != myCatalogCheckBox.isSelected()
|| state.myIsPreferRemoteSchemas != myPreferRemoteCheckBox.isSelected()
|| state.myIsRemoteActivityEnabled != myRemoteCheckBox.isSelected();
}
@Override
public void apply() throws ConfigurationException {
JsonSchemaCatalogProjectConfiguration.getInstance(myProject).setState(myCatalogCheckBox.isSelected(),
myRemoteCheckBox.isSelected());
myRemoteCheckBox.isSelected(),
myPreferRemoteCheckBox.isSelected());
}
@Nls(capitalization = Nls.Capitalization.Title)
@@ -22,6 +22,11 @@ public class JsonSchemaCatalogProjectConfiguration implements PersistentStateCom
return state != null && state.myIsCatalogEnabled;
}
public boolean isPreferRemoteSchemas() {
MyState state = getState();
return state != null && state.myIsPreferRemoteSchemas;
}
public void addChangeHandler(Runnable runnable) {
myChangeHandlers.add(runnable);
}
@@ -33,8 +38,8 @@ public class JsonSchemaCatalogProjectConfiguration implements PersistentStateCom
public JsonSchemaCatalogProjectConfiguration() {
}
public void setState(boolean isEnabled, boolean isRemoteActivityEnabled) {
myState = new MyState(isEnabled, isRemoteActivityEnabled);
public void setState(boolean isEnabled, boolean isRemoteActivityEnabled, boolean isPreferRemoteSchemas) {
myState = new MyState(isEnabled, isRemoteActivityEnabled, isPreferRemoteSchemas);
for (Runnable handler : myChangeHandlers) {
handler.run();
}
@@ -66,12 +71,16 @@ public class JsonSchemaCatalogProjectConfiguration implements PersistentStateCom
@Tag("remoteActivityEnabled")
public boolean myIsRemoteActivityEnabled = true;
@Tag("preferRemoteSchemas")
public boolean myIsPreferRemoteSchemas = false;
MyState() {
}
MyState(boolean isCatalogEnabled, boolean isRemoteActivityEnabled) {
MyState(boolean isCatalogEnabled, boolean isRemoteActivityEnabled, boolean isPreferRemoteSchemas) {
myIsCatalogEnabled = isCatalogEnabled;
myIsRemoteActivityEnabled = isRemoteActivityEnabled;
myIsPreferRemoteSchemas = isPreferRemoteSchemas;
}
}
}
@@ -9,10 +9,12 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.impl.http.HttpVirtualFile;
import com.intellij.util.containers.ConcurrentList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import com.jetbrains.jsonSchema.JsonSchemaCatalogProjectConfiguration;
import com.jetbrains.jsonSchema.JsonSchemaVfsListener;
import com.jetbrains.jsonSchema.extension.*;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
@@ -38,7 +40,7 @@ public class JsonSchemaServiceImpl implements JsonSchemaService {
public JsonSchemaServiceImpl(@NotNull Project project) {
myProject = project;
myState = new MyState(() -> getProvidersFromFactories());
myState = new MyState(() -> getProvidersFromFactories(), myProject);
myBuiltInSchemaIds = new ClearableLazyValue<Set<String>>() {
@NotNull
@Override
@@ -234,7 +236,8 @@ public class JsonSchemaServiceImpl implements JsonSchemaService {
// this hack is needed to handle user-defined mappings via urls
// we cannot perform that inside corresponding provider, because it leads to recursive component dependency
// this way we're preventing http files when a built-in schema exists
if (schemaFile instanceof HttpVirtualFile) {
if (!JsonSchemaCatalogProjectConfiguration.getInstance(myProject).isPreferRemoteSchemas()
&& schemaFile instanceof HttpVirtualFile) {
String url = schemaFile.getUrl();
VirtualFile first1 = getLocalSchemaByUrl(url);
return first1 != null ? first1 : schemaFile;
@@ -379,15 +382,17 @@ public class JsonSchemaServiceImpl implements JsonSchemaService {
private static class MyState {
@NotNull private final Factory<List<JsonSchemaFileProvider>> myFactory;
@NotNull private final Project myProject;
@NotNull private final AtomicClearableLazyValue<Map<VirtualFile, JsonSchemaFileProvider>> myData;
private MyState(@NotNull final Factory<List<JsonSchemaFileProvider>> factory) {
private MyState(@NotNull final Factory<List<JsonSchemaFileProvider>> factory, @NotNull Project project) {
myFactory = factory;
myProject = project;
myData = new AtomicClearableLazyValue<Map<VirtualFile, JsonSchemaFileProvider>>() {
@NotNull
@Override
public Map<VirtualFile, JsonSchemaFileProvider> compute() {
return Collections.unmodifiableMap(createFileProviderMap(myFactory.create()));
return Collections.unmodifiableMap(createFileProviderMap(myFactory.create(), myProject));
}
};
}
@@ -412,12 +417,22 @@ public class JsonSchemaServiceImpl implements JsonSchemaService {
}
@NotNull
private static Map<VirtualFile, JsonSchemaFileProvider> createFileProviderMap(@NotNull final List<JsonSchemaFileProvider> list) {
private static Map<VirtualFile, JsonSchemaFileProvider> createFileProviderMap(@NotNull final List<JsonSchemaFileProvider> list,
@NotNull Project project) {
// if there are different providers with the same schema files,
// stream API does not allow to collect same keys with Collectors.toMap(): throws duplicate key
final Map<VirtualFile, JsonSchemaFileProvider> map = new THashMap<>();
for (JsonSchemaFileProvider provider : list) {
VirtualFile schemaFile = provider.getSchemaFile();
VirtualFile schemaFile = null;
if (JsonSchemaCatalogProjectConfiguration.getInstance(project).isPreferRemoteSchemas()) {
final String source = provider.getRemoteSource();
if (source != null && !source.endsWith("!")) {
schemaFile = VirtualFileManager.getInstance().findFileByUrl(source);
}
}
if (schemaFile == null) {
schemaFile = provider.getSchemaFile();
}
if (schemaFile != null) {
map.put(schemaFile, provider);
}