Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.springframework.ide.vscode.boot.java.BuildCommandProvider;
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.java.IProjectBuild;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.protocol.java.ProjectBuild;
import org.springframework.ide.vscode.commons.util.FileObserver;
Expand Down Expand Up @@ -136,10 +137,29 @@ public DataRepositoryAotMetadataService(FileObserver fileObserver, JavaProjectFi
}
}

/**
* The project's build type, or <code>null</code> when it is not known.
* <p>
* Not every project has a build this server can classify: the invisible project the language server
* creates for a plain folder has none, and neither does a project contributed by an importer that is
* neither Maven nor Gradle - {@code ClasspathUtil.createProjectBuild} then reports a build whose type
* is null. Switching on that throws, and the callers here are on the indexing path, where an
* exception costs a whole type its symbols.
*/
private static String buildType(IJavaProject project) {
IProjectBuild build = project.getProjectBuild();
return build == null ? null : build.getType();
}

public Optional<DataRepositoryAotMetadata> getRepositoryMetadata(IJavaProject project, String repositoryType) {
String metadataFilePath = repositoryType.replace('.', '/') + ".json";

switch (project.getProjectBuild().getType()) {
String buildType = buildType(project);
if (buildType == null) {
return Optional.empty();
}

switch (buildType) {
case ProjectBuild.MAVEN_PROJECT_TYPE:
return IClasspathUtil.getOutputFolders(project.getClasspath())
.map(outputFolder -> outputFolder.getParentFile().toPath().resolve("spring-aot/main/resources/").resolve(metadataFilePath))
Expand Down Expand Up @@ -167,7 +187,12 @@ private Optional<DataRepositoryAotMetadata> readMetadataFile(Path filePath) {
}

Optional<Command> regenerateMetadataCommand(IJavaProject jp) {
switch (jp.getProjectBuild().getType()) {
String buildType = buildType(jp);
if (buildType == null) {
return Optional.empty();
}

switch (buildType) {
case ProjectBuild.MAVEN_PROJECT_TYPE:
List<String> goal = new ArrayList<>();
if (!IClasspathUtil.getOutputFolders(jp.getClasspath()).map(f -> f.toPath()).filter(Files::isDirectory).flatMap(d -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2026 Broadcom
* 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:
* Broadcom - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.data.test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.Optional;

import org.junit.jupiter.api.Test;
import org.springframework.ide.vscode.boot.java.data.DataRepositoryAotMetadataService;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.java.IProjectBuild;

/**
* Asking for AOT metadata on a project whose build is neither Maven nor Gradle.
* <p>
* The answer has to be "no metadata" rather than an exception: the caller is the Spring Data
* repository indexer, which reaches this service for every query method that carries no
* {@code @Query}, and an exception there is caught per type - so the whole repository interface
* loses its symbols.
*
* @author Artem
*/
public class DataRepositoryAotMetadataServiceBuildTypeTest {

private final DataRepositoryAotMetadataService service = new DataRepositoryAotMetadataService(null, null, null);

@Test
void buildWithoutATypeYieldsNoMetadata() {
IJavaProject project = mock(IJavaProject.class);
when(project.getProjectBuild()).thenReturn(IProjectBuild.create(null, null));

assertEquals(Optional.empty(), service.getRepositoryMetadata(project, "com.example.UserRepository"));
}

@Test
void noBuildAtAllYieldsNoMetadata() {
IJavaProject project = mock(IJavaProject.class);
when(project.getProjectBuild()).thenReturn(null);

assertEquals(Optional.empty(), service.getRepositoryMetadata(project, "com.example.UserRepository"));
}
}