diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/plugin.xml b/eclipse-language-servers/org.springframework.tooling.boot.ls/plugin.xml index 7d7798692..94dd8ce06 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/plugin.xml +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/plugin.xml @@ -103,8 +103,8 @@ + class="org.springframework.tooling.boot.ls.commands.OpenJavaElementInEditor" + commandId="org.springframework.tooling.boot.ls.OpenJavaElement"> + id="org.springframework.tooling.boot.ls.OpenJavaElement" + name="Open Java Element in Editor"> + + diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenFullyQualifiedNameInEditor.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenFullyQualifiedNameInEditor.java deleted file mode 100644 index 739da9d31..000000000 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenFullyQualifiedNameInEditor.java +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.tooling.boot.ls.commands; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.WorkingCopyOwner; -import org.eclipse.jdt.core.search.IJavaSearchConstants; -import org.eclipse.jdt.core.search.IJavaSearchScope; -import org.eclipse.jdt.core.search.SearchEngine; -import org.eclipse.jdt.core.search.SearchPattern; -import org.eclipse.jdt.core.search.TypeNameMatch; -import org.eclipse.jdt.core.search.TypeNameMatchRequestor; -import org.eclipse.jdt.ui.JavaUI; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PartInitException; -import org.springframework.tooling.boot.ls.BootLanguageServerPlugin; - -/** - * Command for opening Java type given by its fully qualified name in an editor - * - * @author Alex Boyko - * - */ -public class OpenFullyQualifiedNameInEditor extends AbstractHandler { - - private static final String FQ_NAME = "fqName"; - private static final String PROJECT_NAME = "projectName"; - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - String fqName = event.getParameter(FQ_NAME); - String projectName = event.getParameter(PROJECT_NAME); - - String packageName = ""; - String typeName = fqName; - int idx = fqName.lastIndexOf('.'); - if (idx >= 0) { - packageName = fqName.substring(0, idx); - typeName = idx < fqName.length() - 1 ? fqName.substring(idx + 1) : ""; - } - - if (!typeName.isEmpty()) { - SearchEngine engine= new SearchEngine((WorkingCopyOwner) null); - List matches = new ArrayList<>(); - String searchedTypeName = getSearchedTypeName(typeName); - final boolean isInnerType = searchedTypeName != typeName; - TypeNameMatchRequestor requestor = new TypeNameMatchRequestor() { - @Override - public void acceptTypeNameMatch(TypeNameMatch match) { - if (isInnerType) { - if (match.getFullyQualifiedName().equals(fqName.replace("$", "."))) { - matches.add(match); - } - } else { - matches.add(match); - } - } - }; - try { - IJavaSearchScope searchScope = createSearchScope(projectName); - engine.searchAllTypeNames(packageName.toCharArray(), SearchPattern.R_EXACT_MATCH, - searchedTypeName.toCharArray(), SearchPattern.R_EXACT_MATCH, IJavaSearchConstants.TYPE, searchScope, - requestor, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, new NullProgressMonitor()); - if (matches.isEmpty()) { - BootLanguageServerPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, BootLanguageServerPlugin.ID, "Cannot find type: " + fqName)); - } else { - if (matches.size() > 1) { - BootLanguageServerPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, BootLanguageServerPlugin.ID, "More than one type is defined for: " + fqName)); - } - try { - IType type = matches.get(0).getType(); - IEditorPart editorPart= JavaUI.openInEditor(type); - JavaUI.revealInEditor(editorPart, (IJavaElement)type); - } catch (JavaModelException ex) { - throw new ExecutionException("Error opening java element in editor", ex); //$NON-NLS-1$ - } catch (PartInitException ex) { - throw new ExecutionException("Error opening java element in editor", ex); //$NON-NLS-1$ - } - } - } catch (JavaModelException e) { - BootLanguageServerPlugin.getDefault().getLog().log(e.getStatus()); - } - - - } - return null; - } - - private String getSearchedTypeName(String typeName) { - int idx = typeName.lastIndexOf('$'); - if (idx >= 0 && idx < typeName.length()) { - return typeName.substring(idx + 1); - } - return typeName; - } - - private IJavaSearchScope createSearchScope(String projectName) { - try { - if (projectName != null) { - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); - if (project != null) { - IJavaProject javaProject = JavaCore.create(project); - if (javaProject != null) { - return SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject }); - - } - } - } - } catch (Throwable t) { - BootLanguageServerPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, BootLanguageServerPlugin.ID, "Failed creating Java search scope for project: " + projectName)); - } - return SearchEngine.createWorkspaceScope(); - } - -} diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenJavaElementInEditor.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenJavaElementInEditor.java new file mode 100644 index 000000000..296700c1b --- /dev/null +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/commands/OpenJavaElementInEditor.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.tooling.boot.ls.commands; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PartInitException; +import org.springframework.tooling.boot.ls.BootLanguageServerPlugin; +import org.springframework.tooling.ls.eclipse.commons.Utils; + +/** + * Command for opening Java type given by its fully qualified name in an editor + * + * @author Alex Boyko + * + */ +public class OpenJavaElementInEditor extends AbstractHandler { + + private static final String BINDING_KEY = "bindingKey"; + private static final String PROJECT_NAME = "projectName"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + String bindingKey = event.getParameter(BINDING_KEY); + String projectName = event.getParameter(PROJECT_NAME); + + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + + if (project != null && bindingKey != null) { + IJavaProject javaProject = JavaCore.create(project); + if (javaProject != null) { + IJavaElement element = Utils.findElement(javaProject, bindingKey); + if (element == null) { + BootLanguageServerPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, BootLanguageServerPlugin.ID, "Cannot find element: " + bindingKey)); + } + if (element instanceof IMember) { + IMember member = (IMember) element; + try { + IEditorPart editorPart = JavaUI.openInEditor(member.getDeclaringType()); + JavaUI.revealInEditor(editorPart, (IJavaElement)member); + } catch (PartInitException | JavaModelException e) { + throw new ExecutionException("Error opening java element in editor", e); + } + } + } else { + BootLanguageServerPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, BootLanguageServerPlugin.ID, "Cannot find project: " + projectName)); + } + } + + return null; + } + +} diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/Utils.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/Utils.java index 0a02c5a92..1a64a254b 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/Utils.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/Utils.java @@ -15,6 +15,8 @@ import java.util.Arrays; import java.util.Objects; import java.util.stream.Stream; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.source.ISourceViewer; @@ -69,4 +71,38 @@ public class Utils { return false; } + + public static IJavaElement findElement(IJavaProject project, String bindingKey) { + IJavaElement element = null; + try { + element = project.findElement(bindingKey, null); + } catch (Throwable t) { + // ignore + } + if (element == null) { + // Try modifying the binding key to search for the alternate binding + try { + String alternateBinding = alternateBinding(bindingKey); + if (alternateBinding != null) { + element = project.findElement(alternateBinding, null); + } + } catch (Throwable t) { + // ignore + } + } + return element; + } + + private static String alternateBinding(String bindingKey) { + int idxStartParams = bindingKey.indexOf('('); + if (idxStartParams >= 0) { + int idxEndParams = bindingKey.indexOf(')', idxStartParams); + if (idxEndParams > idxStartParams) { + String params = bindingKey.substring(idxStartParams, idxEndParams); + return bindingKey.substring(0, idxStartParams) + params.replace('/', '.') + bindingKey.substring(idxEndParams); + } + } + return null; + } + } diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/javadoc/JavadocUtils.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/javadoc/JavadocUtils.java index bc22192a2..966fc35c6 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/javadoc/JavadocUtils.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/javadoc/JavadocUtils.java @@ -42,7 +42,7 @@ public class JavadocUtils { public static final String javadoc(Function readerProvider, URI projectUri, String bindingKey) throws Exception { IJavaProject project = ResourceUtils.getJavaProject(projectUri); - IJavaElement element = project.findElement(bindingKey, null); + IJavaElement element = findElement(project, bindingKey); return computeJavadoc(readerProvider, element); } @@ -71,5 +71,39 @@ public class JavadocUtils { } return getString(r); } + + public static IJavaElement findElement(IJavaProject project, String bindingKey) { + IJavaElement element = null; + try { + element = project.findElement(bindingKey, null); + } catch (Throwable t) { + // ignore + } + if (element == null) { + // Try modifying the binding key to search for the alternate binding + try { + String alternateBinding = alternateBinding(bindingKey); + if (alternateBinding != null) { + element = project.findElement(alternateBinding, null); + } + } catch (Throwable t) { + // ignore + } + } + return element; + } + + private static String alternateBinding(String bindingKey) { + int idxStartParams = bindingKey.indexOf('('); + if (idxStartParams >= 0) { + int idxEndParams = bindingKey.indexOf(')', idxStartParams); + if (idxEndParams > idxStartParams) { + String params = bindingKey.substring(idxStartParams, idxEndParams); + return bindingKey.substring(0, idxStartParams) + params.replace('/', '.') + bindingKey.substring(idxEndParams); + } + } + return null; + } + } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java index 56838f0d2..d8d7d7edc 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguagServerBootApp.java @@ -15,12 +15,15 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.context.annotation.Bean; import org.springframework.ide.vscode.boot.java.links.DefaultJavaElementLocationProvider; -import org.springframework.ide.vscode.boot.java.links.JavaElementLocationProvider; +import org.springframework.ide.vscode.boot.java.links.EclipseJavaDocumentUriProvider; +import org.springframework.ide.vscode.boot.java.links.EclipseJavaElementLocationProvider; import org.springframework.ide.vscode.boot.java.links.JavaDocumentUriProvider; +import org.springframework.ide.vscode.boot.java.links.JavaElementLocationProvider; import org.springframework.ide.vscode.boot.java.links.JdtJavaDocumentUriProvider; import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory; import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache; +import org.springframework.ide.vscode.commons.languageserver.util.LspClient; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.util.LogRedirect; @@ -53,11 +56,23 @@ public class BootLanguagServerBootApp { } @Bean JavaDocumentUriProvider javaDocumentUriProvider() { - return new JdtJavaDocumentUriProvider(); + switch (LspClient.currentClient()) { + case ECLIPSE: + // LSP4E doesn't support JDT java doc URIs. Only supports file, eclipse intro and http URIs for docs + return new EclipseJavaDocumentUriProvider(); + default: + return new JdtJavaDocumentUriProvider(); + } } @Bean JavaElementLocationProvider javaElementLocationProvider(CompilationUnitCache cuCache, JavaDocumentUriProvider javaDocUriProvider) { - return new DefaultJavaElementLocationProvider(cuCache, javaDocUriProvider); + switch (LspClient.currentClient()) { + case ECLIPSE: + // LSP4E doesn't support JDT java doc URIs. Only supports file, eclipse intro and http URIs for docs + return new EclipseJavaElementLocationProvider(); + default: + return new DefaultJavaElementLocationProvider(cuCache, javaDocUriProvider); + } } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseJavaDocumentUriProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseJavaDocumentUriProvider.java new file mode 100644 index 000000000..174254712 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseJavaDocumentUriProvider.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.links; + +import java.net.URI; + +import org.springframework.ide.vscode.commons.java.IJavaProject; + +public class EclipseJavaDocumentUriProvider implements JavaDocumentUriProvider { + + @Override + public URI docUri(IJavaProject project, String fqName) { + return EclipseSourceLinks.eclipseIntroUri(project, fqName); + } +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseJavaElementLocationProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseJavaElementLocationProvider.java new file mode 100644 index 000000000..cc818bd24 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseJavaElementLocationProvider.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.java.links; + +import java.net.URI; + +import org.eclipse.lsp4j.Location; +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.java.IMember; + +public class EclipseJavaElementLocationProvider implements JavaElementLocationProvider { + + @Override + public Location findLocation(IJavaProject project, IMember member) { + URI uri = EclipseSourceLinks.eclipseIntroUri(project, member); + return uri == null ? null : new Location(uri.toString(), null); + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java index 517ec3043..5a9e1b3db 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/EclipseSourceLinks.java @@ -12,6 +12,7 @@ package org.springframework.ide.vscode.boot.java.links; import java.io.File; import java.io.UnsupportedEncodingException; +import java.net.URI; import java.net.URLEncoder; import java.nio.file.Path; import java.nio.file.Paths; @@ -20,57 +21,35 @@ import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ide.vscode.commons.java.IJavaProject; - -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; +import org.springframework.ide.vscode.commons.java.IMember; +import org.springframework.ide.vscode.commons.java.IType; /** * Source links for Eclipse client. Eclipse IntroURLs. - * + * * @author Alex Boyko * */ public class EclipseSourceLinks implements SourceLinks { - + private static final String URL_PREFIX = "http://org.eclipse.ui.intro/execute?command="; private static final String EQUALS = "="; private static final String PARAMETERS_SEPARATOR = ","; private static final String PARAMETERS_START = "("; private static final String PARAMETERS_END = ")"; - - private static final String JAVA_TYPE_COMMAND = "org.springframework.tooling.boot.ls.OpenJavaType"; - private static final String FQ_NAME_PARAMETER_ID = "fqName"; + + private static final String JAVA_ELEMENT_COMMAND = "org.springframework.tooling.boot.ls.OpenJavaElement"; + private static final String BINDING_KEY_PARAMETER_ID = "bindingKey"; private static final String PROJECT_NAME_PARAMETER_ID = "projectName"; private static final String RESOURCE_COMMAND = "org.springframework.tooling.boot.ls.OpenResourceInEditor"; private static final String PATH = "path"; - - private static final Supplier LOG = Suppliers.memoize(() -> LoggerFactory.getLogger(EclipseSourceLinks.class)); + private static final Logger log = LoggerFactory.getLogger(EclipseSourceLinks.class); @Override public Optional sourceLinkUrlForFQName(IJavaProject project, String fqName) { - try { - StringBuilder paramBuilder = new StringBuilder(JAVA_TYPE_COMMAND); - paramBuilder.append(PARAMETERS_START); - paramBuilder.append(FQ_NAME_PARAMETER_ID); - paramBuilder.append(EQUALS); - paramBuilder.append(fqName); - if (project != null && project.getElementName() != null) { - paramBuilder.append(PARAMETERS_SEPARATOR); - paramBuilder.append(PROJECT_NAME_PARAMETER_ID); - paramBuilder.append(EQUALS); - paramBuilder.append(project.getElementName()); - } - paramBuilder.append(PARAMETERS_END); - - StringBuilder urlBuilder = new StringBuilder(URL_PREFIX); - urlBuilder.append(URLEncoder.encode(paramBuilder.toString(), "UTF8")); - return Optional.of(urlBuilder.toString()); - } catch (UnsupportedEncodingException e) { - LOG.get().error("{}", e); - } - return Optional.empty(); + return Optional.ofNullable(eclipseIntroUri(project, fqName)).map(uri -> uri.toString()); } @Override @@ -85,8 +64,12 @@ public class EclipseSourceLinks implements SourceLinks { @Override public Optional sourceLinkForResourcePath(Path path) { - try { - if (path != null) { + return Optional.ofNullable(eclipseIntroUri(path)).map(uri -> uri.toString()); + } + + public static URI eclipseIntroUri(Path path) { + if (path != null) { + try { StringBuilder paramBuilder = new StringBuilder(RESOURCE_COMMAND); paramBuilder.append(PARAMETERS_START); paramBuilder.append(PATH); @@ -96,12 +79,41 @@ public class EclipseSourceLinks implements SourceLinks { StringBuilder urlBuilder = new StringBuilder(URL_PREFIX); urlBuilder.append(URLEncoder.encode(paramBuilder.toString(), "UTF8")); - return Optional.of(urlBuilder.toString()); + return URI.create(urlBuilder.toString()); + } catch (UnsupportedEncodingException e) { + log.error("{}", e); } - } catch (UnsupportedEncodingException e) { - LOG.get().error("{}", e); } - return Optional.empty(); + return null; + } + + public static URI eclipseIntroUri(IJavaProject project, String fqName) { + IType type = project.findType(fqName); + return type == null ? null : eclipseIntroUri(project, type); + } + + public static URI eclipseIntroUri(IJavaProject project, IMember member) { + try { + StringBuilder paramBuilder = new StringBuilder(JAVA_ELEMENT_COMMAND); + paramBuilder.append(PARAMETERS_START); + paramBuilder.append(BINDING_KEY_PARAMETER_ID); + paramBuilder.append(EQUALS); + paramBuilder.append(member.getBindingKey()); + if (project != null && project.getElementName() != null) { + paramBuilder.append(PARAMETERS_SEPARATOR); + paramBuilder.append(PROJECT_NAME_PARAMETER_ID); + paramBuilder.append(EQUALS); + paramBuilder.append(project.getElementName()); + } + paramBuilder.append(PARAMETERS_END); + + StringBuilder urlBuilder = new StringBuilder(URL_PREFIX); + urlBuilder.append(URLEncoder.encode(paramBuilder.toString(), "UTF8")); + return URI.create(urlBuilder.toString()); + } catch (UnsupportedEncodingException e) { + log.error("{}", e); + } + return null; } } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/SpringResourceTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/SpringResourceTest.java index 0e8a377c5..f1958f33e 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/SpringResourceTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/livehover/test/SpringResourceTest.java @@ -13,7 +13,7 @@ package org.springframework.ide.vscode.boot.java.livehover.test; import static org.junit.Assert.assertEquals; import org.junit.Test; -import org.springframework.ide.vscode.boot.java.links.EclipseSourceLinks; +import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory; import org.springframework.ide.vscode.boot.java.links.SourceLinks; import org.springframework.ide.vscode.boot.java.utils.SpringResource; import org.springframework.ide.vscode.boot.java.value.test.MockProjects; @@ -24,13 +24,11 @@ public class SpringResourceTest { private MockProjects projects = new MockProjects(); private MockProject project = projects.create("test-project"); - private SourceLinks sourceLinks = new EclipseSourceLinks(); + private SourceLinks sourceLinks = SourceLinkFactory.NO_SOURCE_LINKS; @Test public void vcapResourceToMarkdown() throws Exception { assertEquals( - "[com/github/kdvolder/helloworldservice/Greeter.class]" + - "(http://org.eclipse.ui.intro/execute?command=org.springframework.tooling.boot.ls.OpenJavaType%28fqName%3Dcom.github.kdvolder.helloworldservice.Greeter%2CprojectName%3Dtest-project%29)" - , + "`com/github/kdvolder/helloworldservice/Greeter.class`", toMarkdown("file [/home/vcap/app/com/github/kdvolder/helloworldservice/Greeter.class]") ); }