下面列出了org.eclipse.jface.text.codemining.ICodeMining#org.eclipse.xtext.util.concurrent.CancelableUnitOfWork 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Create content assist proposals at the given caret offset. This document read
* operation is scheduled with higher priority, so currently running operations
* may be canceled. The document processing is rescheduled as background work
* afterwards.
*/
public ContentAssistResult createProposals(XtextWebDocumentAccess document, ITextRegion selection, int caretOffset,
int proposalsLimit) throws InvalidRequestException {
String[] stateIdWrapper = new String[1];
ContentAssistContext[] contexts = document
.priorityReadOnly(new CancelableUnitOfWork<ContentAssistContext[], IXtextWebDocument>() {
@Override
public ContentAssistContext[] exec(IXtextWebDocument it, CancelIndicator cancelIndicator)
throws Exception {
stateIdWrapper[0] = it.getStateId();
return getContexts(it, selection, caretOffset);
}
});
List<ContentAssistContext> contextsList = Arrays.asList(contexts);
return createProposals(contextsList, stateIdWrapper[0], proposalsLimit);
}
/**
* Apply a text update and then create content assist proposals. This document
* read operation is scheduled with higher priority, so currently running
* operations may be canceled. The document processing is rescheduled as
* background work afterwards.
*/
public ContentAssistResult createProposalsWithUpdate(XtextWebDocumentAccess document, String deltaText,
int deltaOffset, int deltaReplaceLength, ITextRegion selection, int caretOffset, int proposalsLimit)
throws InvalidRequestException {
String[] stateIdWrapper = new String[1];
ContentAssistContext[] contexts = document
.modify(new CancelableUnitOfWork<ContentAssistContext[], IXtextWebDocument>() {
@Override
public ContentAssistContext[] exec(IXtextWebDocument it, CancelIndicator cancelIndicator)
throws Exception {
it.setDirty(true);
it.createNewStateId();
stateIdWrapper[0] = it.getStateId();
it.updateText(deltaText, deltaOffset, deltaReplaceLength);
return getContexts(it, selection, caretOffset);
}
});
List<ContentAssistContext> contextsList = Arrays.asList(contexts);
return createProposals(contextsList, stateIdWrapper[0], proposalsLimit);
}
/**
* Load the content of a document.
*/
public ResourceContentResult load(String resourceId, IServerResourceHandler resourceHandler,
IServiceContext serviceContext) throws InvalidRequestException {
XtextWebDocument document = serviceContext.getSession().get(Pair.of(XtextWebDocument.class, resourceId), () -> {
try {
return resourceHandler.get(resourceId, serviceContext);
} catch (IOException ioe) {
throw new InvalidRequestException.ResourceNotFoundException("The requested resource was not found.",
ioe);
}
});
return documentAccessFactory.create(document, false)
.readOnly(new CancelableUnitOfWork<ResourceContentResult, IXtextWebDocument>() {
@Override
public ResourceContentResult exec(IXtextWebDocument it, CancelIndicator cancelIndicator)
throws Exception {
return new ResourceContentResult(it.getText(), it.getStateId(), it.isDirty());
}
});
}
/**
* Save the content of a document.
*/
public DocumentStateResult save(XtextWebDocumentAccess document, IServerResourceHandler resourceHandler,
IServiceContext serviceContext) throws InvalidRequestException {
return document.readOnly(new CancelableUnitOfWork<DocumentStateResult, IXtextWebDocument>() {
@Override
public DocumentStateResult exec(IXtextWebDocument it, CancelIndicator cancelIndicator) throws Exception {
try {
resourceHandler.put(it, serviceContext);
it.setDirty(false);
} catch (IOException ioe) {
throw new InvalidRequestException.ResourceNotFoundException(ioe.getMessage(), ioe);
}
return new DocumentStateResult(it.getStateId());
}
});
}
public List<Issue> createIssues(final IProgressMonitor monitor) {
final List<Issue> issues = xtextDocument
.tryReadOnly(new CancelableUnitOfWork<List<Issue>, XtextResource>() {
@Override
public List<Issue> exec(XtextResource resource, final CancelIndicator outerIndicator) throws Exception {
if (resource.isValidationDisabled())
return Collections.emptyList();
return resourceValidator.validate(resource, getCheckMode(), new CancelIndicator() {
@Override
public boolean isCanceled() {
return outerIndicator.isCanceled() || monitor.isCanceled();
}
});
}
}, () -> Collections.emptyList());
return issues;
}
@Override
public CompletableFuture<List<? extends ICodeMining>> provideCodeMinings(ITextViewer viewer,
IProgressMonitor monitor) {
CompletableFuture<List<? extends ICodeMining>> future = CompletableFuture.supplyAsync(() -> {
CancelableUnitOfWork<List<ICodeMining>, XtextResource> uow = new CancelableUnitOfWork<List<ICodeMining>, XtextResource>() {
@Override
public List<ICodeMining> exec(XtextResource resource, CancelIndicator uowCancelIndicator) throws Exception {
CombinedCancelIndicator indicator = new CombinedCancelIndicator(monitor, uowCancelIndicator);
return createCodeMinings(viewer.getDocument(), resource, indicator);
}
};
return xtextDocumentUtil.getXtextDocument(viewer).tryReadOnly(uow, () -> Collections.emptyList());
});
return future;
}
public <R extends Object, P extends Resource> R exec(IUnitOfWork<R, P> work, P param) {
Boolean wasCancelationAllowed = cancelationAllowed.get();
try {
if (work instanceof CancelableUnitOfWork) {
((CancelableUnitOfWork<?, ?>) work)
.setCancelIndicator((param == null) ? () -> true : newCancelIndicator(param.getResourceSet()));
} else {
cancelationAllowed.set(false);
}
return work.exec(param);
} catch (Throwable e) {
return Exceptions.throwUncheckedException(e);
} finally {
cancelationAllowed.set(wasCancelationAllowed);
}
}
/**
* Find occurrences of the element at the given offset.
*/
public OccurrencesResult findOccurrences(XtextWebDocumentAccess document, int offset) {
return document.readOnly(new CancelableUnitOfWork<OccurrencesResult, IXtextWebDocument>() {
@Override
public OccurrencesResult exec(IXtextWebDocument doc, CancelIndicator cancelIndicator) throws Exception {
EObject element = elementAtOffsetUtil.getElementAt(doc.getResource(), offset);
OccurrencesResult occurrencesResult = new OccurrencesResult(doc.getStateId());
if (element != null && filter(element)) {
URI elementURI = EcoreUtil2.getPlatformResourceOrNormalizedURI(element);
TargetURIs targetURIs = targetURIsProvider.get();
targetURIs.addURI(elementURI);
IReferenceFinder.Acceptor acceptor = new IReferenceFinder.Acceptor() {
@Override
public void accept(EObject source, URI sourceURI, EReference eReference, int index,
EObject targetOrProxy, URI targetURI) {
ITextRegion region = locationInFileProvider.getSignificantTextRegion(source, eReference,
index);
occurrencesResult.getReadRegions()
.add(new TextRegion(region.getOffset(), region.getLength()));
}
@Override
public void accept(IReferenceDescription description) {
}
};
referenceFinder.findReferences(targetURIs, doc.getResource(), acceptor,
new CancelIndicatorProgressMonitor(cancelIndicator));
if (Objects.equal(element.eResource(), doc.getResource())) {
ITextRegion definitionRegion = locationInFileProvider.getSignificantTextRegion(element);
if (definitionRegion != null
&& definitionRegion != ITextRegionWithLineInformation.EMPTY_REGION) {
occurrencesResult.getWriteRegions()
.add(new TextRegion(definitionRegion.getOffset(), definitionRegion.getLength()));
}
}
}
return occurrencesResult;
}
});
}
/**
* Return the current state identifier. If the services registered in
* {@link PrecomputedServiceRegistry} are not cached yet, they are invoked in a
* background process.
*/
public DocumentStateResult getStateId(XtextWebDocumentAccess document) throws InvalidRequestException {
return document.modify(new CancelableUnitOfWork<DocumentStateResult, IXtextWebDocument>() {
@Override
public DocumentStateResult exec(IXtextWebDocument doc, CancelIndicator cancelIndicator) throws Exception {
return new DocumentStateResult(doc.getStateId());
}
});
}
protected <T extends IServiceResult> T getCachedServiceResult(AbstractCachedService<T> service,
boolean logCacheMiss) {
return readOnly(new CancelableUnitOfWork<T, IXtextWebDocument>() {
@Override
public T exec(IXtextWebDocument d, CancelIndicator cancelIndicator) throws Exception {
if (document.getResourceId() != null) {
return document.getCachedServiceResult(service, cancelIndicator, logCacheMiss);
} else {
return service.compute(document, cancelIndicator);
}
}
});
}
/**
* Compute a hover result at the given offset in the document.
*/
public HoverResult getHover(XtextWebDocumentAccess document, int offset) throws InvalidRequestException {
return document.readOnly(new CancelableUnitOfWork<HoverResult, IXtextWebDocument>() {
@Override
public HoverResult exec(IXtextWebDocument it, CancelIndicator cancelIndicator) throws Exception {
EObject element = elementAtOffsetUtil.getElementAt(it.getResource(), offset);
return createHover(element, it.getStateId(), cancelIndicator);
}
});
}
/**
* Compute a hover result for a content assist proposal at the given offset.
*/
public HoverResult getHover(XtextWebDocumentAccess document, String proposal, ITextRegion selection, int offset)
throws InvalidRequestException {
return document.readOnly(new CancelableUnitOfWork<HoverResult, IXtextWebDocument>() {
@Override
public HoverResult exec(IXtextWebDocument it, CancelIndicator cancelIndicator) throws Exception {
ContentAssistContext[] contexts = contentAssistService.getContexts(it, selection, offset);
Wrapper<Object> proposedElement = new Wrapper<Object>();
Collection<ContentAssistContext> contextsList = Arrays.asList(contexts);
contentAssistService.getProposalProvider().createProposals(contextsList,
new IIdeContentProposalAcceptor() {
@Override
public void accept(ContentAssistEntry entry, int priority) {
operationCanceledManager.checkCanceled(cancelIndicator);
if (entry != null && entry.getSource() != null
&& Objects.equal(entry.getProposal(), proposal)) {
proposedElement.set(entry.getSource());
}
}
@Override
public boolean canAcceptMoreProposals() {
return proposedElement.get() == null;
}
});
return createHover(proposedElement.get(), it.getStateId(), cancelIndicator);
}
});
}
@Test
public void testPriorityReadOnlyCancelsReaders() throws Exception {
Thread.interrupted(); // prevent random test failures: https://github.com/junit-team/junit4/issues/1365
XtextDocument document = new XtextDocument(createTokenSource(), null, outdatedStateManager, operationCanceledManager);
XtextResource resource = new XtextResource();
new XtextResourceSet().getResources().add(resource);
document.setInput(resource);
CountDownLatch check = new CountDownLatch(1);
Runnable runnable = new Runnable() {
@Override
public void run() {
document.readOnly(new CancelableUnitOfWork<Object, XtextResource>() {
@Override
public Object exec(XtextResource state, CancelIndicator cancelIndicator) throws Exception {
check.countDown();
int wait = 4000;
int i = 0;
while (!cancelIndicator.isCanceled()) {
Thread.sleep(10L);
if (i > wait) {
throw new InterruptedException();
}
i = i + 1;
}
return null;
}
});
}
};
Thread thread = new Thread(runnable);
thread.start();
check.await();
document.priorityReadOnly(r -> null);
Assert.assertFalse(thread.isInterrupted());
}
private void addReaderCancelationListener(IXtextDocument document, List<CancelIndicator> cancelIndicators) {
document.addModelListener((XtextResource it) -> {
CancelableUnitOfWork<Boolean, XtextResource> work = new CancelableUnitOfWork<Boolean, XtextResource>() {
@Override
public Boolean exec(XtextResource state, CancelIndicator cancelIndicator) throws Exception {
Assert.assertFalse(cancelIndicator.isCanceled());
return cancelIndicators.add(cancelIndicator);
}
};
document.readOnly(work);
});
}
@Override
public Collection<FoldedPosition> getFoldingRegions(final IXtextDocument xtextDocument) {
return xtextDocument.tryReadOnly(new CancelableUnitOfWork<Collection<FoldedPosition>, XtextResource>() {
@Override
public Collection<FoldedPosition> exec(XtextResource xtextResource, CancelIndicator cancelIndicator)
throws Exception {
try {
DefaultFoldingRegionProvider.this.cancelIndicator = cancelIndicator;
return doGetFoldingRegions(xtextDocument, xtextResource);
} finally {
DefaultFoldingRegionProvider.this.cancelIndicator = null;
}
}
}, () -> Collections.emptyList());
}
/**
* Refreshes the highlighting.
*/
public void refresh() {
if (oldCalculator != null || newCalculator != null) {
new Job("calculating highlighting") {
@Override
protected IStatus run(IProgressMonitor monitor) {
XtextSourceViewer mySourceViewer = sourceViewer;
if (mySourceViewer != null) {
IXtextDocument document = mySourceViewer.getXtextDocument();
if (document != null) {
document.tryReadOnly(new CancelableUnitOfWork<Void,XtextResource>() {
@Override
public java.lang.Void exec(XtextResource state, CancelIndicator cancelIndicator)
throws Exception {
beforeRefresh(state, cancelIndicator);
modelChanged(state, cancelIndicator);
return null;
}
});
}
}
return Status.OK_STATUS;
}
}.schedule();
} else {
Display display = getDisplay();
display.asyncExec(presenter.createSimpleUpdateRunnable());
}
}
/**
* Filter quickfixes for types and constructors.
*/
@Override
public void createLinkingIssueResolutions(final Issue issue, final IssueResolutionAcceptor issueResolutionAcceptor) {
final IModificationContext modificationContext = getModificationContextFactory().createModificationContext(
issue);
final IXtextDocument xtextDocument = modificationContext.getXtextDocument();
if (xtextDocument != null) {
xtextDocument.tryReadOnly(new CancelableUnitOfWork<Void, XtextResource>() {
@Override
public java.lang.Void exec(XtextResource state, CancelIndicator cancelIndicator) throws Exception {
try {
EObject target = state.getEObject(issue.getUriToProblem().fragment());
EReference reference = getUnresolvedEReference(issue, target);
if (reference != null && reference.getEReferenceType() != null) {
createLinkingIssueQuickfixes(issue,
getCancelableAcceptor(issueResolutionAcceptor, cancelIndicator), xtextDocument,
state, target, reference);
}
} catch (WrappedException e) {
// issue information seems to be out of sync, e.g. there is no
// EObject with the given fragment
}
return null;
}
});
}
}
private IStatus updateAnnotationModel(IProgressMonitor monitor) {
if (xtextEditor == null || xtextEditor.getDocument() == null
|| xtextEditor.getInternalSourceViewer().getAnnotationModel() == null) {
return Status.OK_STATUS;
}
IXtextDocument xtextDocument = xtextEditor.getDocument();
IAnnotationModel annotationModel = xtextEditor.getInternalSourceViewer().getAnnotationModel();
Map<Annotation, Position> annotationToPosition = xtextDocument
.readOnly(new CancelableUnitOfWork<Map<Annotation, Position>, XtextResource>() {
@Override
public Map<Annotation, Position> exec(XtextResource xtextResource, CancelIndicator cancelIndicator) {
if (xtextResource == null)
return Collections.emptyMap();
return createOverrideIndicatorAnnotationMap(xtextResource, cancelIndicator);
}
});
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
if (annotationModel instanceof IAnnotationModelExtension) {
IAnnotationModelExtension annotationModelExtension = (IAnnotationModelExtension) annotationModel;
Object lockObject = getLockObject(annotationModel);
synchronized (lockObject) {
annotationModelExtension.replaceAnnotations(
overrideIndicatorAnnotations.toArray(new Annotation[overrideIndicatorAnnotations.size()]),
annotationToPosition);
}
overrideIndicatorAnnotations = annotationToPosition.keySet();
}
return Status.OK_STATUS;
}
/**
* Refreshes the highlighting.
*/
@Override
public void refresh() {
if (oldCalculator != null || newCalculator != null) {
IDocument document = editor != null ? editor.getDocument() : sourceViewer.getDocument();
if (document instanceof IXtextDocument) {
Job job = new Job("Calculating highlighting") { //$NON-NLS-1$
@Override
protected IStatus run(final IProgressMonitor monitor) {
((XtextDocument) document).readOnly(new CancelableUnitOfWork<Void, XtextResource>() {
@Override
public java.lang.Void exec(final XtextResource state, final CancelIndicator cancelIndicator) throws Exception {
beforeRefresh(state, cancelIndicator);
modelChanged(state, cancelIndicator);
return null;
}
});
return Status.OK_STATUS;
}
};
job.setSystem(true);
job.schedule();
}
} else {
Display display = getDisplay();
display.asyncExec(presenter.createSimpleUpdateRunnable());
}
}
@Override
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
if (getContentProposalProvider() == null)
return null;
IXtextDocument document = (IXtextDocument) viewer.getDocument();
final CancelableCompletionProposalComputer computer = createCompletionProposalComputer(viewer, offset);
RunnableWithResult<ICompletionProposal[]> runnable = new RunnableWithResult.Impl<ICompletionProposal[]>() {
@Override
public void run() {
setResult(document.priorityReadOnly(new CancelableUnitOfWork<ICompletionProposal[], XtextResource>() {
@Override
public ICompletionProposal[] exec(XtextResource state, CancelIndicator cancelIndicator)
throws Exception {
computer.setCancelIndicator(cancelIndicator);
try {
return computer.exec(state);
} catch (Throwable t) {
return new ICompletionProposal[] {};
}
}
}));
}
};
if (Display.getCurrent() == null) {
Display.getDefault().syncExec(runnable);
} else {
runnable.run();
}
ICompletionProposal[] result = runnable.getResult();
Arrays.sort(result, getCompletionProposalComparator());
result = getCompletionProposalPostProcessor().postProcess(result);
return result;
}
@Override
public <T> T readOnly(IUnitOfWork<T, XtextResource> work) {
if (work instanceof CancelableUnitOfWork) {
return super.readOnly(new CancelableUnitOfWorkOnTransactionalEditingDomain<T>(
(CancelableUnitOfWork<T, XtextResource>) work));
}
return super.readOnly(new UnitOfWorkOnTransactionalEditingDomain<T>(work));
}
@Override
public <T> T priorityReadOnly(IUnitOfWork<T, XtextResource> work) {
if (work instanceof CancelableUnitOfWork) {
return super.priorityReadOnly(new CancelableUnitOfWorkOnTransactionalEditingDomain<T>(
(CancelableUnitOfWork<T, XtextResource>) work));
}
return super.priorityReadOnly(new UnitOfWorkOnTransactionalEditingDomain<T>(work));
}
@Override
public <T> T modify(IUnitOfWork<T, XtextResource> work) {
if (work instanceof CancelableUnitOfWork) {
return super.modify(new CancelableUnitOfWorkOnTransactionalEditingDomain<T>(
(CancelableUnitOfWork<T, XtextResource>) work));
}
return super.modify(new UnitOfWorkOnTransactionalEditingDomain<T>(work));
}
@Override
public IHyperlink[] detectHyperlinks(final ITextViewer textViewer, final IRegion region,
final boolean canShowMultipleHyperlinks) {
final IXtextDocument document = (IXtextDocument) textViewer.getDocument();
final IHyperlink[] importHyperlinks = importHyperlinks(document, region);
if (importHyperlinks != NO_HYPERLINKS) { return importHyperlinks; }
return document.readOnly(new CancelableUnitOfWork<IHyperlink[], XtextResource>() {
@Override
public IHyperlink[] exec(final XtextResource resource, final CancelIndicator c) {
return getHelper().createHyperlinksByOffset(resource, region.getOffset(), canShowMultipleHyperlinks);
}
});
}
public void openOutlinePopup() {
getDocument().readOnly(new CancelableUnitOfWork<Object, XtextResource>() {
@Override
public Object exec(final XtextResource state, final CancelIndicator c) throws Exception {
final QuickOutlinePopup popup = new GamlQuickOutlinePopup(GamlEditor.this, toolbar);
injector.injectMembers(popup);
return popup.open();
}
});
}
/**
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(final SelectionEvent e) {
editor.getDocument().readOnly(new CancelableUnitOfWork<Object, XtextResource>() {
@Override
public Object exec(final XtextResource state, final CancelIndicator c) throws Exception {
return GamlModelBuilder.getDefaultInstance().compile(state.getURI(), null);
}
});
}
/**
* Execute the given work unit with read-only access and return its result.
*/
public <T extends Object> T readOnly(CancelableUnitOfWork<T, IXtextWebDocument> work) {
return doAccess(work, false, false, null);
}
/**
* The implementation of this method is mainly taken from its super
* implementation
*/
@Override
public Map<Annotation, Position> createAnnotationMap(XtextEditor editor,
final ITextSelection selection, final SubMonitor monitor) {
Map<Annotation, Position> annotationMap = super.createAnnotationMap(
editor, selection, monitor);
final IXtextDocument document = editor.getDocument();
if (document != null) {
return document.readOnly(
new CancelableUnitOfWork<Map<Annotation, Position>, XtextResource>() {
@Override
public Map<Annotation, Position> exec(
XtextResource resource,
final CancelIndicator cancelIndicator)
throws Exception {
if (resource != null
&& resource.getContents().size() > 0) {
INode node = NodeModelUtils
.findLeafNodeAtOffset(
NodeModelUtils.getNode(resource
.getContents().get(0)),
selection.getOffset());
EObject target = eObjectAtOffsetHelper
.resolveElementAt(resource,
selection.getOffset());
List<ITextRegion> textRegions = new ArrayList<>();
if (target instanceof NodeId
&& !target.eIsProxy()) {
textRegions = nodeId((NodeId) target);
} else if (target instanceof Attribute
&& !target.eIsProxy()) {
textRegions = attribute((Attribute) target,
node);
}
for (ITextRegion occurrence : textRegions) {
try {
addOccurrenceAnnotation(
OCCURRENCE_ANNOTATION_TYPE,
document, occurrence,
annotationMap);
} catch (Exception exc) {
// outdated index information. Ignore
}
}
}
return annotationMap;
}
});
} else {
return annotationMap;
}
}
public CancelableUnitOfWorkOnTransactionalEditingDomain(CancelableUnitOfWork<T, XtextResource> delegate) {
this.delegate = delegate;
}
/**
* Execute the given work unit with read-only access and return its result. The
* work unit is handled with higher priority, i.e. currently running work units
* are canceled if they support cancellation.
*/
public <T extends Object> T priorityReadOnly(CancelableUnitOfWork<T, IXtextWebDocument> work) {
return doAccess(work, true, false, null);
}