PT #150740880: VSCode/Eclipse file watching. Back to project finder
Eclipse client file change listening mechanics Reworked file/project observer implementation Merge fixes
This commit is contained in:
3
atom-extensions/atom-commons/.gitignore
vendored
3
atom-extensions/atom-commons/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/dist
|
||||
/node_modules
|
||||
/node_modules
|
||||
/build
|
||||
@@ -15,7 +15,8 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.9.0",
|
||||
org.eclipse.ui.workbench,
|
||||
org.eclipse.jface,
|
||||
org.eclipse.xtext.xbase.lib,
|
||||
org.springframework.tooling.ls.eclipse.commons
|
||||
org.springframework.tooling.ls.eclipse.commons,
|
||||
org.eclipse.core.resources
|
||||
Import-Package: com.google.gson;version="2.7.0",
|
||||
org.eclipse.jface.preference,
|
||||
org.eclipse.lsp4j.jsonrpc.messages;version="0.1.0.v20170117-0759",
|
||||
|
||||
@@ -13,6 +13,7 @@ package org.springframework.tooling.boot.java.ls;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.lsp4e.server.StreamConnectionProvider;
|
||||
|
||||
@@ -41,7 +42,12 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
|
||||
this.provider = new SpringBootJavaLanguageServer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getInitializationOptions(URI rootUri) {
|
||||
return provider.getInitializationOptions(rootUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws IOException {
|
||||
this.provider.start();
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.boot.java.ls;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResourceChangeEvent;
|
||||
import org.eclipse.core.resources.IResourceChangeListener;
|
||||
import org.eclipse.core.resources.IResourceDelta;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.lsp4e.LanguageServersRegistry;
|
||||
import org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition;
|
||||
import org.eclipse.lsp4e.LanguageServiceAccessor;
|
||||
import org.eclipse.lsp4e.ProjectSpecificLanguageServerWrapper;
|
||||
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
|
||||
import org.eclipse.lsp4j.FileChangeType;
|
||||
import org.eclipse.lsp4j.FileEvent;
|
||||
|
||||
/**
|
||||
* Resource listener for LSP4E taken from CPP-LS
|
||||
* https://github.com/eclipse/cdt/blob/master/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/CPPResourceChangeListener.java
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class ResourceListener implements IResourceChangeListener {
|
||||
|
||||
private final String lsId;
|
||||
private final IProject fProject;
|
||||
private List<PathMatcher> pathMatchers;
|
||||
|
||||
ResourceListener(String lsId, IProject project, List<PathMatcher> pathMatchers) {
|
||||
this.lsId = lsId;
|
||||
fProject = project;
|
||||
this.pathMatchers = pathMatchers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resourceChanged(IResourceChangeEvent event) {
|
||||
LanguageServerDefinition definition = LanguageServersRegistry.getInstance().getDefinition(lsId);
|
||||
ProjectSpecificLanguageServerWrapper wrapper = getLanguageSeverWrapper(definition);
|
||||
if (event.getType() != IResourceChangeEvent.POST_CHANGE || !isRelevantDelta(event.getDelta())
|
||||
|| wrapper == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendFileEvents(wrapper, createFileEventsFromResourceEvent(event));
|
||||
}
|
||||
|
||||
private static void sendFileEvents(ProjectSpecificLanguageServerWrapper wrapper, List<FileEvent> fileEvents) {
|
||||
if (!fileEvents.isEmpty()) {
|
||||
DidChangeWatchedFilesParams params = new DidChangeWatchedFilesParams(fileEvents);
|
||||
wrapper.getServer().getWorkspaceService().didChangeWatchedFiles(params);
|
||||
}
|
||||
}
|
||||
|
||||
private List<FileEvent> createFileEventsFromResourceEvent(IResourceChangeEvent event) {
|
||||
List<FileEvent> fileEvents = new ArrayList<>();
|
||||
try {
|
||||
event.getDelta().accept((delta) -> {
|
||||
if (delta.getResource() instanceof IFile && isRelevantDelta(delta) && isApplicableFile((IFile) delta.getResource())) {
|
||||
FileEvent fileEvent = createFileEventFromDelta(delta);
|
||||
if (fileEvent != null) {
|
||||
fileEvents.add(fileEvent);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
} catch (CoreException e) {
|
||||
// Do nothing
|
||||
}
|
||||
return fileEvents;
|
||||
}
|
||||
|
||||
private boolean isApplicableFile(IFile resource) {
|
||||
return pathMatchers.stream().filter(m -> m.matches(resource.getLocation().toFile().toPath())).findFirst().isPresent();
|
||||
}
|
||||
|
||||
private ProjectSpecificLanguageServerWrapper getLanguageSeverWrapper(LanguageServerDefinition definition) {
|
||||
try {
|
||||
return LanguageServiceAccessor.getLSWrapperForConnection(fProject, definition);
|
||||
} catch (IOException e) {
|
||||
// Do nothing
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isRelevantDelta(IResourceDelta delta) {
|
||||
int kind = delta.getKind();
|
||||
int flags = delta.getFlags();
|
||||
if (delta.getResource() instanceof IFile && kind == IResourceDelta.CHANGED) {
|
||||
return (flags & IResourceDelta.CONTENT) != 0;
|
||||
}
|
||||
|
||||
return kind == IResourceDelta.ADDED || kind == IResourceDelta.CHANGED || kind == IResourceDelta.REMOVED;
|
||||
}
|
||||
|
||||
private static FileEvent createFileEventFromDelta(IResourceDelta delta) {
|
||||
URI locationURI = delta.getResource().getLocationURI();
|
||||
if (locationURI == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FileChangeType changeType = null;
|
||||
if (delta.getKind() == IResourceDelta.ADDED) {
|
||||
changeType = FileChangeType.Created;
|
||||
} else if (delta.getKind() == IResourceDelta.CHANGED) {
|
||||
changeType = FileChangeType.Changed;
|
||||
} else if (delta.getKind() == IResourceDelta.REMOVED) {
|
||||
changeType = FileChangeType.Deleted;
|
||||
} else {
|
||||
throw new IllegalStateException("Unsupported resource delta kind: " + delta.getKind()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
return new FileEvent(locationURI.toString(), changeType);
|
||||
}
|
||||
}
|
||||
@@ -13,30 +13,30 @@ package org.springframework.tooling.boot.java.ls;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jdt.internal.launching.StandardVMType;
|
||||
import org.eclipse.jface.action.IStatusLineManager;
|
||||
import org.eclipse.lsp4e.server.ProcessStreamConnectionProvider;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Message;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class SpringBootJavaLanguageServer extends ProcessStreamConnectionProvider {
|
||||
|
||||
private ResourceListener fResourceListener;
|
||||
|
||||
public SpringBootJavaLanguageServer() {
|
||||
List<String> commands = new ArrayList<>();
|
||||
@@ -107,4 +107,44 @@ public class SpringBootJavaLanguageServer extends ProcessStreamConnectionProvide
|
||||
Files.copy(stream, dataFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
if (fResourceListener != null) {
|
||||
ResourcesPlugin.getWorkspace().removeResourceChangeListener(fResourceListener);
|
||||
fResourceListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInitializationOptions(URI rootPath) {
|
||||
installResourceChangeListener(rootPath);
|
||||
return super.getInitializationOptions(rootPath);
|
||||
}
|
||||
|
||||
private void installResourceChangeListener(URI rootPath) {
|
||||
if (rootPath == null || fResourceListener != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
IContainer[] containers = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocationURI(rootPath);
|
||||
if (containers.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (IContainer c : containers) {
|
||||
if (!(c instanceof IProject)) {
|
||||
continue;
|
||||
}
|
||||
IProject project = (IProject) c;
|
||||
fResourceListener = new ResourceListener("org.eclipse.languageserver.languages.springbootjava", project, Arrays.asList(
|
||||
FileSystems.getDefault().getPathMatcher("glob:**/pom.xml"),
|
||||
FileSystems.getDefault().getPathMatcher("glob:**/build.gradle")
|
||||
));
|
||||
project.getWorkspace().addResourceChangeListener(fResourceListener);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -44,15 +45,24 @@ import org.springframework.ide.vscode.boot.java.value.ValueCompletionProcessor;
|
||||
import org.springframework.ide.vscode.boot.java.value.ValueHoverProvider;
|
||||
import org.springframework.ide.vscode.boot.java.value.ValuePropertyReferencesProvider;
|
||||
import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleCore;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleProjectCache;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.HighlightParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeProjectOvserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.ReferencesHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectCache;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -69,10 +79,11 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
private final VscodeCompletionEngineAdapter completionEngine;
|
||||
private final SpringIndexer indexer;
|
||||
private final SpringLiveHoverWatchdog liveHoverWatchdog;
|
||||
private final CompositeProjectOvserver projectObserver;
|
||||
|
||||
private final WordHighlighter testHightlighter = null; //new WordHighlighter("foo");
|
||||
|
||||
public BootJavaLanguageServer(JavaProjectManager javaProjectManager, SpringPropertyIndexProvider indexProvider) {
|
||||
public BootJavaLanguageServer(CompositeJavaProjectFinder javaProjectFinder, SpringPropertyIndexProvider indexProvider) {
|
||||
super("vscode-boot-java");
|
||||
|
||||
System.setProperty(LANGUAGE_SERVER_PROCESS_PROPERTY, LANGUAGE_SERVER_PROCESS_PROPERTY);
|
||||
@@ -86,13 +97,13 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
validateWith(doc.getId(), reconcileEngine);
|
||||
});
|
||||
|
||||
ICompletionEngine bootCompletionEngine = createCompletionEngine(javaProjectManager, indexProvider);
|
||||
ICompletionEngine bootCompletionEngine = createCompletionEngine(javaProjectFinder, indexProvider);
|
||||
completionEngine = createCompletionEngineAdapter(this, bootCompletionEngine);
|
||||
completionEngine.setMaxCompletions(100);
|
||||
documents.onCompletion(completionEngine::getCompletions);
|
||||
documents.onCompletionResolve(completionEngine::resolveCompletion);
|
||||
|
||||
BootJavaHoverProvider hoverInfoProvider = createHoverHandler(javaProjectManager);
|
||||
BootJavaHoverProvider hoverInfoProvider = createHoverHandler(javaProjectFinder);
|
||||
documents.onHover(hoverInfoProvider);
|
||||
|
||||
liveHoverWatchdog = new SpringLiveHoverWatchdog(this, hoverInfoProvider);
|
||||
@@ -106,10 +117,10 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
}
|
||||
});
|
||||
|
||||
ReferencesHandler referencesHandler = createReferenceHandler(this, javaProjectManager);
|
||||
ReferencesHandler referencesHandler = createReferenceHandler(this, javaProjectFinder);
|
||||
documents.onReferences(referencesHandler);
|
||||
|
||||
indexer = createAnnotationIndexer(this, javaProjectManager);
|
||||
indexer = createAnnotationIndexer(this, javaProjectFinder);
|
||||
documents.onDidSave(params -> {
|
||||
String docURI = params.getDocument().getId().getUri();
|
||||
String content = params.getDocument().get();
|
||||
@@ -119,10 +130,18 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
documents.onDocumentSymbol(new BootJavaDocumentSymbolHandler(indexer));
|
||||
workspaceService.onWorkspaceSymbol(new BootJavaWorkspaceSymbolHandler(indexer));
|
||||
|
||||
BootJavaCodeLensEngine codeLensHandler = createCodeLensEngine(this, javaProjectManager);
|
||||
BootJavaCodeLensEngine codeLensHandler = createCodeLensEngine(this, javaProjectFinder);
|
||||
documents.onCodeLens(codeLensHandler::createCodeLenses);
|
||||
documents.onCodeLensResolve(codeLensHandler::resolveCodeLens);
|
||||
|
||||
// Initialize project finders, project caches and project observers
|
||||
MavenProjectCache mavenProjectCache = new MavenProjectCache(getWorkspaceService().getFileObserver(), MavenCore.getDefault());
|
||||
javaProjectFinder.addJavaProjectFinder(new MavenProjectFinder(mavenProjectCache));
|
||||
|
||||
GradleProjectCache gradleProjectCache = new GradleProjectCache(getWorkspaceService().getFileObserver(), GradleCore.getDefault());
|
||||
javaProjectFinder.addJavaProjectFinder(new GradleProjectFinder(gradleProjectCache));
|
||||
|
||||
projectObserver = new CompositeProjectOvserver(Arrays.asList(mavenProjectCache, gradleProjectCache));
|
||||
}
|
||||
|
||||
public void setMaxCompletionsNumber(int number) {
|
||||
@@ -156,7 +175,7 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
return super.shutdown();
|
||||
}
|
||||
|
||||
protected ICompletionEngine createCompletionEngine(JavaProjectManager javaProjectManager, SpringPropertyIndexProvider indexProvider) {
|
||||
protected ICompletionEngine createCompletionEngine(JavaProjectFinder javaProjectFinder, SpringPropertyIndexProvider indexProvider) {
|
||||
Map<String, CompletionProvider> providers = new HashMap<>();
|
||||
providers.put(org.springframework.ide.vscode.boot.java.scope.Constants.SPRING_SCOPE, new ScopeCompletionProcessor());
|
||||
providers.put(org.springframework.ide.vscode.boot.java.value.Constants.SPRING_VALUE, new ValueCompletionProcessor(indexProvider));
|
||||
@@ -220,10 +239,10 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
" return ${entity};\n" +
|
||||
"}"
|
||||
));
|
||||
return new BootJavaCompletionEngine(javaProjectManager, providers, snippetManager);
|
||||
return new BootJavaCompletionEngine(javaProjectFinder, providers, snippetManager);
|
||||
}
|
||||
|
||||
protected BootJavaHoverProvider createHoverHandler(JavaProjectManager javaProjectFinder) {
|
||||
protected BootJavaHoverProvider createHoverHandler(JavaProjectFinder javaProjectFinder) {
|
||||
HashMap<String, HoverProvider> providers = new HashMap<>();
|
||||
|
||||
providers.put(org.springframework.ide.vscode.boot.java.value.Constants.SPRING_VALUE, new ValueHoverProvider());
|
||||
@@ -241,7 +260,7 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
return new BootJavaHoverProvider(this, javaProjectFinder, providers);
|
||||
}
|
||||
|
||||
protected SpringIndexer createAnnotationIndexer(SimpleLanguageServer server, JavaProjectManager projectManager) {
|
||||
protected SpringIndexer createAnnotationIndexer(SimpleLanguageServer server, JavaProjectFinder projectFinder) {
|
||||
HashMap<String, SymbolProvider> providers = new HashMap<>();
|
||||
providers.put(org.springframework.ide.vscode.boot.java.requestmapping.Constants.SPRING_REQUEST_MAPPING, new RequestMappingSymbolProvider());
|
||||
providers.put(org.springframework.ide.vscode.boot.java.requestmapping.Constants.SPRING_GET_MAPPING, new RequestMappingSymbolProvider());
|
||||
@@ -253,19 +272,22 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
providers.put(org.springframework.ide.vscode.boot.java.beans.Constants.SPRING_BEAN, new BeansSymbolProvider());
|
||||
providers.put(org.springframework.ide.vscode.boot.java.beans.Constants.SPRING_COMPONENT, new ComponentSymbolProvider());
|
||||
|
||||
return new SpringIndexer(this, projectManager, providers);
|
||||
return new SpringIndexer(this, projectFinder, providers);
|
||||
}
|
||||
|
||||
protected ReferencesHandler createReferenceHandler(SimpleLanguageServer server, JavaProjectManager projectManager) {
|
||||
protected ReferencesHandler createReferenceHandler(SimpleLanguageServer server, JavaProjectFinder projectFinder) {
|
||||
Map<String, ReferenceProvider> providers = new HashMap<>();
|
||||
providers.put(org.springframework.ide.vscode.boot.java.value.Constants.SPRING_VALUE, new ValuePropertyReferencesProvider(server));
|
||||
|
||||
return new BootJavaReferencesHandler(server, projectManager, providers);
|
||||
return new BootJavaReferencesHandler(server, projectFinder, providers);
|
||||
}
|
||||
|
||||
protected BootJavaCodeLensEngine createCodeLensEngine(SimpleLanguageServer server, JavaProjectManager projectFinder) {
|
||||
protected BootJavaCodeLensEngine createCodeLensEngine(SimpleLanguageServer server, JavaProjectFinder projectFinder) {
|
||||
return new BootJavaCodeLensEngine(server, projectFinder);
|
||||
}
|
||||
|
||||
public ProjectObserver getProjectObserver() {
|
||||
return projectObserver;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,15 +13,9 @@ package org.springframework.ide.vscode.boot.java;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.ide.vscode.boot.metadata.DefaultSpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleCore;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectManager;
|
||||
import org.springframework.ide.vscode.commons.maven.java.classpathfile.JavaProjectWithClasspathFileManager;
|
||||
|
||||
/**
|
||||
* Starts up Language Server process
|
||||
@@ -32,14 +26,9 @@ public class Main {
|
||||
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
LaunguageServerApp.start(() -> {
|
||||
CompositeJavaProjectManager javaProjectManager = new CompositeJavaProjectManager(new JavaProjectManager[] {
|
||||
new MavenProjectManager(MavenCore.getDefault()),
|
||||
new GradleProjectManager(GradleCore.getDefault()),
|
||||
new JavaProjectWithClasspathFileManager()
|
||||
});
|
||||
DefaultSpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectManager);
|
||||
SimpleLanguageServer server = new BootJavaLanguageServer(javaProjectManager, indexProvider);
|
||||
javaProjectManager.setFileObserver(server.getWorkspaceService());
|
||||
CompositeJavaProjectFinder javaProjectFinder = new CompositeJavaProjectFinder();
|
||||
DefaultSpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
|
||||
SimpleLanguageServer server = new BootJavaLanguageServer(javaProjectFinder, indexProvider);
|
||||
return server;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.eclipse.lsp4j.CodeLensParams;
|
||||
import org.eclipse.lsp4j.Command;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
@@ -30,9 +30,9 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
public class BootJavaCodeLensEngine {
|
||||
|
||||
private final SimpleLanguageServer server;
|
||||
private final JavaProjectManager projectFinder;
|
||||
private final JavaProjectFinder projectFinder;
|
||||
|
||||
public BootJavaCodeLensEngine(SimpleLanguageServer server, JavaProjectManager projectFinder) {
|
||||
public BootJavaCodeLensEngine(SimpleLanguageServer server, JavaProjectFinder projectFinder) {
|
||||
this.server = server;
|
||||
this.projectFinder = projectFinder;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
@@ -38,12 +38,12 @@ import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
*/
|
||||
public class BootJavaCompletionEngine implements ICompletionEngine {
|
||||
|
||||
private JavaProjectManager projectManager;
|
||||
private JavaProjectFinder projectFinder;
|
||||
private Map<String, CompletionProvider> completionProviders;
|
||||
private JavaSnippetManager snippets;
|
||||
|
||||
public BootJavaCompletionEngine(JavaProjectManager projectManager, Map<String, CompletionProvider> specificProviders, JavaSnippetManager snippets) {
|
||||
this.projectManager = projectManager;
|
||||
public BootJavaCompletionEngine(JavaProjectFinder projectFinder, Map<String, CompletionProvider> specificProviders, JavaSnippetManager snippets) {
|
||||
this.projectFinder = projectFinder;
|
||||
this.completionProviders = specificProviders;
|
||||
this.snippets = snippets;
|
||||
}
|
||||
@@ -108,7 +108,7 @@ public class BootJavaCompletionEngine implements ICompletionEngine {
|
||||
}
|
||||
|
||||
private String[] getClasspathEntries(IDocument doc) throws Exception {
|
||||
IJavaProject project = this.projectManager.find(doc);
|
||||
IJavaProject project = this.projectFinder.find(doc);
|
||||
IClasspath classpath = project.getClasspath();
|
||||
Stream<Path> classpathEntries = classpath.getClasspathEntries();
|
||||
return classpathEntries
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
@@ -49,11 +49,11 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public class BootJavaHoverProvider implements HoverHandler {
|
||||
|
||||
private JavaProjectManager projectFinder;
|
||||
private JavaProjectFinder projectFinder;
|
||||
private SimpleLanguageServer server;
|
||||
private Map<String, HoverProvider> hoverProviders;
|
||||
|
||||
public BootJavaHoverProvider(SimpleLanguageServer server, JavaProjectManager projectFinder, Map<String, HoverProvider> specificProviders) {
|
||||
public BootJavaHoverProvider(SimpleLanguageServer server, JavaProjectFinder projectFinder, Map<String, HoverProvider> specificProviders) {
|
||||
this.server = server;
|
||||
this.projectFinder = projectFinder;
|
||||
this.hoverProviders = specificProviders;
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.ReferenceParams;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.ReferencesHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
@@ -40,13 +40,13 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
|
||||
private JavaProjectManager projectManager;
|
||||
private JavaProjectFinder projectFinder;
|
||||
private SimpleLanguageServer server;
|
||||
private Map<String, ReferenceProvider> referenceProviders;
|
||||
|
||||
public BootJavaReferencesHandler(SimpleLanguageServer server, JavaProjectManager projectManager, Map<String, ReferenceProvider> specificProviders) {
|
||||
public BootJavaReferencesHandler(SimpleLanguageServer server, JavaProjectFinder projectFinder, Map<String, ReferenceProvider> specificProviders) {
|
||||
this.server = server;
|
||||
this.projectManager = projectManager;
|
||||
this.projectFinder = projectFinder;
|
||||
this.referenceProviders = specificProviders;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ public class BootJavaReferencesHandler implements ReferencesHandler {
|
||||
}
|
||||
|
||||
private String[] getClasspathEntries(IDocument doc) throws Exception {
|
||||
IJavaProject project = this.projectManager.find(doc);
|
||||
IJavaProject project = this.projectFinder.find(doc);
|
||||
IClasspath classpath = project.getClasspath();
|
||||
Stream<Path> classpathEntries = classpath.getClasspathEntries();
|
||||
return classpathEntries
|
||||
|
||||
@@ -44,12 +44,13 @@ import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager.Listener;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver.Listener;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
@@ -58,8 +59,8 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public class SpringIndexer {
|
||||
|
||||
private SimpleLanguageServer server;
|
||||
private JavaProjectManager projectManager;
|
||||
private BootJavaLanguageServer server;
|
||||
private JavaProjectFinder projectFinder;
|
||||
private Map<String, SymbolProvider> symbolProviders;
|
||||
|
||||
private List<SymbolInformation> symbols;
|
||||
@@ -91,9 +92,9 @@ public class SpringIndexer {
|
||||
|
||||
};
|
||||
|
||||
public SpringIndexer(SimpleLanguageServer server, JavaProjectManager projectManager, Map<String, SymbolProvider> specificProviders) {
|
||||
public SpringIndexer(BootJavaLanguageServer server, JavaProjectFinder projectFinder, Map<String, SymbolProvider> specificProviders) {
|
||||
this.server = server;
|
||||
this.projectManager = projectManager;
|
||||
this.projectFinder = projectFinder;
|
||||
this.symbolProviders = specificProviders;
|
||||
|
||||
this.symbols = Collections.synchronizedList(new ArrayList<>());
|
||||
@@ -105,8 +106,8 @@ public class SpringIndexer {
|
||||
synchronized(this) {
|
||||
if (this.initializeTask == null) {
|
||||
initializing.set(true);
|
||||
if (projectManager != null) {
|
||||
projectManager.addListener(projectListener);
|
||||
if (server.getProjectObserver() != null) {
|
||||
server.getProjectObserver().addListener(projectListener);
|
||||
}
|
||||
this.initializeTask = CompletableFuture.runAsync(new Runnable() {
|
||||
@Override
|
||||
@@ -126,6 +127,9 @@ public class SpringIndexer {
|
||||
updateItem.getFuture().complete(null);
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -152,6 +156,7 @@ public class SpringIndexer {
|
||||
initializeTask = null;
|
||||
symbols.clear();
|
||||
symbolsByDoc.clear();
|
||||
Log.info("Rebuilding SpringIndexer...");
|
||||
initialize(server.getWorkspaceRoot());
|
||||
}
|
||||
}
|
||||
@@ -166,8 +171,8 @@ public class SpringIndexer {
|
||||
updateWorker.interrupt();
|
||||
}
|
||||
|
||||
if (projectManager != null) {
|
||||
projectManager.removeListener(projectListener);
|
||||
if (server.getProjectObserver() != null) {
|
||||
server.getProjectObserver().removeListener(projectListener);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -180,7 +185,7 @@ public class SpringIndexer {
|
||||
try {
|
||||
initializeTask.get();
|
||||
|
||||
IJavaProject project = projectManager.find(new File(new URI(docURI)));
|
||||
IJavaProject project = projectFinder.find(new File(new URI(docURI)));
|
||||
if (project != null) {
|
||||
String[] classpathEntries = getClasspathEntries(project);
|
||||
|
||||
@@ -263,7 +268,7 @@ public class SpringIndexer {
|
||||
.filter(path -> path.getFileName().toString().endsWith(".java"))
|
||||
.filter(Files::isRegularFile)
|
||||
.map(path -> path.toAbsolutePath().toString())
|
||||
.collect(Collectors.groupingBy((javaFile) -> projectManager.find(new File(javaFile))));
|
||||
.collect(Collectors.groupingBy((javaFile) -> projectFinder.find(new File(javaFile))));
|
||||
|
||||
System.out.println("scan directory done!!!");
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ package org.springframework.ide.vscode.boot.metadata;
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ProgressService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
@@ -22,19 +22,19 @@ public class DefaultSpringPropertyIndexProvider implements SpringPropertyIndexPr
|
||||
|
||||
private static final FuzzyMap<ConfigurationMetadataProperty> EMPTY_INDEX = new SpringPropertyIndex(null);
|
||||
|
||||
private JavaProjectManager javaProjectManager;
|
||||
private JavaProjectFinder javaProjectFinder;
|
||||
private SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager();
|
||||
|
||||
private ProgressService progressService = (id, msg) -> {
|
||||
/* ignore */ };
|
||||
|
||||
public DefaultSpringPropertyIndexProvider(JavaProjectManager javaProjectManager) {
|
||||
this.javaProjectManager = javaProjectManager;
|
||||
public DefaultSpringPropertyIndexProvider(JavaProjectFinder javaProjectFinder) {
|
||||
this.javaProjectFinder = javaProjectFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FuzzyMap<ConfigurationMetadataProperty> getIndex(IDocument doc) {
|
||||
IJavaProject jp = javaProjectManager.find(doc);
|
||||
IJavaProject jp = javaProjectFinder.find(doc);
|
||||
if (jp != null) {
|
||||
return indexManager.get(jp, progressService);
|
||||
}
|
||||
|
||||
@@ -45,12 +45,8 @@ import org.springframework.ide.vscode.boot.java.autowired.AutowiredHoverProvider
|
||||
import org.springframework.ide.vscode.boot.java.autowired.SpringBootAppProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.BasicFileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
@@ -62,22 +58,19 @@ import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
*/
|
||||
public class AutowiredHoverProviderTest {
|
||||
|
||||
private JavaProjectManager projectManager;
|
||||
private CompositeJavaProjectFinder projectFinder;
|
||||
private LanguageServerHarness<BootJavaLanguageServer> harness;
|
||||
private PropertyIndexHarness indexHarness;
|
||||
private BasicFileObserver fileObserver;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
projectManager = new CompositeJavaProjectManager(new JavaProjectManager[] {new MavenProjectManager(MavenCore.getDefault())});
|
||||
fileObserver = new BasicFileObserver();
|
||||
projectManager.setFileObserver(fileObserver);
|
||||
projectFinder = new CompositeJavaProjectFinder();
|
||||
|
||||
indexHarness = new PropertyIndexHarness();
|
||||
harness = new LanguageServerHarness<BootJavaLanguageServer>(new Callable<BootJavaLanguageServer>() {
|
||||
@Override
|
||||
public BootJavaLanguageServer call() throws Exception {
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(projectManager, indexHarness.getIndexProvider());
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(projectFinder, indexHarness.getIndexProvider());
|
||||
return server;
|
||||
}
|
||||
}) {
|
||||
@@ -94,7 +87,7 @@ public class AutowiredHoverProviderTest {
|
||||
harness.intialize(directory);
|
||||
|
||||
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutowiredComponent.java";
|
||||
IJavaProject project = projectManager.find(directory);
|
||||
IJavaProject project = projectFinder.find(directory);
|
||||
TextDocument document = createTempTextDocument(docURI);
|
||||
|
||||
CompilationUnit cu = parse(document, project);
|
||||
@@ -120,7 +113,7 @@ public class AutowiredHoverProviderTest {
|
||||
harness.intialize(directory);
|
||||
|
||||
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutowiredComponent.java";
|
||||
IJavaProject project = projectManager.find(directory);
|
||||
IJavaProject project = projectFinder.find(directory);
|
||||
TextDocument document = createTempTextDocument(docURI);
|
||||
|
||||
CompilationUnit cu = parse(document, project);
|
||||
@@ -139,7 +132,7 @@ public class AutowiredHoverProviderTest {
|
||||
harness.intialize(directory);
|
||||
|
||||
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutowiredComponent.java";
|
||||
IJavaProject project = projectManager.find(directory);
|
||||
IJavaProject project = projectFinder.find(directory);
|
||||
TextDocument document = createTempTextDocument(docURI);
|
||||
|
||||
CompilationUnit cu = parse(document, project);
|
||||
@@ -160,7 +153,7 @@ public class AutowiredHoverProviderTest {
|
||||
harness.intialize(directory);
|
||||
|
||||
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutowiredComponent.java";
|
||||
IJavaProject project = projectManager.find(directory);
|
||||
IJavaProject project = projectFinder.find(directory);
|
||||
TextDocument document = createTempTextDocument(docURI);
|
||||
|
||||
CompilationUnit cu = parse(document, project);
|
||||
|
||||
@@ -45,12 +45,8 @@ import org.springframework.ide.vscode.boot.java.autowired.SpringBootAppProvider;
|
||||
import org.springframework.ide.vscode.boot.java.beans.ComponentHoverProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.BasicFileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
@@ -62,22 +58,19 @@ import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
*/
|
||||
public class ComponentHoverProviderTest {
|
||||
|
||||
private JavaProjectManager projectManager;
|
||||
private CompositeJavaProjectFinder projectFinder;
|
||||
private LanguageServerHarness<BootJavaLanguageServer> harness;
|
||||
private PropertyIndexHarness indexHarness;
|
||||
private BasicFileObserver fileObserver;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
projectManager = new CompositeJavaProjectManager(new JavaProjectManager[] {new MavenProjectManager(MavenCore.getDefault())});
|
||||
fileObserver = new BasicFileObserver();
|
||||
projectManager.setFileObserver(fileObserver);
|
||||
projectFinder = new CompositeJavaProjectFinder();
|
||||
|
||||
indexHarness = new PropertyIndexHarness();
|
||||
harness = new LanguageServerHarness<BootJavaLanguageServer>(new Callable<BootJavaLanguageServer>() {
|
||||
@Override
|
||||
public BootJavaLanguageServer call() throws Exception {
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(projectManager, indexHarness.getIndexProvider());
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(projectFinder, indexHarness.getIndexProvider());
|
||||
return server;
|
||||
}
|
||||
}) {
|
||||
@@ -94,7 +87,7 @@ public class ComponentHoverProviderTest {
|
||||
harness.intialize(directory);
|
||||
|
||||
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutomaticallyWiredComponent.java";
|
||||
IJavaProject project = projectManager.find(directory);
|
||||
IJavaProject project = projectFinder.find(directory);
|
||||
TextDocument document = createTempTextDocument(docURI);
|
||||
|
||||
CompilationUnit cu = parse(document, project);
|
||||
@@ -120,7 +113,7 @@ public class ComponentHoverProviderTest {
|
||||
harness.intialize(directory);
|
||||
|
||||
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutowiredComponent.java";
|
||||
IJavaProject project = projectManager.find(directory);
|
||||
IJavaProject project = projectFinder.find(directory);
|
||||
TextDocument document = createTempTextDocument(docURI);
|
||||
|
||||
CompilationUnit cu = parse(document, project);
|
||||
@@ -141,7 +134,7 @@ public class ComponentHoverProviderTest {
|
||||
harness.intialize(directory);
|
||||
|
||||
String docURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/MyAutomaticallyWiredComponent.java";
|
||||
IJavaProject project = projectManager.find(directory);
|
||||
IJavaProject project = projectFinder.find(directory);
|
||||
TextDocument document = createTempTextDocument(docURI);
|
||||
|
||||
CompilationUnit cu = parse(document, project);
|
||||
|
||||
@@ -29,10 +29,7 @@ import org.springframework.ide.vscode.boot.java.beans.ComponentSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.beans.Constants;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
@@ -43,7 +40,7 @@ import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
public class SpringIndexerBeansTest {
|
||||
|
||||
private Map<String, SymbolProvider> symbolProviders;
|
||||
private JavaProjectManager projectManager;
|
||||
private CompositeJavaProjectFinder projectManager;
|
||||
private LanguageServerHarness<BootJavaLanguageServer> harness;
|
||||
private PropertyIndexHarness indexHarness;
|
||||
|
||||
@@ -53,7 +50,7 @@ public class SpringIndexerBeansTest {
|
||||
symbolProviders.put(Constants.SPRING_BEAN, new BeansSymbolProvider());
|
||||
symbolProviders.put(Constants.SPRING_COMPONENT, new ComponentSymbolProvider());
|
||||
|
||||
projectManager = new CompositeJavaProjectManager(new JavaProjectManager[] {new MavenProjectManager(MavenCore.getDefault())});
|
||||
projectManager = new CompositeJavaProjectFinder();
|
||||
|
||||
indexHarness = new PropertyIndexHarness();
|
||||
harness = new LanguageServerHarness<BootJavaLanguageServer>(new Callable<BootJavaLanguageServer>() {
|
||||
|
||||
@@ -28,10 +28,7 @@ import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.Constants;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
@@ -42,7 +39,7 @@ import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
public class RequestMappingSymbolProviderTest {
|
||||
|
||||
private Map<String, SymbolProvider> symbolProviders;
|
||||
private JavaProjectManager projectManager;
|
||||
private CompositeJavaProjectFinder projectManager;
|
||||
private LanguageServerHarness<BootJavaLanguageServer> harness;
|
||||
private PropertyIndexHarness indexHarness;
|
||||
|
||||
@@ -51,7 +48,7 @@ public class RequestMappingSymbolProviderTest {
|
||||
symbolProviders = new HashMap<>();
|
||||
symbolProviders.put(Constants.SPRING_REQUEST_MAPPING, new RequestMappingSymbolProvider());
|
||||
|
||||
projectManager = new CompositeJavaProjectManager(new JavaProjectManager[] {new MavenProjectManager(MavenCore.getDefault())});
|
||||
projectManager = new CompositeJavaProjectFinder();
|
||||
|
||||
indexHarness = new PropertyIndexHarness();
|
||||
harness = new LanguageServerHarness<BootJavaLanguageServer>(new Callable<BootJavaLanguageServer>() {
|
||||
|
||||
@@ -15,6 +15,7 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
@@ -24,8 +25,8 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
@@ -38,7 +39,7 @@ import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
*/
|
||||
public class ScopeCompletionTest {
|
||||
|
||||
protected final JavaProjectManager javaProjectFinder = new AbstractJavaProjectManager() {
|
||||
protected final CompositeJavaProjectFinder javaProjectFinder = new CompositeJavaProjectFinder(Arrays.asList(new JavaProjectFinder() {
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return false;
|
||||
@@ -51,7 +52,7 @@ public class ScopeCompletionTest {
|
||||
public IJavaProject find(IDocument doc) {
|
||||
return getTestProject();
|
||||
}
|
||||
};
|
||||
}));
|
||||
|
||||
private LanguageServerHarness<BootJavaLanguageServer> harness;
|
||||
private PropertyIndexHarness indexHarness;
|
||||
|
||||
@@ -33,11 +33,10 @@ import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.Constants;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.RequestMappingSymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectManager;
|
||||
import org.springframework.ide.vscode.commons.util.BasicFileObserver;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
@@ -48,25 +47,28 @@ import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
public class SpringIndexerTest {
|
||||
|
||||
private Map<String, SymbolProvider> symbolProviders;
|
||||
private JavaProjectManager projectManager;
|
||||
private CompositeJavaProjectFinder projectFinder;
|
||||
private LanguageServerHarness<BootJavaLanguageServer> harness;
|
||||
private PropertyIndexHarness indexHarness;
|
||||
private BasicFileObserver fileObserver;
|
||||
private SpringIndexer indexer;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
symbolProviders = new HashMap<>();
|
||||
symbolProviders.put(Constants.SPRING_REQUEST_MAPPING, new RequestMappingSymbolProvider());
|
||||
|
||||
projectManager = new CompositeJavaProjectManager(new JavaProjectManager[] {new MavenProjectManager(MavenCore.getDefault())});
|
||||
fileObserver = new BasicFileObserver();
|
||||
projectManager.setFileObserver(fileObserver);
|
||||
projectFinder = new CompositeJavaProjectFinder();
|
||||
|
||||
indexHarness = new PropertyIndexHarness();
|
||||
harness = new LanguageServerHarness<BootJavaLanguageServer>(new Callable<BootJavaLanguageServer>() {
|
||||
@Override
|
||||
public BootJavaLanguageServer call() throws Exception {
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(projectManager, indexHarness.getIndexProvider());
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(projectFinder, indexHarness.getIndexProvider()) {
|
||||
@Override
|
||||
protected SpringIndexer createAnnotationIndexer(SimpleLanguageServer server, JavaProjectFinder projectManager) {
|
||||
return indexer = new SpringIndexer((BootJavaLanguageServer) server, projectFinder, symbolProviders);
|
||||
}
|
||||
};
|
||||
return server;
|
||||
}
|
||||
}) {
|
||||
@@ -81,9 +83,7 @@ public class SpringIndexerTest {
|
||||
public void testScanningAllAnnotationsSimpleProjectUpfront() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()));
|
||||
|
||||
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectManager, symbolProviders);
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI());
|
||||
indexer.initialize(directory.toPath());
|
||||
|
||||
List<? extends SymbolInformation> allSymbols = indexer.getAllSymbols("");
|
||||
|
||||
@@ -105,9 +105,7 @@ public class SpringIndexerTest {
|
||||
public void testRetrievingSymbolsPerDocument() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()));
|
||||
|
||||
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectManager, symbolProviders);
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI());
|
||||
indexer.initialize(directory.toPath());
|
||||
|
||||
String uriPrefix = "file://" + directory.getAbsolutePath();
|
||||
List<? extends SymbolInformation> symbols = indexer.getSymbols(uriPrefix + "/src/main/java/org/test/MainClass.java");
|
||||
@@ -132,9 +130,7 @@ public class SpringIndexerTest {
|
||||
public void testScanningAllAnnotationsMultiModuleProjectUpfront() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/").toURI()));
|
||||
|
||||
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectManager, symbolProviders);
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/").toURI());
|
||||
indexer.initialize(directory.toPath());
|
||||
|
||||
List<? extends SymbolInformation> allSymbols = indexer.getAllSymbols("");
|
||||
|
||||
@@ -156,10 +152,7 @@ public class SpringIndexerTest {
|
||||
public void testUpdateChangedDocument() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()));
|
||||
|
||||
// create initial index content
|
||||
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectManager, symbolProviders);
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI());
|
||||
indexer.initialize(directory.toPath());
|
||||
|
||||
// update document and update index
|
||||
String changedDocURI = "file://" + directory.getAbsolutePath() + "/src/main/java/org/test/SimpleMappingClass.java";
|
||||
@@ -194,9 +187,7 @@ public class SpringIndexerTest {
|
||||
public void testFilterSymbolsUsingQueryString() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()));
|
||||
|
||||
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectManager, symbolProviders);
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI());
|
||||
indexer.initialize(directory.toPath());
|
||||
|
||||
List<? extends SymbolInformation> allSymbols = indexer.getAllSymbols("mapp");
|
||||
|
||||
@@ -216,9 +207,7 @@ public class SpringIndexerTest {
|
||||
public void testFilterSymbolsUsingQueryStringSplittedResult() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()));
|
||||
|
||||
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectManager, symbolProviders);
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI());
|
||||
indexer.initialize(directory.toPath());
|
||||
|
||||
List<? extends SymbolInformation> allSymbols = indexer.getAllSymbols("@/foo-root-mapping -- (no method defined)");
|
||||
|
||||
@@ -234,9 +223,7 @@ public class SpringIndexerTest {
|
||||
public void testFilterSymbolsUsingQueryStringFullSymbolString() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()));
|
||||
|
||||
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectManager, symbolProviders);
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI());
|
||||
indexer.initialize(directory.toPath());
|
||||
|
||||
List<? extends SymbolInformation> allSymbols = indexer.getAllSymbols("@/foo-root-mapping/embedded-foo-mapping-with-root -- (no method defined)");
|
||||
|
||||
@@ -268,9 +255,7 @@ public class SpringIndexerTest {
|
||||
public void testRefreshOnProjectChange() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI()));
|
||||
|
||||
SpringIndexer indexer = new SpringIndexer(harness.getServer(), projectManager, symbolProviders);
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-annotation-indexing-parent/test-annotation-indexing/").toURI());
|
||||
indexer.initialize(directory.toPath()).get();
|
||||
|
||||
List<? extends SymbolInformation> allSymbols = indexer.getAllSymbols("");
|
||||
assertEquals(8, allSymbols.size());
|
||||
@@ -278,7 +263,7 @@ public class SpringIndexerTest {
|
||||
File pomFile = directory.toPath().resolve(MavenCore.POM_XML).toFile();
|
||||
|
||||
assertFalse(indexer.isInitializing());
|
||||
fileObserver.notifyFileChanged(pomFile.toURI().toString());
|
||||
harness.changeFile(pomFile.toURI().toString());
|
||||
// Refresh in progress
|
||||
assertTrue(indexer.isInitializing());
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
@@ -25,8 +27,8 @@ import org.junit.Test;
|
||||
import org.springframework.ide.vscode.boot.java.BootJavaLanguageServer;
|
||||
import org.springframework.ide.vscode.boot.java.value.ValueCompletionProcessor;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
@@ -39,21 +41,6 @@ import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
*/
|
||||
public class ValueCompletionTest {
|
||||
|
||||
protected final JavaProjectManager javaProjectFinder = new AbstractJavaProjectManager() {
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
return getTestProject();
|
||||
}
|
||||
};
|
||||
|
||||
private LanguageServerHarness<BootJavaLanguageServer> harness;
|
||||
private IJavaProject testProject;
|
||||
|
||||
@@ -69,7 +56,24 @@ public class ValueCompletionTest {
|
||||
harness = new LanguageServerHarness<BootJavaLanguageServer>(new Callable<BootJavaLanguageServer>() {
|
||||
@Override
|
||||
public BootJavaLanguageServer call() throws Exception {
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(javaProjectFinder, indexHarness.getIndexProvider());
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(
|
||||
new CompositeJavaProjectFinder(new ArrayList<>(Collections.singleton(new AbstractJavaProjectFinder() {
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
return getTestProject();
|
||||
}
|
||||
}))),
|
||||
indexHarness.getIndexProvider());
|
||||
return server;
|
||||
}
|
||||
}) {
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.ide.vscode.boot.common.PropertyCompletionFactory;
|
||||
import org.springframework.ide.vscode.boot.common.RelaxedNameConfig;
|
||||
import org.springframework.ide.vscode.boot.metadata.PropertyInfo;
|
||||
@@ -20,15 +22,23 @@ import org.springframework.ide.vscode.boot.properties.hover.PropertiesHoverInfoP
|
||||
import org.springframework.ide.vscode.boot.properties.reconcile.SpringPropertiesReconcileEngine;
|
||||
import org.springframework.ide.vscode.boot.yaml.completions.ApplicationYamlAssistContext;
|
||||
import org.springframework.ide.vscode.boot.yaml.reconcile.ApplicationYamlReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleCore;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleProjectCache;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter.HoverType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeProjectOvserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectCache;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
@@ -60,7 +70,8 @@ public class BootPropertiesLanguageServer extends SimpleLanguageServer {
|
||||
public boolean includeDeindentedProposals() { return false; };
|
||||
};
|
||||
// Shared:
|
||||
private final JavaProjectManager javaProjectManager;
|
||||
private final CompositeProjectOvserver projectObserver;
|
||||
private final CompositeJavaProjectFinder javaProjectFinder;
|
||||
private final SpringPropertyIndexProvider indexProvider;
|
||||
private final TypeUtilProvider typeUtilProvider;
|
||||
private final VscodeCompletionEngineAdapter completionEngine;
|
||||
@@ -75,12 +86,12 @@ public class BootPropertiesLanguageServer extends SimpleLanguageServer {
|
||||
private final YamlStructureProvider yamlStructureProvider= YamlStructureProvider.DEFAULT;
|
||||
private YamlAssistContextProvider yamlAssistContextProvider;
|
||||
|
||||
public BootPropertiesLanguageServer(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectManager javaProjectManager) {
|
||||
public BootPropertiesLanguageServer(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, CompositeJavaProjectFinder javaProjectFinder) {
|
||||
super("vscode-boot-properties");
|
||||
this.indexProvider = indexProvider;
|
||||
this.typeUtilProvider = typeUtilProvider;
|
||||
this.javaProjectManager = javaProjectManager;
|
||||
this.completionFactory = new PropertyCompletionFactory(javaProjectManager);
|
||||
this.javaProjectFinder = javaProjectFinder;
|
||||
this.completionFactory = new PropertyCompletionFactory(javaProjectFinder);
|
||||
this.yamlAssistContextProvider = new YamlAssistContextProvider() {
|
||||
@Override
|
||||
public YamlAssistContext getGlobalAssistContext(YamlDocument ydoc) {
|
||||
@@ -107,10 +118,20 @@ public class BootPropertiesLanguageServer extends SimpleLanguageServer {
|
||||
HoverInfoProvider hoverInfoProvider = getHoverProvider();
|
||||
hoverEngine = new VscodeHoverEngineAdapter(this, hoverInfoProvider);
|
||||
documents.onHover(hoverEngine::getHover);
|
||||
|
||||
// Initialize project finders, project caches and project observers
|
||||
MavenProjectCache mavenProjectCache = new MavenProjectCache(getWorkspaceService().getFileObserver(), MavenCore.getDefault());
|
||||
javaProjectFinder.addJavaProjectFinder(new MavenProjectFinder(mavenProjectCache));
|
||||
|
||||
GradleProjectCache gradleProjectCache = new GradleProjectCache(getWorkspaceService().getFileObserver(), GradleCore.getDefault());
|
||||
javaProjectFinder.addJavaProjectFinder(new GradleProjectFinder(gradleProjectCache));
|
||||
|
||||
projectObserver = new CompositeProjectOvserver(Arrays.asList(mavenProjectCache, gradleProjectCache));
|
||||
|
||||
}
|
||||
|
||||
private ICompletionEngine getCompletionEngine() {
|
||||
ICompletionEngine propertiesCompletions = new SpringPropertiesCompletionEngine(indexProvider, typeUtilProvider, javaProjectManager);
|
||||
ICompletionEngine propertiesCompletions = new SpringPropertiesCompletionEngine(indexProvider, typeUtilProvider, javaProjectFinder);
|
||||
ICompletionEngine yamlCompletions = new YamlCompletionEngine(yamlStructureProvider, yamlAssistContextProvider, COMPLETION_OPTIONS);
|
||||
return (IDocument document, int offset) -> {
|
||||
String uri = document.getUri();
|
||||
@@ -126,7 +147,7 @@ public class BootPropertiesLanguageServer extends SimpleLanguageServer {
|
||||
}
|
||||
|
||||
protected HoverInfoProvider getHoverProvider() {
|
||||
HoverInfoProvider propertiesHovers = new PropertiesHoverInfoProvider(indexProvider, typeUtilProvider, javaProjectManager);
|
||||
HoverInfoProvider propertiesHovers = new PropertiesHoverInfoProvider(indexProvider, typeUtilProvider, javaProjectFinder);
|
||||
HoverInfoProvider ymlHovers = new YamlHoverInfoProvider(parser, yamlStructureProvider, yamlAssistContextProvider);
|
||||
|
||||
return (IDocument document, int offset) -> {
|
||||
@@ -171,5 +192,7 @@ public class BootPropertiesLanguageServer extends SimpleLanguageServer {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public ProjectObserver getProjectObserver() {
|
||||
return projectObserver;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* Copyright (c) 2016, 2017 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
|
||||
@@ -15,15 +15,9 @@ import java.io.IOException;
|
||||
import org.springframework.ide.vscode.boot.metadata.DefaultSpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtil;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleCore;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectManager;
|
||||
import org.springframework.ide.vscode.commons.maven.java.classpathfile.JavaProjectWithClasspathFileManager;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
@@ -37,15 +31,10 @@ public class Main {
|
||||
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
LaunguageServerApp.start(() -> {
|
||||
CompositeJavaProjectManager javaProjectManager = new CompositeJavaProjectManager(new JavaProjectManager[] {
|
||||
new MavenProjectManager(MavenCore.getDefault()),
|
||||
new GradleProjectManager(GradleCore.getDefault()),
|
||||
new JavaProjectWithClasspathFileManager()
|
||||
});
|
||||
DefaultSpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectManager);
|
||||
TypeUtilProvider typeUtilProvider = (IDocument doc) -> new TypeUtil(javaProjectManager.find(doc));
|
||||
SimpleLanguageServer server = new BootPropertiesLanguageServer(indexProvider, typeUtilProvider, javaProjectManager);
|
||||
javaProjectManager.setFileObserver(server.getWorkspaceService());
|
||||
CompositeJavaProjectFinder javaProjectFinder = new CompositeJavaProjectFinder();
|
||||
DefaultSpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
|
||||
TypeUtilProvider typeUtilProvider = (IDocument doc) -> new TypeUtil(javaProjectFinder.find(doc));
|
||||
SimpleLanguageServer server = new BootPropertiesLanguageServer(indexProvider, typeUtilProvider, javaProjectFinder);
|
||||
indexProvider.setProgressService(server.getProgressService());
|
||||
return server;
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014-2016 Pivotal, Inc.
|
||||
* Copyright (c) 2014-2017 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
|
||||
@@ -19,7 +19,7 @@ import org.springframework.ide.vscode.boot.metadata.types.TypedProperty;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap.Match;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
@@ -113,9 +113,9 @@ public class PropertyCompletionFactory {
|
||||
return proposal;
|
||||
}
|
||||
|
||||
private JavaProjectManager documentContextFinder;
|
||||
private JavaProjectFinder documentContextFinder;
|
||||
|
||||
public PropertyCompletionFactory(JavaProjectManager documentContextFinder) {
|
||||
public PropertyCompletionFactory(JavaProjectFinder documentContextFinder) {
|
||||
this.documentContextFinder = documentContextFinder;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ package org.springframework.ide.vscode.boot.metadata;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ProgressService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
@@ -21,18 +21,18 @@ public class DefaultSpringPropertyIndexProvider implements SpringPropertyIndexPr
|
||||
|
||||
private static final FuzzyMap<PropertyInfo> EMPTY_INDEX = new SpringPropertyIndex(null, null);
|
||||
|
||||
private JavaProjectManager javaProjectManager;
|
||||
private JavaProjectFinder javaProjectFinder;
|
||||
private SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager(ValueProviderRegistry.getDefault());
|
||||
|
||||
private ProgressService progressService = (id, msg) -> { /*ignore*/ };
|
||||
|
||||
public DefaultSpringPropertyIndexProvider(JavaProjectManager javaProjectManager) {
|
||||
this.javaProjectManager = javaProjectManager;
|
||||
public DefaultSpringPropertyIndexProvider(JavaProjectFinder javaProjectFinder) {
|
||||
this.javaProjectFinder = javaProjectFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FuzzyMap<PropertyInfo> getIndex(IDocument doc) {
|
||||
IJavaProject jp = javaProjectManager.find(doc);
|
||||
IJavaProject jp = javaProjectFinder.find(doc);
|
||||
if (jp!=null) {
|
||||
return indexManager.get(jp, progressService);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;;
|
||||
|
||||
@@ -37,10 +37,10 @@ public class SpringPropertiesCompletionEngine implements ICompletionEngine {
|
||||
* Constructor used in 'production'. Wires up stuff properly for running inside a normal
|
||||
* Eclipse runtime.
|
||||
*/
|
||||
public SpringPropertiesCompletionEngine(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectManager projectManager) {
|
||||
public SpringPropertiesCompletionEngine(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectFinder projectFinder) {
|
||||
this.indexProvider = indexProvider;
|
||||
this.typeUtilProvider = typeUtilProvider;
|
||||
this.completionFactory = new PropertyCompletionFactory(projectManager);
|
||||
this.completionFactory = new PropertyCompletionFactory(projectFinder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,7 @@ package org.springframework.ide.vscode.boot.properties.hover;
|
||||
import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
@@ -25,9 +25,9 @@ public class PropertiesHoverInfoProvider implements HoverInfoProvider {
|
||||
|
||||
private SpringPropertyIndexProvider indexProvider;
|
||||
private TypeUtilProvider typeUtilProvider;
|
||||
private JavaProjectManager projectFinder;
|
||||
private JavaProjectFinder projectFinder;
|
||||
|
||||
public PropertiesHoverInfoProvider(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectManager projectFinder) {
|
||||
public PropertiesHoverInfoProvider(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectFinder projectFinder) {
|
||||
this.indexProvider = indexProvider;
|
||||
this.typeUtilProvider = typeUtilProvider;
|
||||
this.projectFinder = projectFinder;
|
||||
|
||||
@@ -28,8 +28,8 @@ import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtil;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
@@ -46,7 +46,7 @@ public abstract class AbstractPropsEditorTest {
|
||||
private ProjectsHarness projects = ProjectsHarness.INSTANCE;
|
||||
|
||||
protected PropertyIndexHarness md;
|
||||
protected final JavaProjectManager javaProjectFinder = new AbstractJavaProjectManager() {
|
||||
protected final CompositeJavaProjectFinder javaProjectFinder = new CompositeJavaProjectFinder(Arrays.asList(new AbstractJavaProjectFinder() {
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return false;
|
||||
@@ -59,7 +59,7 @@ public abstract class AbstractPropsEditorTest {
|
||||
public IJavaProject find(IDocument doc) {
|
||||
return getTestProject();
|
||||
}
|
||||
};
|
||||
}));
|
||||
|
||||
private LanguageServerHarness harness;
|
||||
private IJavaProject testProject;
|
||||
|
||||
@@ -21,11 +21,8 @@ import org.eclipse.lsp4j.InitializeResult;
|
||||
import org.eclipse.lsp4j.TextDocumentSyncKind;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.boot.BootPropertiesLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
|
||||
/**
|
||||
@@ -41,23 +38,7 @@ public class BootPropertiesLanguageServerTest {
|
||||
}
|
||||
|
||||
private LanguageServerHarness newHarness() throws Exception {
|
||||
JavaProjectManager nullJavaProjectFinder = new AbstractJavaProjectManager() {
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Callable<? extends SimpleLanguageServer> f = () -> new BootPropertiesLanguageServer((d) -> null, (d) -> null, nullJavaProjectFinder);
|
||||
Callable<? extends SimpleLanguageServer> f = () -> new BootPropertiesLanguageServer((d) -> null, (d) -> null, new CompositeJavaProjectFinder());
|
||||
return new LanguageServerHarness(f);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,18 +23,26 @@ import org.springframework.ide.vscode.commons.util.Log;
|
||||
*/
|
||||
public class GradleJavaProject implements IJavaProject {
|
||||
|
||||
private GradleCore gradle;
|
||||
private GradleProjectClasspath classpath;
|
||||
private File projectDir;
|
||||
|
||||
public GradleJavaProject(GradleCore gradle, File projectDir) throws GradleException {
|
||||
this.gradle = gradle;
|
||||
this.projectDir = projectDir;
|
||||
this.classpath = new GradleProjectClasspath(gradle, projectDir);
|
||||
}
|
||||
|
||||
public File getLocation() {
|
||||
return projectDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GradleProjectClasspath getClasspath() {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
void update(GradleCore gradle, File projectDir) {
|
||||
void update() {
|
||||
try {
|
||||
this.classpath = new GradleProjectClasspath(gradle, projectDir);
|
||||
} catch (GradleException e) {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.gradle;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractFileToProjectCache;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
|
||||
/**
|
||||
* Tests whether document belongs to a Gradle project
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class GradleProjectCache extends AbstractFileToProjectCache<GradleJavaProject> {
|
||||
|
||||
private GradleCore gradle;
|
||||
|
||||
public GradleProjectCache(FileObserver fileObserver, GradleCore gradle) {
|
||||
super(fileObserver);
|
||||
this.gradle = gradle;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update(GradleJavaProject project) {
|
||||
project.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GradleJavaProject createProject(File gradleBuild) throws Exception {
|
||||
return new GradleJavaProject(gradle, gradleBuild.getParentFile());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.gradle;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.FileUtils;
|
||||
|
||||
/**
|
||||
* Finder for Gradle Projects
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class GradleProjectFinder extends AbstractJavaProjectFinder {
|
||||
|
||||
private GradleProjectCache cache;
|
||||
|
||||
public GradleProjectFinder(GradleProjectCache cache) {
|
||||
super();
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
File gradlebuild = FileUtils.findFile(file, GradleCore.GRADLE_BUILD_FILE);
|
||||
return cache.project(gradlebuild);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return FileUtils.findFile(file, GradleCore.GRADLE_BUILD_FILE, false) != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.gradle;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver.FileListener;
|
||||
import org.springframework.ide.vscode.commons.util.FileUtils;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
/**
|
||||
* Tests whether document belongs to a Gradle project
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class GradleProjectManager extends AbstractJavaProjectManager {
|
||||
|
||||
private Cache<File, GradleJavaProject> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
private GradleCore gradle;
|
||||
|
||||
public GradleProjectManager(GradleCore gradle) {
|
||||
this.gradle = gradle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GradleJavaProject find(File file) {
|
||||
File gradlebuild = FileUtils.findFile(file, GradleCore.GRADLE_BUILD_FILE);
|
||||
if (gradlebuild != null) {
|
||||
try {
|
||||
return cache.get(gradlebuild.getParentFile(), () -> {
|
||||
System.out.println("create gradle project: " + file.getAbsolutePath());
|
||||
GradleJavaProject project = new GradleJavaProject(gradle, gradlebuild.getParentFile());
|
||||
System.out.println("gradle project created");
|
||||
return project;
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return FileUtils.findFile(file, GradleCore.GRADLE_BUILD_FILE, false) != null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setFileObserver(FileObserver fileObserver) {
|
||||
super.setFileObserver(fileObserver);
|
||||
cache.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileListener createFileListener() {
|
||||
return new FileListener() {
|
||||
|
||||
private File getProjectFolderFromUri(String uri) {
|
||||
return Paths.get(URI.create(uri)).toFile().getParentFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleted(String uri) {
|
||||
File gradleProjectFolder = getProjectFolderFromUri(uri);
|
||||
GradleJavaProject project = cache.getIfPresent(gradleProjectFolder);
|
||||
if (project != null) {
|
||||
cache.invalidate(gradleProjectFolder);
|
||||
notifyProjectDeleted(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(String uri) {
|
||||
// Ignore created projects - cache should take care of newly created ones
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(String uri) {
|
||||
File gradleProjectFolder = getProjectFolderFromUri(uri);
|
||||
GradleJavaProject project = cache.getIfPresent(gradleProjectFolder);
|
||||
if (project != null) {
|
||||
project.update(gradle, gradleProjectFolder);
|
||||
notifyProjectChanged(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(String uri) {
|
||||
return GradleCore.GRADLE_BUILD_FILE.equals(Paths.get(URI.create(uri)).getFileName().toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager.Listener;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver.Listener;
|
||||
import org.springframework.ide.vscode.commons.util.BasicFileObserver;
|
||||
|
||||
/**
|
||||
@@ -64,9 +64,8 @@ public class GradleProjectTest {
|
||||
public void testGradleFileChanges() throws Exception {
|
||||
Path testProjectPath = Paths.get(GradleProjectTest.class.getResource("/empty-gradle-project").toURI());
|
||||
File gradleFile = testProjectPath.resolve(GradleCore.GRADLE_BUILD_FILE).toFile();
|
||||
GradleProjectManager manager = new GradleProjectManager(GradleCore.getDefault());
|
||||
BasicFileObserver fileObserver = new BasicFileObserver();
|
||||
manager.setFileObserver(fileObserver);
|
||||
GradleProjectCache manager = new GradleProjectCache(fileObserver, GradleCore.getDefault());
|
||||
IJavaProject[] projectChanged = new IJavaProject[] { null };
|
||||
IJavaProject[] projectDeleted = new IJavaProject[] { null };
|
||||
manager.addListener(new Listener() {
|
||||
@@ -84,7 +83,7 @@ public class GradleProjectTest {
|
||||
});
|
||||
|
||||
// Get the project from cache
|
||||
GradleJavaProject cachedProject = manager.find(gradleFile);
|
||||
GradleJavaProject cachedProject = manager.project(gradleFile);
|
||||
assertNotNull(cachedProject);
|
||||
|
||||
fileObserver.notifyFileChanged(gradleFile.toURI().toString());
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
|
||||
/**
|
||||
* Cache fo java projects. The key for the cache is a "project" specific file
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
* @param <P> java project sub-class
|
||||
*/
|
||||
public abstract class AbstractFileToProjectCache<P extends IJavaProject> extends AbstractJavaProjectCache<File, P> {
|
||||
|
||||
private String changeSubscription;
|
||||
private String deleteSubscription;
|
||||
|
||||
public AbstractFileToProjectCache(FileObserver fileObserver) {
|
||||
super(fileObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachListeners(File file, P project) {
|
||||
super.attachListeners(file, project);
|
||||
List<String> globPattern = Arrays.asList(file.toString());
|
||||
changeSubscription = getFileObserver().onFileChanged(globPattern, (uri) -> {
|
||||
update(project);
|
||||
notifyProjectChanged(project);
|
||||
});
|
||||
deleteSubscription = getFileObserver().onFileDeleted(globPattern, (uri) -> {
|
||||
cache.invalidate(file);
|
||||
notifyProjectDeleted(project);
|
||||
getFileObserver().unsubscribe(changeSubscription);
|
||||
getFileObserver().unsubscribe(deleteSubscription);
|
||||
});
|
||||
}
|
||||
|
||||
abstract protected void update(P project);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
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.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.ListenerList;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
/**
|
||||
* Abstract implementation of java project cache indexed by keys
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
* @param <K> key class
|
||||
* @param <P> project class
|
||||
*/
|
||||
public abstract class AbstractJavaProjectCache<K, P extends IJavaProject> implements JavaProjectCache<K, P> {
|
||||
|
||||
private FileObserver fileObserver;
|
||||
|
||||
private ListenerList<Listener> listeners = new ListenerList<>();
|
||||
|
||||
protected Cache<K, P> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
public AbstractJavaProjectCache(FileObserver fileObserver) {
|
||||
this.fileObserver = fileObserver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public P project(K key) {
|
||||
if (key != null) {
|
||||
try {
|
||||
return cache.get(key, () -> {
|
||||
try {
|
||||
P project = createProject(key);
|
||||
attachListeners(key, project);
|
||||
return project;
|
||||
} catch (Throwable t) {
|
||||
throw new ExecutionException(t);
|
||||
}
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
abstract protected P createProject(K key) throws Exception;
|
||||
|
||||
protected void attachListeners(K key, P project) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
final protected void notifyProjectCreated(P project) {
|
||||
listeners.forEach(l -> l.created(project));
|
||||
}
|
||||
|
||||
final protected void notifyProjectChanged(P project) {
|
||||
listeners.forEach(l -> l.changed(project));
|
||||
}
|
||||
|
||||
final protected void notifyProjectDeleted(P project) {
|
||||
listeners.forEach(l -> l.deleted(project));
|
||||
}
|
||||
|
||||
final protected FileObserver getFileObserver() {
|
||||
return fileObserver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* Abstract implementation of Java project finder interface
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractJavaProjectFinder implements JavaProjectFinder {
|
||||
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
try {
|
||||
String uriStr = doc.getUri();
|
||||
if (StringUtil.hasText(uriStr)) {
|
||||
URI uri = new URI(uriStr);
|
||||
// TODO: This only work with File uri. Should it work with others
|
||||
// too?
|
||||
if (uri.getScheme().equalsIgnoreCase("file")) {
|
||||
File file = new File(uri).getAbsoluteFile();
|
||||
return find(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver.FileListener;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.ListenerList;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
/**
|
||||
* Base implementation of {@link JavaProjectManager}
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractJavaProjectManager implements JavaProjectManager {
|
||||
|
||||
private ListenerList<Listener> listeners;
|
||||
|
||||
private FileObserver fileObserver;
|
||||
|
||||
private Supplier<FileListener> fileListener;
|
||||
|
||||
public AbstractJavaProjectManager() {
|
||||
this.fileListener = Suppliers.memoize(() -> createFileListener());
|
||||
this.listeners = new ListenerList<>();
|
||||
}
|
||||
|
||||
protected FileListener createFileListener() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
try {
|
||||
String uriStr = doc.getUri();
|
||||
if (StringUtil.hasText(uriStr)) {
|
||||
URI uri = new URI(uriStr);
|
||||
// TODO: This only work with File uri. Should it work with others
|
||||
// too?
|
||||
if (uri.getScheme().equalsIgnoreCase("file")) {
|
||||
File file = new File(uri).getAbsoluteFile();
|
||||
return find(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFileObserver(FileObserver fileObserver) {
|
||||
FileListener listener= fileListener.get();
|
||||
if (this.fileObserver != null && listener != null) {
|
||||
this.fileObserver.removeListener(listener);
|
||||
}
|
||||
this.fileObserver = fileObserver;
|
||||
if (this.fileObserver != null && listener != null) {
|
||||
this.fileObserver.addListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
final protected FileObserver getFileObserver() {
|
||||
return this.fileObserver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
final protected void notifyProjectCreated(IJavaProject project) {
|
||||
listeners.forEach(l -> l.created(project));
|
||||
}
|
||||
|
||||
final protected void notifyProjectChanged(IJavaProject project) {
|
||||
listeners.forEach(l -> l.changed(project));
|
||||
}
|
||||
|
||||
final protected void notifyProjectDeleted(IJavaProject project) {
|
||||
listeners.forEach(l -> l.deleted(project));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* Composite project manager that acts a single project manager but consissts of many project managers
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class CompositeJavaProjectFinder implements JavaProjectFinder {
|
||||
|
||||
private final List<JavaProjectFinder> projectFinders;
|
||||
|
||||
public CompositeJavaProjectFinder(Collection<JavaProjectFinder> projectFinders) {
|
||||
this.projectFinders = new ArrayList<>(projectFinders);
|
||||
}
|
||||
|
||||
public CompositeJavaProjectFinder() {
|
||||
this(Collections.emptyList());
|
||||
}
|
||||
|
||||
public boolean addJavaProjectFinder(JavaProjectFinder javaProjectFinder) {
|
||||
return projectFinders.add(javaProjectFinder);
|
||||
}
|
||||
|
||||
public boolean removeJavaProjectFinder(JavaProjectFinder javaProjectFinder) {
|
||||
return projectFinders.remove(javaProjectFinder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
return projectFinders.stream().map(finder -> finder.find(doc)).filter(Objects::nonNull).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
return projectFinders.stream().map(finder -> finder.find(file)).filter(Objects::nonNull).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return projectFinders.stream().filter(finder -> finder.isProjectRoot(file)) != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* Composite project manager that acts a single project manager but consissts of many project managers
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class CompositeJavaProjectManager implements JavaProjectManager {
|
||||
|
||||
private final JavaProjectManager[] projectManagers;
|
||||
|
||||
public CompositeJavaProjectManager(JavaProjectManager[] projectManagers) {
|
||||
this.projectManagers = projectManagers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
try {
|
||||
String uriStr = doc.getUri();
|
||||
if (StringUtil.hasText(uriStr)) {
|
||||
URI uri = new URI(uriStr);
|
||||
// TODO: This only work with File uri. Should it work with others
|
||||
// too?
|
||||
if (uri.getScheme().equalsIgnoreCase("file")) {
|
||||
File file = new File(uri).getAbsoluteFile();
|
||||
return find(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
for (JavaProjectManager strategy : projectManagers) {
|
||||
try {
|
||||
IJavaProject project = strategy.find(file);
|
||||
if (project != null) {
|
||||
return project;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
for (JavaProjectManager strategy : projectManagers) {
|
||||
try {
|
||||
if (strategy.isProjectRoot(file)) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setFileObserver(FileObserver fileObserver) {
|
||||
Arrays.stream(projectManagers).forEach(pm -> pm.setFileObserver(fileObserver));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
Arrays.stream(projectManagers).forEach(pm -> pm.addListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
Arrays.stream(projectManagers).forEach(pm -> pm.removeListener(listener));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Project Observer that is able to act as a single project observer for a list of observers
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class CompositeProjectOvserver implements ProjectObserver {
|
||||
|
||||
private List<ProjectObserver> observers;
|
||||
|
||||
public CompositeProjectOvserver(List<ProjectObserver> observers) {
|
||||
this.observers = observers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
observers.forEach(o -> o.addListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
observers.forEach(o -> o.removeListener(listener));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
/**
|
||||
* Java Projects Cache
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
* @param <K> key class
|
||||
* @param <P> java project class
|
||||
*/
|
||||
public interface JavaProjectCache<K, P extends IJavaProject> extends ProjectObserver {
|
||||
|
||||
P project(K key);
|
||||
|
||||
}
|
||||
@@ -13,29 +13,17 @@ package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
import java.io.File;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* Java project manager. Able to find a java project for a file or document and
|
||||
* provide project change listening mechanism
|
||||
* Java project finder. Able to find a java project for a file or document
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*/
|
||||
public interface JavaProjectManager {
|
||||
public interface JavaProjectFinder {
|
||||
|
||||
interface Listener {
|
||||
void created(IJavaProject project);
|
||||
void changed(IJavaProject project);
|
||||
void deleted(IJavaProject project);
|
||||
}
|
||||
|
||||
void setFileObserver(FileObserver fileObserver);
|
||||
IJavaProject find(IDocument doc);
|
||||
IJavaProject find(File file);
|
||||
boolean isProjectRoot(File file);
|
||||
|
||||
void addListener(Listener listener);
|
||||
void removeListener( Listener listener);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
/**
|
||||
* Projects Observer. Able to add/remove project listeners which are notified on project changes
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public interface ProjectObserver {
|
||||
|
||||
interface Listener {
|
||||
void created(IJavaProject project);
|
||||
void changed(IJavaProject project);
|
||||
void deleted(IJavaProject project);
|
||||
}
|
||||
|
||||
void addListener(Listener listener);
|
||||
void removeListener(Listener listener);
|
||||
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.java.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager.Listener;
|
||||
import org.springframework.ide.vscode.commons.util.BasicFileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver.FileListener;
|
||||
import org.springframework.ide.vscode.commons.util.FileUtils;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
/**
|
||||
* Tests for {@link CompositeJavaProjectManager}
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class CompositeJavaProjectManagerTest {
|
||||
|
||||
private AbstractJavaProjectManager createProjectManagerForFile(String fileName) {
|
||||
return new AbstractJavaProjectManager() {
|
||||
|
||||
private Cache<File, IJavaProject> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return FileUtils.findFile(file, fileName, false) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
if (fileName.equals(file.toPath().getFileName().toString())) {
|
||||
try {
|
||||
return cache.get(file, () -> {
|
||||
return new IJavaProject() {
|
||||
@Override
|
||||
public IClasspath getClasspath() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileListener createFileListener() {
|
||||
return new FileListener() {
|
||||
|
||||
private File getFileFromUri(String uri) {
|
||||
return Paths.get(URI.create(uri)).toFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleted(String uri) {
|
||||
File file = getFileFromUri(uri);
|
||||
IJavaProject project = cache.getIfPresent(file);
|
||||
if (project != null) {
|
||||
cache.invalidate(file);
|
||||
notifyProjectDeleted(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(String uri) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(String uri) {
|
||||
File file = getFileFromUri(uri);
|
||||
IJavaProject project = cache.getIfPresent(file);
|
||||
if (project != null) {
|
||||
notifyProjectChanged(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(String uri) {
|
||||
return fileName.equals(Paths.get(URI.create(uri)).getFileName().toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListeners() throws Exception {
|
||||
AbstractJavaProjectManager manager1 = createProjectManagerForFile("test-1");
|
||||
AbstractJavaProjectManager manager2 = createProjectManagerForFile("test-2");
|
||||
CompositeJavaProjectManager compositeManager = new CompositeJavaProjectManager(new JavaProjectManager[] {
|
||||
manager1,
|
||||
manager2
|
||||
});
|
||||
BasicFileObserver fileObserver = new BasicFileObserver();
|
||||
compositeManager.setFileObserver(fileObserver);
|
||||
|
||||
Path containerPath = Paths.get(CompositeJavaProjectManagerTest.class.getResource("/").toURI());
|
||||
|
||||
File projectFile1 = containerPath.resolve("test-1").toFile();
|
||||
IJavaProject p1 = compositeManager.find(projectFile1);
|
||||
assertNotNull(p1);
|
||||
|
||||
File projectFile2 = containerPath.resolve("test-2").toFile();
|
||||
IJavaProject p2 = compositeManager.find(projectFile2);
|
||||
assertNotNull(p2);
|
||||
|
||||
IJavaProject[] projectChanged = new IJavaProject[] { null };
|
||||
IJavaProject[] projectDeleted = new IJavaProject[] { null };
|
||||
|
||||
compositeManager.addListener(new Listener() {
|
||||
|
||||
@Override
|
||||
public void created(IJavaProject project) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(IJavaProject project) {
|
||||
projectChanged[0] = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleted(IJavaProject project) {
|
||||
projectDeleted[0] = project;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
fileObserver.notifyFileChanged(projectFile1.toURI().toString());
|
||||
assertEquals(p1, projectChanged[0]);
|
||||
assertNull(projectDeleted[0]);
|
||||
projectChanged[0] = projectDeleted[0] = null;
|
||||
|
||||
fileObserver.notifyFileDeleted(projectFile1.toURI().toString());
|
||||
assertNull(projectChanged[0]);
|
||||
assertEquals(p1, projectDeleted[0]);
|
||||
projectChanged[0] = projectDeleted[0] = null;
|
||||
|
||||
fileObserver.notifyFileChanged(projectFile2.toURI().toString());
|
||||
assertEquals(p2, projectChanged[0]);
|
||||
assertNull(projectDeleted[0]);
|
||||
projectChanged[0] = projectDeleted[0] = null;
|
||||
|
||||
fileObserver.notifyFileDeleted(projectFile2.toURI().toString());
|
||||
assertNull(projectChanged[0]);
|
||||
assertEquals(p2, projectDeleted[0]);
|
||||
projectChanged[0] = projectDeleted[0] = null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.json;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
|
||||
|
||||
/**
|
||||
* Model object to be used in <code>client/registerCapability</code> JSON message to register file watchers
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class DidChangeWatchedFilesRegistrationOptions {
|
||||
|
||||
@NonNull
|
||||
private List<FileSystemWatcher> watchers;
|
||||
|
||||
public DidChangeWatchedFilesRegistrationOptions() {
|
||||
this(new ArrayList<FileSystemWatcher>());
|
||||
}
|
||||
|
||||
public DidChangeWatchedFilesRegistrationOptions(@NonNull final List<FileSystemWatcher> watchers) {
|
||||
this.watchers = watchers;
|
||||
}
|
||||
|
||||
@Pure
|
||||
@NonNull
|
||||
public List<FileSystemWatcher> getRegistrations() {
|
||||
return this.watchers;
|
||||
}
|
||||
|
||||
public void setRegistrations(@NonNull final List<FileSystemWatcher> watchers) {
|
||||
this.watchers = watchers;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this);
|
||||
b.add("watchers", this.watchers);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
DidChangeWatchedFilesRegistrationOptions other = (DidChangeWatchedFilesRegistrationOptions) obj;
|
||||
if (this.watchers == null) {
|
||||
if (other.watchers != null)
|
||||
return false;
|
||||
} else if (!this.watchers.equals(other.watchers))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.watchers == null) ? 0 : this.watchers.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.json;
|
||||
|
||||
import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
|
||||
|
||||
/**
|
||||
* Model object to be used in <code>client/registerCapability</code> JSON message to register a file watcher
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class FileSystemWatcher {
|
||||
|
||||
/**
|
||||
* Interested in create events
|
||||
*/
|
||||
public static final int CREATE = 1;
|
||||
|
||||
/**
|
||||
* Interested in change events
|
||||
*/
|
||||
public static final int CHANGE = 2;
|
||||
|
||||
/**
|
||||
* Interested in delete events
|
||||
*/
|
||||
public static final int DELETE = 4;
|
||||
|
||||
@NonNull
|
||||
private String globPattern;
|
||||
|
||||
private int kind = CREATE | CHANGE | DELETE;
|
||||
|
||||
public FileSystemWatcher() {
|
||||
}
|
||||
|
||||
public FileSystemWatcher(@NonNull final String globPattern) {
|
||||
this(globPattern, CREATE | CHANGE | DELETE);
|
||||
}
|
||||
|
||||
public FileSystemWatcher(@NonNull final String globPattern, final int kind) {
|
||||
this.globPattern = globPattern;
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
@Pure
|
||||
@NonNull
|
||||
public String getGlobPattern() {
|
||||
return this.globPattern;
|
||||
}
|
||||
|
||||
public void setGlobPattern(@NonNull final String globPattern) {
|
||||
this.globPattern = globPattern;
|
||||
}
|
||||
|
||||
@Pure
|
||||
@NonNull
|
||||
public int getKind() {
|
||||
return this.kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* The method / capability to unregister for.
|
||||
*/
|
||||
public void setKind(final int kind) {
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this);
|
||||
b.add("globPattern", this.globPattern);
|
||||
b.add("kind", this.kind);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
FileSystemWatcher other = (FileSystemWatcher) obj;
|
||||
if (this.globPattern == null) {
|
||||
if (other.globPattern != null)
|
||||
return false;
|
||||
} else if (!this.globPattern.equals(other.globPattern))
|
||||
return false;
|
||||
if (this.kind != other.kind)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.globPattern == null) ? 0 : this.globPattern.hashCode());
|
||||
result = prime * result + (this.kind);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -103,6 +103,8 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
|
||||
|
||||
private boolean hasExecuteCommandSupport;
|
||||
|
||||
private boolean hasFileWatcherRegistrationSupport;
|
||||
|
||||
@Override
|
||||
public void connect(LanguageClient _client) {
|
||||
this.client = (STS4LanguageClient) _client;
|
||||
@@ -175,6 +177,7 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
|
||||
}
|
||||
this.hasCompletionSnippetSupport = safeGet(false, () -> params.getCapabilities().getTextDocument().getCompletion().getCompletionItem().getSnippetSupport());
|
||||
this.hasExecuteCommandSupport = safeGet(false, () -> params.getCapabilities().getWorkspace().getExecuteCommand()!=null);
|
||||
this.hasFileWatcherRegistrationSupport = safeGet(false, () -> params.getCapabilities().getWorkspace().getDidChangeWatchedFiles().getDynamicRegistration());
|
||||
Log.debug("workspaceRoot = "+workspaceRoot);
|
||||
Log.debug("hasCompletionSnippetSupport = "+hasCompletionSnippetSupport);
|
||||
Log.debug("hasExecuteCommandSupport = "+hasExecuteCommandSupport);
|
||||
@@ -295,6 +298,7 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Object> shutdown() {
|
||||
getWorkspaceService().dispose();
|
||||
return CompletableFuture.completedFuture(new Object());
|
||||
}
|
||||
|
||||
@@ -459,4 +463,8 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
|
||||
Assert.isLegal(this.testListener==null);
|
||||
testListener = languageServerTestListener;
|
||||
}
|
||||
|
||||
public boolean canRegisterFileWatchersDynamically() {
|
||||
return hasFileWatcherRegistrationSupport;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.lsp4j.Registration;
|
||||
import org.eclipse.lsp4j.RegistrationParams;
|
||||
import org.eclipse.lsp4j.Unregistration;
|
||||
import org.eclipse.lsp4j.UnregistrationParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.json.DidChangeWatchedFilesRegistrationOptions;
|
||||
import org.springframework.ide.vscode.commons.languageserver.json.FileSystemWatcher;
|
||||
import org.springframework.ide.vscode.commons.util.BasicFileObserver;
|
||||
|
||||
/**
|
||||
* File Observer implementation for a language server. Able to register listeners to specific files via LS protocol
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class SimpleServerFileObserver extends BasicFileObserver {
|
||||
|
||||
private static final String WORKSPACE_DID_CHANGE_WATCHED_FILES = "workspace/didChangeWatchedFiles";
|
||||
|
||||
private SimpleLanguageServer server;
|
||||
|
||||
public SimpleServerFileObserver(SimpleLanguageServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFileCreated(List<String> globPattern, Consumer<String> handler) {
|
||||
String subscriptionId = super.onFileCreated(globPattern, handler);
|
||||
subscribe(subscriptionId, globPattern, FileSystemWatcher.CREATE);
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFileChanged(List<String> globPattern, Consumer<String> handler) {
|
||||
String subscriptionId = super.onFileChanged(globPattern, handler);
|
||||
subscribe(subscriptionId, globPattern, FileSystemWatcher.CHANGE);
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFileDeleted(List<String> globPattern, Consumer<String> handler) {
|
||||
String subscriptionId = super.onFileDeleted(globPattern, handler);
|
||||
subscribe(subscriptionId, globPattern, FileSystemWatcher.DELETE);
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
private void subscribe(String subscriptionId, List<String> globPattern, int kind) {
|
||||
if (server.canRegisterFileWatchersDynamically()) {
|
||||
List<FileSystemWatcher> watchers = globPattern.stream().map(pattern -> new FileSystemWatcher(pattern, kind)).collect(Collectors.toList());
|
||||
Registration registration = new Registration(subscriptionId, WORKSPACE_DID_CHANGE_WATCHED_FILES, new DidChangeWatchedFilesRegistrationOptions(watchers));
|
||||
server.getClient().registerCapability(new RegistrationParams(Arrays.asList(registration)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unsubscribe(String subscriptionId) {
|
||||
if (server.canRegisterFileWatchersDynamically()) {
|
||||
server.getClient().unregisterCapability(new UnregistrationParams(Arrays.asList(new Unregistration(subscriptionId, WORKSPACE_DID_CHANGE_WATCHED_FILES))));
|
||||
}
|
||||
return super.unsubscribe(subscriptionId);
|
||||
}
|
||||
|
||||
private void unsubscribeAll(Collection<String> subscriptions) {
|
||||
List<Unregistration> unregisterations = subscriptions.stream().map(s -> new Unregistration(s, WORKSPACE_DID_CHANGE_WATCHED_FILES)).collect(Collectors.toList());
|
||||
if (!unregisterations.isEmpty()) {
|
||||
server.getClient().unregisterCapability(new UnregistrationParams(unregisterations));
|
||||
}
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
if (server.canRegisterFileWatchersDynamically()) {
|
||||
unsubscribeAll(createRegistry.keySet());
|
||||
unsubscribeAll(changeRegistry.keySet());
|
||||
unsubscribeAll(deleteRegistry.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,17 +28,18 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class SimpleWorkspaceService implements WorkspaceService, FileObserver {
|
||||
public class SimpleWorkspaceService implements WorkspaceService {
|
||||
|
||||
private SimpleLanguageServer server;
|
||||
|
||||
private ListenerList<Settings> configurationListeners = new ListenerList<>();
|
||||
private ExecuteCommandHandler executeCommandHandler;
|
||||
private WorkspaceSymbolHandler workspaceSymbolHandler;
|
||||
private org.springframework.ide.vscode.commons.util.ListenerList<FileListener> fileListeners = new org.springframework.ide.vscode.commons.util.ListenerList<>();
|
||||
private SimpleServerFileObserver fileObserver;
|
||||
|
||||
public SimpleWorkspaceService(SimpleLanguageServer server) {
|
||||
this.server = server;
|
||||
this.fileObserver = new SimpleServerFileObserver(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,32 +63,29 @@ public class SimpleWorkspaceService implements WorkspaceService, FileObserver {
|
||||
|
||||
@Override
|
||||
public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) {
|
||||
params.getChanges().forEach(event -> fileListeners.forEach(listener -> {
|
||||
params.getChanges().forEach(event -> {
|
||||
try {
|
||||
String uri = event.getUri();
|
||||
if (uri != null) {
|
||||
if (listener.accept(event.getUri())) {
|
||||
switch (event.getType()) {
|
||||
case Created:
|
||||
listener.created(uri);
|
||||
break;
|
||||
case Changed:
|
||||
listener.changed(uri);
|
||||
break;
|
||||
case Deleted:
|
||||
listener.deleted(uri);
|
||||
break;
|
||||
default:
|
||||
Log.log("Uknown file change type '" + event.getType() + "' for file: " + uri);
|
||||
break;
|
||||
|
||||
}
|
||||
switch (event.getType()) {
|
||||
case Created:
|
||||
fileObserver.notifyFileCreated(uri);
|
||||
break;
|
||||
case Changed:
|
||||
fileObserver.notifyFileChanged(uri);
|
||||
break;
|
||||
case Deleted:
|
||||
fileObserver.notifyFileDeleted(uri);
|
||||
break;
|
||||
default:
|
||||
Log.log("Uknown file change type '" + event.getType() + "' for file: " + uri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.log(t);
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,14 +114,12 @@ public class SimpleWorkspaceService implements WorkspaceService, FileObserver {
|
||||
return this.workspaceSymbolHandler != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(FileListener listener) {
|
||||
fileListeners.add(listener);
|
||||
public FileObserver getFileObserver() {
|
||||
return fileObserver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(FileListener listener) {
|
||||
fileListeners.remove(listener);
|
||||
public void dispose() {
|
||||
fileObserver.dispose();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ public class MavenJavaProject implements IJavaProject {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
void update(MavenCore maven, File pom) {
|
||||
this.classpath = new MavenProjectClasspath(maven, pom);
|
||||
void update(MavenCore maven) {
|
||||
this.classpath = new MavenProjectClasspath(maven, classpath.getPomFile());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.maven.java;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractFileToProjectCache;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
|
||||
/**
|
||||
* Cache for Maven projects
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*/
|
||||
public class MavenProjectCache extends AbstractFileToProjectCache<MavenJavaProject> {
|
||||
|
||||
private MavenCore maven;
|
||||
|
||||
public MavenProjectCache(FileObserver fileObserver, MavenCore maven) {
|
||||
super(fileObserver);
|
||||
this.maven = maven;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update(MavenJavaProject project) {
|
||||
project.update(maven);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MavenJavaProject createProject(File pomFile) throws Exception {
|
||||
return new MavenJavaProject(maven, pomFile);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -77,6 +77,10 @@ public class MavenProjectClasspath extends JandexClasspath {
|
||||
}
|
||||
}
|
||||
|
||||
public File getPomFile() {
|
||||
return pom;
|
||||
}
|
||||
|
||||
public boolean exists() {
|
||||
return pom.exists();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.maven.java;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.util.FileUtils;
|
||||
|
||||
/**
|
||||
* Finds Maven projects. Looks for <code>pom.xml</code> file
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class MavenProjectFinder extends AbstractJavaProjectFinder {
|
||||
|
||||
private MavenProjectCache cache;
|
||||
|
||||
public MavenProjectFinder(MavenProjectCache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
File pomFile = FileUtils.findFile(file, MavenCore.POM_XML);
|
||||
return cache.project(pomFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return FileUtils.findFile(file, MavenCore.POM_XML, false) != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.maven.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver.FileListener;
|
||||
import org.springframework.ide.vscode.commons.util.FileUtils;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
/**
|
||||
* Finds Maven Project based
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*/
|
||||
public class MavenProjectManager extends AbstractJavaProjectManager {
|
||||
|
||||
private Cache<File, MavenJavaProject> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
private MavenCore maven;
|
||||
|
||||
public MavenProjectManager(MavenCore maven) {
|
||||
this.maven = maven;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MavenJavaProject find(File file) {
|
||||
File pomFile = FileUtils.findFile(file, MavenCore.POM_XML);
|
||||
if (pomFile != null) {
|
||||
try {
|
||||
return cache.get(pomFile, () -> {
|
||||
System.out.println("create maven project: " + file.getAbsolutePath());
|
||||
MavenJavaProject project = new MavenJavaProject(maven, pomFile);
|
||||
System.out.println("maven project created");
|
||||
return project;
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return FileUtils.findFile(file, MavenCore.POM_XML, false) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFileObserver(FileObserver fileObserver) {
|
||||
super.setFileObserver(fileObserver);
|
||||
cache.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileListener createFileListener() {
|
||||
return new FileListener() {
|
||||
|
||||
private File getFileFromUri(String uri) {
|
||||
return Paths.get(URI.create(uri)).toFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleted(String uri) {
|
||||
File pomFile = getFileFromUri(uri);
|
||||
MavenJavaProject project = cache.getIfPresent(pomFile);
|
||||
if (project != null) {
|
||||
// Only invalidate and fire event if projects was cached.
|
||||
cache.invalidate(pomFile);
|
||||
notifyProjectDeleted(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(String uri) {
|
||||
// Ignore created projects - cache should take care of newly created ones
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(String uri) {
|
||||
File pomFile = getFileFromUri(uri);
|
||||
MavenJavaProject project = cache.getIfPresent(pomFile);
|
||||
if (project != null) {
|
||||
// Only update and fire event if project cached
|
||||
project.update(maven, pomFile);
|
||||
notifyProjectChanged(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(String uri) {
|
||||
return MavenCore.POM_XML.equals(Paths.get(URI.create(uri)).getFileName().toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* Copyright (c) 2016, 2017 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
|
||||
@@ -67,8 +67,7 @@ public class JavaProjectWithClasspathFile implements IJavaProject {
|
||||
return true;
|
||||
}
|
||||
|
||||
void update(File cpFile) {
|
||||
this.cpFile = cpFile;
|
||||
void update() {
|
||||
this.classpath = new FileClasspath(Paths.get(cpFile.toURI()));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.maven.java.classpathfile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractFileToProjectCache;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
|
||||
public class JavaProjectWithClasspathFileCache extends AbstractFileToProjectCache<JavaProjectWithClasspathFile> {
|
||||
|
||||
public JavaProjectWithClasspathFileCache(FileObserver fileObserver) {
|
||||
super(fileObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update(JavaProjectWithClasspathFile project) {
|
||||
project.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JavaProjectWithClasspathFile createProject(File cpFile) throws Exception {
|
||||
return new JavaProjectWithClasspathFile(cpFile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.maven.java.classpathfile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.util.FileUtils;
|
||||
|
||||
/**
|
||||
* Finder for projects with classpath.txt file that contains classpath entries
|
||||
* For test purposes only.
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class JavaProjectWithClasspathFileFinder extends AbstractJavaProjectFinder {
|
||||
|
||||
private JavaProjectWithClasspathFileCache cache;
|
||||
|
||||
public JavaProjectWithClasspathFileFinder(JavaProjectWithClasspathFileCache cache) {
|
||||
super();
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
File cpFile = FileUtils.findFile(file, MavenCore.CLASSPATH_TXT);
|
||||
return cache.project(cpFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return FileUtils.findFile(file, MavenCore.CLASSPATH_TXT, false) != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.maven.java.classpathfile;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver.FileListener;
|
||||
import org.springframework.ide.vscode.commons.util.FileUtils;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
public class JavaProjectWithClasspathFileManager extends AbstractJavaProjectManager {
|
||||
|
||||
private Cache<File, JavaProjectWithClasspathFile> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
@Override
|
||||
public JavaProjectWithClasspathFile find(File file) {
|
||||
File cpFile = FileUtils.findFile(file, MavenCore.CLASSPATH_TXT);
|
||||
if (cpFile != null) {
|
||||
try {
|
||||
return cache.get(cpFile, () -> {
|
||||
return new JavaProjectWithClasspathFile(cpFile);
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return FileUtils.findFile(file, MavenCore.CLASSPATH_TXT, false) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFileObserver(FileObserver fileObserver) {
|
||||
super.setFileObserver(fileObserver);
|
||||
cache.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileListener createFileListener() {
|
||||
return new FileListener() {
|
||||
|
||||
@Override
|
||||
public boolean accept(String uri) {
|
||||
return MavenCore.CLASSPATH_TXT.equals(Paths.get(URI.create(uri)).getFileName().toString());
|
||||
}
|
||||
|
||||
private File getFileFromUri(String uri) {
|
||||
return Paths.get(URI.create(uri)).toFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleted(String uri) {
|
||||
File cpFile = getFileFromUri(uri);
|
||||
JavaProjectWithClasspathFile project = cache.getIfPresent(cpFile);
|
||||
if (project != null) {
|
||||
// Only invalidate and fire event if projects was cached.
|
||||
cache.invalidate(cpFile);
|
||||
notifyProjectDeleted(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(String uri) {
|
||||
// Ignore created projects - cache should take care of newly created ones
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(String uri) {
|
||||
File cpFile = getFileFromUri(uri);
|
||||
JavaProjectWithClasspathFile project = cache.getIfPresent(cpFile);
|
||||
if (project != null) {
|
||||
// Only update and fire event if project cached
|
||||
project.update(cpFile);
|
||||
notifyProjectChanged(project);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,13 +19,13 @@ import java.nio.file.Paths;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager.Listener;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver.Listener;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectManager;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectCache;
|
||||
import org.springframework.ide.vscode.commons.util.BasicFileObserver;
|
||||
|
||||
/**
|
||||
* Tests for {@link MavenProjectManager}
|
||||
* Tests for {@link MavenProjectCache}
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
@@ -36,12 +36,11 @@ public class MavenProjectManagerTest {
|
||||
public void testPomFileChanges() throws Exception {
|
||||
Path testProjectPath = Paths.get(DependencyTreeTest.class.getResource("/empty-boot-project-with-classpath-file").toURI());
|
||||
File pomFile = testProjectPath.resolve(MavenCore.POM_XML).toFile();
|
||||
MavenProjectManager manager = new MavenProjectManager(MavenCore.getDefault());
|
||||
BasicFileObserver fileObserver = new BasicFileObserver();
|
||||
manager.setFileObserver(fileObserver);
|
||||
MavenProjectCache cache = new MavenProjectCache(fileObserver, MavenCore.getDefault());
|
||||
IJavaProject[] projectChanged = new IJavaProject[] { null };
|
||||
IJavaProject[] projectDeleted = new IJavaProject[] { null };
|
||||
manager.addListener(new Listener() {
|
||||
cache.addListener(new Listener() {
|
||||
@Override
|
||||
public void created(IJavaProject project) {}
|
||||
|
||||
@@ -56,7 +55,7 @@ public class MavenProjectManagerTest {
|
||||
});
|
||||
|
||||
// Get the project from cache
|
||||
MavenJavaProject cachedProject = manager.find(pomFile);
|
||||
MavenJavaProject cachedProject = cache.project(pomFile);
|
||||
assertNotNull(cachedProject);
|
||||
|
||||
fileObserver.notifyFileChanged(pomFile.toURI().toString());
|
||||
|
||||
@@ -10,6 +10,20 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
/**
|
||||
* Basic implementation of File Observer interface
|
||||
*
|
||||
@@ -18,52 +32,65 @@ package org.springframework.ide.vscode.commons.util;
|
||||
*/
|
||||
public class BasicFileObserver implements FileObserver {
|
||||
|
||||
private ListenerList<FileListener> listeners = new ListenerList<>();
|
||||
|
||||
protected ConcurrentHashMap<String, ImmutablePair<List<PathMatcher>, Consumer<String>>> createRegistry = new ConcurrentHashMap<>();
|
||||
protected ConcurrentHashMap<String, ImmutablePair<List<PathMatcher>, Consumer<String>>> deleteRegistry = new ConcurrentHashMap<>();
|
||||
protected ConcurrentHashMap<String, ImmutablePair<List<PathMatcher>, Consumer<String>>> changeRegistry = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void addListener(FileListener listener) {
|
||||
listeners.add(listener);
|
||||
public String onFileCreated(List<String> globPattern, Consumer<String> handler) {
|
||||
return registerFileListener(createRegistry, globPattern, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(FileListener listener) {
|
||||
listeners.remove(listener);
|
||||
public String onFileChanged(List<String> globPattern, Consumer<String> handler) {
|
||||
return registerFileListener(changeRegistry, globPattern, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFileDeleted(List<String> globPattern, Consumer<String> handler) {
|
||||
return registerFileListener(deleteRegistry, globPattern, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unsubscribe(String subscriptionId) {
|
||||
if (createRegistry.remove(subscriptionId) != null) {
|
||||
return true;
|
||||
}
|
||||
if (changeRegistry.remove(subscriptionId) != null) {
|
||||
return true;
|
||||
}
|
||||
if (deleteRegistry.remove(subscriptionId) != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void notifyFileChanged(String uri) {
|
||||
listeners.forEach(l -> {
|
||||
try {
|
||||
if (l.accept(uri)) {
|
||||
l.changed(uri);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.log(t);
|
||||
}
|
||||
});
|
||||
private static String registerFileListener(Map<String, ImmutablePair<List<PathMatcher>, Consumer<String>>> registry, List<String> globPattern, Consumer<String> handler) {
|
||||
String subscriptionId = UUID.randomUUID().toString();
|
||||
registry.put(subscriptionId, ImmutablePair.of(globPattern.stream().map(g -> FileSystems.getDefault().getPathMatcher("glob:" + g)).collect(Collectors.toList()), handler));
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
public void notifyFileCreated(String uri) {
|
||||
listeners.forEach(l -> {
|
||||
try {
|
||||
if (l.accept(uri)) {
|
||||
l.created(uri);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.log(t);
|
||||
}
|
||||
});
|
||||
final public void notifyFileCreated(String uri) {
|
||||
notify(createRegistry, uri);
|
||||
}
|
||||
|
||||
public void notifyFileDeleted(String uri) {
|
||||
listeners.forEach(l -> {
|
||||
try {
|
||||
if (l.accept(uri)) {
|
||||
l.deleted(uri);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.log(t);
|
||||
}
|
||||
});
|
||||
final public void notifyFileChanged(String uri) {
|
||||
notify(changeRegistry, uri);
|
||||
}
|
||||
|
||||
final public void notifyFileDeleted(String uri) {
|
||||
notify(deleteRegistry, uri);
|
||||
}
|
||||
|
||||
private static void notify(Map<String, ImmutablePair<List<PathMatcher>, Consumer<String>>> registry, String uri) {
|
||||
Path path = Paths.get(URI.create(uri));
|
||||
registry.values().stream()
|
||||
.filter(pair -> pair.left.stream()
|
||||
.filter(matcher -> matcher.matches(path))
|
||||
.findFirst()
|
||||
.isPresent())
|
||||
.forEach(pair -> pair.right.accept(uri));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Object able to add/remove {@link FileListener} objects and fire events via these listeners
|
||||
*
|
||||
@@ -18,15 +21,12 @@ package org.springframework.ide.vscode.commons.util;
|
||||
*/
|
||||
public interface FileObserver {
|
||||
|
||||
public interface FileListener {
|
||||
boolean accept(String uri);
|
||||
void changed(String uri);
|
||||
void deleted(String uri);
|
||||
void created(String uri);
|
||||
}
|
||||
String onFileCreated(List<String> globPattern, Consumer<String> handler);
|
||||
|
||||
void addListener(FileListener listener);
|
||||
String onFileChanged(List<String> globPattern, Consumer<String> handler);
|
||||
|
||||
String onFileDeleted(List<String> globPattern, Consumer<String> handler);
|
||||
|
||||
boolean unsubscribe(String subscriptionId);
|
||||
|
||||
void removeListener(FileListener listener);
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -47,10 +48,13 @@ import org.eclipse.lsp4j.CompletionList;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
import org.eclipse.lsp4j.DiagnosticSeverity;
|
||||
import org.eclipse.lsp4j.DidChangeTextDocumentParams;
|
||||
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
|
||||
import org.eclipse.lsp4j.DidOpenTextDocumentParams;
|
||||
import org.eclipse.lsp4j.DocumentSymbolParams;
|
||||
import org.eclipse.lsp4j.ExecuteCommandCapabilities;
|
||||
import org.eclipse.lsp4j.ExecuteCommandParams;
|
||||
import org.eclipse.lsp4j.FileChangeType;
|
||||
import org.eclipse.lsp4j.FileEvent;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.InitializeParams;
|
||||
import org.eclipse.lsp4j.InitializeResult;
|
||||
@@ -306,6 +310,21 @@ public class LanguageServerHarness<S extends SimpleLanguageServer> {
|
||||
return documents.get(uri);
|
||||
}
|
||||
|
||||
public synchronized void changeFile(String uri) {
|
||||
FileEvent fileEvent = new FileEvent(uri, FileChangeType.Changed);
|
||||
getServer().getWorkspaceService().didChangeWatchedFiles(new DidChangeWatchedFilesParams(Arrays.asList(fileEvent)));
|
||||
}
|
||||
|
||||
public synchronized void createFile(String uri) {
|
||||
FileEvent fileEvent = new FileEvent(uri, FileChangeType.Created);
|
||||
getServer().getWorkspaceService().didChangeWatchedFiles(new DidChangeWatchedFilesParams(Arrays.asList(fileEvent)));
|
||||
}
|
||||
|
||||
public synchronized void deleteFile(String uri) {
|
||||
FileEvent fileEvent = new FileEvent(uri, FileChangeType.Deleted);
|
||||
getServer().getWorkspaceService().didChangeWatchedFiles(new DidChangeWatchedFilesParams(Arrays.asList(fileEvent)));
|
||||
}
|
||||
|
||||
public TextDocumentInfo changeDocument(String uri, String newContent) throws Exception {
|
||||
TextDocumentItem textDocument = setDocumentContent(uri, newContent);
|
||||
DidChangeTextDocumentParams didChange = new DidChangeTextDocumentParams();
|
||||
|
||||
Reference in New Issue
Block a user