Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor file content synchronization and git checkout notification #2153

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public class FileContentUpdateEvent extends GwtEvent<FileContentUpdateHandler> {
*/
private final String filePath;

/**
* Encoded content.
*/
private String modificationStamp;

/**
* Constructor.
*
Expand All @@ -33,6 +38,11 @@ public FileContentUpdateEvent(final String filePath) {
this.filePath = filePath;
}

public FileContentUpdateEvent(final String filePath, final String contentStamp) {
this.filePath = filePath;
this.modificationStamp = contentStamp;
}

@Override
public Type<FileContentUpdateHandler> getAssociatedType() {
return TYPE;
Expand All @@ -51,4 +61,13 @@ protected void dispatch(FileContentUpdateHandler handler) {
public String getFilePath() {
return filePath;
}

/**
* Returns content's stamp of the file that had changes.
*
* @return the path
*/
public String getModificationStamp() {
return modificationStamp;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
*******************************************************************************/
package org.eclipse.che.ide.api.event.ng;

import com.google.inject.Provider;
import com.google.web.bindery.event.shared.EventBus;

import org.eclipse.che.api.core.jsonrpc.shared.JsonRpcRequest;
import org.eclipse.che.api.project.shared.dto.event.FileClosedDto;
import org.eclipse.che.api.project.shared.dto.event.FileOpenedDto;
import org.eclipse.che.ide.api.event.FileEvent;
import org.eclipse.che.api.project.shared.dto.event.FileTrackingOperationDto;
import org.eclipse.che.ide.api.editor.EditorAgent;
import org.eclipse.che.ide.dto.DtoFactory;
import org.eclipse.che.ide.jsonrpc.JsonRpcRequestTransmitter;
import org.eclipse.che.ide.util.loging.Log;
Expand All @@ -39,52 +39,30 @@ public ClientServerEventService(final JsonRpcRequestTransmitter transmitter,
this.dtoFactory = dtoFactory;

Log.info(getClass(), "Adding file event listener");
eventBus.addHandler(FileEvent.TYPE, new FileEvent.FileEventHandler() {
eventBus.addHandler(FileTrackingEvent.TYPE, new FileTrackingEvent.FileTrackingEventHandler() {
@Override
public void onFileOperation(FileEvent event) {
final String path = event.getFile().getLocation().toString();
public void onEvent(FileTrackingEvent event) {
final FileTrackingOperationDto.Type type = event.getType();
final String path = event.getPath();
final String oldPath = event.getOldPath();

switch (event.getOperationType()) {
case OPEN: {
transmitOpenFileNotification(path);

break;
}
case CLOSE: {
transmitCloseFileNotification(path);

break;
}
}
transmit(path, oldPath, type);
}
});


}

private void transmitCloseFileNotification(String path) {
Log.info(ClientServerEventService.class, "Sending file closed event: " + path);

final FileClosedDto dto = dtoFactory.createDto(FileClosedDto.class).withPath(path);
private void transmit(String path, String oldPath, FileTrackingOperationDto.Type type) {
final String params = dtoFactory.createDto(FileTrackingOperationDto.class)
.withPath(path)
.withType(type)
.withOldPath(oldPath)
.toString();

final JsonRpcRequest request = dtoFactory.createDto(JsonRpcRequest.class)
.withJsonrpc("2.0")
.withMethod("event:file-closed")
.withParams(dto.toString());
.withMethod("track:editor-file")
.withParams(params);

transmitter.transmit(request);
}

private void transmitOpenFileNotification(String path) {
Log.info(ClientServerEventService.class, "Sending file opened event: " + path);

final FileOpenedDto dto = dtoFactory.createDto(FileOpenedDto.class).withPath(path);

final JsonRpcRequest notification = dtoFactory.createDto(JsonRpcRequest.class)
.withJsonrpc("2.0")
.withMethod("event:file-opened")
.withParams(dto.toString());

transmitter.transmit(notification);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.api.event.ng;


import com.google.web.bindery.event.shared.EventBus;

import org.eclipse.che.api.core.jsonrpc.shared.JsonRpcRequest;
import org.eclipse.che.api.project.shared.dto.event.FileWatcherEventType;
import org.eclipse.che.api.project.shared.dto.event.VfsFileStatusUpdateDto;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.event.FileContentUpdateEvent;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.resources.ExternalResourceDelta;
import org.eclipse.che.ide.dto.DtoFactory;
import org.eclipse.che.ide.jsonrpc.JsonRpcRequestReceiver;
import org.eclipse.che.ide.resource.Path;
import org.eclipse.che.ide.util.loging.Log;

import javax.inject.Inject;
import javax.inject.Singleton;

import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.EMERGE_MODE;
import static org.eclipse.che.ide.api.notification.StatusNotification.Status.SUCCESS;
import static org.eclipse.che.ide.api.resources.ResourceDelta.REMOVED;

/**
* @author Dmitry Kuleshov
*/
@Singleton
public class EditorFileStatusNotificationReceiver implements JsonRpcRequestReceiver {
private final DtoFactory dtoFactory;
private final EventBus eventBus;
private final AppContext appContext;

private NotificationManager notificationManager;

@Inject
public EditorFileStatusNotificationReceiver(DtoFactory dtoFactory,
EventBus eventBus,
AppContext appContext) {
this.dtoFactory = dtoFactory;
this.eventBus = eventBus;
this.appContext = appContext;

}

public void inject(NotificationManager notificationManager) {
this.notificationManager = notificationManager;
}

@Override
public void receive(JsonRpcRequest request) {
final String params = request.getParams();
final VfsFileStatusUpdateDto vfsFileStatusUpdateDto = dtoFactory.createDtoFromJson(params, VfsFileStatusUpdateDto.class);

final FileWatcherEventType status = vfsFileStatusUpdateDto.getType();
final String path = vfsFileStatusUpdateDto.getPath();
final String name = path.substring(path.lastIndexOf("/") + 1);

switch (status) {
case MODIFIED: {
Log.info(getClass(), "Received updated file event status: " + path);

eventBus.fireEvent(new FileContentUpdateEvent(path, vfsFileStatusUpdateDto.getHashCode()));

break;
}
case DELETED: {

Log.info(getClass(), "Received removed file event status: " + path);

appContext.getWorkspaceRoot().synchronize(new ExternalResourceDelta(Path.valueOf(path), Path.valueOf(path), REMOVED));
if (notificationManager != null) {
notificationManager.notify("External operation", "File '" + name + "' is removed", SUCCESS, EMERGE_MODE);
}


break;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.api.event.ng;

import com.google.inject.Provider;
import com.google.web.bindery.event.shared.EventBus;

import org.eclipse.che.ide.api.editor.EditorAgent;
import org.eclipse.che.ide.api.editor.EditorPartPresenter;
import org.eclipse.che.ide.api.event.FileEvent;
import org.eclipse.che.ide.resource.Path;
import org.eclipse.che.ide.util.loging.Log;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.List;
import java.util.Objects;

import static org.eclipse.che.api.project.shared.dto.event.FileTrackingOperationDto.Type.START;
import static org.eclipse.che.api.project.shared.dto.event.FileTrackingOperationDto.Type.STOP;

/**
* @author Dmitry Kuleshov
*/
@Singleton
public class FileOpenCloseEventListener {

@Inject
public FileOpenCloseEventListener(final Provider<EditorAgent> editorAgentProvider,
final EventBus eventBus) {

Log.info(getClass(), "Adding file event listener");
eventBus.addHandler(FileEvent.TYPE, new FileEvent.FileEventHandler() {
@Override
public void onFileOperation(FileEvent event) {
final Path path = event.getFile().getLocation();

switch (event.getOperationType()) {
case OPEN: {
processFileOpen(path);

break;
}
case CLOSE: {
final EditorPartPresenter closingEditor = event.getEditorTab().getRelativeEditorPart();
final List<EditorPartPresenter> openedEditors = editorAgentProvider.get().getOpenedEditors();

processFileClose(closingEditor, openedEditors, path);

break;
}
}
}

private void processFileOpen(Path path) {
eventBus.fireEvent(new FileTrackingEvent(path.toString(), null, START));
}

private void processFileClose(EditorPartPresenter closingEditor, List<EditorPartPresenter> openedEditors, Path path) {
for (final EditorPartPresenter editor : openedEditors) {
final Path editorFilePath = editor.getEditorInput().getFile().getLocation();
if (Objects.equals(path, editorFilePath) && closingEditor != editor) {
return;
}
}

eventBus.fireEvent(new FileTrackingEvent(path.toString(), null, STOP));
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.api.event.ng;

import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;

import org.eclipse.che.api.project.shared.dto.event.FileTrackingOperationDto;

/**
* @author Dmitry Kuleshov
*/
public class FileTrackingEvent extends GwtEvent<FileTrackingEvent.FileTrackingEventHandler> {

public static Type<FileTrackingEventHandler> TYPE = new Type<>();

private final String path;

private final String oldPath;

private final FileTrackingOperationDto.Type type;

public FileTrackingEvent(String path, String oldPath, FileTrackingOperationDto.Type type) {
this.path = path;
this.oldPath = oldPath;
this.type = type;
}

public String getOldPath() {
return oldPath;
}

public FileTrackingOperationDto.Type getType() {
return type;
}

public String getPath() {
return path;
}

@Override
public Type<FileTrackingEventHandler> getAssociatedType() {
return TYPE;
}

@Override
protected void dispatch(FileTrackingEventHandler handler) {
handler.onEvent(this);
}

public interface FileTrackingEventHandler extends EventHandler {
void onEvent(FileTrackingEvent event);
}
}
Loading