From 83d61f1a8fdf512bd525467d56a3eac647ebd8c1 Mon Sep 17 00:00:00 2001 From: Nieraj Singh Date: Sun, 13 Nov 2022 13:17:35 -0800 Subject: [PATCH] Various changes to version validation Refactored version validation into separate validators that can each compute its own severity, enablement and version to upgrade. This facilitates reading of preferences. Cleaned up other API. Finished implementing releases support. --- .../vscode/boot/app/BootVersionValidator.java | 16 +- .../generations/BootDiagnosticProvider.java | 58 ------ .../ProjectVersionDiagnosticProvider.java | 172 ++++++++++++++++ .../SpringBootProjectValidations.java | 50 ----- .../generations/SpringDependencyInfo.java | 45 ---- .../generations/SpringIoProjectsProvider.java | 43 ++-- .../generations/SpringProjectsClient.java | 5 + .../generations/SpringProjectsProvider.java | 7 +- .../UnsupportedVersionDiagnostic.java | 193 ------------------ .../generations/VersionValidation.java | 46 +++++ .../generations/VersionValidationUtils.java | 61 ++++++ .../generations/VersionValidator.java | 31 +++ .../generations/VersionValidators.java | 132 ++++++++++++ .../generations/json/JsonHalLinks.java | 4 + .../validation/generations/json/Links.java | 5 + .../validation/generations/json/Release.java | 24 ++- .../validation/generations/json/Releases.java | 10 + .../json/ResolvedSpringProject.java | 61 ++++++ .../generations/json/SpringProject.java | 45 ++-- .../generations/json/SpringProjects.java | 1 + .../ProjectGenerationsValidationTest.java | 9 +- .../test/SampleProjectsProvider.java | 45 ++-- 22 files changed, 623 insertions(+), 440 deletions(-) delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/BootDiagnosticProvider.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/ProjectVersionDiagnosticProvider.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringBootProjectValidations.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringDependencyInfo.java delete mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/UnsupportedVersionDiagnostic.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidation.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidationUtils.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidator.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidators.java create mode 100644 headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/ResolvedSpringProject.java diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootVersionValidator.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootVersionValidator.java index 6ccb189f1..02a5cad6f 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootVersionValidator.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootVersionValidator.java @@ -15,11 +15,12 @@ import java.util.List; import org.eclipse.lsp4j.TextDocumentIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.ide.vscode.boot.validation.generations.SpringBootProjectValidations; +import org.springframework.ide.vscode.boot.validation.generations.ProjectVersionDiagnosticProvider; import org.springframework.ide.vscode.boot.validation.generations.SpringIoProjectsProvider; import org.springframework.ide.vscode.boot.validation.generations.SpringProjectDiagnostic; import org.springframework.ide.vscode.boot.validation.generations.SpringProjectsClient; import org.springframework.ide.vscode.boot.validation.generations.SpringProjectsProvider; +import org.springframework.ide.vscode.boot.validation.generations.VersionValidators; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; @@ -42,13 +43,14 @@ public class BootVersionValidator { @Override public void created(IJavaProject project) { - String url = "https://spring.io/api/projects"; + String url = getSpringProjectsUrl(); SpringProjectsClient client = new SpringProjectsClient(url); SpringProjectsProvider provider = new SpringIoProjectsProvider(client); + VersionValidators validators = new VersionValidators(); + ProjectVersionDiagnosticProvider diagnosticProvider = new ProjectVersionDiagnosticProvider(provider, validators); - SpringBootProjectValidations validations = new SpringBootProjectValidations(provider); try { - List diagnostics = validations.validateBootVersion(project); + List diagnostics = diagnosticProvider.getDiagnostics(project); if (diagnostics != null) { for (SpringProjectDiagnostic springProjectDiagnostic : diagnostics) { server.getTextDocumentService().publishDiagnostics(new TextDocumentIdentifier(springProjectDiagnostic.getUri().toString()), List.of(springProjectDiagnostic.getDiagnostic())); @@ -66,5 +68,11 @@ public class BootVersionValidator { } }); } + + + private String getSpringProjectsUrl() { + // TODO: Read from preferences + return "https://spring.io/api/projects"; + } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/BootDiagnosticProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/BootDiagnosticProvider.java deleted file mode 100644 index 236ca5e5b..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/BootDiagnosticProvider.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * 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.io.File; -import java.net.URI; -import java.util.List; - -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.commons.java.IJavaProject; -import org.springframework.ide.vscode.commons.java.SpringProjectUtil; -import org.springframework.ide.vscode.commons.java.Version; - -public abstract class BootDiagnosticProvider { - - public static final String BOOT_VERSION_VALIDATION_CODE = "BOOT_VERSION_VALIDATION_CODE"; - private static final String[] BUILD_FILES = new String[] {"pom.xml", "build.gradle", "build.gradle.kts"}; - - /** - * - * @param javaProject - * @param info Spring Dependency Info - * @param Spring project Generation information - * @return Diagnostic if applicable to the given version, or null - */ - abstract SpringProjectDiagnostic getDiagnostic(IJavaProject javaProject, SpringDependencyInfo info, Generations generations) throws Exception; - - protected URI getBuildFileUri(IJavaProject javaProject) throws Exception { - - File file = null; - for (String fileName : BUILD_FILES) { - file = SpringProjectUtil.getFile(javaProject, fileName); - if (file != null) { - return file.toURI(); - } - } - - return null; - } - - protected File getSpringBootDependency(IJavaProject project) { - List libs = SpringProjectUtil.getLibrariesOnClasspath(project, "spring-boot"); - return libs != null && libs.size() > 0 ? libs.get(0) : null; - } - - protected Version getVersion(Generation generation) throws Exception { - return SpringProjectUtil.getVersionFromGeneration(generation.getName()); - } -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/ProjectVersionDiagnosticProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/ProjectVersionDiagnosticProvider.java new file mode 100644 index 000000000..e61d5d6cf --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/ProjectVersionDiagnosticProvider.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * 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.io.File; +import java.net.URI; +import java.util.List; + +import org.eclipse.lsp4j.CodeAction; +import org.eclipse.lsp4j.CodeActionKind; +import org.eclipse.lsp4j.Command; +import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.DiagnosticSeverity; +import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.Range; +import org.openrewrite.java.tree.J.If; +import org.springframework.ide.vscode.boot.validation.generations.json.Generation; +import org.springframework.ide.vscode.boot.validation.generations.json.ResolvedSpringProject; +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.java.SpringProjectUtil; +import org.springframework.ide.vscode.commons.java.Version; + +import com.google.common.collect.ImmutableList; + +public class ProjectVersionDiagnosticProvider { + + public static final String BOOT_VERSION_VALIDATION_CODE = "BOOT_VERSION_VALIDATION_CODE"; + private static final String[] BUILD_FILES = new String[] { "pom.xml", "build.gradle", "build.gradle.kts" }; + private static final String SPRING_BOOT_PROJECT_SLUG = "spring-boot"; + + private final SpringProjectsProvider provider; + private final VersionValidators validators; + + public ProjectVersionDiagnosticProvider(SpringProjectsProvider provider, VersionValidators validationConditions) { + this.provider = provider; + this.validators = validationConditions; + } + + /** + * + * @return Non-null list of Diagnostics. Can be empty if no diagnostics are + * applicable. + * @throws If error encountered while getting diagnostics + */ + public List getDiagnostics(IJavaProject javaProject) throws Exception { + + URI uri = getBuildFileUri(javaProject); + if (uri == null) { + return ImmutableList.of(); + } + + ResolvedSpringProject springProject = provider.getProject(SPRING_BOOT_PROJECT_SLUG); + Version javaProjectVersion = SpringProjectUtil.getDependencyVersion(javaProject, springProject.getSlug()); + + if (javaProjectVersion == null) { + throw new Exception("Unable to resolve version for project: " + javaProject.getLocationUri().toString()); + } + + // The generation of the current dependency + Generation javaProjectGeneration = getGenerationForJavaProject(javaProject, springProject); + + if (javaProjectGeneration == null) { + throw new Exception("Unable to find Spring Generation for project: " + javaProjectVersion.toString()); + } + + VersionValidation validation = null; + + for (VersionValidator validator : validators.getValidators()) { + validation = validator.getValidation(springProject, javaProjectGeneration, javaProjectVersion); + if (validation != null) { + break; + } + } + + if (validation != null) { + + DiagnosticSeverity severity = validation.getSeverity(); + Version toUpgrade = validation.getVersionToUprade(); + + StringBuffer msg = new StringBuffer(); + msg.append(validation.getMessage()); + + if (toUpgrade != null) { + msg.append('\n'); + msg.append("Consider upgrading to a newer supported version: "); + msg.append(toUpgrade.toString()); + } + + Diagnostic diagnostic = new Diagnostic(); + diagnostic.setCode(BOOT_VERSION_VALIDATION_CODE); + diagnostic.setMessage(msg.toString()); + + Range range = new Range(); + Position start = new Position(); + start.setLine(0); + start.setCharacter(0); + range.setStart(start); + Position end = new Position(); + end.setLine(0); + end.setCharacter(1); + range.setEnd(end); + diagnostic.setRange(range); + diagnostic.setSeverity(severity); + + setQuickfix(diagnostic); + + return ImmutableList.of(new SpringProjectDiagnostic(diagnostic, uri)); + + } + + return ImmutableList.of(); + } + + private Generation getGenerationForJavaProject(IJavaProject javaProject, ResolvedSpringProject springProject) + throws Exception { + List genList = springProject.getGenerations(); + Version javaProjectVersion = SpringProjectUtil.getDependencyVersion(javaProject, springProject.getSlug()); + + // Find the generation belonging to the dependency + for (Generation gen : genList) { + Version genVersion = getVersion(gen); + if (genVersion.getMajor() == javaProjectVersion.getMajor() + && genVersion.getMinor() == javaProjectVersion.getMinor()) { + return gen; + } + } + return null; + } + + private void setQuickfix(Diagnostic diagnostic) { + // TODO: Fix this when open rewrite recipe quickfix becomes available. + Diagnostic refDiagnostic = new Diagnostic(diagnostic.getRange(), diagnostic.getMessage(), + diagnostic.getSeverity(), diagnostic.getSource()); + CodeAction ca = new CodeAction(); + ca.setKind(CodeActionKind.QuickFix); + ca.setTitle("Validation FIX"); + ca.setDiagnostics(List.of(refDiagnostic)); + String commandId = ""; + ca.setCommand(new Command("Validation FIX", commandId, ImmutableList.of())); + diagnostic.setData(ca); + } + + protected URI getBuildFileUri(IJavaProject javaProject) throws Exception { + + File file = null; + for (String fileName : BUILD_FILES) { + file = SpringProjectUtil.getFile(javaProject, fileName); + if (file != null) { + return file.toURI(); + } + } + + return null; + } + + protected File getSpringBootDependency(IJavaProject project) { + List libs = SpringProjectUtil.getLibrariesOnClasspath(project, "spring-boot"); + return libs != null && libs.size() > 0 ? libs.get(0) : null; + } + + protected Version getVersion(Generation generation) throws Exception { + return SpringProjectUtil.getVersionFromGeneration(generation.getName()); + } +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringBootProjectValidations.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringBootProjectValidations.java deleted file mode 100644 index df91eed6b..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringBootProjectValidations.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020, 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.List; - -import org.springframework.ide.vscode.boot.validation.generations.json.Generations; -import org.springframework.ide.vscode.commons.java.IJavaProject; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableList.Builder; - -public class SpringBootProjectValidations { - - private final SpringProjectsProvider projectsProvider; - private static final String SPRING_BOOT_PROJECT_SLUG = "spring-boot"; - - private final BootDiagnosticProvider[] diagnosticProviders = new BootDiagnosticProvider[] { - new UnsupportedVersionDiagnostic() - }; - - public SpringBootProjectValidations(SpringProjectsProvider projectsProvider) { - this.projectsProvider = projectsProvider; - } - - public List validateBootVersion(IJavaProject project) throws Exception { - Builder builder = ImmutableList.builder(); - if (project != null) { - SpringDependencyInfo info = new SpringDependencyInfo(project, SPRING_BOOT_PROJECT_SLUG); - Generations generations = projectsProvider.getGenerations(SPRING_BOOT_PROJECT_SLUG); - - for (BootDiagnosticProvider provider : diagnosticProviders) { - SpringProjectDiagnostic diagnostic = provider.getDiagnostic(project, info, generations); - if (diagnostic != null) { - builder.add(diagnostic); - } - } - } - return builder.build(); - } - -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringDependencyInfo.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringDependencyInfo.java deleted file mode 100644 index 4101070ef..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringDependencyInfo.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2021, 2022 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.vscode.boot.validation.generations; - -import org.springframework.ide.vscode.commons.java.IJavaProject; -import org.springframework.ide.vscode.commons.java.SpringProjectUtil; -import org.springframework.ide.vscode.commons.java.Version; - -/** - * Version info for a spring dependency. - * - * For example, given a spring dependency name: "spring-boot-2.4.0-M4" , the slug is - * "spring-boot", the fullVersion "2.4.0-M4", and the majMin "2.4" - * - */ -public class SpringDependencyInfo { - - private final String slug; - private final Version version; - - /** - * - * @param file spring for dependency, e.g. spring-boot-2.4.0-M4.jar - */ - public SpringDependencyInfo(IJavaProject project, String slug) { - this.slug = slug; - this.version = SpringProjectUtil.getDependencyVersion(project, slug); - } - - public String getSlug() { - return slug; - } - - public Version getVersion() { - return version; - } -} \ No newline at end of file diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringIoProjectsProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringIoProjectsProvider.java index 1d0e831b3..58b6a282f 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringIoProjectsProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringIoProjectsProvider.java @@ -13,7 +13,7 @@ package org.springframework.ide.vscode.boot.validation.generations; import java.util.List; import java.util.Map; -import org.springframework.ide.vscode.boot.validation.generations.json.Generations; +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; @@ -21,24 +21,21 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; /** - * Provides Spring project definitions from a source like "https://spring.io/api/projects" + * Provides Spring project definitions from a source like + * "https://spring.io/api/projects" *

- * If a client is not provided, a default client - * will be used instead that will point to "https://spring.io/api/projects" + * If a client is not provided, a default client will be used instead that will + * point to "https://spring.io/api/projects" * */ public class SpringIoProjectsProvider implements SpringProjectsProvider { private final SpringProjectsClient client; - private Map cache; + private Map cache; public SpringIoProjectsProvider(SpringProjectsClient client) { this.client = client; } - - public SpringIoProjectsProvider() { - this(getDefaultClient()); - } /** * @@ -47,21 +44,12 @@ public class SpringIoProjectsProvider implements SpringProjectsProvider { * @throws Exception */ @Override - public SpringProject getProject(String projectSlug) throws Exception { - SpringProject prj = cache().get(projectSlug); + public ResolvedSpringProject getProject(String projectSlug) throws Exception { + ResolvedSpringProject prj = cache().get(projectSlug); return prj; } - - @Override - public Generations getGenerations(String projectSlug) throws Exception { - SpringProject project = cache().get(projectSlug); - if (project != null) { - return project.getGenerations(client); - } - return null; - } - private Map cache() throws Exception { + private Map cache() throws Exception { if (cache == null) { SpringProjects springProjects = client.getSpringProjects(); cache = asMap(springProjects); @@ -69,23 +57,18 @@ public class SpringIoProjectsProvider implements SpringProjectsProvider { return cache != null ? cache : ImmutableMap.of(); } - private Map asMap(SpringProjects springProjects) { - Builder builder = ImmutableMap.builder(); + private Map asMap(SpringProjects springProjects) { + Builder builder = ImmutableMap.builder(); if (springProjects != null) { List projects = springProjects.getProjects(); if (projects != null) { for (SpringProject project : projects) { - builder.put(project.getSlug(), project); + builder.put(project.getSlug(), new ResolvedSpringProject(project, client)); } } } return builder.build(); } - - private static SpringProjectsClient getDefaultClient() { - String url = "https://spring.io/api/projects"; - return new SpringProjectsClient(url); - } - + } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringProjectsClient.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringProjectsClient.java index 325fe3568..34b3d6a74 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringProjectsClient.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringProjectsClient.java @@ -18,6 +18,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.ide.vscode.boot.validation.generations.json.Generations; +import org.springframework.ide.vscode.boot.validation.generations.json.Releases; import org.springframework.ide.vscode.boot.validation.generations.json.SpringProjects; import org.springframework.web.client.RestTemplate; @@ -39,6 +40,10 @@ public class SpringProjectsClient { return fromEmbedded(generationsUrl, Generations.class); } + public Releases getReleases(String releasesUrl) throws Exception { + return fromEmbedded(releasesUrl, Releases.class); + } + private T fromEmbedded(String url, Class clazz) throws Exception { if (url != null) { Map result = get(url, Map.class); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringProjectsProvider.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringProjectsProvider.java index 202a8f9a3..6aec4af0b 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringProjectsProvider.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/SpringProjectsProvider.java @@ -10,8 +10,7 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.validation.generations; -import org.springframework.ide.vscode.boot.validation.generations.json.Generations; -import org.springframework.ide.vscode.boot.validation.generations.json.SpringProject; +import org.springframework.ide.vscode.boot.validation.generations.json.ResolvedSpringProject; public interface SpringProjectsProvider { @@ -21,8 +20,6 @@ public interface SpringProjectsProvider { * @return * @throws Exception */ - SpringProject getProject(String projectSlug) throws Exception; - - Generations getGenerations(String projectSlug) throws Exception; + ResolvedSpringProject getProject(String projectSlug) throws Exception; } \ No newline at end of file diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/UnsupportedVersionDiagnostic.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/UnsupportedVersionDiagnostic.java deleted file mode 100644 index ff63634a6..000000000 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/UnsupportedVersionDiagnostic.java +++ /dev/null @@ -1,193 +0,0 @@ -/******************************************************************************* - * 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.net.URI; -import java.sql.Date; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.lsp4j.CodeAction; -import org.eclipse.lsp4j.CodeActionKind; -import org.eclipse.lsp4j.Command; -import org.eclipse.lsp4j.Diagnostic; -import org.eclipse.lsp4j.DiagnosticSeverity; -import org.eclipse.lsp4j.Position; -import org.eclipse.lsp4j.Range; -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.commons.java.IJavaProject; -import org.springframework.ide.vscode.commons.java.Version; - -import com.google.common.collect.ImmutableList; - -public class UnsupportedVersionDiagnostic extends BootDiagnosticProvider { - - - @Override - public SpringProjectDiagnostic getDiagnostic(IJavaProject project, SpringDependencyInfo dependency, Generations generations) throws Exception { - - URI uri = getBuildFileUri(project); - if (uri == null) { - return null; - } - - List genList = generations.getGenerations(); - - // The generation of the current dependency - Generation dependencyGeneration = null; - - int dependencyMajor = dependency.getVersion().getMajor(); - int dependencyMinor = dependency.getVersion().getMinor(); - - // Collect the latest versions of each major version that are still supported - List latestSupportedPerMajor = new ArrayList<>(); - - if (genList != null && genList.size() > 1) { - - // The very latest version is first in the list as the generations are ordered by version - latestSupportedPerMajor.add(genList.get(0)); - - for (int i = 1; i < genList.size(); i++) { - Generation toAdd = genList.get(i); - Version toAddVersion = getVersion(toAdd); - - Generation lastAdded = latestSupportedPerMajor.get(latestSupportedPerMajor.size() - 1); - Version lastAddedVersion = getVersion(lastAdded); - - if (isCommercialValid(toAdd) && isOssValid(toAdd) && toAddVersion.getMajor() < lastAddedVersion.getMajor()) { - latestSupportedPerMajor.add(toAdd); - } - if (toAddVersion.getMajor() == dependencyMajor - && toAddVersion.getMinor() == dependencyMinor) { - dependencyGeneration = toAdd; - } - } - } - - if (dependencyGeneration == null) { - throw new Exception("Unable to find Spring Generation for: " + dependency.getVersion().toString()); - } - - StringBuffer message = new StringBuffer(); - DiagnosticSeverity severity = DiagnosticSeverity.Information; - - if (isCommercialValid(dependencyGeneration) && isOssValid(dependencyGeneration)) { - message.append("OSS support ends on: "); - message.append(dependencyGeneration.getOssSupportEndDate()); - message.append('\n'); - message.append("Commercial supports ends on: "); - message.append(dependencyGeneration.getCommercialSupportEndDate()); - } else { - - Generation toUpgrade = null; - - // Calculate latest supported version for the same major version as the dependency - // For example, if the dependency version is 1.5.0 and the latest supported is 1.8.0, - // find the generation for 1.8.0 - for (Generation generation : latestSupportedPerMajor) { - Version dependencyVersion = getVersion(dependencyGeneration); - Version latest = getVersion(generation); - if (latest.getMajor() == dependencyVersion.getMajor()) { - toUpgrade = generation; - break; - } - } - - if (toUpgrade == null) { - // if there are no supported versions in the dependency major range, upgrade to the very - // latest version - toUpgrade = latestSupportedPerMajor.get(0); - } - - if (isCommercialValid(dependencyGeneration)) { - severity = DiagnosticSeverity.Warning; - message.append("Unsupported OSS. Support ended on: "); - message.append(dependencyGeneration.getOssSupportEndDate()); - message.append('\n'); - message.append("Commercial supports ends on: "); - message.append(dependencyGeneration.getCommercialSupportEndDate()); - - } else if (isOssValid(dependencyGeneration)) { - severity = DiagnosticSeverity.Warning; - message.append("OSS support ends on: "); - message.append(dependencyGeneration.getOssSupportEndDate()); - message.append('\n'); - message.append("Unsupported Commercial. Support ended on: "); - message.append(dependencyGeneration.getCommercialSupportEndDate()); - - } else { - // OSS and Commercial support have ended - severity = DiagnosticSeverity.Error; - - message.append("Unsupported OSS. Support ended on: "); - message.append(dependencyGeneration.getOssSupportEndDate()); - message.append('\n'); - message.append("Unsupported Commercial. Support ended on: "); - message.append(dependencyGeneration.getCommercialSupportEndDate()); - } - - message.append('\n'); - message.append("Please upgrade to a newer supported version: "); - message.append(getVersion(toUpgrade).toString()); - } - - Diagnostic diagnostic = new Diagnostic(); - diagnostic.setCode(BOOT_VERSION_VALIDATION_CODE); - diagnostic.setMessage(message.toString()); - - Range range = new Range(); - Position start = new Position(); - start.setLine(0); - start.setCharacter(0); - range.setStart(start); - Position end = new Position(); - end.setLine(0); - end.setCharacter(1); - range.setEnd(end); - diagnostic.setRange(range); - diagnostic.setSeverity(severity); - - - setQuickfix(diagnostic); - - return new SpringProjectDiagnostic(diagnostic, uri); - } - - - private void setQuickfix(Diagnostic diagnostic) { - // TODO: Fix this when open rewrite recipe quickfix becomes available. - Diagnostic refDiagnostic = new Diagnostic(diagnostic.getRange(), diagnostic.getMessage(), diagnostic.getSeverity(), diagnostic.getSource()); - CodeAction ca = new CodeAction(); - ca.setKind(CodeActionKind.QuickFix); - ca.setTitle("Validation FIX"); - ca.setDiagnostics(List.of(refDiagnostic)); - String commandId = ""; - ca.setCommand(new Command("Validation FIX", commandId, ImmutableList.of())); - diagnostic.setData(ca); - } - - - private boolean isOssValid(Generation gen) { - - Date currentDate = new Date(System.currentTimeMillis()); - Date ossEndDate = Date.valueOf(gen.getOssSupportEndDate()); - return currentDate.before(ossEndDate); - } - - private boolean isCommercialValid(Generation gen) { - - Date currentDate = new Date(System.currentTimeMillis()); - Date commercialEndDate = Date.valueOf(gen.getCommercialSupportEndDate()); - - return currentDate.before(commercialEndDate); - } -} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidation.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidation.java new file mode 100644 index 000000000..8ad68363d --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidation.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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 org.eclipse.lsp4j.DiagnosticSeverity; +import org.springframework.ide.vscode.commons.java.Version; + +public class VersionValidation { + + private final Version versionToUpgrade; + private final boolean enabled; + private final DiagnosticSeverity severity; + private final String message; + + public VersionValidation(Version versionToUpgrade, boolean enabled, DiagnosticSeverity severity, String message) { + this.versionToUpgrade = versionToUpgrade; + this.enabled = enabled; + this.severity = severity; + this.message = message; + } + + public boolean isEnabled() { + return this.enabled; + } + + public DiagnosticSeverity getSeverity() { + return this.severity; + } + + public Version getVersionToUprade() { + return this.versionToUpgrade; + } + + public String getMessage() { + return this.message; + } + +} 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 new file mode 100644 index 000000000..6edb99a9d --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidationUtils.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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.sql.Date; +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()); + return currentDate.before(ossEndDate); + } + + public static boolean isCommercialValid(Generation gen) { + Date currentDate = new Date(System.currentTimeMillis()); + Date commercialEndDate = Date.valueOf(gen.getCommercialSupportEndDate()); + return currentDate.before(commercialEndDate); + } + + public static Version getLatestSupportedInSameMajor(ResolvedSpringProject springProject, Version version) + throws Exception { + List rls = springProject.getReleases(); + for (Release release : rls) { + Version rlVersion = release.getVersion(); + if (GENERAL_AVAILABILITY_STATUS.equals(release.getStatus()) + && rlVersion.getMajor() == version.getMajor()) { + return rlVersion; + } + } + return null; + } + + public static Version getLatestSupportedRelease(ResolvedSpringProject springProject, Version version) + throws Exception { + List rls = springProject.getReleases(); + for (Release release : rls) { + if (release.isCurrent()) { + return release.getVersion(); + } + } + return null; + } + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidator.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidator.java new file mode 100644 index 000000000..408510053 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidator.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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 org.springframework.ide.vscode.boot.validation.generations.json.Generation; +import org.springframework.ide.vscode.boot.validation.generations.json.ResolvedSpringProject; +import org.springframework.ide.vscode.commons.java.Version; + +public interface VersionValidator { + + /** + * + * @param springProject contains information about the spring project associated + * with the generation and version to validate + * @param generation to validate + * @param version to validate + * @return validation if application. Null otherwise + * @throws Exception + */ + VersionValidation getValidation(ResolvedSpringProject springProject, Generation generation, Version version) + throws Exception; + +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidators.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidators.java new file mode 100644 index 000000000..52d93e092 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/VersionValidators.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * 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.List; + +import org.eclipse.lsp4j.DiagnosticSeverity; +import org.springframework.ide.vscode.boot.validation.generations.json.Generation; +import org.springframework.ide.vscode.boot.validation.generations.json.ResolvedSpringProject; +import org.springframework.ide.vscode.commons.java.Version; + +import com.google.common.collect.ImmutableList; + +public class VersionValidators { + + public List getValidators() { + return ImmutableList.of(new SupportedValidator(), new UnsupportedCommercialValidator(), + new UnsupportedOssValidator(), new UnsupportedValidator()); + } + + private static class SupportedValidator implements VersionValidator { + + @Override + public VersionValidation getValidation(ResolvedSpringProject springProject, Generation generation, + Version version) throws Exception { + + if (VersionValidationUtils.isCommercialValid(generation) && VersionValidationUtils.isOssValid(generation)) { + DiagnosticSeverity severity = DiagnosticSeverity.Information; + boolean enabled = true; + + StringBuffer message = new StringBuffer(); + + message.append("OSS support ends on: "); + message.append(generation.getOssSupportEndDate()); + message.append('\n'); + message.append("Commercial supports ends on: "); + message.append(generation.getCommercialSupportEndDate()); + Version toUpdate = VersionValidationUtils.getLatestSupportedRelease(springProject, version); + return new VersionValidation(toUpdate, enabled, severity, message.toString()); + } + return null; + } + } + + private static class UnsupportedValidator implements VersionValidator { + + @Override + public VersionValidation getValidation(ResolvedSpringProject springProject, Generation generation, + Version version) throws Exception { + + if (!VersionValidationUtils.isCommercialValid(generation) + && !VersionValidationUtils.isOssValid(generation)) { + DiagnosticSeverity severity = DiagnosticSeverity.Error; + boolean enabled = true; + StringBuffer message = new StringBuffer(); + + message.append("Unsupported OSS. Support ended on: "); + message.append(generation.getOssSupportEndDate()); + message.append('\n'); + message.append("Unsupported Commercial. Support ended on: "); + message.append(generation.getCommercialSupportEndDate()); + + return new VersionValidation( + toUpdateForUnsupported(springProject, version), enabled, severity, message.toString()); + } + return null; + } + } + + private static class UnsupportedOssValidator implements VersionValidator { + + @Override + public VersionValidation getValidation(ResolvedSpringProject springProject, Generation generation, + Version version) throws Exception { + if (!VersionValidationUtils.isOssValid(generation) + && VersionValidationUtils.isCommercialValid(generation)) { + DiagnosticSeverity severity = DiagnosticSeverity.Warning; + boolean enabled = true; + + StringBuffer message = new StringBuffer(); + message.append("Unsupported OSS. Support ended on: "); + message.append(generation.getOssSupportEndDate()); + message.append('\n'); + message.append("Commercial supports ends on: "); + message.append(generation.getCommercialSupportEndDate()); + return new VersionValidation(toUpdateForUnsupported(springProject, version), enabled, severity, message.toString()); + + } + return null; + } + } + + private static class UnsupportedCommercialValidator implements VersionValidator { + + @Override + public VersionValidation getValidation(ResolvedSpringProject springProject, Generation generation, + Version version) throws Exception { + if (!VersionValidationUtils.isCommercialValid(generation) + && VersionValidationUtils.isOssValid(generation)) { + + DiagnosticSeverity severity = DiagnosticSeverity.Warning; + boolean enabled = true; + + StringBuffer message = new StringBuffer(); + message.append("OSS support ends on: "); + message.append(generation.getOssSupportEndDate()); + message.append('\n'); + message.append("Unsupported Commercial. Support ended on: "); + message.append(generation.getCommercialSupportEndDate()); + return new VersionValidation(toUpdateForUnsupported(springProject, version), enabled, severity, message.toString()); + } + return null; + } + } + + private static Version toUpdateForUnsupported(ResolvedSpringProject springProject, Version version) + throws Exception { + Version toUpdate = VersionValidationUtils.getLatestSupportedInSameMajor(springProject, version); + if (toUpdate == null) { + toUpdate = VersionValidationUtils.getLatestSupportedRelease(springProject, version); + } + return toUpdate; + } +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/JsonHalLinks.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/JsonHalLinks.java index c4917c800..4fda40ff2 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/JsonHalLinks.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/JsonHalLinks.java @@ -17,4 +17,8 @@ public class JsonHalLinks { public Links get_links() { return _links; } + + protected void set_links(Links links) { + this._links = links; + } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Links.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Links.java index e6422f633..7b65a43d9 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Links.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Links.java @@ -17,6 +17,7 @@ public class Links { private Link generations; private Link parent; private Link project; + private Link repository; public Link getSelf() { return self; @@ -37,4 +38,8 @@ public class Links { public Link getProject() { return project; } + + public Link getRepository() { + return repository; + } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Release.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Release.java index 5f5a03595..71240a7ee 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Release.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Release.java @@ -1,13 +1,26 @@ +/******************************************************************************* + * 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.json; import org.springframework.ide.vscode.commons.java.SpringProjectUtil; import org.springframework.ide.vscode.commons.java.Version; -public class Release { +public class Release extends JsonHalLinks { private String version; private String status; private boolean current; + private String referenceDocUrl; + private String apiDocUrl; + public Version getVersion() { return SpringProjectUtil.getVersion(version); @@ -20,4 +33,13 @@ public class Release { public boolean isCurrent() { return current; } + + public String getReferenceDocUrl() { + return referenceDocUrl; + } + + public String getApiDocUrl() { + return apiDocUrl; + } + } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Releases.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Releases.java index afe45b46a..44dab01f2 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Releases.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/Releases.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * 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.json; import java.util.Arrays; 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 new file mode 100644 index 000000000..d3f00c0e2 --- /dev/null +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/ResolvedSpringProject.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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.json; + +import java.util.List; + +import org.springframework.ide.vscode.boot.validation.generations.SpringProjectsClient; + +import com.google.common.collect.ImmutableList; + +public class ResolvedSpringProject extends SpringProject { + + private final SpringProjectsClient client; + private Generations generations; + private Releases releases; + + public ResolvedSpringProject(SpringProject project, SpringProjectsClient client) { + this.client = client; + setName(project.getName()); + setRepositoryUrl(project.getRepositoryUrl()); + setSlug(project.getSlug()); + setStatus(project.getStatus()); + set_links(project.get_links()); + } + + public List getGenerations() throws Exception { + // cache the generations to prevent frequent calls to the client + if (this.generations == null) { + Links _links = get_links(); + if (_links != null) { + Link genLink = _links.getGenerations(); + if (genLink != null) { + this.generations = client.getGenerations(genLink.getHref()); + } + } + } + return this.generations != null ? this.generations.getGenerations() : ImmutableList.of(); + } + + 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()); + } + } + } + return this.releases != null ? this.releases.getReleases() : ImmutableList.of(); + } +} diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/SpringProject.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/SpringProject.java index 627cf910d..5cf1e448c 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/SpringProject.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/SpringProject.java @@ -10,14 +10,8 @@ *******************************************************************************/ package org.springframework.ide.vscode.boot.validation.generations.json; -import org.springframework.ide.vscode.boot.validation.generations.SpringProjectsClient; - public class SpringProject extends JsonHalLinks { - private Generations generations; - private Releases releases; - - private String name; private String slug; private String status; @@ -31,7 +25,6 @@ public class SpringProject extends JsonHalLinks { return slug; } - public String getStatus() { return status; } @@ -40,31 +33,19 @@ public class SpringProject extends JsonHalLinks { return repositoryUrl; } - public Generations getGenerations(SpringProjectsClient client) throws Exception { - // cache the generations to prevent frequent calls to the client - if (this.generations == null) { - Links _links = get_links(); - if (_links != null) { - Link genLink = _links.getGenerations(); - if (genLink != null) { - this.generations = client.getGenerations(genLink.getHref()); - } - } - } - return this.generations; + protected void setName(String name) { + this.name = name; } - - public Releases getReleases(SpringProjectsClient client) 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.getGenerations(genLink.getHref()); - } - } - } - return this.releases; + + protected void setSlug(String slug) { + this.slug = slug; + } + + protected void setStatus(String status) { + this.status = status; + } + + protected void setRepositoryUrl(String repositoryUrl) { + this.repositoryUrl = repositoryUrl; } } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/SpringProjects.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/SpringProjects.java index 5199729c5..70434b646 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/SpringProjects.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/validation/generations/json/SpringProjects.java @@ -13,6 +13,7 @@ package org.springframework.ide.vscode.boot.validation.generations.json; import java.util.List; public class SpringProjects { + private List projects; public List getProjects() { diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/validation/test/ProjectGenerationsValidationTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/validation/test/ProjectGenerationsValidationTest.java index 49f5f81f0..c1b0ca4f5 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/validation/test/ProjectGenerationsValidationTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/validation/test/ProjectGenerationsValidationTest.java @@ -28,8 +28,8 @@ import org.springframework.ide.vscode.boot.validation.generations.SpringIoProjec import org.springframework.ide.vscode.boot.validation.generations.SpringProjectsClient; 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.Link; +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.commons.java.SpringProjectUtil; import org.springframework.ide.vscode.commons.java.Version; @@ -86,13 +86,10 @@ public class ProjectGenerationsValidationTest { SampleProjectsProvider provider = new SampleProjectsProvider(); - SpringProject project = provider.getProject("spring-boot"); + ResolvedSpringProject project = provider.getProject("spring-boot"); assertNotNull(project); - Generations generations = provider.getGenerations("spring-boot"); - assertNotNull(generations); - - List genList = generations.getGenerations(); + List genList = project.getGenerations(); assertNotNull(genList); assertTrue(genList.size() > 0); 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 bece551ac..5cfbf170b 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 @@ -14,25 +14,48 @@ import java.util.List; 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 com.fasterxml.jackson.databind.ObjectMapper; - - /** - * Spring-boot sample json. Used for testing or providing a hardcoded fall-back to spring.io, when - * the latter is not available. - * + * Spring-boot sample json. Used for testing or providing a hardcoded fall-back + * to spring.io, when the latter is not available. + * */ public class SampleProjectsProvider implements SpringProjectsProvider { private SpringProjects projects; @Override - public SpringProject getProject(String projectSlug) throws Exception { + public ResolvedSpringProject getProject(String projectSlug) throws Exception { + ResolvedSpringProject project = new ResolvedSpringProject(getSpringProject(projectSlug), null) { + + @Override + public List getGenerations() throws Exception { + SpringProject project = getSpringProject(projectSlug); + if (project != null && project.getSlug().equals("spring-boot")) { + return parse(SPRING_BOOT_PROJECT_GENERATIONS, Generations.class).getGenerations(); + } + return null; + } + + @Override + public List getReleases() throws Exception { + return null; + } + + }; + + return project; + } + + private SpringProject getSpringProject(String projectSlug) throws Exception { if (this.projects == null) { this.projects = parse(SPRING_PROJECTS_JSON_SAMPLE, SpringProjects.class); } @@ -45,15 +68,6 @@ public class SampleProjectsProvider implements SpringProjectsProvider { return null; } - @Override - public Generations getGenerations(String projectSlug) throws Exception { - SpringProject project = getProject(projectSlug); - if (project != null && project.getSlug().equals("spring-boot")) { - return parse(SPRING_BOOT_PROJECT_GENERATIONS, Generations.class); - } - return null; - } - private T parse(String json, Class clazz) throws Exception { ObjectMapper mapper = new ObjectMapper(); @@ -112,5 +126,4 @@ public class SampleProjectsProvider implements SpringProjectsProvider { + " },\n" + " \"parent\" : {\n" + " \"href\" : \"https://spring.io/api/projects/spring-data\"\n" + " }\n" + " }\n" + " } ]\n" + " }\n" + "}"; - }