View Javadoc

1   package org.eparapher.rcp.editors;
2   
3   import java.io.BufferedReader;
4   import java.io.BufferedWriter;
5   import java.io.File;
6   import java.io.FileNotFoundException;
7   import java.io.FileReader;
8   import java.io.FileWriter;
9   import java.io.IOException;
10  import java.io.Reader;
11  import java.io.Writer;
12  
13  import org.apache.log4j.Logger;
14  import org.eclipse.core.runtime.CoreException;
15  import org.eclipse.core.runtime.IPath;
16  import org.eclipse.core.runtime.IProgressMonitor;
17  import org.eclipse.core.runtime.IStatus;
18  import org.eclipse.core.runtime.Status;
19  import org.eclipse.jface.operation.IRunnableContext;
20  import org.eclipse.jface.text.Document;
21  import org.eclipse.jface.text.IDocument;
22  import org.eclipse.jface.text.source.IAnnotationModel;
23  import org.eclipse.ui.IEditorInput;
24  import org.eclipse.ui.IPathEditorInput;
25  import org.eclipse.ui.texteditor.AbstractDocumentProvider;
26  import org.eparapher.core.EParapherManager;
27  import org.eparapher.core.crypto.timestamp.TimeStampManager;
28  
29  /**
30   * A document provider that reads can handle <code>IPathEditorInput</code>
31   * editor inputs. Documents are created by reading them in from the file that
32   * the <code>IPath</code> contained in the editor input points to.
33   * 
34   * @since 3.0
35   */
36  public class SimpleDocumentProvider extends AbstractDocumentProvider {
37  
38  	private static Logger log = Logger.getLogger(SimpleDocumentProvider.class);
39  	/*
40  	 * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(java.lang.Object)
41  	 */
42  	protected IDocument createDocument(Object element) throws CoreException {
43  		if (element instanceof IEditorInput) {
44  			IDocument document= new Document();
45  			if (setDocumentContent(document, (IEditorInput) element)) {
46  				setupDocument(document);
47  			}
48  			return document;
49  		}
50  	
51  		return null;
52  	}
53  	
54  	/**
55  	 * Tries to read the file pointed at by <code>input</code> if it is an
56  	 * <code>IPathEditorInput</code>. If the file does not exist, <code>true</code>
57  	 * is returned.
58  	 *  
59  	 * @param document the document to fill with the contents of <code>input</code>
60  	 * @param input the editor input
61  	 * @return <code>true</code> if setting the content was successful or no file exists, <code>false</code> otherwise
62  	 * @throws CoreException if reading the file fails
63  	 */
64  	private boolean setDocumentContent(IDocument document, IEditorInput input) throws CoreException {
65  		// XXX handle encoding
66  		Reader reader;
67  		try {
68  			if (input instanceof IPathEditorInput)
69  				reader= new FileReader(((IPathEditorInput)input).getPath().toFile());
70  			else
71  				return false;
72  		} catch (FileNotFoundException e) {
73  			// return empty document and save later
74  			return true;
75  		}
76  		
77  		try {
78  			setDocumentContent(document, reader);
79  			return true;
80  		} catch (IOException e) {
81  			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$
82  		}
83  	}
84  
85  	/**
86  	 * Reads in document content from a reader and fills <code>document</code>
87  	 * 
88  	 * @param document the document to fill
89  	 * @param reader the source
90  	 * @throws IOException if reading fails
91  	 */
92  	private void setDocumentContent(IDocument document, Reader reader) throws IOException {
93  		Reader in= new BufferedReader(reader);
94  		try {
95  			
96  			StringBuffer buffer= new StringBuffer(512);
97  			char[] readBuffer= new char[512];
98  			int n= in.read(readBuffer);
99  			while (n > 0) {
100 				buffer.append(readBuffer, 0, n);
101 				n= in.read(readBuffer);
102 			}
103 			
104 			document.set(buffer.toString());
105 		
106 		} finally {
107 			in.close();
108 		}
109 	}
110 
111 	/**
112 	 * Set up the document - default implementation does nothing.
113 	 * 
114 	 * @param document the new document
115 	 */
116 	protected void setupDocument(IDocument document) {
117 	}
118 
119 	/*
120 	 * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createAnnotationModel(java.lang.Object)
121 	 */
122 	protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {
123 		return null;
124 	}
125 
126 	/*
127 	 * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doSaveDocument(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object, org.eclipse.jface.text.IDocument, boolean)
128 	 */
129 	protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {
130 		if (element instanceof IPathEditorInput) {
131 			IPathEditorInput pei= (IPathEditorInput) element;
132 			IPath path= pei.getPath();
133 			File file= path.toFile();
134 			
135 			try {
136 				if (!file.exists())
137 					file.createNewFile();
138 				else if (!EParapherManager.getInstance().getUI().askUserText("Confirm overwriting " + path.toFile().getName())) {
139 					// Dialog with confir
140 					log.info("Saving modifications to " + path.toFile().getName() + " cancelled");
141 					return;
142 				}
143 
144 				if (file.exists()) {
145 					if (file.canWrite()) {
146 						Writer writer= new FileWriter(file);
147 						writeDocumentContent(document, writer, monitor);
148 					} else {
149 						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$
150 					}
151 				} else {
152 					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$
153 				}
154 			} catch (IOException e) {
155 				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$
156 			}
157 
158 		}
159 	}
160 
161 	/**
162 	 * Saves the document contents to a stream.
163 	 * 
164 	 * @param document the document to save
165 	 * @param writer the stream to save it to
166 	 * @param monitor a progress monitor to report progress
167 	 * @throws IOException if writing fails
168 	 */
169 	private void writeDocumentContent(IDocument document, Writer writer, IProgressMonitor monitor) throws IOException {
170 		Writer out= new BufferedWriter(writer);
171 		try {
172 			out.write(document.get());
173 		} finally {
174 			out.close();
175 		}
176 	}
177 
178 	/*
179 	 * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#getOperationRunner(org.eclipse.core.runtime.IProgressMonitor)
180 	 */
181 	protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {
182 		return null;
183 	}
184 	
185 	/*
186 	 * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#isModifiable(java.lang.Object)
187 	 */
188 	public boolean isModifiable(Object element) {
189 		if (element instanceof IPathEditorInput) {
190 			IPathEditorInput pei= (IPathEditorInput) element;
191 			File file= pei.getPath().toFile();
192 			return file.canWrite() || !file.exists(); // Allow to edit new files
193 		}
194 		return false;
195 	}
196 	
197 	/*
198 	 * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#isReadOnly(java.lang.Object)
199 	 */
200 	public boolean isReadOnly(Object element) {
201 		return !isModifiable(element);
202 	}
203 	
204 	/*
205 	 * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#isStateValidated(java.lang.Object)
206 	 */
207 	public boolean isStateValidated(Object element) {
208 		return true;
209 	}
210 }