switch xml bean hyperlink provider to new spring index
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2021 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2024 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
|
||||
@@ -61,6 +61,7 @@ import org.eclipse.lsp4j.LocationLink;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.java.links.JavaElementLocationProvider;
|
||||
import org.springframework.ide.vscode.boot.xml.XMLElementKey;
|
||||
import org.springframework.ide.vscode.boot.xml.hyperlinks.BeanRefHyperlinkProvider;
|
||||
@@ -93,7 +94,7 @@ public class XmlBeansConfigDefinitionHandler implements DefinitionHandler, Langu
|
||||
public XmlBeansConfigDefinitionHandler(SimpleTextDocumentService documents,
|
||||
BootJavaConfig config,
|
||||
JavaElementLocationProvider locationProvider,
|
||||
SpringSymbolIndex symbolIndex,
|
||||
SpringMetamodelIndex springIndex,
|
||||
BootLanguageServerParams serverParams) {
|
||||
this.documents = documents;
|
||||
this.config = config;
|
||||
@@ -101,7 +102,7 @@ public class XmlBeansConfigDefinitionHandler implements DefinitionHandler, Langu
|
||||
|
||||
JavaTypeHyperlinkProvider javaTypeHyperlinkProvider = new JavaTypeHyperlinkProvider(projectFinder, locationProvider);
|
||||
PropertyNameHyperlinkProvider propertyNameHyperlinkProvider = new PropertyNameHyperlinkProvider(projectFinder, locationProvider);
|
||||
BeanRefHyperlinkProvider beanRefHyperlinkProvider = new BeanRefHyperlinkProvider(projectFinder, symbolIndex);
|
||||
BeanRefHyperlinkProvider beanRefHyperlinkProvider = new BeanRefHyperlinkProvider(projectFinder, springIndex);
|
||||
|
||||
List<JavaTypeHyperlinkProvider> typeHandlersOnly = Arrays.asList(javaTypeHyperlinkProvider);
|
||||
List<PropertyNameHyperlinkProvider> propertyNameHandlers = Arrays.asList(propertyNameHyperlinkProvider);
|
||||
@@ -184,15 +185,22 @@ public class XmlBeansConfigDefinitionHandler implements DefinitionHandler, Langu
|
||||
|
||||
List<? extends XMLHyperlinkProvider> providers = hyperlinkProviders.get(key);
|
||||
if (providers != null) {
|
||||
|
||||
ImmutableList.Builder<LocationLink> listBuilder = ImmutableList.builder();
|
||||
for (XMLHyperlinkProvider provider : providers) {
|
||||
Location location = provider.getDefinition(doc, namespace, node, attributeAt);
|
||||
if (location != null) {
|
||||
|
||||
List<Location> locations = provider.getDefinition(doc, namespace, node, attributeAt);
|
||||
if (locations != null) {
|
||||
|
||||
int start = attributeAt.getNodeAttrValue().getStart() + 1;
|
||||
int end = attributeAt.getNodeAttrValue().getEnd() - 1;
|
||||
listBuilder.add(new LocationLink(location.getUri(),
|
||||
location.getRange(), location.getRange(),
|
||||
doc.toRange(start, Math.max(0, end - start))));
|
||||
|
||||
for (Location location : locations) {
|
||||
listBuilder.add(new LocationLink(location.getUri(),
|
||||
location.getRange(), location.getRange(),
|
||||
doc.toRange(start, Math.max(0, end - start))));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return listBuilder.build();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2021 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2024 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
|
||||
@@ -10,22 +10,17 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.xml.hyperlinks;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.lemminx.dom.DOMAttr;
|
||||
import org.eclipse.lemminx.dom.DOMNode;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbol;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
|
||||
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolAddOnInformation;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
@@ -33,71 +28,30 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public class BeanRefHyperlinkProvider implements XMLHyperlinkProvider {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(BeanRefHyperlinkProvider.class);
|
||||
|
||||
private final JavaProjectFinder projectFinder;
|
||||
private final SpringSymbolIndex symbolIndex;
|
||||
private final SpringMetamodelIndex springIndex;
|
||||
|
||||
public BeanRefHyperlinkProvider(JavaProjectFinder projectFinder, SpringSymbolIndex symbolIndex) {
|
||||
public BeanRefHyperlinkProvider(JavaProjectFinder projectFinder, SpringMetamodelIndex springIndex) {
|
||||
this.projectFinder = projectFinder;
|
||||
this.symbolIndex = symbolIndex;
|
||||
this.springIndex = springIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getDefinition(TextDocument doc, String namespace, DOMNode node, DOMAttr attributeAt) {
|
||||
public List<Location> getDefinition(TextDocument doc, String namespace, DOMNode node, DOMAttr attributeAt) {
|
||||
Optional<IJavaProject> foundProject = this.projectFinder.find(doc.getId());
|
||||
if (foundProject.isPresent()) {
|
||||
final IJavaProject project = foundProject.get();
|
||||
String projectLocation = project.getLocationUri() != null ? project.getLocationUri().toASCIIString() : "";
|
||||
|
||||
// make sure the project and the symbol location share the same prefix "file:///"
|
||||
// looks like project locations are containing a "file:/" only
|
||||
if (!projectLocation.startsWith("file:///")) {
|
||||
projectLocation = "file:///" + projectLocation.substring("file:/".length());
|
||||
}
|
||||
String beanID = attributeAt.getValue();
|
||||
Bean[] beans = springIndex.getBeansWithName(project.getElementName(), beanID);
|
||||
|
||||
// make sure that only exact project locations are matched
|
||||
if (!projectLocation.endsWith("/")) {
|
||||
projectLocation = projectLocation + "/";
|
||||
}
|
||||
|
||||
List<WorkspaceSymbol> symbols = symbolIndex.getSymbols(data -> symbolsFilter(data, attributeAt.getValue())).collect(Collectors.toList());
|
||||
if (!symbols.isEmpty()) {
|
||||
for (WorkspaceSymbol symbol : symbols) {
|
||||
if (symbol.getLocation().isLeft()) {
|
||||
Location location = symbol.getLocation().getLeft();
|
||||
String uri = location.getUri();
|
||||
|
||||
if (uri != null && uri.startsWith(projectLocation)) {
|
||||
return location;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: need better handling for the WorkspaceSymbolLocation case
|
||||
for (WorkspaceSymbol symbol : symbols) {
|
||||
if (symbol.getLocation().isLeft()) {
|
||||
return symbol.getLocation().getLeft();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.debug("No Symbols!!!");
|
||||
if (beans != null && beans.length > 0) {
|
||||
return Arrays.stream(beans)
|
||||
.map(bean -> bean.getLocation())
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean symbolsFilter(EnhancedSymbolInformation data, String beanId) {
|
||||
SymbolAddOnInformation[] additionalInformation = data.getAdditionalInformation();
|
||||
if (beanId != null && additionalInformation != null) {
|
||||
for (SymbolAddOnInformation info : additionalInformation) {
|
||||
if (info instanceof BeansSymbolAddOnInformation) {
|
||||
String id = ((BeansSymbolAddOnInformation)info).getBeanID();
|
||||
log.debug("Bean symbol id = " + id);
|
||||
return beanId.equals(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2024 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
|
||||
@@ -10,6 +10,7 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.xml.hyperlinks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.lemminx.dom.DOMAttr;
|
||||
@@ -35,7 +36,7 @@ public class JavaTypeHyperlinkProvider implements XMLHyperlinkProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getDefinition(TextDocument doc, String namespace, DOMNode node, DOMAttr attributeAt) {
|
||||
public List<Location> getDefinition(TextDocument doc, String namespace, DOMNode node, DOMAttr attributeAt) {
|
||||
Optional<IJavaProject> foundProject = this.projectFinder.find(doc.getId());
|
||||
if (foundProject.isPresent()) {
|
||||
IJavaProject project = foundProject.get();
|
||||
@@ -43,7 +44,7 @@ public class JavaTypeHyperlinkProvider implements XMLHyperlinkProvider {
|
||||
if (fqName != null) {
|
||||
IType type = project.getIndex().findType(fqName);
|
||||
if (type != null) {
|
||||
return locationProvider.findLocation(project, type);
|
||||
return List.of(locationProvider.findLocation(project, type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2024 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
|
||||
@@ -10,6 +10,7 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.xml.hyperlinks;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.lemminx.dom.DOMAttr;
|
||||
@@ -35,18 +36,19 @@ public class PropertyNameHyperlinkProvider implements XMLHyperlinkProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getDefinition(TextDocument doc, String namespace, DOMNode node, DOMAttr attributeAt) {
|
||||
public List<Location> getDefinition(TextDocument doc, String namespace, DOMNode node, DOMAttr attributeAt) {
|
||||
Optional<IJavaProject> foundProject = this.projectFinder.find(doc.getId());
|
||||
String propertyName = attributeAt.getValue();
|
||||
|
||||
if (foundProject.isPresent() && propertyName != null && !propertyName.isEmpty()) {
|
||||
IJavaProject project = foundProject.get();
|
||||
String beanClass = PropertyNameCompletionProposalProvider.identifyBeanClass(node);
|
||||
|
||||
if (beanClass != null && beanClass.length() > 0) {
|
||||
return PropertyNameCompletionProposalProvider.propertyNameCandidateMethods(project, beanClass)
|
||||
.filter(method -> propertyName.equals(PropertyNameCompletionProposalProvider.getPropertyName(method)))
|
||||
.map(method -> locationProvider.findLocation(project, method))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2024 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
|
||||
@@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.xml.hyperlinks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lemminx.dom.DOMAttr;
|
||||
import org.eclipse.lemminx.dom.DOMNode;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
@@ -20,6 +22,6 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public interface XMLHyperlinkProvider {
|
||||
|
||||
Location getDefinition(TextDocument doc, String namespace, DOMNode node, DOMAttr attributeAt);
|
||||
List<Location> getDefinition(TextDocument doc, String namespace, DOMNode node, DOMAttr attributeAt);
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -172,7 +171,7 @@ public class XMLBeansHyperlinkTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
// @Disabled
|
||||
void testBeanRefHyperlink() throws Exception {
|
||||
log.debug("------------------ testBeanRefHyperlink ----------------------");
|
||||
Path xmlFilePath = Paths.get(project.getLocationUri()).resolve("beans.xml");
|
||||
|
||||
Reference in New Issue
Block a user