package com.netifera.platform.host.filesystem.ui;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import com.netifera.platform.host.filesystem.File;
import com.netifera.platform.host.filesystem.IFileSystem;
import com.netifera.platform.host.filesystem.IFileSystemListener;
import com.netifera.platform.host.internal.filesystem.ui.Activator;
public class FileSystemContentProvider implements ITreeContentProvider {
private IFileSystem fileSystem;
private File[] roots;
private Map<String,File[]> cache;
private TreeViewer viewer;
private FileSystemView view;
private IFileSystemListener fileSystemListener = new IFileSystemListener() {
public void added(final File file) {
viewer.getControl().getDisplay().asyncExec(new Runnable() {
public void run() {
String parentPath = file.getParent().getAbsolutePath();
File[] siblings = cache.get(parentPath);
if (siblings != null) {
List<File> siblingsList = new ArrayList<File>(siblings.length+1);
for (File sibling: siblings) {
if (sibling.equals(file))
return;
siblingsList.add(sibling);
}
siblingsList.add(file);
cache.put(parentPath, siblingsList.toArray(new File[0]));
}/* else {
clear(file.getParent());
}*/
viewer.refresh(file.getParent(), false);
}
});
}
public void removed(final File file) {
viewer.getControl().getDisplay().asyncExec(new Runnable() {
public void run() {
clear(file);
String parentPath = file.getParent().getAbsolutePath();
File[] siblings = cache.get(parentPath);
if (siblings != null) {
List<File> siblingsList = new ArrayList<File>(siblings.length);
for (File sibling: siblings) {
if (!sibling.equals(file))
siblingsList.add(sibling);
}
cache.put(parentPath, siblingsList.toArray(new File[0]));
}/* else {
clear(file.getParent());
}*/
viewer.refresh(file.getParent(), false);
}
});
}
public void update(final File file) {
viewer.getControl().getDisplay().asyncExec(new Runnable() {
public void run() {
clear(file);
viewer.refresh(file, true);
}
});
}
};
public Object[] getChildren(final Object o) {
final String path = ((File)o).getAbsolutePath();
File[] children = cache.get(path);
if (children != null)
return children;
new Thread(new Runnable() {
public void run() {
try {
final File[] children = fileSystem.getDirectoryList(path);
viewer.getControl().getDisplay().syncExec(new Runnable() {
public void run() {
cache.put(path, children);
viewer.refresh(o, false);
}
});
} catch (Exception e) {
showException(e);
}
}
}).start();
return new String[] {"Loading..."};
}
public File getParent(Object o) {
if (o instanceof File)
return ((File)o).getParent();
return null;
}
public boolean hasChildren(Object o) {
if (o instanceof File)
return ((File)o).isDirectory();
return false;
}
public Object[] getElements(final Object input) {
if(input != fileSystem) {
throw new IllegalArgumentException();
}
if (roots.length != 1)
return roots.clone();
final File root = roots[0];
File[] elements = cache.get(root.getAbsolutePath());
if (elements != null)
return elements;
new Thread(new Runnable() {
public void run() {
try {
final File[] children = fileSystem.getDirectoryList(root.getAbsolutePath());
viewer.getControl().getDisplay().syncExec(new Runnable() {
public void run() {
if (fileSystem != input)
return;
cache.put(root.getAbsolutePath(), children);
viewer.refresh(true);
}
});
} catch (Exception e) {
showException(e);
}
}
}).start();
return new String[] {"Loading..."};
}
public void dispose() {
clear();
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
fileSystem = (IFileSystem) newInput;
// if (fileSystem == null) return;
roots = fileSystem.getRoots();
clear();
if(oldInput instanceof IFileSystem) {
((IFileSystem) oldInput).removeListener(fileSystemListener);
}
this.viewer = (TreeViewer) viewer;
fileSystem.addListener(fileSystemListener);
}
public void clear(File directory) {
cache.remove(directory.getAbsolutePath());
}
public void clear() {
cache = new HashMap<String,File[]>();
}
public void setView(FileSystemView view) {
this.view = view;
}
private void showException(Exception e) {
final String message = e.getMessage() != null ? e.getMessage() : e.toString();
if (view != null)
viewer.getControl().getDisplay().syncExec(new Runnable() {
public void run() {
if (view != null)
view.showMessage("Error: "+message);
else
Activator.getInstance().getBalloonManager().error(message);
}
});
else
Activator.getInstance().getBalloonManager().error(message);
}
}