-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#1799 implement DidChangeWatchedFiles Notification
Signed-off-by: Yevhen Vydolob <evidolob@codenvy.com>
- Loading branch information
Yevhen Vydolob
committed
Aug 16, 2017
1 parent
c9b568d
commit 00f4335
Showing
5 changed files
with
236 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
.../src/main/java/org/eclipse/che/api/languageserver/registry/LanguageServerFileWatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2012-2017 Red Hat, 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: | ||
* Red Hat, Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.che.api.languageserver.registry; | ||
|
||
import com.google.common.annotations.VisibleForTesting; | ||
|
||
import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncher; | ||
import org.eclipse.che.api.vfs.watcher.FileWatcherManager; | ||
import org.eclipse.lsp4j.DidChangeWatchedFilesParams; | ||
import org.eclipse.lsp4j.FileChangeType; | ||
import org.eclipse.lsp4j.FileEvent; | ||
import org.eclipse.lsp4j.ServerCapabilities; | ||
import org.eclipse.lsp4j.services.LanguageServer; | ||
|
||
import javax.annotation.PreDestroy; | ||
import javax.inject.Inject; | ||
import javax.inject.Singleton; | ||
import java.nio.file.FileSystem; | ||
import java.nio.file.FileSystems; | ||
import java.nio.file.PathMatcher; | ||
import java.util.Collections; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
|
||
import static org.eclipse.che.api.languageserver.service.LanguageServiceUtils.prefixURI; | ||
|
||
/** | ||
* Implement <a href="https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#workspace_didChangeWatchedFiles">DidChangeWatchedFiles | ||
* Notification</a> | ||
*/ | ||
@Singleton | ||
public class LanguageServerFileWatcher { | ||
|
||
|
||
private final FileWatcherManager watcherManager; | ||
|
||
private CopyOnWriteArrayList<Integer> watcherIds = new CopyOnWriteArrayList<>(); | ||
|
||
@Inject | ||
public LanguageServerFileWatcher(FileWatcherManager watcherManager, ServerInitializer serverInitializer) { | ||
this.watcherManager = watcherManager; | ||
serverInitializer.addObserver(this::onServerInitialized); | ||
} | ||
|
||
private void send(LanguageServer server, String filePath, FileChangeType changeType) { | ||
DidChangeWatchedFilesParams params = | ||
new DidChangeWatchedFilesParams(Collections.singletonList(new FileEvent(prefixURI(filePath), changeType))); | ||
server.getWorkspaceService().didChangeWatchedFiles(params); | ||
} | ||
|
||
@PreDestroy | ||
@VisibleForTesting | ||
public void removeAllWatchers() { | ||
for (Integer watcherId : watcherIds) { | ||
watcherManager.unRegisterByMatcher(watcherId); | ||
} | ||
} | ||
|
||
private void onServerInitialized(LanguageServerLauncher launcher, | ||
LanguageServer server, | ||
ServerCapabilities capabilities, | ||
String projectPath) { | ||
LanguageServerDescription description = launcher.getDescription(); | ||
FileSystem fileSystem = FileSystems.getDefault(); | ||
for (String pattern : description.getFileWatchPatterns()) { | ||
PathMatcher matcher = fileSystem.getPathMatcher(pattern); | ||
int watcherId = watcherManager.registerByMatcher(matcher, | ||
s -> send(server, s, FileChangeType.Created), | ||
s -> send(server, s, FileChangeType.Changed), | ||
s -> send(server, s, FileChangeType.Deleted)); | ||
|
||
watcherIds.add(watcherId); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
...erver/src/test/java/org/eclipse/che/api/languageserver/LanguageServerFileWatcherTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2012-2017 Red Hat, 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: | ||
* Red Hat, Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.che.api.languageserver; | ||
|
||
import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncher; | ||
import org.eclipse.che.api.languageserver.registry.LanguageServerDescription; | ||
import org.eclipse.che.api.languageserver.registry.LanguageServerFileWatcher; | ||
import org.eclipse.che.api.languageserver.registry.ServerInitializer; | ||
import org.eclipse.che.api.languageserver.registry.ServerInitializerObserver; | ||
import org.eclipse.che.api.vfs.watcher.FileWatcherManager; | ||
import org.eclipse.lsp4j.services.LanguageServer; | ||
import org.eclipse.lsp4j.services.WorkspaceService; | ||
import org.mockito.ArgumentCaptor; | ||
import org.mockito.Captor; | ||
import org.mockito.Mock; | ||
import org.mockito.testng.MockitoTestNGListener; | ||
import org.testng.annotations.AfterMethod; | ||
import org.testng.annotations.Listeners; | ||
import org.testng.annotations.Test; | ||
|
||
import java.io.File; | ||
import java.nio.file.PathMatcher; | ||
import java.util.Collections; | ||
import java.util.function.Consumer; | ||
|
||
import static org.mockito.Mockito.any; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.verify; | ||
import static org.mockito.Mockito.when; | ||
import static org.testng.Assert.assertTrue; | ||
|
||
/** | ||
* | ||
*/ | ||
@Listeners(MockitoTestNGListener.class) | ||
public class LanguageServerFileWatcherTest { | ||
|
||
@Mock | ||
private LanguageServerLauncher launcher; | ||
@Mock | ||
private LanguageServer server; | ||
@Mock | ||
private FileWatcherManager watcherManager; | ||
@Mock | ||
private ServerInitializer initializer; | ||
@Captor | ||
private ArgumentCaptor<Consumer<String>> changedCaptor; | ||
|
||
private LanguageServerFileWatcher watcher; | ||
|
||
@AfterMethod | ||
public void tearDown() throws Exception { | ||
if (watcher != null) { | ||
watcher.removeAllWatchers(); | ||
} | ||
} | ||
|
||
@Test | ||
public void testShouldAddObserver() throws Exception { | ||
watcher = new LanguageServerFileWatcher(watcherManager, initializer); | ||
verify(initializer).addObserver(any()); | ||
} | ||
|
||
@Test | ||
public void testRegisterFileWatcher() throws Exception { | ||
ArgumentCaptor<ServerInitializerObserver> argumentCaptor = ArgumentCaptor.forClass(ServerInitializerObserver.class); | ||
watcher = new LanguageServerFileWatcher(watcherManager, initializer); | ||
verify(initializer).addObserver(argumentCaptor.capture()); | ||
ServerInitializerObserver value = argumentCaptor.getValue(); | ||
|
||
LanguageServerDescription description = | ||
new LanguageServerDescription("foo", Collections.singletonList("bar"), Collections.emptyList(), | ||
Collections.singletonList("glob:*.foo")); | ||
when(launcher.getDescription()).thenReturn(description); | ||
value.onServerInitialized(launcher, server, null, null); | ||
|
||
ArgumentCaptor<PathMatcher> pathMatcherCaptor = ArgumentCaptor.forClass(PathMatcher.class); | ||
verify(watcherManager).registerByMatcher(pathMatcherCaptor.capture(), any(), any(), any()); | ||
assertTrue(pathMatcherCaptor.getValue().matches(new File("bar.foo").toPath())); | ||
} | ||
|
||
@Test | ||
public void testSendNotification() throws Exception { | ||
ArgumentCaptor<ServerInitializerObserver> argumentCaptor = ArgumentCaptor.forClass(ServerInitializerObserver.class); | ||
watcher = new LanguageServerFileWatcher(watcherManager, initializer); | ||
verify(initializer).addObserver(argumentCaptor.capture()); | ||
ServerInitializerObserver value = argumentCaptor.getValue(); | ||
|
||
LanguageServerDescription description = | ||
new LanguageServerDescription("foo", Collections.singletonList("bar"), Collections.emptyList(), | ||
Collections.singletonList("glob:*.foo")); | ||
when(launcher.getDescription()).thenReturn(description); | ||
|
||
WorkspaceService workspaceService = mock(WorkspaceService.class); | ||
when(server.getWorkspaceService()).thenReturn(workspaceService); | ||
|
||
value.onServerInitialized(launcher, server, null, null); | ||
|
||
verify(watcherManager).registerByMatcher(any(), any(), changedCaptor.capture(), any()); | ||
|
||
changedCaptor.getValue().accept("/p/bar.foo"); | ||
|
||
verify(workspaceService).didChangeWatchedFiles(any()); | ||
|
||
} | ||
|
||
|
||
} |