diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java index 8e1624e50..d69d85794 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/src/org/springframework/tooling/ls/eclipse/commons/STS4LanguageClientImpl.java @@ -356,7 +356,8 @@ public class STS4LanguageClientImpl extends LanguageClientImpl implements STS4La public CompletableFuture javadocHoverLink(JavaDataParams params) { JavadocHoverLinkResponse response = new JavadocHoverLinkResponse(null); try { - IJavaElement element = JavaData.findElement(URI.create(params.getProjectUri()), params.getBindingKey(), JavaDataParams.isLookInOtherProjects(params)); + URI projectUri = params.getProjectUri() == null ? null : URI.create(params.getProjectUri()); + IJavaElement element = JavaData.findElement(projectUri, params.getBindingKey(), JavaDataParams.isLookInOtherProjects(params)); if (element != null) { response.setLink(JavaElementLinks.createURI(JavaElementLinks.OPEN_LINK_SCHEME, element)); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java index b918aee79..c36116d63 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/links/SourceLinks.java @@ -11,9 +11,12 @@ package org.springframework.ide.vscode.boot.java.links; import java.io.File; +import java.io.IOException; +import java.net.JarURLConnection; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -110,7 +113,23 @@ public interface SourceLinks { if (idx >= 0) { Path filePath = Paths.get(path.substring(0, idx)); IJavaProject project = projectFinder.find(new TextDocumentIdentifier(filePath.toUri().toString())).orElse(null); - if (project != null) { + if (project == null) { + try { + URL url = new URL(path.substring(0, idx)); + if (url.getProtocol().equals("jar")) { + URLConnection connection = url.openConnection(); + if (connection instanceof JarURLConnection) { + JarURLConnection jarConnection = (JarURLConnection) connection; + String fqName = jarConnection.getEntryName().replace(File.separator, "."); + return sourceLinks.sourceLinkUrlForFQName(null, fqName); + } + } + } catch (MalformedURLException e) { + log.error("", e); + } catch (IOException e) { + log.error("", e); + } + } else { try { for (CPE cpe : project.getClasspath().getClasspathEntries()) { if (Classpath.isSource(cpe)) { diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveChangeDetectionWatchdog.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveChangeDetectionWatchdog.java index 635a34998..7345aca7b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveChangeDetectionWatchdog.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringLiveChangeDetectionWatchdog.java @@ -242,7 +242,7 @@ public class SpringLiveChangeDetectionWatchdog { String path = resource.substring(matcher.start()+1, matcher.end()-1); for (IJavaProject project : projects) { - if (SpringResource.FILE.equals(type)) { + if (SpringResource.FILE.equals(type) || SpringResource.URL.equals(type)) { result = sourceLinks.sourceLinkUrlForClasspathResource(path).get(); if (result == null) { result = sourceLinks.sourceLinkForResourcePath(Paths.get(path)).get(); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringResource.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringResource.java index b59efa279..eac68ea03 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringResource.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/SpringResource.java @@ -31,6 +31,7 @@ public class SpringResource { public static final String FILE = "file"; public static final String CLASS_PATH_RESOURCE = "class path resource"; + public static final String URL = "URL"; private static final String CF_CLASSPATH_PREFIX = "/home/vcap/app/"; private SourceLinks sourceLinks; @@ -70,6 +71,7 @@ public class SpringResource { Optional linkUrl = Optional.empty(); switch (type) { case FILE: + case URL: linkUrl = sourceLinks.sourceLinkUrlForClasspathResource(path); if (!linkUrl.isPresent()) { linkUrl = sourceLinks.sourceLinkForResourcePath(Paths.get(path));