package org.eclipse.core.filebuffers.manipulation;
import java.util.Map;
import org.eclipse.core.internal.filebuffers.FileBuffersPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.filebuffers.IFileBuffer;
import org.eclipse.core.filebuffers.IFileBufferStatusCodes;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentRewriteSession;
import org.eclipse.jface.text.DocumentRewriteSessionType;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension4;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.TextUtilities;
public abstract class TextFileBufferOperation implements IFileBufferOperation {
protected abstract MultiTextEditWithProgress computeTextEdit(ITextFileBuffer textFileBuffer, IProgressMonitor progressMonitor) throws CoreException, OperationCanceledException;
protected abstract DocumentRewriteSessionType getDocumentRewriteSessionType();
private String fOperationName;
private DocumentRewriteSession fDocumentRewriteSession;
protected TextFileBufferOperation(String operationName) {
fOperationName= operationName;
}
@Override
public String getOperationName() {
return fOperationName;
}
@Override
public void run(IFileBuffer fileBuffer, IProgressMonitor progressMonitor) throws CoreException, OperationCanceledException {
if (fileBuffer instanceof ITextFileBuffer) {
ITextFileBuffer textFileBuffer= (ITextFileBuffer) fileBuffer;
IPath path= textFileBuffer.getLocation();
String taskName= path == null ? getOperationName() : path.lastSegment();
SubMonitor subMonitor= SubMonitor.convert(progressMonitor, taskName, 100);
MultiTextEditWithProgress edit= computeTextEdit(textFileBuffer, subMonitor.split(10));
if (edit != null) {
Map<String, IDocumentPartitioner> stateData= startRewriteSession(textFileBuffer);
try {
applyTextEdit(textFileBuffer, edit, subMonitor.split(90));
} finally {
stopRewriteSession(textFileBuffer, stateData);
}
}
}
}
private Map<String, IDocumentPartitioner> startRewriteSession(ITextFileBuffer fileBuffer) {
Map<String, IDocumentPartitioner> stateData= null;
IDocument document= fileBuffer.getDocument();
if (document instanceof IDocumentExtension4) {
IDocumentExtension4 extension= (IDocumentExtension4) document;
fDocumentRewriteSession= extension.startRewriteSession(getDocumentRewriteSessionType());
} else
stateData= TextUtilities.removeDocumentPartitioners(document);
return stateData;
}
private void stopRewriteSession(ITextFileBuffer fileBuffer, Map<String, IDocumentPartitioner> stateData) {
IDocument document= fileBuffer.getDocument();
if (document instanceof IDocumentExtension4) {
IDocumentExtension4 extension= (IDocumentExtension4) document;
extension.stopRewriteSession(fDocumentRewriteSession);
fDocumentRewriteSession= null;
} else if (stateData != null)
TextUtilities.addDocumentPartitioners(document, stateData);
}
private void applyTextEdit(ITextFileBuffer fileBuffer, MultiTextEditWithProgress textEdit, IProgressMonitor progressMonitor) throws CoreException, OperationCanceledException {
try {
textEdit.apply(fileBuffer.getDocument(), TextEdit.NONE, progressMonitor);
} catch (BadLocationException x) {
throw new CoreException(new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IFileBufferStatusCodes.CONTENT_CHANGE_FAILED, "", x));
}
}
}