package org.codefaces.ui.internal.commons;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import org.codefaces.core.models.RepoResource;
import org.codefaces.core.models.RepoWorkspace;
import org.codefaces.ui.internal.CodeFacesUIActivator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.rwt.lifecycle.UICallBack;
import org.eclipse.swt.widgets.Display;
class RepoResourceContentProviderManager {
private final TreeViewer viewer;
private Display display;
private Map<Object, Object> loadedResources = new ConcurrentHashMap<Object, Object>();
private BlockingQueue<RepoResource> waitingQueue = new LinkedBlockingQueue<RepoResource>();
private Thread loadingThread;
private class RepoResourceLoadingRunnable implements Runnable {
private void loadResource(final RepoResource resource) {
// running get children in session;
UICallBack.runNonUIThreadWithFakeContext(display, new Runnable() {
@Override
public void run() {
resource.getChildren();
loadedResources.put(resource, resource);
}
});
display.asyncExec(new Runnable() {
@Override
public void run() {
if (!viewer.getControl().isDisposed()) {
viewer.refresh(resource, true);
}
}
});
display.asyncExec(new Runnable() {
@Override
public void run() {
UICallBack.deactivate(String.valueOf(resource.hashCode()));
}
});
// Make sure that all events in the asynchronous event queue
// are dispatched.
display.syncExec(new Runnable() {
public void run() {
// do nothing
}
});
}
@Override
public void run() {
RepoResource resource = null;
try {
while ((resource = waitingQueue.take()) != null) {
loadResource(resource);
}
} catch (InterruptedException e) {
// do nothing
}
}
}
public RepoResourceContentProviderManager(TreeViewer treeView) {
this.viewer = treeView;
display = viewer.getControl().getDisplay();
loadingThread = new Thread(new RepoResourceLoadingRunnable());
loadingThread.setDaemon(true);
loadingThread.start();
}
public void dispose() {
loadingThread.interrupt();
loadingThread = null;
}
public boolean hasChildren(Object parent) {
if (parent instanceof RepoResource) {
return ((RepoResource) parent).hasChildren();
}
return false;
}
public Object[] getChildren(Object parent) {
if (parent instanceof RepoWorkspace) {
return getChildrenForWorkspace((RepoWorkspace) parent);
}
if (parent instanceof RepoResource) {
return getChildrenForResource((RepoResource) parent);
}
return new Object[0];
}
private Object[] getChildrenForWorkspace(RepoWorkspace workspace) {
return workspace.getProjects().toArray();
}
private Object[] getChildrenForResource(RepoResource resource) {
if (!loadedResources.containsKey(resource)) {
try {
UICallBack.activate(String.valueOf(resource.hashCode()));
waitingQueue.put(resource);
} catch (InterruptedException e) {
IStatus status = new Status(Status.ERROR,
CodeFacesUIActivator.PLUGIN_ID,
"Errors occurs when loading resource "
+ resource.getPath().toString(), e);
CodeFacesUIActivator.getDefault().getLog().log(status);
}
return new Object[] { new LoadingItem() };
}
return resource.getChildren().toArray();
}
}