use of org.eclipse.core.runtime.OperationCanceledException in project eclipse.platform.text by eclipse.
the class FileBufferOperationAction method doRun.
protected final void doRun(final IFile[] files, final IPath location, final IFileBufferOperation fileBufferOperation) {
Job job = new Job(fileBufferOperation.getOperationName()) {
@Override
protected IStatus run(IProgressMonitor monitor) {
IStatus status;
try {
int ticks = 100;
SubMonitor subMonitor = SubMonitor.convert(monitor, fFileBufferOperation.getOperationName(), ticks);
IPath[] locations;
if (files != null) {
ticks -= 30;
locations = generateLocations(files, subMonitor.split(30));
} else
locations = new IPath[] { location };
if (locations != null && locations.length > 0) {
FileBufferOperationRunner runner = new FileBufferOperationRunner(FileBuffers.getTextFileBufferManager(), getShell());
runner.execute(locations, fileBufferOperation, subMonitor.split(ticks));
}
status = Status.OK_STATUS;
} catch (OperationCanceledException e) {
// $NON-NLS-1$
status = new Status(IStatus.CANCEL, EditorsUI.PLUGIN_ID, IStatus.OK, "", null);
} catch (CoreException e) {
// $NON-NLS-1$
status = new Status(IStatus.ERROR, EditorsUI.PLUGIN_ID, IStatus.OK, "", e);
}
return status;
}
};
job.setUser(true);
job.schedule();
}
use of org.eclipse.core.runtime.OperationCanceledException in project eclipse.platform.text by eclipse.
the class FindInWorkingSetActionDelegate method createQuery.
@Override
protected ISearchQuery createQuery(TextSearchQueryProvider provider, String searchForString) throws CoreException {
IWorkbenchPage page = getWorkbenchPage();
if (page != null) {
IWorkingSetManager manager = PlatformUI.getWorkbench().getWorkingSetManager();
IWorkingSetSelectionDialog dialog = manager.createWorkingSetSelectionDialog(page.getWorkbenchWindow().getShell(), true);
if (dialog.open() == Window.OK) {
IWorkingSet[] workingSets = dialog.getSelection();
if (workingSets != null) {
return provider.createQuery(searchForString, workingSets);
}
}
}
throw new OperationCanceledException();
}
use of org.eclipse.core.runtime.OperationCanceledException in project eclipse.platform.text by eclipse.
the class RetrieverAction method run.
@Override
public void run() {
IWorkbenchPage page = getWorkbenchPage();
if (page == null) {
return;
}
TextSearchQueryProvider provider = TextSearchQueryProvider.getPreferred();
String searchForString = getSearchForString(page);
if (searchForString.length() == 0) {
MessageDialog.openInformation(getShell(), SearchMessages.RetrieverAction_dialog_title, SearchMessages.RetrieverAction_empty_selection);
return;
}
try {
ISearchQuery query = createQuery(provider, searchForString);
if (query != null) {
NewSearchUI.runQueryInBackground(query);
}
} catch (OperationCanceledException ex) {
// action cancelled
} catch (CoreException e) {
ErrorDialog.openError(getShell(), SearchMessages.RetrieverAction_error_title, SearchMessages.RetrieverAction_error_message, e.getStatus());
}
}
use of org.eclipse.core.runtime.OperationCanceledException in project eclipse.platform.text by eclipse.
the class TextSearchVisitor method search.
public IStatus search(IFile[] files, IProgressMonitor monitor) {
if (files.length == 0) {
return fStatus;
}
fProgressMonitor = monitor == null ? new NullProgressMonitor() : monitor;
fNumberOfScannedFiles = 0;
fNumberOfFilesToScan = files.length;
fCurrentFile = null;
int maxThreads = fCollector.canRunInParallel() ? NUMBER_OF_LOGICAL_THREADS : 1;
int jobCount = 1;
if (maxThreads > 1) {
jobCount = (files.length + FILES_PER_JOB - 1) / FILES_PER_JOB;
}
// $NON-NLS-1$
final JobGroup jobGroup = new TextSearchJobGroup("Text Search", maxThreads, jobCount);
long startTime = TRACING ? System.currentTimeMillis() : 0;
Job monitorUpdateJob = new Job(SearchMessages.TextSearchVisitor_progress_updating_job) {
private int fLastNumberOfScannedFiles = 0;
@Override
public IStatus run(IProgressMonitor inner) {
while (!inner.isCanceled()) {
// Propagate user cancellation to the JobGroup.
if (fProgressMonitor.isCanceled()) {
jobGroup.cancel();
break;
}
IFile file;
int numberOfScannedFiles;
synchronized (fLock) {
file = fCurrentFile;
numberOfScannedFiles = fNumberOfScannedFiles;
}
if (file != null) {
String fileName = file.getName();
Object[] args = { fileName, Integer.valueOf(numberOfScannedFiles), Integer.valueOf(fNumberOfFilesToScan) };
fProgressMonitor.subTask(Messages.format(SearchMessages.TextSearchVisitor_scanning, args));
int steps = numberOfScannedFiles - fLastNumberOfScannedFiles;
fProgressMonitor.worked(steps);
fLastNumberOfScannedFiles += steps;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return Status.OK_STATUS;
}
}
return Status.OK_STATUS;
}
};
try {
String taskName = fSearchPattern.pattern().length() == 0 ? SearchMessages.TextSearchVisitor_filesearch_task_label : Messages.format(SearchMessages.TextSearchVisitor_textsearch_task_label, fSearchPattern.pattern());
fProgressMonitor.beginTask(taskName, fNumberOfFilesToScan);
monitorUpdateJob.setSystem(true);
monitorUpdateJob.schedule();
try {
fCollector.beginReporting();
Map<IFile, IDocument> documentsInEditors = PlatformUI.isWorkbenchRunning() ? evalNonFileBufferDocuments() : Collections.emptyMap();
int filesPerJob = (files.length + jobCount - 1) / jobCount;
IFile[] filesByLocation = new IFile[files.length];
System.arraycopy(files, 0, filesByLocation, 0, files.length);
// Sorting files to search by location allows to more easily reuse
// search results from one file to the other when they have same location
Arrays.sort(filesByLocation, (o1, o2) -> {
if (o1 == o2) {
return 0;
}
if (o1.getLocation() == o2.getLocation()) {
return 0;
}
if (o1.getLocation() == null) {
return +1;
}
if (o2.getLocation() == null) {
return -1;
}
return o1.getLocation().toString().compareTo(o2.getLocation().toString());
});
for (int first = 0; first < filesByLocation.length; first += filesPerJob) {
int end = Math.min(filesByLocation.length, first + filesPerJob);
Job job = new TextSearchJob(filesByLocation, first, end, documentsInEditors);
job.setJobGroup(jobGroup);
job.schedule();
}
// The monitorUpdateJob is managing progress and cancellation,
// so it is ok to pass a null monitor into the job group.
jobGroup.join(0, null);
if (fProgressMonitor.isCanceled())
throw new OperationCanceledException(SearchMessages.TextSearchVisitor_canceled);
fStatus.addAll(jobGroup.getResult());
return fStatus;
} catch (InterruptedException e) {
throw new OperationCanceledException(SearchMessages.TextSearchVisitor_canceled);
} finally {
monitorUpdateJob.cancel();
}
} finally {
fProgressMonitor.done();
fCollector.endReporting();
if (TRACING) {
Object[] args = { Integer.valueOf(fNumberOfScannedFiles), Integer.valueOf(jobCount), Integer.valueOf(NUMBER_OF_LOGICAL_THREADS), Long.valueOf(System.currentTimeMillis() - startTime) };
System.out.println(Messages.format("[TextSearch] Search duration for {0} files in {1} jobs using {2} threads: {3}ms", // $NON-NLS-1$
args));
}
}
}
use of org.eclipse.core.runtime.OperationCanceledException in project eclipse.platform.text by eclipse.
the class DocumentLineDiffer method initialize.
/**
* (Re-)initializes the differ using the current reference and <code>DiffInitializer</code>.
*
* @since 3.2 protected for testing reasons, package visible before
*/
protected synchronized void initialize() {
// make new incoming changes go into the queue of stored events, plus signal we can't restore.
fState = INITIALIZING;
if (fRightDocument == null)
return;
// there is no point in receiving updates before the job we get a new copy of the document for diffing
fIgnoreDocumentEvents = true;
if (fLeftDocument != null) {
fLeftDocument.removeDocumentListener(this);
fLeftDocument = null;
fLeftEquivalent = null;
}
// if there already is a job:
// return if it has not started yet, cancel it if already running
final Job oldJob = fInitializationJob;
if (oldJob != null) {
// don't chain up jobs if there is one waiting already.
if (oldJob.getState() == Job.WAITING) {
oldJob.wakeUp(INITIALIZE_DELAY);
return;
}
oldJob.cancel();
}
fInitializationJob = new Job(QuickDiffMessages.quickdiff_initialize) {
/*
* This is run in a different thread. As the documents might be synchronized, never ever
* access the documents in a synchronized section or expect deadlocks. See
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=44692
*/
@Override
public IStatus run(IProgressMonitor monitor) {
// It will return relatively quickly as RangeDifferencer supports canceling
if (oldJob != null)
try {
oldJob.join();
} catch (InterruptedException e) {
// will not happen as no one interrupts our thread
Assert.isTrue(false);
}
// 2: get the reference document
IQuickDiffReferenceProvider provider = fReferenceProvider;
final IDocument left;
try {
left = provider == null ? null : provider.getReference(monitor);
} catch (CoreException e) {
synchronized (DocumentLineDiffer.this) {
if (isCanceled(monitor))
return Status.CANCEL_STATUS;
clearModel();
fireModelChanged();
return e.getStatus();
}
} catch (OperationCanceledException e) {
return Status.CANCEL_STATUS;
}
// Getting our own copies of the documents for offline diffing.
//
// We need to make sure that we do get all document modifications after
// copying the documents as we want to re-inject them later on to become consistent.
// fRightDocument, but not subject to change
IDocument right = fRightDocument;
// the copy of the actual (right) document
IDocument actual = null;
// the copy of the reference (left) document
IDocument reference = null;
synchronized (DocumentLineDiffer.this) {
// 4: take an early exit if the documents are not valid
if (left == null || right == null) {
if (isCanceled(monitor))
return Status.CANCEL_STATUS;
clearModel();
fireModelChanged();
return Status.OK_STATUS;
}
// set the reference document
fLeftDocument = left;
// start listening to document events.
fIgnoreDocumentEvents = false;
}
// accessing the reference document from a different thread - reference providers need
// to be able to deal with this.
left.addDocumentListener(DocumentLineDiffer.this);
// create the reference copy - note that any changes on the
// reference will trigger re-initialization anyway
reference = createCopy(left);
if (reference == null)
return Status.CANCEL_STATUS;
// create the actual copy
Object lock = null;
if (right instanceof ISynchronizable)
lock = ((ISynchronizable) right).getLockObject();
if (lock != null) {
// the document
synchronized (lock) {
synchronized (DocumentLineDiffer.this) {
if (isCanceled(monitor))
return Status.CANCEL_STATUS;
fStoredEvents.clear();
actual = createUnprotectedCopy(right);
}
}
} else {
// b) cannot lock the document
// Now this is fun. The reference documents may be PartiallySynchronizedDocuments
// which will result in a deadlock if they get changed externally before we get
// our exclusive copies.
// Here's what we do: we try over and over (without synchronization) to get copies
// without interleaving modification. If there is a document change, we just repeat.
int i = 0;
do {
// this is an arbitrary emergency exit in case a referenced document goes nuts
if (i++ == 100)
return new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.OK, NLSUtility.format(QuickDiffMessages.quickdiff_error_getting_document_content, new Object[] { left.getClass(), right.getClass() }), null);
synchronized (DocumentLineDiffer.this) {
if (isCanceled(monitor))
return Status.CANCEL_STATUS;
fStoredEvents.clear();
}
// access documents non synchronized:
// get an exclusive copy of the actual document
actual = createCopy(right);
synchronized (DocumentLineDiffer.this) {
if (isCanceled(monitor))
return Status.CANCEL_STATUS;
if (fStoredEvents.size() == 0 && actual != null)
break;
}
} while (true);
}
IHashFunction hash = new DJBHashFunction();
DocumentEquivalenceClass leftEquivalent = new DocumentEquivalenceClass(reference, hash);
fLeftEquivalent = leftEquivalent;
IRangeComparator ref = new DocEquivalenceComparator(leftEquivalent, null);
DocumentEquivalenceClass rightEquivalent = new DocumentEquivalenceClass(actual, hash);
fRightEquivalent = rightEquivalent;
IRangeComparator act = new DocEquivalenceComparator(rightEquivalent, null);
ArrayList<QuickDiffRangeDifference> diffs = asQuickDiffRangeDifference(RangeDifferencer.findRanges(fRangeDiffFactory, monitor, ref, act));
// re-inject stored events to get up to date.
synchronized (DocumentLineDiffer.this) {
if (isCanceled(monitor))
return Status.CANCEL_STATUS;
// set the new differences so we can operate on them
fDifferences = diffs;
}
// re-inject events accumulated in the meantime.
try {
do {
DocumentEvent event;
synchronized (DocumentLineDiffer.this) {
if (isCanceled(monitor))
return Status.CANCEL_STATUS;
if (fStoredEvents.isEmpty()) {
// we are back in sync with the life documents
fInitializationJob = null;
fState = SYNCHRONIZED;
fLastDifference = null;
// replace the private documents with the actual
leftEquivalent.setDocument(left);
rightEquivalent.setDocument(right);
break;
}
event = fStoredEvents.remove(0);
}
// access documents non synchronized:
IDocument copy = null;
if (event.fDocument == right)
copy = actual;
else if (event.fDocument == left)
copy = reference;
else
Assert.isTrue(false);
// copy the event to inject it into our diff copies
// don't modify the original event! See https://bugs.eclipse.org/bugs/show_bug.cgi?id=134227
event = new DocumentEvent(copy, event.fOffset, event.fLength, event.fText);
handleAboutToBeChanged(event);
// inject the event into our private copy
actual.replace(event.fOffset, event.fLength, event.fText);
handleChanged(event);
} while (true);
} catch (BadLocationException e) {
left.removeDocumentListener(DocumentLineDiffer.this);
clearModel();
initialize();
return Status.CANCEL_STATUS;
}
fireModelChanged();
return Status.OK_STATUS;
}
private boolean isCanceled(IProgressMonitor monitor) {
return fInitializationJob != this || monitor != null && monitor.isCanceled();
}
private void clearModel() {
synchronized (DocumentLineDiffer.this) {
fLeftDocument = null;
fLeftEquivalent = null;
fInitializationJob = null;
fStoredEvents.clear();
fLastDifference = null;
fDifferences.clear();
}
}
/**
* Creates a copy of <code>document</code> and catches any
* exceptions that may occur if the document is modified concurrently.
* Only call this method in a synchronized block if the document is
* an ISynchronizable and has been locked, as document.get() is called
* and may result in a deadlock otherwise.
*
* @param document the document to create a copy of
* @return a copy of the document, or <code>null</code> if an exception was thrown
*/
private IDocument createCopy(IDocument document) {
Assert.isNotNull(document);
// this fixes https://bugs.eclipse.org/bugs/show_bug.cgi?id=56091
try {
return createUnprotectedCopy(document);
} catch (NullPointerException e) {
} catch (ArrayStoreException e) {
} catch (IndexOutOfBoundsException e) {
} catch (ConcurrentModificationException e) {
} catch (NegativeArraySizeException e) {
}
return null;
}
private IDocument createUnprotectedCopy(IDocument document) {
return new Document(document.get());
}
};
fInitializationJob.setSystem(true);
fInitializationJob.setPriority(Job.DECORATE);
fInitializationJob.setProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, Boolean.TRUE);
fInitializationJob.schedule(INITIALIZE_DELAY);
}
Aggregations