KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > editors > text > StorageDocumentProvider


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.editors.text;
12
13 import java.io.BufferedReader JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.io.InputStreamReader JavaDoc;
17 import java.io.Reader JavaDoc;
18
19 import org.osgi.framework.Bundle;
20
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.ILog;
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.MultiStatus;
27 import org.eclipse.core.runtime.Platform;
28 import org.eclipse.core.runtime.QualifiedName;
29 import org.eclipse.core.runtime.Status;
30 import org.eclipse.core.runtime.content.IContentDescription;
31 import org.eclipse.core.runtime.content.IContentType;
32
33 import org.eclipse.core.resources.IEncodedStorage;
34 import org.eclipse.core.resources.IResourceStatus;
35 import org.eclipse.core.resources.IStorage;
36 import org.eclipse.core.resources.ResourcesPlugin;
37
38 import org.eclipse.jface.operation.IRunnableContext;
39
40 import org.eclipse.jface.text.Document;
41 import org.eclipse.jface.text.IDocument;
42 import org.eclipse.jface.text.source.IAnnotationModel;
43
44 import org.eclipse.ui.IEditorInput;
45 import org.eclipse.ui.IStorageEditorInput;
46 import org.eclipse.ui.PlatformUI;
47 import org.eclipse.ui.internal.editors.text.EditorsPlugin;
48 import org.eclipse.ui.internal.editors.text.NLSUtility;
49 import org.eclipse.ui.texteditor.AbstractDocumentProvider;
50
51
52 /**
53  * Shared document provider specialized for {@link org.eclipse.core.resources.IStorage}s.
54  */

55 public class StorageDocumentProvider extends AbstractDocumentProvider implements IStorageDocumentProvider {
56
57     /**
58      * Default file size.
59      *
60      * @since 2.1
61      */

62     protected static final int DEFAULT_FILE_SIZE= 15 * 1024;
63
64     /**
65      * Constant denoting an empty set of properties
66      * @since 3.1
67      */

68     private static final QualifiedName[] NO_PROPERTIES= new QualifiedName[0];
69
70
71     /**
72      * Bundle of all required information to allow {@link org.eclipse.core.resources.IStorage} as underlying document resources.
73      * @since 2.0
74      */

75     protected class StorageInfo extends ElementInfo {
76
77         /** The flag representing the cached state whether the storage is modifiable. */
78         public boolean fIsModifiable= false;
79         /** The flag representing the cached state whether the storage is read-only. */
80         public boolean fIsReadOnly= true;
81         /** The flag representing the need to update the cached flag. */
82         public boolean fUpdateCache= true;
83         /** The encoding used to create the document from the storage or <code>null</code> for workbench encoding. */
84         public String JavaDoc fEncoding;
85
86         /**
87          * Creates a new storage info.
88          *
89          * @param document the document
90          * @param model the annotation model
91          */

92         public StorageInfo(IDocument document, IAnnotationModel model) {
93             super(document, model);
94             fEncoding= null;
95         }
96     }
97
98     /**
99      * Creates a new document provider.
100      *
101      * @since 2.0
102      */

103     public StorageDocumentProvider() {
104         super();
105     }
106
107     /**
108      * Initializes the given document with the given stream.
109      *
110      * @param document the document to be initialized
111      * @param contentStream the stream which delivers the document content
112      * @throws CoreException if the given stream can not be read
113      *
114      * @deprecated use encoding based version instead
115      */

116     protected void setDocumentContent(IDocument document, InputStream JavaDoc contentStream) throws CoreException {
117         setDocumentContent(document, contentStream, null);
118     }
119
120     /**
121      * Initializes the given document with the given stream using the given encoding.
122      *
123      * @param document the document to be initialized
124      * @param contentStream the stream which delivers the document content
125      * @param encoding the character encoding for reading the given stream
126      * @throws CoreException if the given stream can not be read
127      * @since 2.0
128      */

129     protected void setDocumentContent(IDocument document, InputStream JavaDoc contentStream, String JavaDoc encoding) throws CoreException {
130
131         Reader JavaDoc in= null;
132
133         try {
134
135             if (encoding == null)
136                 encoding= getDefaultEncoding();
137
138             in= new BufferedReader JavaDoc(new InputStreamReader JavaDoc(contentStream, encoding), DEFAULT_FILE_SIZE);
139             StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(DEFAULT_FILE_SIZE);
140             char[] readBuffer= new char[2048];
141             int n= in.read(readBuffer);
142             while (n > 0) {
143                 buffer.append(readBuffer, 0, n);
144                 n= in.read(readBuffer);
145             }
146
147             document.set(buffer.toString());
148
149         } catch (IOException JavaDoc x) {
150             String JavaDoc message= (x.getMessage() != null ? x.getMessage() : ""); //$NON-NLS-1$
151
IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, message, x);
152             throw new CoreException(s);
153         } finally {
154             try {
155                 if (in != null)
156                     in.close();
157                 else
158                     contentStream.close();
159             } catch (IOException JavaDoc x) {
160             }
161         }
162     }
163
164     /**
165      * Initializes the given document from the given editor input using the default character encoding.
166      *
167      * @param document the document to be initialized
168      * @param editorInput the input from which to derive the content of the document
169      * @return <code>true</code> if the document content could be set, <code>false</code> otherwise
170      * @throws CoreException if the given editor input cannot be accessed
171      * @deprecated use the encoding based version instead
172      * @since 2.0
173      */

174     protected boolean setDocumentContent(IDocument document, IEditorInput editorInput) throws CoreException {
175         return setDocumentContent(document, editorInput, null);
176     }
177
178     /**
179      * Initializes the given document from the given editor input using the given character encoding.
180      *
181      * @param document the document to be initialized
182      * @param editorInput the input from which to derive the content of the document
183      * @param encoding the character encoding used to read the editor input
184      * @return <code>true</code> if the document content could be set, <code>false</code> otherwise
185      * @throws CoreException if the given editor input cannot be accessed
186      * @since 2.0
187      */

188     protected boolean setDocumentContent(IDocument document, IEditorInput editorInput, String JavaDoc encoding) throws CoreException {
189         if (editorInput instanceof IStorageEditorInput) {
190             IStorage storage= ((IStorageEditorInput) editorInput).getStorage();
191             InputStream JavaDoc stream= storage.getContents();
192             try {
193                 setDocumentContent(document, stream, encoding);
194             } finally {
195                 try {
196                     stream.close();
197                 } catch (IOException JavaDoc x) {
198                 }
199             }
200             return true;
201         }
202         return false;
203     }
204
205     /*
206      * @see AbstractDocumentProvider#createAnnotationModel(Object)
207      */

208     protected IAnnotationModel createAnnotationModel(Object JavaDoc element) throws CoreException {
209         return null;
210     }
211
212     /**
213      * Factory method for creating empty documents.
214      * @return the newly created document
215      * @since 2.1
216      */

217     protected IDocument createEmptyDocument() {
218         return new Document();
219     }
220
221     /*
222      * @see AbstractDocumentProvider#createDocument(Object)
223      */

224     protected IDocument createDocument(Object JavaDoc element) throws CoreException {
225
226         if (element instanceof IEditorInput) {
227             IDocument document= createEmptyDocument();
228             if (setDocumentContent(document, (IEditorInput) element, getEncoding(element))) {
229                 setupDocument(element, document);
230                 return document;
231             }
232         }
233
234         return null;
235     }
236
237     /**
238      * Sets up the given document as it would be provided for the given element. The
239      * content of the document is not changed. This default implementation is empty.
240      * Subclasses may reimplement.
241      *
242      * @param element the blue-print element
243      * @param document the document to set up
244      * @since 3.0
245      */

246     protected void setupDocument(Object JavaDoc element, IDocument document) {
247     }
248
249     /*
250      * @see AbstractDocumentProvider#createElementInfo(Object)
251      * @since 2.0
252      */

253     protected ElementInfo createElementInfo(Object JavaDoc element) throws CoreException {
254         if (element instanceof IStorageEditorInput) {
255
256             IDocument document= null;
257             IStatus status= null;
258
259             try {
260                 document= createDocument(element);
261             } catch (CoreException x) {
262                 status= x.getStatus();
263                 document= createEmptyDocument();
264             }
265
266             ElementInfo info= new StorageInfo(document, createAnnotationModel(element));
267             info.fStatus= status;
268             ((StorageInfo)info).fEncoding= getPersistedEncoding(element);
269
270             return info;
271         }
272
273         return super.createElementInfo(element);
274     }
275
276     /*
277      * @see AbstractDocumentProvider#doSaveDocument(IProgressMonitor, Object, IDocument, boolean)
278      */

279     protected void doSaveDocument(IProgressMonitor monitor, Object JavaDoc element, IDocument document, boolean overwrite) throws CoreException {
280     }
281
282     /**
283      * Defines the standard procedure to handle <code>CoreExceptions</code>. Exceptions
284      * are written to the plug-in log.
285      *
286      * @param exception the exception to be logged
287      * @param message the message to be logged
288      * @since 2.0
289      */

290     protected void handleCoreException(CoreException exception, String JavaDoc message) {
291
292         Bundle bundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
293         ILog log= Platform.getLog(bundle);
294
295         if (message != null)
296             log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, message, exception));
297         else
298             log.log(exception.getStatus());
299     }
300
301     /**
302      * Updates the internal cache for the given input.
303      *
304      * @param input the input whose cache will be updated
305      * @throws CoreException if the storage cannot be retrieved from the input
306      * @since 2.0
307      */

308     protected void updateCache(IStorageEditorInput input) throws CoreException {
309         StorageInfo info= (StorageInfo) getElementInfo(input);
310         if (info != null) {
311             try {
312                 IStorage storage= input.getStorage();
313                 if (storage != null) {
314                     boolean readOnly= storage.isReadOnly();
315                     info.fIsReadOnly= readOnly;
316                     info.fIsModifiable= !readOnly;
317                 }
318             } catch (CoreException x) {
319                 handleCoreException(x, TextEditorMessages.StorageDocumentProvider_updateCache);
320             }
321             info.fUpdateCache= false;
322         }
323     }
324
325     /*
326      * @see IDocumentProviderExtension#isReadOnly(Object)
327      * @since 2.0
328      */

329     public boolean isReadOnly(Object JavaDoc element) {
330         if (element instanceof IStorageEditorInput) {
331             StorageInfo info= (StorageInfo) getElementInfo(element);
332             if (info != null) {
333                 if (info.fUpdateCache) {
334                     try {
335                         updateCache((IStorageEditorInput) element);
336                     } catch (CoreException x) {
337                         handleCoreException(x, TextEditorMessages.StorageDocumentProvider_isReadOnly);
338                     }
339                 }
340                 return info.fIsReadOnly;
341             }
342         }
343         return super.isReadOnly(element);
344     }
345
346     /*
347      * @see org.eclipse.ui.texteditor.IDocumentProviderExtension5#isNotSynchronizedException(Object, CoreException)
348      * @since 3.2
349      */

350     public boolean isNotSynchronizedException(Object JavaDoc element, CoreException ex) {
351         IStatus status= ex.getStatus();
352         if (status == null || status instanceof MultiStatus)
353             return false;
354         
355         if (status.getException() != null)
356             return false;
357         
358         return status.getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL;
359     }
360
361     /*
362      * @see IDocumentProviderExtension#isModifiable(Object)
363      * @since 2.0
364      */

365     public boolean isModifiable(Object JavaDoc element) {
366         if (element instanceof IStorageEditorInput) {
367             StorageInfo info= (StorageInfo) getElementInfo(element);
368             if (info != null) {
369                 if (info.fUpdateCache) {
370                     try {
371                         updateCache((IStorageEditorInput) element);
372                     } catch (CoreException x) {
373                         handleCoreException(x, TextEditorMessages.StorageDocumentProvider_isModifiable);
374                     }
375                 }
376                 return info.fIsModifiable;
377             }
378         }
379         return super.isModifiable(element);
380     }
381
382     /*
383      * @see AbstractDocumentProvider#doUpdateStateCache(Object)
384      * @since 2.0
385      */

386     protected void doUpdateStateCache(Object JavaDoc element) throws CoreException {
387         if (element instanceof IStorageEditorInput) {
388             StorageInfo info= (StorageInfo) getElementInfo(element);
389             if (info != null)
390                 info.fUpdateCache= true;
391         }
392         super.doUpdateStateCache(element);
393     }
394
395     /*
396      * @see IStorageDocumentProvider#getDefaultEncoding()
397      * @since 2.0
398      */

399     public String JavaDoc getDefaultEncoding() {
400         return ResourcesPlugin.getEncoding();
401     }
402
403     /*
404      * @see IStorageDocumentProvider#getEncoding(Object)
405      * @since 2.0
406      */

407     public String JavaDoc getEncoding(Object JavaDoc element) {
408         if (element instanceof IStorageEditorInput) {
409             StorageInfo info= (StorageInfo) getElementInfo(element);
410             if (info != null)
411                 return info.fEncoding;
412             return getPersistedEncoding(element);
413         }
414         return null;
415     }
416
417     /*
418      * @see IStorageDocumentProvider#setEncoding(Object, String)
419      * @since 2.0
420      */

421     public void setEncoding(Object JavaDoc element, String JavaDoc encoding) {
422         if (element instanceof IStorageEditorInput) {
423             StorageInfo info= (StorageInfo) getElementInfo(element);
424             if (info != null) {
425                 info.fEncoding= encoding;
426                 try {
427                     persistEncoding(element, encoding);
428                 } catch (CoreException ex) {
429                     EditorsPlugin.log(ex.getStatus());
430                 }
431             }
432         }
433     }
434
435     /*
436      * @see org.eclipse.ui.texteditor.IDocumentProviderExtension4#getContentType(java.lang.Object)
437      * @since 3.1
438      */

439     public IContentType getContentType(Object JavaDoc element) throws CoreException {
440         if (element instanceof IStorageEditorInput) {
441             IStorage storage= ((IStorageEditorInput) element).getStorage();
442             Reader JavaDoc reader= null;
443             InputStream JavaDoc stream= null;
444             try {
445                 IContentDescription desc;
446                 IDocument document= getDocument(element);
447                 if (document != null) {
448                     reader= new DocumentReader(document);
449                     desc= Platform.getContentTypeManager().getDescriptionFor(reader, storage.getName(), NO_PROPERTIES);
450                 } else {
451                     stream= storage.getContents();
452                     desc= Platform.getContentTypeManager().getDescriptionFor(stream, storage.getName(), NO_PROPERTIES);
453                 }
454                 if (desc != null && desc.getContentType() != null)
455                     return desc.getContentType();
456             } catch (IOException JavaDoc x) {
457                 IPath path= storage.getFullPath();
458                 String JavaDoc name;
459                 if (path != null)
460                     name= path.toOSString();
461                 else
462                     name= storage.getName();
463                 String JavaDoc message;
464                 if (name != null)
465                     message= NLSUtility.format(TextEditorMessages.StorageDocumentProvider_getContentDescriptionFor, name);
466                 else
467                     message= TextEditorMessages.StorageDocumentProvider_getContentDescription;
468                 throw new CoreException(new Status(IStatus.ERROR, EditorsUI.PLUGIN_ID, IStatus.OK, message, x));
469             } finally {
470                 try {
471                     // Note: either 'reader' or 'stream' is null
472
if (reader != null)
473                         reader.close();
474                     if (stream != null)
475                         stream.close();
476                 } catch (IOException JavaDoc x) {
477                 }
478             }
479         }
480         return super.getContentType(element);
481     }
482
483     /**
484      * Returns the persisted encoding for the given element.
485      *
486      * @param element the element for which to get the persisted encoding
487      * @return the persisted encoding
488      * @since 2.1
489      */

490     protected String JavaDoc getPersistedEncoding(Object JavaDoc element) {
491         if (element instanceof IStorageEditorInput) {
492             IStorage storage;
493             try {
494                 storage= ((IStorageEditorInput)element).getStorage();
495                 if (storage instanceof IEncodedStorage)
496                     return ((IEncodedStorage)storage).getCharset();
497             } catch (CoreException e) {
498                 return null;
499             }
500         }
501         return null;
502     }
503
504     /**
505      * Persists the given encoding for the given element.
506      *
507      * @param element the element for which to store the persisted encoding
508      * @param encoding the encoding
509      * @throws CoreException if the operation fails
510      * @since 2.1
511      */

512     protected void persistEncoding(Object JavaDoc element, String JavaDoc encoding) throws CoreException {
513         // Default is to do nothing
514
}
515
516     /*
517      * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#getOperationRunner(org.eclipse.core.runtime.IProgressMonitor)
518      * @since 3.0
519      */

520     protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {
521         return null;
522     }
523 }
524
Popular Tags