diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/BootVersionsFromMavenCentral.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/BootVersionsFromMavenCentral.java new file mode 100644 index 000000000..f64bdcae2 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/BootVersionsFromMavenCentral.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2022 VMware, 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 + * https://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.validation.generations; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.ide.vscode.commons.java.SpringProjectUtil; +import org.springframework.ide.vscode.commons.java.Version; +import org.springframework.web.client.RestTemplate; + +public class BootVersionsFromMavenCentral { + + private static final String URL = "https://search.maven.org/solrsearch/select?q=g:org.springframework.boot+AND+a:spring-boot-starter-parent&core=gav&rows=200&wt=json"; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static List getBootVersions() { + HttpHeaders headers = new HttpHeaders(); + + headers.setAccept(MediaType.parseMediaTypes("application/json")); + + HttpEntity entity = new HttpEntity(headers); + + RestTemplate restTemplate = new RestTemplate(); + try { + ResponseEntity responseEntity = restTemplate.exchange(URL, HttpMethod.GET, entity, Map.class); + Map json = responseEntity.getBody(); + Map response = (Map) json.get("response"); + if (response != null) { + List versions = new ArrayList<>(); + Object docs = response.get("docs"); + if (docs instanceof List) { + + for (Object o : (List) docs) { + if (o instanceof Map) { + Map e = (Map) o; + if (e.get("v") instanceof String) { + try { + versions.add(SpringProjectUtil.getVersion((String) e.get("v"))); + } catch (Exception ex) { + // ignore + } + } + } + } + } + Collections.sort(versions); + return versions; + } + } catch (Exception e) { + // Error case + } + return null; + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidationUtils.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidationUtils.java index 32181af74..bd46e1a73 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidationUtils.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidationUtils.java @@ -11,17 +11,15 @@ package org.springframework.ide.vscode.boot.validation.generations; import java.sql.Date; +import java.util.Collections; import java.util.List; import org.springframework.ide.vscode.boot.validation.generations.json.Generation; -import org.springframework.ide.vscode.boot.validation.generations.json.Release; import org.springframework.ide.vscode.boot.validation.generations.json.ResolvedSpringProject; import org.springframework.ide.vscode.commons.java.Version; public class VersionValidationUtils { - private static final String GENERAL_AVAILABILITY_STATUS = "GENERAL_AVAILABILITY"; - public static boolean isOssValid(Generation gen) { Date currentDate = new Date(System.currentTimeMillis()); Date ossEndDate = Date.valueOf(gen.getOssSupportEndDate()); @@ -35,65 +33,28 @@ public class VersionValidationUtils { } public static Version getNewerPatchVersion(ResolvedSpringProject springProject, Version version) throws Exception { - Version result = version; - - List rls = springProject.getReleases(); - for (Release release : rls) { - Version rlVersion = release.getVersion(); - - if (GENERAL_AVAILABILITY_STATUS.equals(release.getStatus()) - && rlVersion.getMajor() == result.getMajor() - && rlVersion.getMinor() == result.getMinor() - && rlVersion.getPatch() > result.getPatch()) { - result = rlVersion; - } + Version result = null; + List releases = springProject.getReleases(); + int found = Collections.binarySearch(releases, version); + int index = found < 0 ? -found - 1 : found + 1; + for (int i = index; i < releases.size() && releases.get(i).getMajor() == version.getMajor() && releases.get(i).getMinor() == version.getMinor(); i++) { + result = releases.get(i); } - - return result.equals(version) ? null : result; + return result; } public static Version getNewerMinorVersion(ResolvedSpringProject springProject, Version version) throws Exception { - Version result = version; - - List rls = springProject.getReleases(); - for (Release release : rls) { - Version rlVersion = release.getVersion(); - - if (GENERAL_AVAILABILITY_STATUS.equals(release.getStatus()) - && rlVersion.getMajor() == result.getMajor() - && rlVersion.getMinor() > result.getMinor()) { - result = rlVersion; - } - } - - return result.equals(version) ? null : result; + return getNewerPatchVersion(springProject, new Version(version.getMajor(), version.getMinor() + 1, 0, null)); } public static Version getNewerMajorVersion(ResolvedSpringProject springProject, Version version) throws Exception { - Version result = version; - - List rls = springProject.getReleases(); - for (Release release : rls) { - Version rlVersion = release.getVersion(); - - if (GENERAL_AVAILABILITY_STATUS.equals(release.getStatus()) - && rlVersion.getMajor() > result.getMajor()) { - result = rlVersion; - } - } - - return result.equals(version) ? null : result; + return getNewerPatchVersion(springProject, new Version(version.getMajor() + 1, 0, 0, null)); } public static Version getLatestSupportedRelease(ResolvedSpringProject springProject) throws Exception { - List rls = springProject.getReleases(); - for (Release release : rls) { - if (release.isCurrent()) { - return release.getVersion(); - } - } - return null; + List rls = springProject.getReleases(); + return rls.isEmpty() ? null : rls.get(rls.size() - 1); } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/ResolvedSpringProject.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/ResolvedSpringProject.java index d3f00c0e2..3980a2ddc 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/ResolvedSpringProject.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/ResolvedSpringProject.java @@ -12,7 +12,9 @@ package org.springframework.ide.vscode.boot.validation.generations.json; import java.util.List; +import org.springframework.ide.vscode.boot.validation.generations.BootVersionsFromMavenCentral; import org.springframework.ide.vscode.boot.validation.generations.SpringProjectsClient; +import org.springframework.ide.vscode.commons.java.Version; import com.google.common.collect.ImmutableList; @@ -20,7 +22,7 @@ public class ResolvedSpringProject extends SpringProject { private final SpringProjectsClient client; private Generations generations; - private Releases releases; + private List releases; public ResolvedSpringProject(SpringProject project, SpringProjectsClient client) { this.client = client; @@ -45,17 +47,16 @@ public class ResolvedSpringProject extends SpringProject { return this.generations != null ? this.generations.getGenerations() : ImmutableList.of(); } - public List getReleases() throws Exception { + /** + * Sorted list of released versions + * @return + * @throws Exception + */ + public List getReleases() throws Exception { // cache the releases to prevent frequent calls to the client if (this.releases == null) { - Links _links = get_links(); - if (_links != null) { - Link genLink = _links.getReleases(); - if (genLink != null) { - this.releases = client.getReleases(genLink.getHref()); - } - } + this.releases = BootVersionsFromMavenCentral.getBootVersions(); } - return this.releases != null ? this.releases.getReleases() : ImmutableList.of(); + return this.releases != null ? this.releases : ImmutableList.of(); } } diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/validation/test/SampleProjectsProvider.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/validation/test/SampleProjectsProvider.java index 5cfbf170b..e3c733e82 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/validation/test/SampleProjectsProvider.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/validation/test/SampleProjectsProvider.java @@ -16,10 +16,10 @@ import java.util.Map; import org.springframework.ide.vscode.boot.validation.generations.SpringProjectsProvider; import org.springframework.ide.vscode.boot.validation.generations.json.Generation; import org.springframework.ide.vscode.boot.validation.generations.json.Generations; -import org.springframework.ide.vscode.boot.validation.generations.json.Release; import org.springframework.ide.vscode.boot.validation.generations.json.ResolvedSpringProject; import org.springframework.ide.vscode.boot.validation.generations.json.SpringProject; import org.springframework.ide.vscode.boot.validation.generations.json.SpringProjects; +import org.springframework.ide.vscode.commons.java.Version; import com.fasterxml.jackson.databind.ObjectMapper; @@ -46,7 +46,7 @@ public class SampleProjectsProvider implements SpringProjectsProvider { } @Override - public List getReleases() throws Exception { + public List getReleases() throws Exception { return null; }