Boot Language Server obeys configured problem severities
This commit is contained in:
@@ -12,6 +12,7 @@ package org.springframework.ide.eclipse.boot.validation.preferences;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.springframework.ide.eclipse.boot.validation.BootValidationActivator;
|
||||
import org.springframework.ide.eclipse.boot.validation.rules.BootValidationProblemType;
|
||||
import org.springframework.ide.eclipse.editor.support.preferences.AbstractProblemSeverityPreferencesPage;
|
||||
@@ -45,4 +46,5 @@ public class BootValidationPreferencesPage extends AbstractProblemSeverityPrefer
|
||||
return BootValidationActivator.PLUGIN_ID;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,11 +19,13 @@ import java.util.List;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ProjectScope;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.preferences.DefaultScope;
|
||||
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||
import org.eclipse.jface.dialogs.ControlEnableState;
|
||||
import org.eclipse.jface.preference.ComboFieldEditor;
|
||||
import org.eclipse.jface.preference.FieldEditor;
|
||||
import org.eclipse.jface.preference.FieldEditorPreferencePage;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.swt.SWT;
|
||||
@@ -33,6 +35,7 @@ import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
import org.eclipse.ui.IWorkbenchPreferencePage;
|
||||
import org.eclipse.ui.IWorkbenchPropertyPage;
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.eclipse.ui.preferences.ScopedPreferenceStore;
|
||||
import org.osgi.service.prefs.BackingStoreException;
|
||||
import org.springframework.ide.eclipse.boot.util.Log;
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.osgi.framework.BundleContext;
|
||||
*/
|
||||
public class BootLanguageServerPlugin extends AbstractUIPlugin {
|
||||
|
||||
public static final String PLUGIN_ID = "org.springframework.tooling.boot.java.ls";
|
||||
public static String PLUGIN_ID = "org.springframework.tooling.boot.ls";
|
||||
|
||||
private static final Object LSP4E_COMMAND_SYMBOL_IN_WORKSPACE = "org.eclipse.lsp4e.symbolinworkspace";
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Map;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||
import org.eclipse.lsp4e.server.StreamConnectionProvider;
|
||||
@@ -35,6 +36,7 @@ import org.springframework.tooling.ls.eclipse.commons.LanguageServerCommonsActiv
|
||||
import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder;
|
||||
import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.RemoteAppData;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.ValueListener;
|
||||
import org.springsource.ide.eclipse.commons.livexp.util.Log;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
@@ -64,6 +66,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
|
||||
private LanguageServer languageServer;
|
||||
|
||||
private final IPropertyChangeListener configListener = (e) -> sendConfiguration();
|
||||
|
||||
private final ValueListener<ImmutableSet<RemoteAppData>> remoteAppsListener = (e, v) -> sendConfiguration();
|
||||
|
||||
private long timestampBeforeStart;
|
||||
@@ -117,6 +120,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
|
||||
fResourceListener = null;
|
||||
}
|
||||
BootLanguageServerPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(configListener);
|
||||
// BootLanguageServerPlugin.getPreferences().removePreferenceChangeListener(prefsListener);
|
||||
RemoteBootAppsDataHolder.getDefault().getRemoteApps().removeListener(remoteAppsListener);
|
||||
}
|
||||
|
||||
@@ -134,6 +138,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
|
||||
|
||||
// Add config listener
|
||||
BootLanguageServerPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(configListener);
|
||||
// BootLanguageServerPlugin.getPreferences().addPreferenceChangeListener(prefsListener);
|
||||
|
||||
// Add resource listener
|
||||
ResourcesPlugin.getWorkspace().addResourceChangeListener(fResourceListener = new ResourceListener(languageServer, Arrays.asList(
|
||||
@@ -194,9 +199,46 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
|
||||
bootJavaObj.put("validation", validation);
|
||||
bootJavaObj.put("remote-apps", getAllRemoteApps());
|
||||
settings.put("boot-java", bootJavaObj);
|
||||
|
||||
putValidationPreferences(settings);
|
||||
|
||||
this.languageServer.getWorkspaceService().didChangeConfiguration(new DidChangeConfigurationParams(settings));
|
||||
}
|
||||
|
||||
private void putValidationPreferences(Map<String, Object> settings) {
|
||||
try {
|
||||
IEclipsePreferences prefs = BootLanguageServerPlugin.getPreferences();
|
||||
for (String key : prefs.keys()) {
|
||||
if (key.startsWith("problem.")) {
|
||||
String val = prefs.get(key, null);
|
||||
if (val!=null) {
|
||||
dotPut(settings, "spring-boot.ls."+key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void dotPut(Object _settings, String dottedProperty, Object value) {
|
||||
if (_settings instanceof Map) {
|
||||
Map<String, Object> settings = (Map<String, Object>) _settings;
|
||||
int dot = dottedProperty.indexOf('.');
|
||||
if (dot>=0) {
|
||||
String first = dottedProperty.substring(0, dot);
|
||||
String rest = dottedProperty.substring(dot+1);
|
||||
Object nested = settings.getOrDefault(first, null);
|
||||
if (nested==null) {
|
||||
nested = new HashMap<>();
|
||||
settings.put(first, nested);
|
||||
}
|
||||
dotPut(nested, rest, value);
|
||||
} else {
|
||||
settings.put(dottedProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines remote boot app data from all configuration sources.
|
||||
|
||||
@@ -12,13 +12,14 @@ package org.springframework.tooling.boot.ls.prefs;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.springframework.ide.eclipse.editor.support.preferences.ProblemSeverityPreferencesUtil;
|
||||
import org.springframework.ide.eclipse.editor.support.preferences.ProblemSeverityPreferityPageFromMetadata;
|
||||
import org.springframework.tooling.boot.ls.BootLanguageServerPlugin;
|
||||
|
||||
public class ApplicationPropertiesEditorProblemSeverityPrefsPage extends ProblemSeverityPreferityPageFromMetadata {
|
||||
|
||||
public static final ProblemSeverityPreferencesUtil util = new ProblemSeverityPreferencesUtil("application.properties.problem.");
|
||||
public static final ProblemSeverityPreferencesUtil util = new ProblemSeverityPreferencesUtil("problem.properties.");
|
||||
|
||||
public ApplicationPropertiesEditorProblemSeverityPrefsPage() throws IOException {
|
||||
super(util, LanguageServerProblemTypesMetadata.load().get("application-properties"));
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.springframework.tooling.boot.ls.BootLanguageServerPlugin;
|
||||
|
||||
public class ApplicationYamlEditorProblemSeverityPrefsPage extends ProblemSeverityPreferityPageFromMetadata {
|
||||
|
||||
public static final ProblemSeverityPreferencesUtil util = new ProblemSeverityPreferencesUtil("application.yaml.problem.");
|
||||
public static final ProblemSeverityPreferencesUtil util = new ProblemSeverityPreferencesUtil("problem.yaml.");
|
||||
|
||||
public ApplicationYamlEditorProblemSeverityPrefsPage() throws IOException {
|
||||
super(util, LanguageServerProblemTypesMetadata.load().get("application-yaml"));
|
||||
@@ -28,5 +28,4 @@ public class ApplicationYamlEditorProblemSeverityPrefsPage extends ProblemSeveri
|
||||
protected String getPluginId() {
|
||||
return BootLanguageServerPlugin.PLUGIN_ID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,10 +14,8 @@ import org.eclipse.lsp4j.DiagnosticSeverity;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface DiagnosticSeverityProvider {
|
||||
DiagnosticSeverity getDiagnosticSeverity(ReconcileProblem problem);
|
||||
|
||||
static final DiagnosticSeverityProvider DEFAULT = (problem) -> {
|
||||
ProblemSeverity severity = problem.getType().getDefaultSeverity();
|
||||
|
||||
static DiagnosticSeverity diagnosticSeverity(ProblemSeverity severity) {
|
||||
switch (severity) {
|
||||
case ERROR:
|
||||
return DiagnosticSeverity.Error;
|
||||
@@ -32,5 +30,12 @@ public interface DiagnosticSeverityProvider {
|
||||
default:
|
||||
throw new IllegalStateException("Bug! Missing switch case?");
|
||||
}
|
||||
}
|
||||
|
||||
DiagnosticSeverity getDiagnosticSeverity(ReconcileProblem problem);
|
||||
|
||||
static final DiagnosticSeverityProvider DEFAULT = (problem) -> {
|
||||
ProblemSeverity severity = problem.getType().getDefaultSeverity();
|
||||
return diagnosticSeverity(severity);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -93,4 +93,8 @@ public class ReconcileProblemImpl implements ReconcileProblem {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName()+"("+type+", "+msg+")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,12 @@ import java.util.Set;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
@@ -129,7 +131,38 @@ public class Settings {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return settings.toString();
|
||||
return ""+settings;
|
||||
}
|
||||
|
||||
public Settings navigate(String... names) {
|
||||
if (this.settings!=null && !this.settings.isJsonNull()) {
|
||||
if (names.length==0) {
|
||||
return this;
|
||||
} else if (this.settings.isJsonObject()) {
|
||||
JsonObject obj = (JsonObject) this.settings;
|
||||
if (obj.has(names[0])) {
|
||||
Settings sub = new Settings(obj.get(names[0]));
|
||||
return sub.navigate(cdr(names));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Settings(JsonNull.INSTANCE);
|
||||
}
|
||||
|
||||
private String[] cdr(String[] names) {
|
||||
String[] rest = new String[names.length-1];
|
||||
for (int i = 0; i < rest.length; i++) {
|
||||
rest[i] = names[i+1];
|
||||
}
|
||||
return rest;
|
||||
}
|
||||
|
||||
public Iterable<String> keys() {
|
||||
if (settings!=null && settings.isJsonObject()) {
|
||||
JsonObject obj = (JsonObject) settings;
|
||||
return obj.keySet();
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,9 +39,6 @@ public class BootJavaConfig implements InitializingBean {
|
||||
public static final boolean VALIDAITON_SPEL_EXPRESSIONS_ENABLED_DEFAULT = true;
|
||||
|
||||
|
||||
//TODO: Consider changing this to something that raises Spring application events.
|
||||
// I.e. like described in here: https://www.baeldung.com/spring-events
|
||||
|
||||
private final SimpleWorkspaceService workspace;
|
||||
private Settings settings = new Settings(null);
|
||||
private ListenerList<Void> listeners = new ListenerList<Void>();
|
||||
@@ -140,4 +137,8 @@ public class BootJavaConfig implements InitializingBean {
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
workspace.onDidChangeConfiguraton(this::handleConfigurationChange);
|
||||
}
|
||||
|
||||
public Settings getRawSettings() {
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2020 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.app;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.DiagnosticSeverityProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.Settings;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ProblemSeverityConfigurer implements InitializingBean {
|
||||
|
||||
@Autowired
|
||||
private SimpleLanguageServer server;
|
||||
|
||||
@Autowired
|
||||
private BootJavaConfig config;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
config.addListener((x) -> configChanged());
|
||||
configChanged();
|
||||
}
|
||||
|
||||
private void configChanged() {
|
||||
Settings settings = config.getRawSettings();
|
||||
settings = settings.navigate("spring-boot", "ls", "problem");
|
||||
|
||||
Map<String, ProblemSeverity> severityOverrides = new HashMap<>();
|
||||
for (String editorType : settings.keys()) {
|
||||
Settings problemConf = settings.navigate(editorType);
|
||||
for (String code : problemConf.keys()) {
|
||||
String severity = problemConf.getString(code);
|
||||
System.out.println(code+" => "+severity);
|
||||
Assert.isLegal(!severityOverrides.containsKey(code), "Multpile entries for problem type "+code);
|
||||
severityOverrides.put(code, ProblemSeverity.valueOf(severity));
|
||||
}
|
||||
}
|
||||
server.setDiagnosticSeverityProvider((ReconcileProblem problem) -> {
|
||||
ProblemSeverity severity = severityOverrides.get(problem.getType().getCode());
|
||||
if (severity==null) {
|
||||
severity = problem.getType().getDefaultSeverity();
|
||||
}
|
||||
return DiagnosticSeverityProvider.diagnosticSeverity(severity);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -45,5 +45,5 @@ public class SpringPropertyProblem extends ReconcileProblemImpl {
|
||||
public void setPropertyName(String name) {
|
||||
propertyName = name;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user