package tool.editors.method;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnmappableCharacterException;
import java.nio.charset.UnsupportedCharsetException;
import org.eclipse.core.filebuffers.manipulation.ContainerCreator;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.ui.internal.editors.text.NLSUtility;
import org.eclipse.ui.internal.editors.text.WorkspaceOperationRunner;
import org.eclipse.ui.texteditor.AbstractDocumentProvider;
import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
import tool.ToolPlugin;
import tool.editors.text.ToolPartitionScanner;
import tool.model.ToolMethod;
public class ToolMethodDocumentProvider extends AbstractDocumentProvider {
@SuppressWarnings("restriction")
private WorkspaceOperationRunner fOperationRunner;
protected IDocument createDocument(Object element) throws CoreException {
ToolMethod method = ((MethodEditorInput)element).getMethod();
IDocument document = method.getImplementationDocument();
IDocumentPartitioner partitioner =
new FastPartitioner(
new ToolPartitionScanner(),
new String[] {
ToolPartitionScanner.TOOL_COMMENT,
ToolPartitionScanner.TOOL_SQL});
partitioner.connect(document);
document.setDocumentPartitioner(partitioner);
return document;
}
@Override
protected IAnnotationModel createAnnotationModel(Object element)
throws CoreException {
if (element instanceof MethodEditorInput) {
MethodEditorInput input = (MethodEditorInput) element;
IAnnotationModel model = new ResourceMarkerAnnotationModel(input.getFile());
input.setAnnotationModel(model);
return model;
}
return null;
}
@Override
public boolean isModifiable(Object element) {
return true;
}
@Override
public boolean isReadOnly(Object element) {
return false;
}
@Override
protected void doSaveDocument(IProgressMonitor monitor, Object element,
IDocument document, boolean overwrite) throws CoreException {
if (element instanceof MethodEditorInput) {
MethodEditorInput input = (MethodEditorInput) element;
IFile file = input.getFile();
String encoding = file.getCharset();
Charset charset;
try {
charset = Charset.forName(encoding);
} catch (UnsupportedCharsetException ex) {
String message = NLSUtility
.format(
"Unsupported encoding: ",
encoding);
IStatus s = new Status(IStatus.ERROR,
ToolPlugin.PLUGIN_ID, IStatus.OK, message, ex);
throw new CoreException(s);
} catch (IllegalCharsetNameException ex) {
String message = NLSUtility
.format(
"Unsupported encoding: ",
encoding);
IStatus s = new Status(IStatus.ERROR,
ToolPlugin.PLUGIN_ID, IStatus.OK, message, ex);
throw new CoreException(s);
}
CharsetEncoder encoder = charset.newEncoder();
encoder.onMalformedInput(CodingErrorAction.REPLACE);
encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
InputStream stream;
try {
byte[] bytes;
ByteBuffer byteBuffer = encoder.encode(CharBuffer
.wrap(document.get()));
if (byteBuffer.hasArray())
bytes = byteBuffer.array();
else {
bytes = new byte[byteBuffer.limit()];
byteBuffer.get(bytes);
}
stream = new ByteArrayInputStream(bytes, 0, byteBuffer
.limit());
} catch (CharacterCodingException ex) {
Assert
.isTrue(ex instanceof UnmappableCharacterException);
String message = NLSUtility
.format(
"Charecter set mapping failed for: ",
encoding);
IStatus s = new Status(IStatus.ERROR,
ToolPlugin.PLUGIN_ID, message, null);
throw new CoreException(s);
}
if (file.exists()) {
// inform about the upcoming content change
fireElementStateChanging(element);
try {
file.setContents(stream, overwrite, true, monitor);
} catch (CoreException x) {
// inform about failure
fireElementStateChangeFailed(element);
throw x;
} catch (RuntimeException x) {
// inform about failure
fireElementStateChangeFailed(element);
throw x;
}
// If here, the editor state will be flipped to "not dirty".
// Thus, the state changing flag will be reset.
ResourceMarkerAnnotationModel model = (ResourceMarkerAnnotationModel) input.getAnnotationModel();
if (model != null)
model.updateMarkers(document);
} else {
try {
monitor.beginTask("Saving ", 2000);
ContainerCreator creator = new ContainerCreator(
file.getWorkspace(), file.getParent().getFullPath());
creator.createContainer(new SubProgressMonitor(monitor, 1000));
file.create(stream, false, new SubProgressMonitor(monitor, 1000));
} finally {
monitor.done();
}
}
}
}
@Override
protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {
if (fOperationRunner == null)
fOperationRunner = new WorkspaceOperationRunner();
fOperationRunner.setProgressMonitor(monitor);
return fOperationRunner;
}
}