From c0d6a775a8e85c407f08d874ae1f2a383d6b28a4 Mon Sep 17 00:00:00 2001 From: Roman Nikitenko Date: Mon, 11 Sep 2017 13:35:52 +0300 Subject: [PATCH] CHE-6063. Improve mechanism of handling file watcher 'MODIFIED' events Signed-off-by: Roman Nikitenko --- .../EditorGroupSynchronizationImpl.java | 86 ++++++++++--------- .../EditorGroupSynchronizationImplTest.java | 1 + .../vfs/impl/file/LocalVirtualFileSystem.java | 4 +- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/editor/synchronization/EditorGroupSynchronizationImpl.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/editor/synchronization/EditorGroupSynchronizationImpl.java index e6767cdd634..8856b6c6e7f 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/editor/synchronization/EditorGroupSynchronizationImpl.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/editor/synchronization/EditorGroupSynchronizationImpl.java @@ -10,6 +10,7 @@ */ package org.eclipse.che.ide.editor.synchronization; +import static com.google.common.base.Strings.isNullOrEmpty; import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.EMERGE_MODE; import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.NOT_EMERGE_MODE; import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAIL; @@ -144,7 +145,7 @@ public void onDocumentChanged(DocumentChangedEvent event) { } @Override - public void onFileContentUpdate(final FileContentUpdateEvent event) { + public void onFileContentUpdate(FileContentUpdateEvent event) { if (synchronizedEditors.keySet().isEmpty()) { return; } @@ -159,13 +160,54 @@ public void onFileContentUpdate(final FileContentUpdateEvent event) { return; } + if (!(virtualFile instanceof File)) { + updateContent(virtualFile, false); + return; + } + + File file = (File) virtualFile; + + String eventModificationStamp = event.getModificationStamp(); + String currentModificationStamp = file.getModificationStamp(); + if (isNullOrEmpty(currentModificationStamp) || isNullOrEmpty(eventModificationStamp)) { + updateContent(virtualFile, false); + return; + } + + if (!Objects.equals(eventModificationStamp, currentModificationStamp)) { + updateContent(virtualFile, true); + } + } + + private void updateContent(VirtualFile virtualFile, boolean externalOperation) { + final DocumentHandle documentHandle = getDocumentHandleFor(groupLeaderEditor); + if (documentHandle == null) { + return; + } + documentStorage.getDocument( virtualFile, new DocumentStorage.DocumentCallback() { @Override - public void onDocumentReceived(final String content) { - updateContent(content, event.getModificationStamp(), virtualFile); + public void onDocumentReceived(String newContent) { + Document document = documentHandle.getDocument(); + + String oldContent = document.getContents(); + if (Objects.equals(newContent, oldContent)) { + return; + } + + TextPosition cursorPosition = document.getCursorPosition(); + replaceContent(document, newContent, oldContent, cursorPosition); + + if (externalOperation) { + notificationManager.notify( + "External operation", + "File '" + virtualFile.getName() + "' is updated", + SUCCESS, + NOT_EMERGE_MODE); + } } @Override @@ -179,44 +221,6 @@ public void onDocumentLoadFailure(final Throwable caught) { }); } - private void updateContent( - String newContent, String eventModificationStamp, VirtualFile virtualFile) { - final DocumentHandle documentHandle = getDocumentHandleFor(groupLeaderEditor); - if (documentHandle == null) { - return; - } - - final Document document = documentHandle.getDocument(); - final String oldContent = document.getContents(); - if (Objects.equals(newContent, oldContent)) { - return; - } - - final TextPosition cursorPosition = document.getCursorPosition(); - if (!(virtualFile instanceof File)) { - replaceContent(document, newContent, oldContent, cursorPosition); - return; - } - - final File file = (File) virtualFile; - final String currentStamp = file.getModificationStamp(); - - if (eventModificationStamp == null) { - replaceContent(document, newContent, oldContent, cursorPosition); - return; - } - - if (!Objects.equals(eventModificationStamp, currentStamp)) { - replaceContent(document, newContent, oldContent, cursorPosition); - - notificationManager.notify( - "External operation", - "File '" + file.getName() + "' is updated", - SUCCESS, - NOT_EMERGE_MODE); - } - } - private void replaceContent( Document document, String newContent, String oldContent, TextPosition cursorPosition) { document.replace(0, oldContent.length(), newContent); diff --git a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/editor/synchronization/EditorGroupSynchronizationImplTest.java b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/editor/synchronization/EditorGroupSynchronizationImplTest.java index 2fb58183f2e..a7b0116f4cf 100644 --- a/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/editor/synchronization/EditorGroupSynchronizationImplTest.java +++ b/ide/che-core-ide-app/src/test/java/org/eclipse/che/ide/editor/synchronization/EditorGroupSynchronizationImplTest.java @@ -158,6 +158,7 @@ public void shouldNotifyAboutExternalOperationAtUpdateContentWhenStampIsDifferen reset(documentEventBus); when(fileContentUpdateEvent.getFilePath()).thenReturn(FILE_LOCATION); when(fileContentUpdateEvent.getModificationStamp()).thenReturn("some stamp"); + when(((File) virtualFile).getModificationStamp()).thenReturn("current modification stamp"); editorGroupSynchronization.onFileContentUpdate(fileContentUpdateEvent); diff --git a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/vfs/impl/file/LocalVirtualFileSystem.java b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/vfs/impl/file/LocalVirtualFileSystem.java index 4722b27cc0c..260d9983a3b 100644 --- a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/vfs/impl/file/LocalVirtualFileSystem.java +++ b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/vfs/impl/file/LocalVirtualFileSystem.java @@ -616,8 +616,8 @@ private File createTempIoFile(VirtualFile parent, String prefix, String suffix) private void doUpdateContent(LocalVirtualFile virtualFile, InputStream content) throws ServerException { - try (FileOutputStream fileOut = new FileOutputStream(virtualFile.toIoFile())) { - ByteStreams.copy(content, fileOut); + try { + Files.write(ByteStreams.toByteArray(content), virtualFile.toIoFile()); } catch (IOException e) { String errorMessage = String.format("Unable set content of '%s'", virtualFile.getPath()); LOG.error(errorMessage + "\n" + e.getMessage(), e);