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; | |
} | |
} | |
} |