package org.simantics.graphfile.ui.editor; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.AnnotationModel; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.ui.texteditor.AbstractDocumentProvider; import org.simantics.Simantics; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.UniqueRead; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.document.DocumentResource; import org.simantics.graphfile.ontology.GraphFileResource; import org.simantics.ui.workbench.ResourceEditorInput; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PlainTextEditorDocumentProvider extends AbstractDocumentProvider { private static final Logger LOGGER = LoggerFactory.getLogger(PlainTextEditor.class); protected String currentText; @Override protected IDocument createDocument(Object element) throws CoreException { ResourceEditorInput input = (ResourceEditorInput)element; final Resource resource = input.getResource(); try { return Simantics.getSession().syncRequest(new UniqueRead() { @Override public Document perform(ReadGraph graph) throws DatabaseException { GraphFileResource GF = GraphFileResource.getInstance(graph); DocumentResource DOC = DocumentResource.getInstance(graph); if (!graph.isInstanceOf(resource, DOC.FileDocument)) throw new DatabaseException("Invalid input resource for PlainTextEditor: " + NameUtils.getSafeName(graph, resource)); byte[] bytes = graph.getPossibleRelatedValue(resource, GF.HasFiledata, Bindings.BYTE_ARRAY); currentText = bytes != null ? new String(bytes, StandardCharsets.UTF_8) : ""; return new Document(currentText); } }); } catch (DatabaseException e) { StringWriter sw = new StringWriter(); LOGGER.error("Failed to create document", e); return new Document(sw.toString()); } } @Override protected IAnnotationModel createAnnotationModel(Object element) throws CoreException { return new AnnotationModel(); } @Override protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException { ResourceEditorInput input = (ResourceEditorInput)element; final Resource resource = input.getResource(); final String text = document.get(); currentText = text; Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { graph.markUndoPoint(); GraphFileResource GF = GraphFileResource.getInstance(graph); graph.claimLiteral(resource, GF.HasFiledata, text.getBytes(StandardCharsets.UTF_8)); graph.claimLiteral(resource, GF.LastModified, System.currentTimeMillis()); } }); } @Override protected IRunnableContext getOperationRunner(IProgressMonitor monitor) { return null; } @Override public boolean isModifiable(Object element) { return true; } @Override public boolean isReadOnly(Object element) { return false; } @Override public boolean canSaveDocument(Object element) { return !getDocument(element).get().equals(currentText); } }