Add Remote apps prefs page

This was moved from boot dash.

See: https://www.pivotaltracker.com/story/show/163360865
This commit is contained in:
Kris De Volder
2019-06-04 12:27:04 -07:00
parent c1ec235398
commit 83d7ddecd7
8 changed files with 259 additions and 10 deletions

View File

@@ -26,7 +26,8 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.9.0",
org.eclipse.ui.editors;bundle-version="3.11.100",
org.springsource.ide.eclipse.commons.livexp,
org.apache.commons.lang3,
org.eclipse.wst.sse.ui;bundle-version="1.5.0";resolution:=optional
org.eclipse.wst.sse.ui;bundle-version="1.5.0";resolution:=optional,
org.json;bundle-version="1.0.0"
Import-Package: com.google.gson;version="2.7.0",
org.eclipse.jface.preference,
org.osgi.framework

View File

@@ -105,9 +105,15 @@
contentTypeId="org.eclipse.jdt.core.javaSource">
</participant>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
<page
category="org.springframework.tooling.boot.java.ls.preferences"
class="org.springframework.tooling.boot.ls.prefs.RemoteAppsPrefsPage"
id="org.springframework.tooling.boot.ls.prefs.RemoteAppsPrefsPage"
name="Remote Boot Apps">
</page>
<page
category="org.springframework.tooling.boot.ls.preferences"
class="org.springframework.tooling.boot.ls.BootJavaPreferencesPage"

View File

@@ -14,6 +14,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.keys.IBindingService;
@@ -29,7 +31,7 @@ import org.springsource.ide.eclipse.commons.livexp.core.LiveSetVariable;
*/
public class BootLanguageServerPlugin extends AbstractUIPlugin {
public static final String ID = "org.springframework.tooling.boot.java.ls";
public static final String PLUGIN_ID = "org.springframework.tooling.boot.java.ls";
private static final Object LSP4E_COMMAND_SYMBOL_IN_WORKSPACE = "org.eclipse.lsp4e.symbolinworkspace";
@@ -40,6 +42,10 @@ public class BootLanguageServerPlugin extends AbstractUIPlugin {
// Empty
}
public static IEclipsePreferences getPreferences() {
return InstanceScope.INSTANCE.getNode(PLUGIN_ID);
}
@Override
public void start(BundleContext context) throws Exception {
plugin = this;

View File

@@ -17,8 +17,11 @@ import java.net.URI;
import java.nio.file.FileSystems;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
@@ -32,8 +35,10 @@ import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.jsonrpc.messages.Message;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
import org.eclipse.lsp4j.services.LanguageServer;
import org.springframework.tooling.boot.ls.prefs.RemoteAppsPrefs;
import org.springframework.tooling.ls.eclipse.commons.LanguageServerCommonsActivator;
import org.springsource.ide.eclipse.commons.livexp.core.ValueListener;
import org.springsource.ide.eclipse.commons.livexp.ui.Disposable;
import com.google.common.collect.ImmutableSet;
@@ -49,7 +54,7 @@ import com.google.common.collect.ImmutableSet;
* @author Martin Lippert
*/
public class DelegatingStreamConnectionProvider implements StreamConnectionProvider {
private StreamConnectionProvider provider;
private ResourceListener fResourceListener;
private LanguageServer languageServer;
@@ -59,6 +64,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
private long timestampBeforeStart;
private long timestampWhenInitialized;
private Disposable remoteAppsPrefsListener;
public DelegatingStreamConnectionProvider() {
LanguageServerCommonsActivator.logInfo("Entering DelegatingStreamConnectionProvider()");
@@ -83,6 +89,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
public void start() throws IOException {
this.timestampBeforeStart = System.currentTimeMillis();
this.provider.start();
this.remoteAppsPrefsListener = RemoteAppsPrefs.addListener(this::sendConfiguration);
}
@Override
@@ -109,6 +116,10 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
}
BootLanguageServerPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(configListener);
BootLanguageServerPlugin.getRemoteBootApps().removeListener(remoteAppsListener);
if (remoteAppsPrefsListener!=null) {
remoteAppsPrefsListener.dispose();
remoteAppsPrefsListener = null;
}
}
@Override
@@ -223,16 +234,29 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
bootJavaObj.put("change-detection", bootChangeDetection);
bootJavaObj.put("scan-java-test-sources", scanTestJavaSources);
bootJavaObj.put("remote-apps", BootLanguageServerPlugin.getRemoteBootApps().getValues()
.stream()
.map(this::parseData)
.collect(Collectors.toList())
bootJavaObj.put("remote-apps", getAllRemoteApps()
);
settings.put("boot-java", bootJavaObj);
this.languageServer.getWorkspaceService().didChangeConfiguration(new DidChangeConfigurationParams(settings));
}
/**
* Combines remote boot app data from all configuration sources.
*/
protected List<RemoteBootAppData> getAllRemoteApps() {
ImmutableSet<Object> fromBootDash = BootLanguageServerPlugin.getRemoteBootApps().getValues();
List<List<String>> fromUserPrefs = new RemoteAppsPrefs().getRemoteAppData();
Set<Object> combined = new LinkedHashSet<>();
combined.addAll(fromBootDash);
combined.addAll(fromUserPrefs);
return combined
.stream()
.map(this::parseData)
.collect(Collectors.toList());
}
@SuppressWarnings("unchecked")
private RemoteBootAppData parseData(Object incomingData) {

View File

@@ -0,0 +1,99 @@
/*******************************************************************************
* Copyright (c) 2018 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.tooling.boot.ls.prefs;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.tooling.boot.ls.BootLanguageServerPlugin;
import org.springsource.ide.eclipse.commons.livexp.ui.Disposable;
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
import org.springsource.ide.eclipse.commons.livexp.util.Log;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
public class RemoteAppsPrefs {
public static final String REMOTE_APPS_KEY = "remote-apps";
private IEclipsePreferences prefs = BootLanguageServerPlugin.getPreferences();
public void setRawJson(String json) {
prefs.put(REMOTE_APPS_KEY, json);
}
public String getRawJson() {
return prefs.get(REMOTE_APPS_KEY, "");
}
public List<List<String>> getRemoteAppData() {
String json = getRawJson();
try {
return parse(json);
} catch (Exception e) {
Log.warn("Problem parsing manually configured boot remote apps data: "+ExceptionUtil.getMessage(e));
return ImmutableList.of();
}
}
public static List<List<String>> parse(String json) throws JSONException {
Builder<List<String>> buider = ImmutableList.builder();
if (!json.trim().equals("")) {
JSONArray remoteApps = new JSONArray(json);
for (int i = 0; i < remoteApps.length(); i++) {
JSONObject app = remoteApps.getJSONObject(i);
String host = app.getString("host");
String jmxUrl = app.getString("jmxurl");
String port = app.optString("port");
String urlScheme = app.optString("urlScheme");
if (host!=null && jmxUrl!=null) {
//Not using ImmutableList because it doesn't allow null values in elements.
ArrayList<String> remoteApp = new ArrayList<>(4);
remoteApp.add(jmxUrl);
remoteApp.add(host);
if (urlScheme!=null) {
remoteApp.add(port); //could be null!
remoteApp.add(urlScheme);
} else if (host!=null) {
remoteApp.add(port);
//don't need to add urlScheme because we know it is null
}
buider.add(remoteApp);
}
}
}
return buider.build();
}
public static Disposable addListener(Runnable runnable) {
IPreferenceChangeListener l = event -> {
if (event.getKey().equals(REMOTE_APPS_KEY)) {
runnable.run();
}
};
getPreferences().addPreferenceChangeListener(l);
return () -> {
getPreferences().removePreferenceChangeListener(l);
};
}
private static IEclipsePreferences getPreferences() {
return BootLanguageServerPlugin.getPreferences();
}
}

View File

@@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2018 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.tooling.boot.ls.prefs;
import java.util.List;
import org.springsource.ide.eclipse.commons.livexp.ui.CommentSection;
import org.springsource.ide.eclipse.commons.livexp.ui.PreferencePageWithSections;
import org.springsource.ide.eclipse.commons.livexp.ui.PrefsPageSection;
import com.google.common.collect.ImmutableList;
public class RemoteAppsPrefsPage extends PreferencePageWithSections {
public static final String PREF_REMOTE_BOOT_APPS_JSON = "boot-java.remote-apps";
@Override
protected List<PrefsPageSection> createSections() {
return ImmutableList.of(
new CommentSection(this, "For boot live hover support. Add jmxurl and hostname information for remote boot apps below. The format is as in this example:\n\n" +
"[\n" +
" {\n" +
" \"jmxurl\" : \"service:jmx:rmi://localhost:44251/jndi/rmi://localhost:44251/jmxrmi\",\n" +
" \"host\" : \"my-remote-app.cfapps.io\"\n" +
" \"urlScheme\": \"http\", //optional, defaults to 'https'\n" +
" \"port\": 80 //optional, defaults to '443'\n" +
" }\n" +
"]\n"
),
new RemoteAppsSection(this)
);
}
}

View File

@@ -0,0 +1,70 @@
package org.springframework.tooling.boot.ls.prefs;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.springsource.ide.eclipse.commons.livexp.core.AsyncLiveExpression;
import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression;
import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable;
import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult;
import org.springsource.ide.eclipse.commons.livexp.ui.IPageWithSections;
import org.springsource.ide.eclipse.commons.livexp.ui.PrefsPageSection;
import org.springsource.ide.eclipse.commons.livexp.ui.UIConstants;
import org.springsource.ide.eclipse.commons.livexp.ui.util.SwtConnect;
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
public class RemoteAppsSection extends PrefsPageSection {
private RemoteAppsPrefs prefs = new RemoteAppsPrefs();
private Text text;
private static final int HEIGHT_HINT = 150;
private LiveVariable<String> model = new LiveVariable<>("");
private LiveExpression<ValidationResult> validator = new AsyncLiveExpression<ValidationResult>(ValidationResult.OK) {
{
dependsOn(model);
}
@Override
protected ValidationResult compute() {
try {
RemoteAppsPrefs.parse(model.getValue());
return ValidationResult.OK;
} catch (Exception e) {
return ValidationResult.error(ExceptionUtil.getMessage(e));
}
}
};
public RemoteAppsSection(IPageWithSections owner) {
super(owner);
}
@Override
public boolean performOK() {
prefs.setRawJson(model.getValue());
return true;
}
@Override
public void performDefaults() {
model.setValue("");
}
@Override
public void createContents(Composite parent) {
model.setValue(prefs.getRawJson());
text = new Text(parent, SWT.BORDER|SWT.MULTI|SWT.H_SCROLL|SWT.V_SCROLL|SWT.WRAP);
GridDataFactory.fillDefaults()
.hint(UIConstants.FIELD_TEXT_AREA_WIDTH, HEIGHT_HINT)
.grab(true, false)
.applyTo(text);
SwtConnect.connect(text, model);
}
@Override
public LiveExpression<ValidationResult> getValidator() {
return validator;
}
}

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry exported="true" kind="lib" path="icons/"/>
<classpathentry exported="true" kind="lib" path="syntaxes/"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="lib" path="icons" sourcepath="icons"/>
<classpathentry exported="true" kind="lib" path="syntaxes" sourcepath="syntaxes"/>
<classpathentry kind="output" path="bin"/>
</classpath>