PT #152867134 Progress and Error feedback for Maven/Gradle project load
This commit is contained in:
@@ -19,6 +19,7 @@ import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -29,7 +30,6 @@ import org.json.JSONTokener;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
@@ -93,20 +93,17 @@ public class DelegatingCachedClasspath<T extends IClasspath> implements IClasspa
|
||||
}
|
||||
|
||||
private AtomicReference<ClasspathData> cachedData;
|
||||
private Supplier<T> delegateCreator;
|
||||
private Callable<T> delegateCreator;
|
||||
private AtomicReference<T> cachedDelegate;
|
||||
|
||||
final private File cacheFile;
|
||||
|
||||
public DelegatingCachedClasspath(Supplier<T> delegateCreator, File cacheFile) {
|
||||
public DelegatingCachedClasspath(Callable<T> delegateCreator, File cacheFile) {
|
||||
super();
|
||||
this.cacheFile = cacheFile;
|
||||
this.cachedDelegate = new AtomicReference<>(delegateCreator.get());
|
||||
this.cachedDelegate = new AtomicReference<>(null);
|
||||
this.cachedData = new AtomicReference<>(init());
|
||||
this.delegateCreator = delegateCreator;
|
||||
if (!isCached()) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
public T delegate() {
|
||||
@@ -197,34 +194,43 @@ public class DelegatingCachedClasspath<T extends IClasspath> implements IClasspa
|
||||
}
|
||||
}
|
||||
|
||||
public boolean update() {
|
||||
final ClasspathData newData = createClasspathData();
|
||||
if (!Objects.equal(cachedData.get(), newData)) {
|
||||
cachedData.set(newData);
|
||||
persistCachedData(newData);
|
||||
return true;
|
||||
public boolean update() throws Exception {
|
||||
try {
|
||||
final ClasspathData newData = createClasspathData();
|
||||
if (!Objects.equal(cachedData.get(), newData)) {
|
||||
cachedData.set(newData);
|
||||
persistCachedData(newData);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
cachedData.set(new ClasspathData(null, Collections.emptySet(), Collections.emptySet(), null));
|
||||
throw e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return cachedDelegate.get().exists();
|
||||
T t = cachedDelegate.get();
|
||||
return t != null && t.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType findType(String fqName) {
|
||||
return cachedDelegate.get().findType(fqName);
|
||||
T t = cachedDelegate.get();
|
||||
return t == null ? null : t.findType(fqName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, Predicate<IType> typeFilter) {
|
||||
return cachedDelegate.get().fuzzySearchTypes(searchTerm, typeFilter);
|
||||
T t = cachedDelegate.get();
|
||||
return t == null ? Flux.empty() : t.fuzzySearchTypes(searchTerm, typeFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
return cachedDelegate.get().fuzzySearchPackages(searchTerm);
|
||||
T t = cachedDelegate.get();
|
||||
return t == null ? Flux.empty() : t.fuzzySearchPackages(searchTerm);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,16 +238,12 @@ public class DelegatingCachedClasspath<T extends IClasspath> implements IClasspa
|
||||
return cachedDelegate.get().allSubtypesOf(type);
|
||||
}
|
||||
|
||||
protected ClasspathData createClasspathData() {
|
||||
T newDelegate = delegateCreator.get();
|
||||
protected ClasspathData createClasspathData() throws Exception {
|
||||
T newDelegate = delegateCreator.call();
|
||||
cachedDelegate.set(newDelegate);
|
||||
try {
|
||||
LinkedHashSet<Path> classpathEntries = new LinkedHashSet<>(newDelegate.getClasspathEntries());
|
||||
return new ClasspathData(newDelegate.getName(), classpathEntries, new LinkedHashSet<>(newDelegate.getClasspathResources()), newDelegate.getOutputFolder());
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
return new ClasspathData(newDelegate.getName(), Collections.emptySet(), new LinkedHashSet<>(newDelegate.getClasspathResources()), newDelegate.getOutputFolder());
|
||||
}
|
||||
LinkedHashSet<Path> classpathEntries = new LinkedHashSet<>(newDelegate.getClasspathEntries());
|
||||
return new ClasspathData(newDelegate.getName(), classpathEntries,
|
||||
new LinkedHashSet<>(newDelegate.getClasspathResources()), newDelegate.getOutputFolder());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,9 +15,11 @@ import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ProgressService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.Sts4LanguageServer;
|
||||
|
||||
/**
|
||||
* Cache for java projects. The key for the cache is a "project" specific file
|
||||
@@ -32,24 +34,26 @@ public abstract class AbstractFileToProjectCache<P extends IJavaProject> extends
|
||||
private String deleteSubscription;
|
||||
protected boolean asyncUpdate;
|
||||
protected final Path projectCacheFolder;
|
||||
private boolean alwaysFireEventOnFileChanged;
|
||||
private boolean alwaysFireEventOnUpdate;
|
||||
|
||||
public AbstractFileToProjectCache(FileObserver fileObserver, boolean asyncUpdate, Path projectCacheFolder) {
|
||||
super(fileObserver);
|
||||
private static AtomicInteger progressIdCt = new AtomicInteger(0);
|
||||
|
||||
public AbstractFileToProjectCache(Sts4LanguageServer server, boolean asyncUpdate, Path projectCacheFolder) {
|
||||
super(server);
|
||||
this.projectCacheFolder = projectCacheFolder;
|
||||
this.asyncUpdate = asyncUpdate;
|
||||
}
|
||||
|
||||
|
||||
final public void setAlwaysFireEventOnFileChanged(boolean alwaysFireEventOnFileChanged) {
|
||||
this.alwaysFireEventOnFileChanged = alwaysFireEventOnFileChanged;
|
||||
final public void setAlwaysFireEventOnFileChanged(boolean alwaysFireEventOnUpdate) {
|
||||
this.alwaysFireEventOnUpdate = alwaysFireEventOnUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachListeners(File file, P project) {
|
||||
super.attachListeners(file, project);
|
||||
List<String> globPattern = Arrays.asList(file.toString());
|
||||
changeSubscription = getFileObserver().onFileChanged(globPattern, (uri) -> performUpdate(project, asyncUpdate));
|
||||
changeSubscription = getFileObserver().onFileChanged(globPattern, (uri) -> performUpdate(project, asyncUpdate, true));
|
||||
deleteSubscription = getFileObserver().onFileDeleted(globPattern, (uri) -> {
|
||||
cache.invalidate(file);
|
||||
notifyProjectDeleted(project);
|
||||
@@ -58,20 +62,37 @@ public abstract class AbstractFileToProjectCache<P extends IJavaProject> extends
|
||||
});
|
||||
}
|
||||
|
||||
final protected void performUpdate(P project, boolean async) {
|
||||
final protected void performUpdate(P project, boolean async, boolean notify) {
|
||||
final String taskId = getProgressId();
|
||||
final ProgressService progressService = server.getProgressService();
|
||||
if (progressService != null) {
|
||||
progressService.progressEvent(taskId, "Updating data for project `" + project.getElementName() + "'");
|
||||
}
|
||||
if (async) {
|
||||
CompletableFuture.supplyAsync(() -> update(project)).thenAccept((changed) -> {
|
||||
if (changed || alwaysFireEventOnFileChanged) {
|
||||
notifyProjectChanged(project);
|
||||
}
|
||||
});
|
||||
CompletableFuture.supplyAsync(() -> update(project)).thenAccept((changed) -> afterUpdate(project, changed, notify, taskId));
|
||||
} else {
|
||||
if (update(project) || alwaysFireEventOnFileChanged) {
|
||||
boolean changed = update(project);
|
||||
afterUpdate(project, changed, notify, taskId);
|
||||
}
|
||||
}
|
||||
|
||||
private void afterUpdate(P project, boolean changed, boolean notify, String taskId) {
|
||||
final ProgressService progressService = server.getProgressService();
|
||||
if (progressService != null) {
|
||||
progressService.progressEvent(taskId, null);
|
||||
}
|
||||
if (changed || alwaysFireEventOnUpdate) {
|
||||
if (notify) {
|
||||
notifyProjectChanged(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getProgressId() {
|
||||
return AbstractFileToProjectCache.class.getName()+ (progressIdCt.incrementAndGet());
|
||||
}
|
||||
|
||||
|
||||
abstract protected boolean update(P project);
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.Sts4LanguageServer;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.ListenerList;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
@@ -30,14 +31,14 @@ import com.google.common.cache.CacheBuilder;
|
||||
*/
|
||||
public abstract class AbstractJavaProjectCache<K, P extends IJavaProject> implements JavaProjectCache<K, P> {
|
||||
|
||||
private FileObserver fileObserver;
|
||||
protected Sts4LanguageServer server;
|
||||
|
||||
private ListenerList<Listener> listeners = new ListenerList<>();
|
||||
|
||||
protected Cache<K, P> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
public AbstractJavaProjectCache(FileObserver fileObserver) {
|
||||
this.fileObserver = fileObserver;
|
||||
public AbstractJavaProjectCache(Sts4LanguageServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,6 +91,6 @@ public abstract class AbstractJavaProjectCache<K, P extends IJavaProject> implem
|
||||
}
|
||||
|
||||
final protected FileObserver getFileObserver() {
|
||||
return fileObserver;
|
||||
return server.getWorkspaceService().getFileObserver();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user