Add resource change listener (WIP)

This commit is contained in:
MrLetsplay 2024-06-22 22:30:30 +02:00
parent 08bcf39865
commit a1f5c9bc60
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
2 changed files with 81 additions and 3 deletions

View File

@ -12,9 +12,12 @@ import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.ResourcesPlugin;
@ -37,7 +40,6 @@ import me.mrletsplay.shareclient.util.listeners.ShareClientPageListener;
import me.mrletsplay.shareclient.util.listeners.ShareClientPartListener; import me.mrletsplay.shareclient.util.listeners.ShareClientPartListener;
import me.mrletsplay.shareclient.util.listeners.ShareClientWindowListener; import me.mrletsplay.shareclient.util.listeners.ShareClientWindowListener;
import me.mrletsplay.shareclient.views.ShareView; import me.mrletsplay.shareclient.views.ShareView;
import me.mrletsplay.shareclientcore.connection.Change;
import me.mrletsplay.shareclientcore.connection.ConnectionException; import me.mrletsplay.shareclientcore.connection.ConnectionException;
import me.mrletsplay.shareclientcore.connection.DisconnectListener; import me.mrletsplay.shareclientcore.connection.DisconnectListener;
import me.mrletsplay.shareclientcore.connection.MessageListener; import me.mrletsplay.shareclientcore.connection.MessageListener;
@ -92,6 +94,65 @@ public class ShareClient extends AbstractUIPlugin implements MessageListener, Di
Arrays.stream(p.getEditorReferences()).forEach(e -> partListener.addDocumentListener(e)); Arrays.stream(p.getEditorReferences()).forEach(e -> partListener.addDocumentListener(e));
}); });
}); });
ResourcesPlugin.getWorkspace().addResourceChangeListener(event -> handleChange(event.getDelta()), IResourceChangeEvent.POST_CHANGE);
// TODO: handle PRE_CLOSE events?
}
private void handleChange(IResourceDelta delta) {
ShareSession session = ShareClient.getDefault().getActiveSession();
if(session == null) return;
IResource resource = delta.getResource();
SharedProject project = session.getSharedProject(resource.getProject());
if(project != null) {
switch(delta.getKind()) {
case IResourceDelta.ADDED -> {
if(resource instanceof IFile file) {
if(file.isDerived()) return;
Path filePath = file.getFullPath().toPath();
ProjectAndPath path = getProjectAndPath(file);
ProjectRelativePath relativePath = new ProjectRelativePath(project.getRemoteName(), path.path());
SharedDocument document = session.getSharedDocument(relativePath);
if(document != null) {
// Shouldn't be the case
System.err.println("Resource was created but is already shared");
session.removeSharedDocument(relativePath); // Remove the existing shared document
}
try {
document = session.createSharedDocument(relativePath, Files.readAllBytes(filePath));
sendFullSyncOrChecksum(session.getConnection(), AddressableMessage.BROADCAST_SITE_ID, relativePath, filePath, false);
} catch (IOException e) {
e.printStackTrace();
MessageDialog.openError(null, "Share Client", "Failed to update file: " + e.toString());
return;
}
}
System.out.println("ADDED " + delta.getResource() + " | Derived: " + delta.getResource().isDerived());
}
case IResourceDelta.REMOVED -> {
if(resource instanceof IFile file) {
if(file.isDerived()) return;
ProjectAndPath path = getProjectAndPath(file);
ProjectRelativePath relativePath = new ProjectRelativePath(project.getRemoteName(), path.path());
session.removeSharedDocument(relativePath);
// TODO: send delete message
}
System.out.println("REMOVED " + delta.getResource() + " | Derived: " + delta.getResource().isDerived());
}
case IResourceDelta.CHANGED -> /* TODO: check for (external) file changes? */ System.out.println("CHANGED " + delta.getResource() + " | Derived: " + delta.getResource().isDerived());
}
}
for(IResourceDelta child : delta.getAffectedChildren()) {
handleChange(child);
}
} }
@Override @Override
@ -289,10 +350,9 @@ public class ShareClient extends AbstractUIPlugin implements MessageListener, Di
} }
if(message instanceof ChangeMessage change) { if(message instanceof ChangeMessage change) {
Change c = change.change();
ProjectRelativePath path; ProjectRelativePath path;
try { try {
path = ProjectRelativePath.of(c.documentPath()); path = ProjectRelativePath.of(change.documentPath());
}catch(IllegalArgumentException e) { }catch(IllegalArgumentException e) {
return; return;
} }
@ -373,6 +433,12 @@ public class ShareClient extends AbstractUIPlugin implements MessageListener, Di
return filePath; return filePath;
} }
private ProjectAndPath getProjectAndPath(IFile file) {
IProject project = file.getProject();
Path projectLocation = project.getLocation().toPath();
return new ProjectAndPath(file.getProject(), projectLocation.relativize(file.getFullPath().toPath()).toString());
}
private Map<ProjectRelativePath, Path> getProjectFiles(SharedProject project) { private Map<ProjectRelativePath, Path> getProjectFiles(SharedProject project) {
try { try {
Path projectLocation = project.getLocal().getLocation().toPath(); Path projectLocation = project.getLocal().getLocation().toPath();

View File

@ -81,6 +81,18 @@ public class ShareSession {
return sharedDocuments.get(path); return sharedDocuments.get(path);
} }
public SharedDocument createSharedDocument(ProjectRelativePath path, byte[] initialContents) {
if(sharedDocuments.containsKey(path)) return null;
SharedDocument document = new SharedDocument(connection, path.toString());
sharedDocuments.put(path, document);
return document;
}
public void removeSharedDocument(ProjectRelativePath path) {
sharedDocuments.remove(path);
}
public SharedDocument getOrCreateSharedDocument(ProjectRelativePath path, Supplier<byte[]> initialContents) { public SharedDocument getOrCreateSharedDocument(ProjectRelativePath path, Supplier<byte[]> initialContents) {
return sharedDocuments.computeIfAbsent(path, p -> { return sharedDocuments.computeIfAbsent(path, p -> {
SharedDocument doc = new SharedDocument(connection, path.toString(), initialContents == null ? null : initialContents.get()); SharedDocument doc = new SharedDocument(connection, path.toString(), initialContents == null ? null : initialContents.get());