Add URL link to Additional Java Reconcile popup

This commit is contained in:
aboyko
2023-01-19 16:07:45 -05:00
parent 75f577c74b
commit c1accd1016
3 changed files with 147 additions and 21 deletions

View File

@@ -36,7 +36,8 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.9.0",
com.google.guava,
org.eclipse.core.expressions,
org.springsource.ide.eclipse.commons.core;bundle-version="4.17.0",
org.springframework.tooling.jdt.ls.commons;bundle-version="4.17.0"
org.springframework.tooling.jdt.ls.commons;bundle-version="4.17.0",
org.eclipse.jface.notifications
Import-Package: com.google.common.base,
com.google.common.collect,
com.google.gson;version="2.7.0",

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2022 Pivotal, Inc.
* Copyright (c) 2017, 2023 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
@@ -14,6 +14,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.FileSystems;
import java.util.Arrays;
import java.util.Collection;
@@ -24,7 +25,8 @@ import java.util.Map;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.notifications.AbstractNotificationPopup;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.lsp4e.server.StreamConnectionProvider;
@@ -34,7 +36,18 @@ import org.eclipse.lsp4j.jsonrpc.messages.Message;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
import org.eclipse.lsp4j.services.LanguageServer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.springframework.tooling.boot.ls.prefs.CategoryProblemsSeverityPrefsPage;
import org.springframework.tooling.boot.ls.prefs.FileListEditor;
@@ -164,19 +177,19 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
if (preferenceStore.getBoolean(Constants.PREF_REWRITE_RECONCILE_PROMPT) && !preferenceStore.getBoolean(Constants.PREF_REWRITE_RECONCILE)) {
PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
int result = MessageDialog.open(MessageDialog.INFORMATION, Display.getCurrent().getActiveShell(),
"Spring Boot Java Reconciling",
"Do you wish to enable additional Java sources reconciling to get Spring specific validations and suggestions?",
SWT.NONE, "Yes", "No", "Do not show again");
switch (result) {
case 0:
preferenceStore.setValue(Constants.PREF_REWRITE_RECONCILE, true);
break;
case 2:
preferenceStore.setValue(Constants.PREF_REWRITE_RECONCILE_PROMPT, false);
break;
default:
break;
try {
NotificationQuestionWithLink question = new NotificationQuestionWithLink(
"Spring Java Reconcile",
"Do you wish to enable additional Java sources reconciling to get Spring specific validations and suggestions?\n\n" +
"See <a>Validations And Quick Fixes</a> for more details.",
new URL("https://github.com/spring-projects/sts4/wiki/Validations-And-Quick-Fixes"),
() -> preferenceStore.setValue(Constants.PREF_REWRITE_RECONCILE, true),
() -> {},
() -> preferenceStore.setValue(Constants.PREF_REWRITE_RECONCILE_PROMPT, false));
question.setDelayClose(-1);
question.open();
} catch (Exception e) {
BootLanguageServerPlugin.getDefault().getLog().error("Failed to Spring Java Reconcile popup", e);
}
});
}
@@ -294,4 +307,115 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
return RemoteBootAppsDataHolder.getDefault().getRemoteApps().getValues();
}
private static class NotificationQuestionWithLink extends AbstractNotificationPopup {
private final String title;
private final String textWithLinkTag;
private final URL linkUrl;
/*
* Notification open does not block on open and ignores setBlockOnOpen(true)
* Therefore handlers are passed directly in until this changes
*/
private Runnable yesHandler;
private Runnable noHandler;
private Runnable stopAskingHandler;
public NotificationQuestionWithLink(String title, String textWithLinkTag, URL linkUrl,
Runnable yesHandler, Runnable noHandler, Runnable stopAskingHandler) {
super(Display.getCurrent());
this.title = title;
this.textWithLinkTag = textWithLinkTag;
this.linkUrl = linkUrl;
this.yesHandler = yesHandler;
this.noHandler = noHandler;
this.stopAskingHandler = stopAskingHandler;
setParentShell(PlatformUI.getWorkbench().getDisplay().getActiveShell());
setBlockOnOpen(true);
}
@Override
public String getPopupShellTitle() {
return title;
}
@Override
protected void createContentArea(Composite parent) {
Link link = new Link(parent, SWT.WRAP);
link.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
link.setText(textWithLinkTag);
if (linkUrl != null) {
link.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
try {
PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(linkUrl);
} catch (PartInitException ex) {
BootLanguageServerPlugin.getDefault().getLog().error("Failed to open browser", ex);
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
Composite buttonsComposite = new Composite(parent, SWT.None);
buttonsComposite.setLayoutData(GridDataFactory.swtDefaults().grab(true, false).align(SWT.RIGHT, SWT.CENTER).create());
GridLayout buttonsLayout = new GridLayout(3, false);
buttonsLayout.horizontalSpacing = 0;
buttonsComposite.setLayout(buttonsLayout);
Button yesButton = new Button(buttonsComposite, SWT.None);
yesButton.setText("Yes");
yesButton.setLayoutData(GridDataFactory.swtDefaults().create());
yesButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
setReturnCode(SWT.YES);
close();
yesHandler.run();
}
});
Button noButton = new Button(buttonsComposite, SWT.None);
noButton.setText("No");
noButton.setLayoutData(GridDataFactory.swtDefaults().create());
noButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
setReturnCode(SWT.NO);
close();
noHandler.run();
}
});
Button stopAskingButton = new Button(buttonsComposite, SWT.None);
stopAskingButton.setText("Stop Asking");
stopAskingButton.setLayoutData(GridDataFactory.swtDefaults().create());
stopAskingButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
setReturnCode(SWT.SAVE);
close();
stopAskingHandler.run();
}
});
}
@Override
public Image getPopupShellImage(int maximumHeight) {
return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_INFO_TSK);
}
}
}

View File

@@ -22,7 +22,7 @@ const FACTORIES_LANGUAGE_ID = "spring-factories";
const YES = 'Yes';
const NO = 'No';
const NEVER_SHOW_AGAIN = "Do not show again";
const STOP_ASKING = "Stop Asking";
const RECONCILING_PREF_KEY = 'boot-java.rewrite.reconcile';
const RECONCILING_PROMPT_PREF_KEY = 'vscode-spring-boot.rewrite.reconcile-prompt';
@@ -48,8 +48,8 @@ export function activate(context: VSCode.ExtensionContext): Thenable<ExtensionAP
if (!jvm.isJdk()) {
VSCode.window.showWarningMessage(
'JAVA_HOME or PATH environment variable seems to point to a JRE. A JDK is required, hence Boot Hints are unavailable.',
NEVER_SHOW_AGAIN).then(selection => {
if (selection === NEVER_SHOW_AGAIN) {
STOP_ASKING).then(selection => {
if (selection === STOP_ASKING) {
options.workspaceOptions.update('checkJVM', false);
}
}
@@ -143,12 +143,13 @@ export function activate(context: VSCode.ExtensionContext): Thenable<ExtensionAP
// Ask user to enable Boot java source reconciling feature if disabled
if (VSCode.workspace.getConfiguration().get(RECONCILING_PROMPT_PREF_KEY) && !VSCode.workspace.getConfiguration().get(RECONCILING_PREF_KEY)) {
VSCode.window.showInformationMessage('Do you wish to enable additional Java sources reconciling to get Spring specific validations and suggestions?', YES, NO, NEVER_SHOW_AGAIN).then(answer => {
VSCode.window.showInformationMessage('Do you wish to enable additional Java sources reconciling to get Spring specific validations and suggestions?\n\n' +
'For more details see [Validations And Quick Fixes](https://github.com/spring-projects/sts4/wiki/Validations-And-Quick-Fixes)', YES, NO, STOP_ASKING).then(answer => {
switch (answer) {
case YES:
VSCode.workspace.getConfiguration().update(RECONCILING_PREF_KEY, true, true);
break;
case NEVER_SHOW_AGAIN:
case STOP_ASKING:
VSCode.workspace.getConfiguration().update(RECONCILING_PROMPT_PREF_KEY, false, true);
break;
default: