package org.eparapher.rcp.editors; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.io.Writer; import org.apache.log4j.Logger; 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.Status; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IPathEditorInput; import org.eclipse.ui.texteditor.AbstractDocumentProvider; import org.eparapher.core.EParapherManager; import org.eparapher.core.crypto.timestamp.TimeStampManager; /** * A document provider that reads can handle IPathEditorInput * editor inputs. Documents are created by reading them in from the file that * the IPath contained in the editor input points to. * * @since 3.0 */ public class SimpleDocumentProvider extends AbstractDocumentProvider { private static Logger log = Logger.getLogger(SimpleDocumentProvider.class); /* * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(java.lang.Object) */ protected IDocument createDocument(Object element) throws CoreException { if (element instanceof IEditorInput) { IDocument document= new Document(); if (setDocumentContent(document, (IEditorInput) element)) { setupDocument(document); } return document; } return null; } /** * Tries to read the file pointed at by input if it is an * IPathEditorInput. If the file does not exist, true * is returned. * * @param document the document to fill with the contents of input * @param input the editor input * @return true if setting the content was successful or no file exists, false otherwise * @throws CoreException if reading the file fails */ private boolean setDocumentContent(IDocument document, IEditorInput input) throws CoreException { // XXX handle encoding Reader reader; try { if (input instanceof IPathEditorInput) reader= new FileReader(((IPathEditorInput)input).getPath().toFile()); else return false; } catch (FileNotFoundException e) { // return empty document and save later return true; } try { setDocumentContent(document, reader); return true; } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.ui.examples.rcp.texteditor", IStatus.OK, "error reading file", e)); //$NON-NLS-1$ //$NON-NLS-2$ } } /** * Reads in document content from a reader and fills document * * @param document the document to fill * @param reader the source * @throws IOException if reading fails */ private void setDocumentContent(IDocument document, Reader reader) throws IOException { Reader in= new BufferedReader(reader); try { StringBuffer buffer= new StringBuffer(512); char[] readBuffer= new char[512]; int n= in.read(readBuffer); while (n > 0) { buffer.append(readBuffer, 0, n); n= in.read(readBuffer); } document.set(buffer.toString()); } finally { in.close(); } } /** * Set up the document - default implementation does nothing. * * @param document the new document */ protected void setupDocument(IDocument document) { } /* * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createAnnotationModel(java.lang.Object) */ protected IAnnotationModel createAnnotationModel(Object element) throws CoreException { return null; } /* * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doSaveDocument(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object, org.eclipse.jface.text.IDocument, boolean) */ protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException { if (element instanceof IPathEditorInput) { IPathEditorInput pei= (IPathEditorInput) element; IPath path= pei.getPath(); File file= path.toFile(); try { if (!file.exists()) file.createNewFile(); else if (!EParapherManager.getInstance().getUI().askUserText("Confirm overwriting " + path.toFile().getName())) { // Dialog with confir log.info("Saving modifications to " + path.toFile().getName() + " cancelled"); return; } if (file.exists()) { if (file.canWrite()) { Writer writer= new FileWriter(file); writeDocumentContent(document, writer, monitor); } else { throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.ui.examples.rcp.texteditor", IStatus.OK, "file is read-only", null)); //$NON-NLS-1$ //$NON-NLS-2$ } } else { throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.ui.examples.rcp.texteditor", IStatus.OK, "error creating file", null)); //$NON-NLS-1$ //$NON-NLS-2$ } } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.ui.examples.rcp.texteditor", IStatus.OK, "error when saving file", e)); //$NON-NLS-1$ //$NON-NLS-2$ } } } /** * Saves the document contents to a stream. * * @param document the document to save * @param writer the stream to save it to * @param monitor a progress monitor to report progress * @throws IOException if writing fails */ private void writeDocumentContent(IDocument document, Writer writer, IProgressMonitor monitor) throws IOException { Writer out= new BufferedWriter(writer); try { out.write(document.get()); } finally { out.close(); } } /* * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#getOperationRunner(org.eclipse.core.runtime.IProgressMonitor) */ protected IRunnableContext getOperationRunner(IProgressMonitor monitor) { return null; } /* * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#isModifiable(java.lang.Object) */ public boolean isModifiable(Object element) { if (element instanceof IPathEditorInput) { IPathEditorInput pei= (IPathEditorInput) element; File file= pei.getPath().toFile(); return file.canWrite() || !file.exists(); // Allow to edit new files } return false; } /* * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#isReadOnly(java.lang.Object) */ public boolean isReadOnly(Object element) { return !isModifiable(element); } /* * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#isStateValidated(java.lang.Object) */ public boolean isStateValidated(Object element) { return true; } }