blob: 3aaa89a57f5538225c58492bf0028101880bf61c [file] [log] [blame]
package org.eclipse.platform.discovery.compatibility.internal.container;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.platform.discovery.util.api.longop.ILongOperation;
import org.eclipse.platform.discovery.util.api.longop.ILongOperationRunner;
import org.eclipse.platform.discovery.util.api.longop.LongOpCanceledException;
import org.eclipse.platform.discovery.util.internal.longop.CurrentThreadOperationRunner;
import org.eclipse.platform.discovery.util.internal.longop.ModalContextLongOpRunner;
public class OperationRunnerToRunnableContextAdapter implements IRunnableContext {
private static final ISchedulingRule rule = new MutexSchedRule();
private IProgressMonitor monitor;
public OperationRunnerToRunnableContextAdapter(IProgressMonitor monitor) {
this.monitor = monitor;
}
@Override
public void run(boolean fork, boolean cancelable, final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
try {
ILongOperationRunner runner = fork ? new ModalContextLongOpRunner(monitor, rule) : new CurrentThreadOperationRunner(monitor);
runner.run(new ILongOperation<Void>() {
@Override
public Void run(IProgressMonitor monitor) throws LongOpCanceledException, Exception {
try{
runnable.run(monitor);
return null;
}catch(InterruptedException ex) {
throw new LongOpCanceledException(ex);
}
}
});
} catch (LongOpCanceledException e) {
throw (InterruptedException)e.getCause();
} catch(InvocationTargetException ex) {
//We need to handle these
//See modalcontext implementation
OperationCanceledException cancelledEx = extractOpCancelled(ex);
if(cancelledEx!=null) {
throw new InterruptedException();
}
throw ex;
}catch(OperationCanceledException ex) {
throw new InterruptedException();
}
}
private OperationCanceledException extractOpCancelled(Throwable ex) {
Throwable cause = ex.getCause();
if(cause==null) {
return null;
}
if(cause instanceof OperationCanceledException) {
return (OperationCanceledException) cause;
}
return extractOpCancelled(cause);
}
private static class MutexSchedRule implements ISchedulingRule {
@Override
public boolean contains(ISchedulingRule rule) {
return rule==this;
}
@Override
public boolean isConflicting(ISchedulingRule rule) {
return rule==this;
}
}
}