Skip to content

Commit 6e98255

Browse files
BoykoAlexCopilot
andauthored
Adoption of index changed event with a list of affected projects (#1710)
* Index updated for specific projects Eclipse support Signed-off-by: BoykoAlex <[email protected]> * Index update event for structure view in VSCode Signed-off-by: BoykoAlex <[email protected]> * Populate view initially Signed-off-by: BoykoAlex <[email protected]> * Update eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/views/LogicalStructureView.java Co-authored-by: Copilot <[email protected]> Signed-off-by: Alex Boyko <[email protected]> * Update vscode-extensions/vscode-spring-boot/lib/explorer/structure-tree-manager.ts Co-authored-by: Copilot <[email protected]> Signed-off-by: Alex Boyko <[email protected]> * Update vscode-extensions/vscode-spring-boot/lib/explorer/structure-tree-manager.ts Co-authored-by: Copilot <[email protected]> Signed-off-by: Alex Boyko <[email protected]> * Update vscode-extensions/vscode-spring-boot/lib/explorer/structure-tree-manager.ts Co-authored-by: Copilot <[email protected]> Signed-off-by: Alex Boyko <[email protected]> * Update eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/SpringIndexState.java Co-authored-by: Copilot <[email protected]> Signed-off-by: Alex Boyko <[email protected]> --------- Signed-off-by: BoykoAlex <[email protected]> Signed-off-by: Alex Boyko <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent c7a41fa commit 6e98255

File tree

22 files changed

+243
-250
lines changed

22 files changed

+243
-250
lines changed

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/BootLanguageServerPlugin.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ public class BootLanguageServerPlugin extends AbstractUIPlugin {
6161

6262
public static final String BOOT_LS_DEFINITION_ID = "org.eclipse.languageserver.languages.springboot";
6363

64-
private BootLsState lsState = new BootLsState();
65-
6664
public BootLanguageServerPlugin() {
6765
// Empty
6866
}
@@ -181,10 +179,6 @@ private ImageDescriptor createStereotypeImageDescriptor(URL url, IPath p) {
181179
return ImageDescriptor.createFromURL(url);
182180
}
183181

184-
public BootLsState getLsState() {
185-
return lsState;
186-
}
187-
188182
public Image getStereotypeImage(String name) {
189183
return getImageRegistry().get(STEREOTYPE_IMG_PREFIX + name);
190184
}

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/BootLsState.java

Lines changed: 0 additions & 46 deletions
This file was deleted.

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import org.eclipse.lsp4j.ExecuteCommandParams;
3737
import org.eclipse.lsp4j.InitializeResult;
3838
import org.eclipse.lsp4j.jsonrpc.messages.Message;
39-
import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
4039
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage;
4140
import org.eclipse.lsp4j.services.LanguageServer;
4241
import org.eclipse.ui.PlatformUI;
@@ -128,7 +127,6 @@ public InputStream getErrorStream() {
128127

129128
@Override
130129
public void stop() {
131-
BootLanguageServerPlugin.getDefault().getLsState().stopped();
132130
IProxyService proxyService = PlatformUI.getWorkbench().getService(IProxyService.class);
133131
if (proxyService != null) {
134132
proxyService.removeProxyChangeListener(proxySettingsListener);
@@ -182,14 +180,6 @@ public void handleMessage(Message message, LanguageServer languageServer, URI ro
182180
));
183181
}
184182

185-
BootLanguageServerPlugin.getDefault().getLsState().initialized();
186-
}
187-
} else if (message instanceof NotificationMessage) {
188-
NotificationMessage notification = (NotificationMessage) message;
189-
// Handle spring/index/updated notification
190-
if ("spring/index/updated".equals(notification.getMethod())) {
191-
// Emit event to the Flux
192-
BootLanguageServerPlugin.getDefault().getLsState().indexed();
193183
}
194184
}
195185

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/views/GroupingAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public void run() {
3030
GroupingDialog dialog = new GroupingDialog(UI.getActiveShell(), structureView::fetchGroups, structureView::getGroupings);
3131
if (dialog.open() == IDialogConstants.OK_ID) {
3232
structureView.setGroupings(dialog.getResult());
33-
structureView.fetchStructure(false);
33+
structureView.fetchStructure(null, false);
3434
}
3535
}
3636

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/views/LogicalStructureView.java

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
*******************************************************************************/
1111
package org.springframework.tooling.boot.ls.views;
1212

13+
import java.util.ArrayList;
1314
import java.util.Collections;
1415
import java.util.List;
1516
import java.util.Map;
17+
import java.util.Optional;
18+
import java.util.Set;
1619
import java.util.concurrent.CompletableFuture;
17-
import java.util.concurrent.atomic.AtomicBoolean;
1820
import java.util.function.Consumer;
21+
import java.util.stream.Collectors;
1922

2023
import org.eclipse.jface.viewers.IStructuredSelection;
2124
import org.eclipse.jface.viewers.TreeViewer;
@@ -26,10 +29,10 @@
2629
import org.eclipse.swt.widgets.Composite;
2730
import org.eclipse.ui.IActionBars;
2831
import org.eclipse.ui.part.ViewPart;
29-
import org.springframework.tooling.boot.ls.BootLanguageServerPlugin;
30-
import org.springframework.tooling.boot.ls.BootLsState;
3132
import org.springframework.tooling.boot.ls.views.StructureClient.Groups;
3233
import org.springframework.tooling.boot.ls.views.StructureClient.StructureParameter;
34+
import org.springframework.tooling.ls.eclipse.commons.LanguageServerCommonsActivator;
35+
import org.springframework.tooling.ls.eclipse.commons.SpringIndexState;
3336

3437

3538
/**
@@ -47,27 +50,38 @@ public class LogicalStructureView extends ViewPart {
4750

4851
final private GroupingRepository groupingRepository = new GroupingRepository();
4952

50-
private final AtomicBoolean fetching = new AtomicBoolean();
53+
private Consumer<Set<String>> indexStateListener = projectNames -> fetchStructure(projectNames, false);
5154

52-
private Consumer<BootLsState> lsStateListener = state -> {
53-
if (state.isIndexed()) {
54-
fetchStructure(false);
55-
} else {
56-
UI.getDisplay().asyncExec(() -> treeViewer.setInput(null));
57-
}
58-
};
59-
60-
void fetchStructure(boolean updateMetadata) {
61-
if (!fetching.compareAndExchange(false, true)) {
62-
structureClient.fetchStructure(new StructureParameter(updateMetadata, getGroupings())).thenAccept(nodes -> {
63-
fetching.set(false);
64-
UI.getDisplay().asyncExec(() -> {
65-
Object[] expanded = treeViewer.getExpandedElements();
66-
treeViewer.setInput(nodes);
67-
treeViewer.setExpandedElements(expanded);
55+
void fetchStructure(Set<String> affectedProjects, boolean updateMetadata) {
56+
structureClient.fetchStructure(new StructureParameter(updateMetadata, affectedProjects, getGroupings()))
57+
.thenAccept(nodes -> {
58+
UI.getDisplay().asyncExec(() -> {
59+
Object[] expanded = treeViewer.getExpandedElements();
60+
if (affectedProjects == null || affectedProjects.isEmpty()) {
61+
treeViewer.setInput(nodes);
62+
} else {
63+
@SuppressWarnings("unchecked")
64+
List<StereotypeNode> oldNodes = (List<StereotypeNode>) treeViewer.getInput();
65+
if (oldNodes == null) {
66+
oldNodes = Collections.emptyList();
67+
}
68+
List<StereotypeNode> newNodes = new ArrayList<>(oldNodes.size() + nodes.size());
69+
Map<String, Optional<StereotypeNode>> nodesMap = affectedProjects.stream().collect(Collectors.toMap(e -> e, e -> nodes.stream().filter(n -> e.equals(n.getProjectId())).findFirst()));
70+
for (StereotypeNode n : oldNodes) {
71+
String projectName = n.getProjectId();
72+
if (nodesMap.containsKey(projectName)) {
73+
nodesMap.remove(projectName).ifPresent(newNodes::add);
74+
} else {
75+
newNodes.add(n);
76+
}
77+
}
78+
nodesMap.values().stream().filter(opt -> opt.isPresent()).map(opt -> opt.get()).forEach(newNodes::add);
79+
treeViewer.setInput(newNodes);
80+
}
81+
82+
treeViewer.setExpandedElements(expanded);
83+
});
6884
});
69-
});
70-
}
7185
}
7286

7387
CompletableFuture<List<Groups>> fetchGroups() {
@@ -88,15 +102,13 @@ public void createPartControl(Composite parent) {
88102
// Set initial input - placeholder data
89103
treeViewer.setInput(Collections.emptyList());
90104

91-
BootLsState lsState = BootLanguageServerPlugin.getDefault().getLsState();
105+
fetchStructure(null, false);
92106

93-
if (lsState.isIndexed()) {
94-
fetchStructure(false);
95-
}
107+
final SpringIndexState springIndexState = LanguageServerCommonsActivator.getInstance().getSpringIndexState();
96108

97-
lsState.addStateChangedListener(lsStateListener);
109+
springIndexState.addStateChangedListener(indexStateListener);
98110

99-
treeViewer.getControl().addDisposeListener(e -> lsState.removeStateChangedListener(lsStateListener));
111+
treeViewer.getControl().addDisposeListener(e -> springIndexState.removeStateChangedListener(indexStateListener));
100112

101113
treeViewer.addDoubleClickListener(e -> {
102114
Object o = ((IStructuredSelection) e.getSelection()).getFirstElement();

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/views/RefreshAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ class RefreshAction extends Action {
2727

2828
@Override
2929
public void run() {
30-
this.logicalStructureView.fetchStructure(true);
30+
this.logicalStructureView.fetchStructure(null, true);
3131
}
3232
}

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/views/StereotypeNode.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,14 @@
2020
*
2121
* @author Alex Boyko
2222
*/
23-
record StereotypeNode(String id, String text, String icon, Location location, Location reference, Map<String, Object> attributes, StereotypeNode[] children) {
23+
record StereotypeNode(
24+
String id,
25+
String text,
26+
String icon,
27+
Location location,
28+
Location reference,
29+
Map<String, Object> attributes,
30+
StereotypeNode[] children) {
2431

2532
@Override
2633
public boolean equals(Object obj) {
@@ -39,6 +46,11 @@ public int hashCode() {
3946
public String toString() {
4047
return text;
4148
}
42-
49+
50+
public String getProjectId() {
51+
return attributes.containsKey(StereotypeNodeDeserializer.PROJECT_ID)
52+
? (String) attributes.get(StereotypeNodeDeserializer.PROJECT_ID)
53+
: null;
54+
}
4355
}
4456

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/views/StereotypeNodeDeserializer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import com.google.gson.JsonObject;
2222
import com.google.gson.JsonParseException;
2323

24-
@SuppressWarnings({ "restriction", "serial" })
24+
@SuppressWarnings({ "restriction" })
2525
public class StereotypeNodeDeserializer implements com.google.gson.JsonDeserializer<StereotypeNode> {
2626

2727
private static final String LOCATION = "location";
@@ -30,6 +30,8 @@ public class StereotypeNodeDeserializer implements com.google.gson.JsonDeseriali
3030
private static final String CHILDREN = "children";
3131
private static final String REFERENCE = "reference";
3232

33+
static final String PROJECT_ID = "projectId";
34+
3335
private static final String NODE_ID = "nodeId";
3436

3537

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/views/StructureClient.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.ArrayList;
44
import java.util.Arrays;
5+
import java.util.Collection;
56
import java.util.Collections;
67
import java.util.List;
78
import java.util.Map;
@@ -22,12 +23,12 @@
2223
import com.google.gson.GsonBuilder;
2324
import com.google.gson.JsonElement;
2425

25-
@SuppressWarnings({ "restriction", "serial" })
26+
@SuppressWarnings({ "restriction" })
2627
class StructureClient {
2728

2829
record Groups (String projectName, List<Group> groups) {}
2930
record Group (String identifier, String displayName) {}
30-
record StructureParameter(boolean updateMetadata, Map<String, List<String>> groups) {}
31+
record StructureParameter(boolean updateMetadata, Collection<String> affectedProjects, Map<String, List<String>> groups) {}
3132

3233
private static final String FETCH_SPRING_BOOT_STRUCTURE = "sts/spring-boot/structure";
3334
private static final String FETCH_STRUCTURE_GROUPS = "sts/spring-boot/structure/groups";

eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/LanguageServerCommonsActivator.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ public void propertyChange(PropertyChangeEvent event) {
6464

6565
private AnnotationPreference bootHintAnnotationPreference;
6666

67+
/*
68+
* Singleton state. We assume there is going to be one server at most serving info about SpringIndex
69+
*/
70+
private SpringIndexState springIndexState = new SpringIndexState();
71+
6772
public LanguageServerCommonsActivator() {
6873
}
6974

@@ -131,4 +136,8 @@ public static void logInfo(String message) {
131136
instance.getLog().log(new Status(IStatus.INFO, instance.getBundle().getSymbolicName(), message));
132137
}
133138

139+
public SpringIndexState getSpringIndexState() {
140+
return springIndexState;
141+
}
142+
134143
}

0 commit comments

Comments
 (0)