KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > texteditor > AbstractDocumentProvider


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
12 package org.eclipse.ui.texteditor;
13
14
15 import java.lang.reflect.InvocationTargetException JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.HashSet JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.Set JavaDoc;
23
24 import org.eclipse.core.runtime.Assert;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IProgressMonitor;
27 import org.eclipse.core.runtime.IStatus;
28 import org.eclipse.core.runtime.NullProgressMonitor;
29 import org.eclipse.core.runtime.Status;
30 import org.eclipse.core.runtime.content.IContentType;
31 import org.eclipse.core.runtime.jobs.ISchedulingRule;
32
33 import org.eclipse.jface.operation.IRunnableContext;
34 import org.eclipse.jface.operation.IRunnableWithProgress;
35
36 import org.eclipse.jface.text.DocumentEvent;
37 import org.eclipse.jface.text.IDocument;
38 import org.eclipse.jface.text.IDocumentListener;
39 import org.eclipse.jface.text.source.IAnnotationModel;
40
41 import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
42
43
44
45 /**
46  * An abstract implementation of a sharable document provider.
47  * <p>
48  * Subclasses must implement <code>createDocument</code>,
49  * <code>createAnnotationModel</code>, and <code>doSaveDocument</code>.
50  * </p>
51  */

52 public abstract class AbstractDocumentProvider implements IDocumentProvider, IDocumentProviderExtension, IDocumentProviderExtension2, IDocumentProviderExtension3, IDocumentProviderExtension4, IDocumentProviderExtension5 {
53
54         /**
55          * Operation created by the document provider and to be executed by the providers runnable context.
56          *
57          * @since 3.0
58          */

59         protected static abstract class DocumentProviderOperation implements IRunnableWithProgress {
60
61             /**
62              * The actual functionality of this operation.
63              *
64              * @param monitor a progress monitor to track execution
65              * @throws CoreException
66              */

67             protected abstract void execute(IProgressMonitor monitor) throws CoreException;
68
69             /*
70              * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
71              */

72             public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc, InterruptedException JavaDoc {
73                 try {
74                     execute(monitor);
75                 } catch (CoreException x) {
76                     throw new InvocationTargetException JavaDoc(x);
77                 }
78             }
79         }
80
81         /**
82          * Collection of all information managed for a connected element.
83          */

84         protected class ElementInfo implements IDocumentListener {
85
86             /** The element for which the info is stored */
87             public Object JavaDoc fElement;
88             /** How often the element has been connected */
89             public int fCount;
90             /** Can the element be saved */
91             public boolean fCanBeSaved;
92             /** The element's document */
93             public IDocument fDocument;
94             /** The element's annotation model */
95             public IAnnotationModel fModel;
96             /**
97              * Has element state been validated
98              * @since 2.0
99              */

100             public boolean fIsStateValidated;
101             /**
102              * The status of this element
103              * @since 2.0
104              */

105             public IStatus fStatus;
106
107
108             /**
109              * Creates a new element info, initialized with the given
110              * document and annotation model.
111              *
112              * @param document the document
113              * @param model the annotation model
114              */

115             public ElementInfo(IDocument document, IAnnotationModel model) {
116                 fDocument= document;
117                 fModel= model;
118                 fCount= 0;
119                 fCanBeSaved= false;
120                 fIsStateValidated= false;
121             }
122
123             /**
124              * An element info equals another object if this object is an element info
125              * and if the documents of the two element infos are equal.
126              * @see Object#equals(java.lang.Object)
127              */

128             public boolean equals(Object JavaDoc o) {
129                 if (o instanceof ElementInfo) {
130                     ElementInfo e= (ElementInfo) o;
131                     return fDocument.equals(e.fDocument);
132                 }
133                 return false;
134             }
135
136             /*
137              * @see Object#hashCode()
138              */

139             public int hashCode() {
140                 return fDocument.hashCode();
141             }
142
143             /*
144              * @see IDocumentListener#documentChanged(DocumentEvent)
145              */

146             public void documentChanged(DocumentEvent event) {
147                 fCanBeSaved= true;
148                 removeUnchangedElementListeners(fElement, this);
149                 fireElementDirtyStateChanged(fElement, fCanBeSaved);
150             }
151
152             /*
153              * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
154              */

155             public void documentAboutToBeChanged(DocumentEvent event) {
156             }
157         }
158
159
160     /**
161      * Enables a certain behavior.
162      * Indicates whether this provider should behave as described in
163      * use case 5 of http://bugs.eclipse.org/bugs/show_bug.cgi?id=10806.
164      * Current value: <code>true</code> since 3.0
165      * @since 2.0
166      */

167     static final protected boolean PR10806_UC5_ENABLED= true;
168
169     /**
170      * Enables a certain behavior.
171      * Indicates whether this provider should behave as described in
172      * http://bugs.eclipse.org/bugs/show_bug.cgi?id=14469
173      * Notes: This contradicts <code>PR10806_UC5_ENABLED</code>.
174      * Current value: <code>false</code> since 3.0
175      * @since 2.0
176      */

177     static final protected boolean PR14469_ENABLED= false;
178
179     /**
180      * Constant for representing the OK status. This is considered a value object.
181      * @since 2.0
182      */

183     static final protected IStatus STATUS_OK= new Status(IStatus.OK, TextEditorPlugin.PLUGIN_ID, IStatus.OK, EditorMessages.AbstractDocumentProvider_ok, null);
184
185     /**
186      * Constant for representing the error status. This is considered a value object.
187      * @since 2.0
188      */

189     static final protected IStatus STATUS_ERROR= new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.INFO, EditorMessages.AbstractDocumentProvider_error, null);
190
191
192     /** Element information of all connected elements */
193     private Map JavaDoc fElementInfoMap= new HashMap JavaDoc();
194     /** The element state listeners */
195     private List JavaDoc fElementStateListeners= new ArrayList JavaDoc();
196     /**
197      * The current progress monitor
198      * @since 2.1
199      */

200     private IProgressMonitor fProgressMonitor;
201
202
203     /**
204      * Creates a new document provider.
205      */

206     protected AbstractDocumentProvider() {
207     }
208
209     /**
210      * Creates the document for the given element.
211      * <p>
212      * Subclasses must implement this method.</p>
213      *
214      * @param element the element
215      * @return the document
216      * @exception CoreException if the document could not be created
217      */

218     protected abstract IDocument createDocument(Object JavaDoc element) throws CoreException;
219
220     /**
221      * Creates an annotation model for the given element.
222      * <p>
223      * Subclasses must implement this method.</p>
224      *
225      * @param element the element
226      * @return the annotation model or <code>null</code> if none
227      * @exception CoreException if the annotation model could not be created
228      */

229     protected abstract IAnnotationModel createAnnotationModel(Object JavaDoc element) throws CoreException;
230
231     /**
232      * Performs the actual work of saving the given document provided for the
233      * given element.
234      * <p>
235      * Subclasses must implement this method.</p>
236      *
237      * @param monitor a progress monitor to report progress and request cancelation
238      * @param element the element
239      * @param document the document
240      * @param overwrite indicates whether an overwrite should happen if necessary
241      * @exception CoreException if document could not be stored to the given element
242      */

243     protected abstract void doSaveDocument(IProgressMonitor monitor, Object JavaDoc element, IDocument document, boolean overwrite) throws CoreException;
244
245     /**
246      * Returns the runnable context for this document provider.
247      *
248      * @param monitor a progress monitor to track the operation
249      * @return the runnable context for this document provider
250      * @since 3.0
251      */

252     protected abstract IRunnableContext getOperationRunner(IProgressMonitor monitor);
253
254     /**
255      * Returns the scheduling rule required for executing
256      * <code>synchronize</code> on the given element. This default
257      * implementation returns <code>null</code>.
258      *
259      * @param element the element
260      * @return the scheduling rule for <code>synchronize</code>
261      * @since 3.0
262      */

263     protected ISchedulingRule getSynchronizeRule(Object JavaDoc element) {
264         return null;
265     }
266
267     /**
268      * Returns the scheduling rule required for executing
269      * <code>validateState</code> on the given element. This default
270      * implementation returns <code>null</code>.
271      *
272      * @param element the element
273      * @return the scheduling rule for <code>validateState</code>
274      * @since 3.0
275      */

276     protected ISchedulingRule getValidateStateRule(Object JavaDoc element) {
277         return null;
278     }
279
280     /**
281      * Returns the scheduling rule required for executing
282      * <code>save</code> on the given element. This default
283      * implementation returns <code>null</code>.
284      *
285      * @param element the element
286      * @return the scheduling rule for <code>save</code>
287      * @since 3.0
288      */

289     protected ISchedulingRule getSaveRule(Object JavaDoc element) {
290         return null;
291     }
292
293     /**
294      * Returns the scheduling rule required for executing
295      * <code>reset</code> on the given element. This default
296      * implementation returns <code>null</code>.
297      *
298      * @param element the element
299      * @return the scheduling rule for <code>reset</code>
300      * @since 3.0
301      */

302     protected ISchedulingRule getResetRule(Object JavaDoc element) {
303         return null;
304     }
305
306     /**
307      * Returns the element info object for the given element.
308      *
309      * @param element the element
310      * @return the element info object, or <code>null</code> if none
311      */

312     protected ElementInfo getElementInfo(Object JavaDoc element) {
313         return (ElementInfo) fElementInfoMap.get(element);
314     }
315
316     /**
317      * Creates a new element info object for the given element.
318      * <p>
319      * This method is called from <code>connect</code> when an element info needs
320      * to be created. The <code>AbstractDocumentProvider</code> implementation
321      * of this method returns a new element info object whose document and
322      * annotation model are the values of <code>createDocument(element)</code>
323      * and <code>createAnnotationModel(element)</code>, respectively. Subclasses
324      * may override.</p>
325      *
326      * @param element the element
327      * @return a new element info object
328      * @exception CoreException if the document or annotation model could not be created
329      */

330     protected ElementInfo createElementInfo(Object JavaDoc element) throws CoreException {
331         return new ElementInfo(createDocument(element), createAnnotationModel(element));
332     }
333
334     /**
335      * Disposes of the given element info object.
336      * <p>
337      * This method is called when an element info is disposed. The
338      * <code>AbstractDocumentProvider</code> implementation of this
339      * method does nothing. Subclasses may reimplement.</p>
340      *
341      * @param element the element
342      * @param info the element info object
343      */

344     protected void disposeElementInfo(Object JavaDoc element, ElementInfo info) {
345     }
346
347     /**
348      * Called on initial creation and when the dirty state of the element
349      * changes to <code>false</code>. Adds all listeners which must be
350      * active as long as the element is not dirty. This method is called
351      * before <code>fireElementDirtyStateChanged</code> or <code>
352      * fireElementContentReplaced</code> is called.
353      * Subclasses may extend.
354      *
355      * @param element the element
356      * @param info the element info object
357      */

358     protected void addUnchangedElementListeners(Object JavaDoc element, ElementInfo info) {
359         if (info.fDocument != null)
360             info.fDocument.addDocumentListener(info);
361     }
362
363     /**
364      * Called when the given element gets dirty. Removes all listeners
365      * which must be active only when the element is not dirty. This
366      * method is called before <code>fireElementDirtyStateChanged</code>
367      * or <code>fireElementContentReplaced</code> is called.
368      * Subclasses may extend.
369      *
370      * @param element the element
371      * @param info the element info object
372      */

373     protected void removeUnchangedElementListeners(Object JavaDoc element, ElementInfo info) {
374         if (info.fDocument != null)
375             info.fDocument.removeDocumentListener(info);
376     }
377
378     /**
379      * Enumerates the elements connected via this document provider.
380      *
381      * @return the list of elements (element type: <code>Object</code>)
382      */

383     protected Iterator JavaDoc getConnectedElements() {
384         Set JavaDoc s= new HashSet JavaDoc();
385         Set JavaDoc keys= fElementInfoMap.keySet();
386         if (keys != null)
387             s.addAll(keys);
388         return s.iterator();
389     }
390
391     /*
392      * @see IDocumentProvider#connect(Object)
393      */

394     public final void connect(Object JavaDoc element) throws CoreException {
395         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
396         if (info == null) {
397
398             info= createElementInfo(element);
399             if (info == null)
400                 info= new ElementInfo(null, null);
401
402             info.fElement= element;
403
404             addUnchangedElementListeners(element, info);
405
406             fElementInfoMap.put(element, info);
407             if (fElementInfoMap.size() == 1)
408                 connected();
409         }
410         ++ info.fCount;
411     }
412
413     /**
414      * This hook method is called when this provider starts managing documents for
415      * elements. I.e. it is called when the first element gets connected to this provider.
416      * Subclasses may extend.
417      * @since 2.0
418      */

419     protected void connected() {
420     }
421
422     /*
423      * @see IDocumentProvider#disconnect
424      */

425     public final void disconnect(Object JavaDoc element) {
426         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
427
428         if (info == null)
429             return;
430
431         if (info.fCount == 1) {
432
433             fElementInfoMap.remove(element);
434             removeUnchangedElementListeners(element, info);
435             disposeElementInfo(element, info);
436
437             if (fElementInfoMap.size() == 0)
438                 disconnected();
439
440         } else
441             -- info.fCount;
442     }
443
444     /**
445      * This hook method is called when this provider stops managing documents for
446      * element. I.e. it is called when the last element gets disconnected from this provider.
447      * Subclasses may extend.
448      * @since 2.0
449      */

450     protected void disconnected() {
451     }
452
453     /*
454      * @see IDocumentProvider#getDocument(Object)
455      */

456     public IDocument getDocument(Object JavaDoc element) {
457
458         if (element == null)
459             return null;
460
461         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
462         return (info != null ? info.fDocument : null);
463     }
464
465     /*
466      * @see IDocumentProvider#mustSaveDocument(Object)
467      */

468     public boolean mustSaveDocument(Object JavaDoc element) {
469
470         if (element == null)
471             return false;
472
473         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
474         return (info != null ? info.fCount == 1 && info.fCanBeSaved : false);
475     }
476
477     /*
478      * @see IDocumentProvider#getAnnotationModel(Object)
479      */

480     public IAnnotationModel getAnnotationModel(Object JavaDoc element) {
481
482         if (element == null)
483             return null;
484
485         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
486         return (info != null ? info.fModel : null);
487     }
488
489     /*
490      * @see IDocumentProvider#canSaveDocument(Object)
491      */

492     public boolean canSaveDocument(Object JavaDoc element) {
493
494         if (element == null)
495             return false;
496
497         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
498         return (info != null ? info.fCanBeSaved : false);
499     }
500
501     /**
502      * Executes the actual work of reseting the given elements document.
503      *
504      * @param element the element
505      * @param monitor the progress monitor
506      * @throws CoreException
507      * @since 3.0
508      */

509     protected void doResetDocument(Object JavaDoc element, IProgressMonitor monitor) throws CoreException {
510         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
511         if (info != null) {
512
513             IDocument original= null;
514             IStatus status= null;
515
516             try {
517                 original= createDocument(element);
518             } catch (CoreException x) {
519                 status= x.getStatus();
520             }
521
522             info.fStatus= status;
523
524             if (original != null) {
525                 fireElementContentAboutToBeReplaced(element);
526                 info.fDocument.set(original.get());
527                 if (info.fCanBeSaved) {
528                     info.fCanBeSaved= false;
529                     addUnchangedElementListeners(element, info);
530                 }
531                 fireElementContentReplaced(element);
532                 fireElementDirtyStateChanged(element, false);
533             }
534         }
535     }
536
537     /**
538      * Executes the given operation in the providers runnable context.
539      *
540      * @param operation the operation to be executes
541      * @param monitor the progress monitor
542      * @exception CoreException the operation's core exception
543      * @since 3.0
544      */

545     protected void executeOperation(DocumentProviderOperation operation, IProgressMonitor monitor) throws CoreException {
546         try {
547             IRunnableContext runner= getOperationRunner(monitor);
548             if (runner != null)
549                 runner.run(false, false, operation);
550             else
551                 operation.run(monitor);
552         } catch (InvocationTargetException JavaDoc x) {
553             Throwable JavaDoc e= x.getTargetException();
554             if (e instanceof CoreException)
555                 throw (CoreException) e;
556             String JavaDoc message= (e.getMessage() != null ? e.getMessage() : ""); //$NON-NLS-1$
557
throw new CoreException(new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.ERROR, message, e));
558         } catch (InterruptedException JavaDoc x) {
559             String JavaDoc message= (x.getMessage() != null ? x.getMessage() : ""); //$NON-NLS-1$
560
throw new CoreException(new Status(IStatus.CANCEL, TextEditorPlugin.PLUGIN_ID, IStatus.OK, message, x));
561         }
562     }
563
564     /*
565      * @see IDocumentProvider#resetDocument(Object)
566      */

567     public final void resetDocument(final Object JavaDoc element) throws CoreException {
568
569         if (element == null)
570             return;
571
572         class ResetOperation extends DocumentProviderOperation implements ISchedulingRuleProvider {
573
574             protected void execute(IProgressMonitor monitor) throws CoreException {
575                 doResetDocument(element, monitor);
576             }
577
578             public ISchedulingRule getSchedulingRule() {
579                 return getResetRule(element);
580             }
581         }
582
583         executeOperation(new ResetOperation(), getProgressMonitor());
584     }
585
586
587     /*
588      * @see IDocumentProvider#saveDocument(IProgressMonitor, Object, IDocument, boolean)
589      */

590     public final void saveDocument(IProgressMonitor monitor, final Object JavaDoc element, final IDocument document, final boolean overwrite) throws CoreException {
591
592         if (element == null)
593             return;
594
595         class SaveOperation extends DocumentProviderOperation implements ISchedulingRuleProvider {
596
597             /*
598              * @see org.eclipse.ui.texteditor.AbstractDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
599              */

600             protected void execute(IProgressMonitor pm) throws CoreException {
601                 ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
602                 if (info != null) {
603                     if (info.fDocument != document) {
604                         Status status= new Status(IStatus.WARNING, TextEditorPlugin.PLUGIN_ID, IStatus.ERROR, EditorMessages.AbstractDocumentProvider_error_save_inuse, null);
605                         throw new CoreException(status);
606                     }
607
608                     doSaveDocument(pm, element, document, overwrite);
609
610                     if (pm != null && pm.isCanceled())
611                         return;
612
613                     info.fCanBeSaved= false;
614                     addUnchangedElementListeners(element, info);
615                     fireElementDirtyStateChanged(element, false);
616
617                 } else {
618                     doSaveDocument(pm, element, document, overwrite);
619                 }
620             }
621
622             public ISchedulingRule getSchedulingRule() {
623                 return getSaveRule(element);
624             }
625         }
626
627         executeOperation(new SaveOperation(), monitor);
628     }
629
630     /**
631      * The <code>AbstractDocumentProvider</code> implementation of this
632      * <code>IDocumentProvider</code> method does nothing. Subclasses may
633      * reimplement.
634      *
635      * @param element the element
636      */

637     public void aboutToChange(Object JavaDoc element) {
638     }
639
640     /**
641      * The <code>AbstractDocumentProvider</code> implementation of this
642      * <code>IDocumentProvider</code> method does nothing. Subclasses may
643      * reimplement.
644      *
645      * @param element the element
646      */

647     public void changed(Object JavaDoc element) {
648     }
649
650     /*
651      * @see IDocumentProvider#addElementStateListener(IElementStateListener)
652      */

653     public void addElementStateListener(IElementStateListener listener) {
654         Assert.isNotNull(listener);
655         if (!fElementStateListeners.contains(listener))
656             fElementStateListeners.add(listener);
657     }
658
659     /*
660      * @see IDocumentProvider#removeElementStateListener(IElementStateListener)
661      */

662     public void removeElementStateListener(IElementStateListener listener) {
663         Assert.isNotNull(listener);
664         fElementStateListeners.remove(listener);
665     }
666
667     /**
668      * Informs all registered element state listeners about a change in the
669      * dirty state of the given element.
670      *
671      * @param element the element
672      * @param isDirty the new dirty state
673      * @see IElementStateListener#elementDirtyStateChanged(Object, boolean)
674      */

675     protected void fireElementDirtyStateChanged(Object JavaDoc element, boolean isDirty) {
676         Iterator JavaDoc e= new ArrayList JavaDoc(fElementStateListeners).iterator();
677         while (e.hasNext()) {
678             IElementStateListener l= (IElementStateListener) e.next();
679             l.elementDirtyStateChanged(element, isDirty);
680         }
681     }
682
683     /**
684      * Informs all registered element state listeners about an impending
685      * replace of the given element's content.
686      *
687      * @param element the element
688      * @see IElementStateListener#elementContentAboutToBeReplaced(Object)
689      */

690     protected void fireElementContentAboutToBeReplaced(Object JavaDoc element) {
691         Iterator JavaDoc e= new ArrayList JavaDoc(fElementStateListeners).iterator();
692         while (e.hasNext()) {
693             IElementStateListener l= (IElementStateListener) e.next();
694             l.elementContentAboutToBeReplaced(element);
695         }
696     }
697
698     /**
699      * Informs all registered element state listeners about the just-completed
700      * replace of the given element's content.
701      *
702      * @param element the element
703      * @see IElementStateListener#elementContentReplaced(Object)
704      */

705     protected void fireElementContentReplaced(Object JavaDoc element) {
706         Iterator JavaDoc e= new ArrayList JavaDoc(fElementStateListeners).iterator();
707         while (e.hasNext()) {
708             IElementStateListener l= (IElementStateListener) e.next();
709             l.elementContentReplaced(element);
710         }
711     }
712
713     /**
714      * Informs all registered element state listeners about the deletion
715      * of the given element.
716      *
717      * @param element the element
718      * @see IElementStateListener#elementDeleted(Object)
719      */

720     protected void fireElementDeleted(Object JavaDoc element) {
721         Iterator JavaDoc e= new ArrayList JavaDoc(fElementStateListeners).iterator();
722         while (e.hasNext()) {
723             IElementStateListener l= (IElementStateListener) e.next();
724             l.elementDeleted(element);
725         }
726     }
727
728     /**
729      * Informs all registered element state listeners about a move.
730      *
731      * @param originalElement the element before the move
732      * @param movedElement the element after the move
733      * @see IElementStateListener#elementMoved(Object, Object)
734      */

735     protected void fireElementMoved(Object JavaDoc originalElement, Object JavaDoc movedElement) {
736         Iterator JavaDoc e= new ArrayList JavaDoc(fElementStateListeners).iterator();
737         while (e.hasNext()) {
738             IElementStateListener l= (IElementStateListener) e.next();
739             l.elementMoved(originalElement, movedElement);
740         }
741     }
742
743     /*
744      * @see IDocumentProvider#getModificationStamp(Object)
745      * @since 2.0
746      */

747     public long getModificationStamp(Object JavaDoc element) {
748         return 0;
749     }
750
751     /*
752      * @see IDocumentProvider#getSynchronizationStamp(Object)
753      * @since 2.0
754      */

755     public long getSynchronizationStamp(Object JavaDoc element) {
756         return 0;
757     }
758
759     /*
760      * @see IDocumentProvider#isDeleted(Object)
761      * @since 2.0
762      */

763     public boolean isDeleted(Object JavaDoc element) {
764         return false;
765     }
766
767     /*
768      * @see IDocumentProviderExtension#isReadOnly(Object)
769      * @since 2.0
770      */

771     public boolean isReadOnly(Object JavaDoc element) {
772         return true;
773     }
774
775     /*
776      * @see IDocumentProviderExtension#isModifiable(Object)
777      * @since 2.0
778      */

779     public boolean isModifiable(Object JavaDoc element) {
780         return false;
781     }
782
783     /**
784      * Returns whether <code>validateState</code> has been called for the given element
785      * since the element's state has potentially been invalidated.
786      *
787      * @param element the element
788      * @return whether <code>validateState</code> has been called for the given element
789      * @since 2.0
790      */

791     public boolean isStateValidated(Object JavaDoc element) {
792         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
793         if (info != null)
794             return info.fIsStateValidated;
795         return false;
796     }
797
798     /**
799      * Hook method for validating the state of the given element. Must not take care of cache updating etc.
800      * Default implementation is empty.
801      *
802      * @param element the element
803      * @param computationContext the context in which validation happens
804      * @exception CoreException in case validation fails
805      * @since 2.0
806      */

807     protected void doValidateState(Object JavaDoc element, Object JavaDoc computationContext) throws CoreException {
808     }
809
810     /*
811      * @see IDocumentProviderExtension#validateState(Object, Object)
812      * @since 2.0
813      */

814     public void validateState(final Object JavaDoc element, final Object JavaDoc computationContext) throws CoreException {
815         if (element == null)
816             return;
817
818         class ValidateStateOperation extends DocumentProviderOperation implements ISchedulingRuleProvider {
819
820             protected void execute(IProgressMonitor monitor) throws CoreException {
821                 ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
822                 if (info == null)
823                     return;
824
825                 doValidateState(element, computationContext);
826
827                 doUpdateStateCache(element);
828                 info.fIsStateValidated= true;
829                 fireElementStateValidationChanged(element, true);
830             }
831
832             public ISchedulingRule getSchedulingRule() {
833                 return getValidateStateRule(element);
834             }
835         }
836
837         executeOperation(new ValidateStateOperation(), getProgressMonitor());
838     }
839
840     /**
841      * Hook method for updating the state of the given element.
842      * Default implementation is empty.
843      *
844      * @param element the element
845      * @exception CoreException in case state cache updating fails
846      * @since 2.0
847      */

848     protected void doUpdateStateCache(Object JavaDoc element) throws CoreException {
849     }
850
851     /**
852      * Returns whether the state of the element must be invalidated given its
853      * previous read-only state.
854      *
855      * @param element the element
856      * @param wasReadOnly the previous read-only state
857      * @return <code>true</code> if the state of the given element must be invalidated
858      * @since 2.0
859      */

860     protected boolean invalidatesState(Object JavaDoc element, boolean wasReadOnly) {
861         Assert.isTrue(PR10806_UC5_ENABLED != PR14469_ENABLED);
862         boolean readOnlyChanged= (isReadOnly(element) != wasReadOnly && !wasReadOnly);
863         if (PR14469_ENABLED)
864             return readOnlyChanged && !canSaveDocument(element);
865         return readOnlyChanged;
866     }
867
868     /*
869      * @see IDocumentProviderExtension#updateStateCache(Object)
870      * @since 2.0
871      */

872     final public void updateStateCache(Object JavaDoc element) throws CoreException {
873         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
874         if (info != null) {
875             boolean wasReadOnly= isReadOnly(element);
876             doUpdateStateCache(element);
877             if (invalidatesState(element, wasReadOnly)) {
878                 info.fIsStateValidated= false;
879                 fireElementStateValidationChanged(element, false);
880             }
881         }
882     }
883
884     /*
885      * @see IDocumentProviderExtension#setCanSaveDocument(Object)
886      * @since 2.0
887      */

888     public void setCanSaveDocument(Object JavaDoc element) {
889         if (element != null) {
890             ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
891             if (info != null) {
892                 info.fCanBeSaved= true;
893                 removeUnchangedElementListeners(element, info);
894                 fireElementDirtyStateChanged(element, info.fCanBeSaved);
895             }
896         }
897     }
898
899     /**
900      * Informs all registered element state listeners about a change in the
901      * state validation of the given element.
902      *
903      * @param element the element
904      * @param isStateValidated
905      * @see IElementStateListenerExtension#elementStateValidationChanged(Object, boolean)
906      * @since 2.0
907      */

908     protected void fireElementStateValidationChanged(Object JavaDoc element, boolean isStateValidated) {
909         Iterator JavaDoc e= new ArrayList JavaDoc(fElementStateListeners).iterator();
910         while (e.hasNext()) {
911             Object JavaDoc o= e.next();
912             if (o instanceof IElementStateListenerExtension) {
913                 IElementStateListenerExtension l= (IElementStateListenerExtension) o;
914                 l.elementStateValidationChanged(element, isStateValidated);
915             }
916         }
917     }
918
919     /**
920      * Informs all registered element state listeners about the current state
921      * change of the element
922      *
923      * @param element the element
924      * @see IElementStateListenerExtension#elementStateChanging(Object)
925      * @since 2.0
926      */

927     protected void fireElementStateChanging(Object JavaDoc element) {
928         Iterator JavaDoc e= new ArrayList JavaDoc(fElementStateListeners).iterator();
929         while (e.hasNext()) {
930             Object JavaDoc o= e.next();
931             if (o instanceof IElementStateListenerExtension) {
932                 IElementStateListenerExtension l= (IElementStateListenerExtension) o;
933                 l.elementStateChanging(element);
934             }
935         }
936     }
937
938     /**
939      * Informs all registered element state listeners about the failed
940      * state change of the element
941      *
942      * @param element the element
943      * @see IElementStateListenerExtension#elementStateChangeFailed(Object)
944      * @since 2.0
945      */

946     protected void fireElementStateChangeFailed(Object JavaDoc element) {
947         Iterator JavaDoc e= new ArrayList JavaDoc(fElementStateListeners).iterator();
948         while (e.hasNext()) {
949             Object JavaDoc o= e.next();
950             if (o instanceof IElementStateListenerExtension) {
951                 IElementStateListenerExtension l= (IElementStateListenerExtension) o;
952                 l.elementStateChangeFailed(element);
953             }
954         }
955     }
956
957     /*
958      * @see IDocumentProviderExtension#getStatus(Object)
959      * @since 2.0
960      */

961     public IStatus getStatus(Object JavaDoc element) {
962         ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
963         if (info != null) {
964             if (info.fStatus != null)
965                 return info.fStatus;
966             return (info.fDocument == null ? STATUS_ERROR : STATUS_OK);
967         }
968
969         return STATUS_ERROR;
970     }
971
972     /**
973      * Performs the actual work of synchronizing the given element.
974      *
975      * @param element the element
976      * @param monitor the progress monitor
977      * @exception CoreException in the case that synchronization fails
978      * @since 3.0
979      */

980     protected void doSynchronize(Object JavaDoc element, IProgressMonitor monitor) throws CoreException {
981     }
982
983     /*
984      * @see org.eclipse.ui.texteditor.IDocumentProviderExtension#synchronize(Object)
985      * @since 2.0
986      */

987     public final void synchronize(final Object JavaDoc element) throws CoreException {
988
989         if (element == null)
990             return;
991
992         class SynchronizeOperation extends DocumentProviderOperation implements ISchedulingRuleProvider {
993
994             protected void execute(IProgressMonitor monitor) throws CoreException {
995                 doSynchronize(element, monitor);
996             }
997
998             public ISchedulingRule getSchedulingRule() {
999                 return getSynchronizeRule(element);
1000            }
1001        }
1002
1003        executeOperation(new SynchronizeOperation(), getProgressMonitor());
1004    }
1005
1006    /*
1007     * @see org.eclipse.ui.texteditor.IDocumentProviderExtension2#getProgressMonitor()
1008     * @since 2.1
1009     */

1010    public IProgressMonitor getProgressMonitor() {
1011        return fProgressMonitor == null ? new NullProgressMonitor() : fProgressMonitor;
1012    }
1013
1014    /*
1015     * @see org.eclipse.ui.texteditor.IDocumentProviderExtension2#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
1016     * @since 2.1
1017     */

1018    public void setProgressMonitor(IProgressMonitor progressMonitor) {
1019        fProgressMonitor= progressMonitor;
1020    }
1021
1022    /*
1023     * @see org.eclipse.ui.texteditor.IDocumentProviderExtension3#isSynchronized(java.lang.Object)
1024     * @since 3.0
1025     */

1026    public boolean isSynchronized(Object JavaDoc element) {
1027        return true;
1028    }
1029    
1030    /*
1031     * @see org.eclipse.ui.texteditor.IDocumentProviderExtension5#isNotSynchronizedException(Object, CoreException)
1032     * @since 3.2
1033     */

1034    public boolean isNotSynchronizedException(Object JavaDoc element, CoreException ex) {
1035        return false;
1036    }
1037
1038    /*
1039     * @see org.eclipse.ui.texteditor.IDocumentProviderExtension4#getContentType(java.lang.Object)
1040     * @since 3.1
1041     */

1042    public IContentType getContentType(Object JavaDoc element) throws CoreException {
1043        return null;
1044    }
1045}
1046
Popular Tags