Skip to content

Commit

Permalink
Show with progress bar the load of long process
Browse files Browse the repository at this point in the history
Fixes eclipse-lemminx#471

Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr committed Jul 29, 2023
1 parent fef6bdf commit 00b052a
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -74,6 +73,8 @@
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.repository.WorkspaceReader;
import org.eclipse.lemminx.commons.TextDocument;
import org.eclipse.lemminx.commons.progress.ProgressMonitor;
import org.eclipse.lemminx.commons.progress.ProgressSupport;
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMParser;
import org.eclipse.lemminx.extensions.maven.participants.codeaction.ExtractPropertyCodeAction;
Expand Down Expand Up @@ -145,6 +146,8 @@ public class MavenLemminxExtension implements IXMLExtension {
// Thread which loads Maven component (plexus container, maven session, etc) which can take some time.
private CompletableFuture<Void> mavenInitializer;

private ProgressSupport progressSupport;

@Override
public void doSave(ISaveContext context) {
if (context.getType() == SaveContextType.SETTINGS) {
Expand Down Expand Up @@ -175,6 +178,7 @@ public void start(InitializeParams params, XMLExtensionsRegistry registry) {
}
this.currentRegistry = registry;
this.resolverExtensionManager = registry.getResolverExtensionManager();
this.progressSupport = registry.getProgressSupport();
try {
// Do not invoke getters the MavenLemminxExtension in participant constructors,
// or that will trigger loading of plexus, Maven and so on even for non pom files
Expand Down Expand Up @@ -233,28 +237,112 @@ private synchronized CompletableFuture<Void> getOrCreateMavenInitializer() {
}

private void doInitialize() {
try {
ProgressMonitor progressMonitor = progressSupport != null ? progressSupport.createProgressMonitor() : null;
try {
if (progressMonitor != null) {
progressMonitor.begin("Loading Maven components...", "", 100, null);
}
boolean skipCentralRepository = settings.getCentral().isSkip();
int nbSteps = 7 -(skipCentralRepository ? 1 : 0);
int currentStep = 1;
int percentage = 15;

// Step1 : initialize Plexus container
if (progressMonitor != null) {
progressMonitor.report("Initializing Plexus container" + getStepMessage(currentStep, nbSteps) + "...",
percentage, null);
}
this.container = newPlexusContainer();

// Step2 : initialize Maven request
if (progressMonitor != null) {
currentStep++;
percentage += 15;
progressMonitor.report("Initializing Maven request" + getStepMessage(currentStep, nbSteps) + "...",
percentage, null);
}
mavenRequest = initMavenRequest(container, settings);
DefaultRepositorySystemSessionFactory repositorySessionFactory = container.lookup(DefaultRepositorySystemSessionFactory.class);
RepositorySystemSession repositorySystemSession = repositorySessionFactory.newRepositorySession(mavenRequest);

// Step3 : initialize Repository system session
if (progressMonitor != null) {
currentStep++;
percentage += 15;
progressMonitor.report(
"Initializing Repository system session" + getStepMessage(currentStep, nbSteps) + "...",
percentage, null);
}
DefaultRepositorySystemSessionFactory repositorySessionFactory = container
.lookup(DefaultRepositorySystemSessionFactory.class);
RepositorySystemSession repositorySystemSession = repositorySessionFactory
.newRepositorySession(mavenRequest);

// Step4 : initialize Maven session
if (progressMonitor != null) {
currentStep++;
percentage += 15;
progressMonitor.report("Initializing Maven session" + getStepMessage(currentStep, nbSteps) + "...",
percentage, null);
}
MavenExecutionResult mavenResult = new DefaultMavenExecutionResult();
// TODO: MavenSession is deprecated. Investigate for alternative
mavenSession = new MavenSession(container, repositorySystemSession, mavenRequest, mavenResult);
cache = new MavenProjectCache(mavenSession);
localRepositorySearcher = new LocalRepositorySearcher(mavenSession.getRepositorySession().getLocalRepository().getBasedir());
if (!settings.getCentral().isSkip()) {

// Step5 : create local repository searcher
if (progressMonitor != null) {
currentStep++;
percentage += 15;
progressMonitor.report(
"Creating local repository searcher" + getStepMessage(currentStep, nbSteps) + "...", percentage,
null);
}
localRepositorySearcher = new LocalRepositorySearcher(
mavenSession.getRepositorySession().getLocalRepository().getBasedir(), progressSupport);

if (!skipCentralRepository) {
// Step6 : create central repository searcher
if (progressMonitor != null) {
currentStep++;
percentage += 15;
progressMonitor.report(
"Creating central repository searcher" + getStepMessage(currentStep, nbSteps) + "...",
percentage, null);
}

centralSearcher = new RemoteCentralRepositorySearcher();
} else {
percentage += 15;
}

buildPluginManager = null;
mavenPluginManager = container.lookup(MavenPluginManager.class);
buildPluginManager = container.lookup(BuildPluginManager.class);
internalDidChangeWorkspaceFolders(this.initialWorkspaceFolders.stream().map(WorkspaceFolder::getUri).map(URI::create).toArray(URI[]::new), null);

// Step7 : initializing Workspace readers
if (progressMonitor != null) {
currentStep++;
percentage += 15;
progressMonitor.report("Initializing Workspace readers" + getStepMessage(currentStep, nbSteps) + "...",
percentage, null);
}
internalDidChangeWorkspaceFolders(this.initialWorkspaceFolders.stream().map(WorkspaceFolder::getUri)
.map(URI::create).toArray(URI[]::new), null);
} catch (Exception e) {
if (progressMonitor != null) {
progressMonitor.end("Error while initializing Maven");
}
LOGGER.log(Level.SEVERE, e.getMessage(), e);
stop(currentRegistry);
stop(currentRegistry);
}
finally {
if (progressMonitor != null) {
progressMonitor.end("Maven initialization done");
}
}
}
private static String getStepMessage(int currentStep, int nbSteps) {
return " (" + currentStep + "/" + nbSteps + ")";
}

private MavenExecutionRequest initMavenRequest(PlexusContainer container, XMLMavenSettings options) throws Exception {
MavenExecutionRequest mavenRequest = new DefaultMavenExecutionRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,21 @@
import org.apache.maven.model.Dependency;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.lemminx.commons.progress.ProgressMonitor;
import org.eclipse.lemminx.commons.progress.ProgressSupport;
import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension;

public class LocalRepositorySearcher {

private static final Logger LOGGER = Logger.getLogger(LocalRepositorySearcher.class.getName());

private final File localRepository;

public LocalRepositorySearcher(File localRepository) {
private final ProgressSupport progressSupport;

public LocalRepositorySearcher(File localRepository, ProgressSupport progressSupport) {
this.localRepository = localRepository;
this.progressSupport = progressSupport;
}

private Map<File, CompletableFuture<Collection<Artifact>>> cache = new HashMap<>();
Expand Down Expand Up @@ -130,43 +135,56 @@ private synchronized CompletableFuture<Collection<Artifact>> getOrCreateLocalArt
return loadLocalArtifacts;
}

public Collection<Artifact> computeLocalArtifacts() throws IOException {
final Path repoPath = localRepository.toPath();
private Collection<Artifact> computeLocalArtifacts() throws IOException {
Map<String, Artifact> groupIdArtifactIdToVersion = new HashMap<>();
Files.walkFileTree(repoPath, Collections.emptySet(), 10, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path file, BasicFileAttributes attrs) throws IOException {
if (file.getFileName().toString().charAt(0) == '.') {
return FileVisitResult.SKIP_SUBTREE;
}
if (!Character.isDigit(file.getFileName().toString().charAt(0))) {
return FileVisitResult.CONTINUE;
}
Path artifactFolderPath = repoPath.relativize(file);
if (artifactFolderPath.getNameCount() < 3) {
// eg "maven-dependency-plugin/3.1.2"
return FileVisitResult.SKIP_SUBTREE;
}
ArtifactVersion version = new DefaultArtifactVersion(artifactFolderPath.getFileName().toString());
String artifactId = artifactFolderPath.getParent().getFileName().toString();
String groupId = artifactFolderPath.getParent().getParent().toString().replace(artifactFolderPath.getFileSystem().getSeparator(), ".");
if (!new File(file.toFile(), artifactId + '-' + version.toString() + ".pom").isFile()) {
final Path repoPath = localRepository.toPath();
ProgressMonitor progressMonitor = progressSupport != null ? progressSupport.createProgressMonitor() : null;
if (progressMonitor != null) {
progressMonitor.begin("Loading local artifacts from '" + repoPath + "'...", "", 100, null);
}
try {
Files.walkFileTree(repoPath, Collections.emptySet(), 10, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path file, BasicFileAttributes attrs) throws IOException {
if (file.getFileName().toString().charAt(0) == '.') {
return FileVisitResult.SKIP_SUBTREE;
}
if (!Character.isDigit(file.getFileName().toString().charAt(0))) {
return FileVisitResult.CONTINUE;
}
Path artifactFolderPath = repoPath.relativize(file);
if (artifactFolderPath.getNameCount() < 3) {
// eg "maven-dependency-plugin/3.1.2"
return FileVisitResult.SKIP_SUBTREE;
}
ArtifactVersion version = new DefaultArtifactVersion(artifactFolderPath.getFileName().toString());
String artifactId = artifactFolderPath.getParent().getFileName().toString();
String groupId = artifactFolderPath.getParent().getParent().toString()
.replace(artifactFolderPath.getFileSystem().getSeparator(), ".");
if (!new File(file.toFile(), artifactId + '-' + version.toString() + ".pom").isFile()) {
return FileVisitResult.SKIP_SUBTREE;
}
String groupIdArtifactId = groupId + ':' + artifactId;
Artifact existingGav = groupIdArtifactIdToVersion.get(groupIdArtifactId);
boolean replace = existingGav == null;
if (existingGav != null) {
ArtifactVersion existingVersion = new DefaultArtifactVersion(existingGav.getVersion());
replace |= existingVersion.compareTo(version) < 0;
replace |= (existingVersion.toString().endsWith("-SNAPSHOT")
&& !version.toString().endsWith("-SNAPSHOT"));
}
if (replace) {
groupIdArtifactIdToVersion.put(groupIdArtifactId,
new DefaultArtifact(groupId, artifactId, null, version.toString()));
}
return FileVisitResult.SKIP_SUBTREE;
}
String groupIdArtifactId = groupId + ':' + artifactId;
Artifact existingGav = groupIdArtifactIdToVersion.get(groupIdArtifactId);
boolean replace = existingGav == null;
if (existingGav != null) {
ArtifactVersion existingVersion = new DefaultArtifactVersion(existingGav.getVersion());
replace |= existingVersion.compareTo(version) < 0;
replace |= (existingVersion.toString().endsWith("-SNAPSHOT") && !version.toString().endsWith("-SNAPSHOT"));
}
if (replace) {
groupIdArtifactIdToVersion.put(groupIdArtifactId, new DefaultArtifact(groupId, artifactId, null, version.toString()));
}
return FileVisitResult.SKIP_SUBTREE;
});
} finally {
if (progressMonitor != null) {
progressMonitor.end("Local artifacts loaded");
}
});
}
return groupIdArtifactIdToVersion.values();
}

Expand Down

0 comments on commit 00b052a

Please sign in to comment.