Skip to content
This repository has been archived by the owner on Feb 21, 2019. It is now read-only.

Implement filesystem sync in Eclipse Flux #22

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5e7d7f9
Integrated the file-watcher project into the flux repo
fjodorver Jun 21, 2016
327b106
Imported the flux-watcher library into Flux Core
fjodorver Jun 21, 2016
bfc2135
Changed implementation
fjodorver Jun 21, 2016
7c91148
Check if a thread is already started or not
fjodorver Jun 21, 2016
8227524
Cleanup: obsolete methods
fjodorver Jun 21, 2016
85a6c74
Сonnection through flux-watcher library
fjodorver Jun 22, 2016
8b8b371
Fixed bug when the editor of eclipse cant do local update
fjodorver Aug 11, 2016
bbff9f1
Changed mechanism of building/sending/receiving messages for Metadata
fjodorver Aug 14, 2016
c6f5fec
Imported and integrated all tests from watcher library
fjodorver Aug 14, 2016
3b4ee6e
Refactored: Repository to RepositoryAdapter
fjodorver Aug 15, 2016
e0b82c0
Methon toJson was rewritten
fjodorver Aug 15, 2016
cbb159d
Refactored handlers
fjodorver Aug 15, 2016
8503e4b
Fixed move issue for linux
fjodorver Aug 16, 2016
18a6f34
Temporary fix for vim issue
fjodorver Aug 18, 2016
6cd3641
Refactored: Changed enum filelds to static final
fjodorver Aug 18, 2016
fff65a7
Implemented method hasResource and refactored ResourceDeleteHandler
fjodorver Aug 18, 2016
9b13648
Refactored listeners for watcher
fjodorver Aug 19, 2016
da92db4
Fixed updated on move from external directory
fjodorver Aug 19, 2016
8744abf
Changed mechanism of creating/receiving/sending messages for LiveEdit…
fjodorver Aug 19, 2016
0dc37f5
Cleanup code
fjodorver Aug 19, 2016
3558b3d
Adopted ConnectedProject for Flux Project
fjodorver Aug 20, 2016
04054a9
Set Java 7 for Watcher Library
fjodorver Aug 20, 2016
2bf1853
Commented INTERSECTION_CAST_TYPE visitor
fjodorver Aug 20, 2016
7f18a84
Added static fields in order to store message types
fjodorver Aug 21, 2016
5a47d5b
Added static fields in order to store message fields
fjodorver Aug 21, 2016
1d7a00b
Switched back to the old mechanism of sending/receiving messages
fjodorver Aug 21, 2016
f352ae7
Improved code: Add callback to the constructor of AbstractMsgHandler
fjodorver Aug 22, 2016
8a4e848
Added listeners for eclipse
fjodorver Aug 22, 2016
1134f62
Switched back to the old mechanism of sending/receiving messages[live…
fjodorver Aug 22, 2016
abd5ed8
Removed connection for the Flux File Watcher
fjodorver Aug 22, 2016
9eb3fa9
Flux File Watcher: Removed functional for sending/receiving messages …
fjodorver Aug 22, 2016
9a0df03
Improved code && used static fields for building messages
fjodorver Aug 23, 2016
1b01a23
Separated the logic of file system sync from RepositoryAdapter
fjodorver Aug 23, 2016
a029c73
Added to git: FluxSystemSync.java and resource listeners
fjodorver Aug 24, 2016
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
5 changes: 4 additions & 1 deletion node.server/repository-message-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,11 @@ MessagesRepository.prototype.resourceCreated = function(data) {
var hash = data.hash;
var type = data.type;

var repoProject = this.repository._getProjectStorage(username, projectName);
var repoResource = repoProject.resources[resource];

this.repository.hasResource(username, projectName, resource, function(err, resourceExists) {
if (err === null && !resourceExists) {
if (err === null && (!resourceExists || repoResource.hash !== hash)) {
this.socket.emit('getResourceRequest', {
'callback_id' : 0,
'username' : username,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,25 @@
*
*/
public interface IMessageHandler {
public static final String GET_PROJECT_REQUEST = "getProjectRequest";
public static final String GET_PROJECT_RESPONSE = "getProjectResponse";
public static final String GET_PROJECTS_REQUEST = "getProjectsRequest";
public static final String GET_PROJECTS_RESPONSE = "getProjectsResponse";
public static final String GET_LIVE_RESOURCE_REQUEST = "getLiveResourcesRequest";
public static final String GET_METADATA_REQUEST = "getMetadataRequest";
public static final String GET_METADATA_RESPONSE = "getMetadataResponse";
public static final String GET_RESOURCE_REQUEST = "getResourceRequest";
public static final String GET_RESOURCE_RESPONSE = "getResourceResponse";
public static final String LIVE_RESOURCE_STARTED = "liveResourceStarted";
public static final String LIVE_RESOURCE_STARTED_RESPONSE = "liveResourceStartedResponse";
public static final String LIVE_RESOURCE_CHANGED = "liveResourceChanged";
public static final String METADATA_CHANGED = "metadataChanged";
public static final String PROJECT_CONNECTED = "projectConnected";
public static final String PROJECT_DISCONNECTED = "projectDisconnected";
public static final String RESOURCE_CHANGED = "resourceChanged";
public static final String RESOURCE_CREATED = "resourceCreated";
public static final String RESOURCE_DELETED = "resourceDeleted";
public static final String RESOURCE_STORED = "resourceStored";

boolean canHandle(String type, JSONObject message);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,28 @@ public abstract class MessageConstants {
* Name of the Flux super user.
*/
public static final String SUPER_USER = "$super$";


public static final String CHANNEL = "channel";
public static final String CONNECTED_TO_CHANNEL = "connectedToChannel";
public static final String CONTENT = "content";
public static final String DELETED = "deleted";
public static final String FILES = "files";
public static final String HASH = "hash";
public static final String INCLUDE_DELETED = "includeDeleted";
public static final String PATH = "path";
public static final String RESOURCE = "resource";
public static final String TIMESTAMP = "timestamp";
public static final String TYPE = "type";
public static final String SAVE_POINT_HASH = "savePointHash";
public static final String SAVE_POINT_TIMESTAMP = "savePointTimestamp";
public static final String LIVE_CONTENT = "liveContent";
public static final String OFFSET = "offset";
public static final String REMOVED_CHAR_COUNT = "removedCharCount";
public static final String ADDED_CHARACTERS = "addedCharacters";
public static final String PROJECT_REG_EX = "projectRegEx";
public static final String RESOURCE_REG_EX = "resourceRegEx";
public static final String METADATA = "metadata";
public static final String PROJECTS = "projects";
public static final String NAME = "name";
public static final String MARKER = "marker";
}
4 changes: 3 additions & 1 deletion org.eclipse.flux.core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ Require-Bundle: org.eclipse.flux.client.java.osgi,
org.eclipse.core.runtime,
org.apache.commons.io,
org.eclipse.jdt.core,
org.eclipse.m2e.core;resolution:=optional
org.eclipse.m2e.core;resolution:=optional,
org.eclipse.flux.watcher;bundle-version="1.0.0",
com.google.inject;bundle-version="3.0.0"
Export-Package: org.eclipse.flux.core,
org.eclipse.flux.core.util
Bundle-ActivationPolicy: lazy; exclude:="io.socket, org.java_websocket, org.java_websocket.client, org.java_websocket.drafts, org.java_websocket.exceptions, org.java_websocket.framing, org.java_websocket.handshake, org.java_websocket.server, org.java_websocket.util, org.json"
Expand Down
21 changes: 11 additions & 10 deletions org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.flux.core;

import java.net.URL;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.Executors;
Expand All @@ -35,11 +36,15 @@
import org.eclipse.flux.client.MessageConstants;
import org.eclipse.flux.client.config.SocketIOFluxConfig;
import org.eclipse.flux.core.internal.CloudSyncMetadataListener;
import org.eclipse.flux.core.internal.CloudSyncResourceListener;
import org.eclipse.flux.core.util.ExceptionUtil;
import org.eclipse.flux.watcher.core.RepositoryModule;
import org.eclipse.flux.watcher.fs.JDKProjectModule;
import org.osgi.framework.BundleContext;
import org.osgi.service.prefs.BackingStoreException;

import com.google.inject.Guice;
import com.google.inject.Injector;

/**
* @author Martin Lippert
* @author Miles Parker
Expand All @@ -57,11 +62,10 @@ public class Activator extends Plugin {
private MessageConnector messageConnector;
private ChannelSwitcher channelSwitcher;

private Repository repository;
private RepositoryAdapter repository;
private LiveEditCoordinator liveEditCoordinator;
private boolean lazyStart = false;

private CloudSyncResourceListener resourceListener;
private CloudSyncMetadataListener metadataListener;
private IRepositoryListener repositoryListener;
private IResourceChangeListener workspaceListener;
Expand Down Expand Up @@ -109,6 +113,7 @@ public void start(BundleContext context) throws Exception {

final String userChannel = lazyStart ? MessageConstants.SUPER_USER : channel;

Injector injector = Guice.createInjector(new RepositoryModule(), new JDKProjectModule());
//Connecting to channel done asynchronously. To avoid blocking plugin state initialization.
FluxClient.DEFAULT_INSTANCE.getExecutor().execute(new Runnable() {
@Override
Expand Down Expand Up @@ -165,14 +170,11 @@ public void stop(BundleContext context) throws Exception {
}

private void initCoreService(String userChannel) throws CoreException {
repository = new Repository(messageConnector, userChannel);
repository = new RepositoryAdapter(messageConnector, userChannel);
liveEditCoordinator = new LiveEditCoordinator(messageConnector);

IWorkspace workspace = ResourcesPlugin.getWorkspace();

resourceListener = new CloudSyncResourceListener(repository);
workspace.addResourceChangeListener(resourceListener, IResourceChangeEvent.POST_CHANGE);

metadataListener = new CloudSyncMetadataListener(repository);
workspace.addResourceChangeListener(metadataListener, IResourceChangeEvent.POST_BUILD);

Expand Down Expand Up @@ -225,7 +227,6 @@ private void disposeCoreServices(String userChannel) {
if (userChannel.equals(repository.getUsername())) {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
workspace.removeResourceChangeListener(workspaceListener);
workspace.removeResourceChangeListener(resourceListener);
workspace.removeResourceChangeListener(metadataListener);
repository.removeRepositoryListener(repositoryListener);
liveEditCoordinator.dispose();
Expand All @@ -242,7 +243,7 @@ private void updateProjectConnections() throws CoreException {
if (!project.isOpen()) {
project.open(null);
}
Repository repository = org.eclipse.flux.core.Activator.getDefault()
RepositoryAdapter repository = org.eclipse.flux.core.Activator.getDefault()
.getRepository();
repository.addProject(project);
}
Expand Down Expand Up @@ -310,7 +311,7 @@ public MessageConnector getMessageConnector() {
return messageConnector;
}

public Repository getRepository() {
public RepositoryAdapter getRepository() {
return repository;
}

Expand Down
141 changes: 63 additions & 78 deletions org.eclipse.flux.core/src/org/eclipse/flux/core/ConnectedProject.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,93 +10,78 @@
*******************************************************************************/
package org.eclipse.flux.core;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.codec.digest.DigestUtils;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.flux.watcher.core.Resource;
import org.eclipse.flux.watcher.core.spi.Project;

/**
* @author Martin Lippert
*/
public class ConnectedProject {

private IProject project;
private Map<String, String> resourceHash;
private Map<String, Long> resourceTimestamp;

public ConnectedProject(IProject project) {
this.project = project;
this.resourceHash = new ConcurrentHashMap<String, String>();
this.resourceTimestamp = new ConcurrentHashMap<String, Long>();

try {
project.refreshLocal(IResource.DEPTH_INFINITE, null);
project.accept(new IResourceVisitor() {
@Override
public boolean visit(IResource resource) throws CoreException {
String path = resource.getProjectRelativePath().toString();
ConnectedProject.this.setTimestamp(path, resource.getLocalTimeStamp());

if (resource instanceof IFile) {
try {
IFile file = (IFile) resource;
ConnectedProject.this.setHash(path, DigestUtils.shaHex(file.getContents()));
} catch (IOException e) {
e.printStackTrace();
}
}
else if (resource instanceof IFolder) {
ConnectedProject.this.setHash(path, "0");
}

return true;
}
}, IResource.DEPTH_INFINITE, IContainer.EXCLUDE_DERIVED);
} catch (Exception e) {
e.printStackTrace();
}

}

public IProject getProject() {
return project;
}

public String getName() {
return this.project.getName();
}
private String name;
private Project project;

public ConnectedProject(Project project) {
this.project = project;
this.name = project.id();
}

public IProject getProject() {
return null;
}

public String getName() {
return this.project.id();
}

public static ConnectedProject readFromJSON(InputStream inputStream, IProject project) {
return null;
}

public long getTimestamp(String resourcePath) {
Resource resource = this.project.getResource(resourcePath);
return resource.timestamp();
}

public String getHash(String resourcePath) {
Resource resource = this.project.getResource(resourcePath);
return resource.hash();
}

public boolean containsResource(String resourcePath) {
return this.project.hasResource(resourcePath);
}

public static ConnectedProject readFromJSON(InputStream inputStream, IProject project) {
return new ConnectedProject(project);
}

public void setTimestamp(String resourcePath, long newTimestamp) {
this.resourceTimestamp.put(resourcePath, newTimestamp);
}

public long getTimestamp(String resourcePath) {
return this.resourceTimestamp.get(resourcePath);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}

public void setHash(String resourcePath, String hash) {
this.resourceHash.put(resourcePath, hash);
}

public String getHash(String resourcePath) {
return this.resourceHash.get(resourcePath);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ConnectedProject)) {
return false;
}
ConnectedProject other = (ConnectedProject)obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}

public boolean containsResource(String resourcePath) {
return this.resourceTimestamp.containsKey(resourcePath);
}

}
Loading