KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > java > JavaReconcilingStrategy


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.jdt.internal.ui.text.java;
13
14
15 import org.eclipse.core.runtime.Assert;
16 import org.eclipse.core.runtime.IProgressMonitor;
17 import org.eclipse.core.runtime.ISafeRunnable;
18 import org.eclipse.core.runtime.IStatus;
19 import org.eclipse.core.runtime.NullProgressMonitor;
20 import org.eclipse.core.runtime.OperationCanceledException;
21 import org.eclipse.core.runtime.SafeRunner;
22 import org.eclipse.core.runtime.Status;
23
24 import org.eclipse.jface.text.IDocument;
25 import org.eclipse.jface.text.IRegion;
26 import org.eclipse.jface.text.reconciler.DirtyRegion;
27 import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
28 import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
29 import org.eclipse.jface.text.source.IAnnotationModel;
30
31 import org.eclipse.ui.texteditor.IDocumentProvider;
32 import org.eclipse.ui.texteditor.ITextEditor;
33
34 import org.eclipse.jdt.core.ICompilationUnit;
35 import org.eclipse.jdt.core.JavaModelException;
36 import org.eclipse.jdt.core.dom.ASTNode;
37 import org.eclipse.jdt.core.dom.CompilationUnit;
38
39 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
40
41 import org.eclipse.jdt.ui.JavaUI;
42
43 import org.eclipse.jdt.internal.ui.JavaPlugin;
44 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
45 import org.eclipse.jdt.internal.ui.javaeditor.WorkingCopyManager;
46
47 public class JavaReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension {
48
49
50     private ITextEditor fEditor;
51
52     private WorkingCopyManager fManager;
53     private IDocumentProvider fDocumentProvider;
54     private IProgressMonitor fProgressMonitor;
55     private boolean fNotify= true;
56
57     private IJavaReconcilingListener fJavaReconcilingListener;
58     private boolean fIsJavaReconcilingListener;
59
60
61     public JavaReconcilingStrategy(ITextEditor editor) {
62         fEditor= editor;
63         fManager= JavaPlugin.getDefault().getWorkingCopyManager();
64         fDocumentProvider= JavaPlugin.getDefault().getCompilationUnitDocumentProvider();
65         fIsJavaReconcilingListener= fEditor instanceof IJavaReconcilingListener;
66         if (fIsJavaReconcilingListener)
67             fJavaReconcilingListener= (IJavaReconcilingListener)fEditor;
68     }
69
70     private IProblemRequestorExtension getProblemRequestorExtension() {
71         IAnnotationModel model= fDocumentProvider.getAnnotationModel(fEditor.getEditorInput());
72         if (model instanceof IProblemRequestorExtension)
73             return (IProblemRequestorExtension) model;
74         return null;
75     }
76
77     private void reconcile(final boolean initialReconcile) {
78         final CompilationUnit[] ast= new CompilationUnit[1];
79         try {
80             final ICompilationUnit unit= fManager.getWorkingCopy(fEditor.getEditorInput(), false);
81             if (unit != null) {
82                 SafeRunner.run(new ISafeRunnable() {
83                     public void run() {
84                         try {
85                             
86                             /* fix for missing cancel flag communication */
87                             IProblemRequestorExtension extension= getProblemRequestorExtension();
88                             if (extension != null) {
89                                 extension.setProgressMonitor(fProgressMonitor);
90                                 extension.setIsActive(true);
91                             }
92                             
93                             try {
94                                 boolean isASTNeeded= initialReconcile || JavaPlugin.getDefault().getASTProvider().isActive(unit);
95                                 // reconcile
96
if (fIsJavaReconcilingListener && isASTNeeded) {
97                                     int reconcileFlags= ICompilationUnit.FORCE_PROBLEM_DETECTION
98                                         | (ASTProvider.SHARED_AST_STATEMENT_RECOVERY ? ICompilationUnit.ENABLE_STATEMENTS_RECOVERY : 0)
99                                         | (ASTProvider.SHARED_BINDING_RECOVERY ? ICompilationUnit.ENABLE_BINDINGS_RECOVERY : 0);
100                                             
101                                     ast[0]= unit.reconcile(ASTProvider.SHARED_AST_LEVEL, reconcileFlags, null, fProgressMonitor);
102                                     if (ast[0] != null) {
103                                         // mark as unmodifiable
104
ASTNodes.setFlagsToAST(ast[0], ASTNode.PROTECT);
105                                     }
106                                 } else
107                                     unit.reconcile(ICompilationUnit.NO_AST, true, null, fProgressMonitor);
108                             } catch (OperationCanceledException ex) {
109                                 Assert.isTrue(fProgressMonitor == null || fProgressMonitor.isCanceled());
110                                 ast[0]= null;
111                             } finally {
112                                 /* fix for missing cancel flag communication */
113                                 if (extension != null) {
114                                     extension.setProgressMonitor(null);
115                                     extension.setIsActive(false);
116                                 }
117                             }
118                             
119                         } catch (JavaModelException ex) {
120                             handleException(ex);
121                         }
122                     }
123                     public void handleException(Throwable JavaDoc ex) {
124                         IStatus status= new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.OK, "Error in JDT Core during reconcile", ex); //$NON-NLS-1$
125
JavaPlugin.getDefault().getLog().log(status);
126                     }
127                 });
128                 
129             }
130         } finally {
131             // Always notify listeners, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=55969 for the final solution
132
try {
133                 if (fIsJavaReconcilingListener) {
134                     IProgressMonitor pm= fProgressMonitor;
135                     if (pm == null)
136                         pm= new NullProgressMonitor();
137                     fJavaReconcilingListener.reconciled(ast[0], !fNotify, pm);
138                 }
139             } finally {
140                 fNotify= true;
141             }
142         }
143     }
144
145     /*
146      * @see IReconcilingStrategy#reconcile(IRegion)
147      */

148     public void reconcile(IRegion partition) {
149         reconcile(false);
150     }
151
152     /*
153      * @see IReconcilingStrategy#reconcile(DirtyRegion, IRegion)
154      */

155     public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
156         reconcile(false);
157     }
158
159     /*
160      * @see IReconcilingStrategy#setDocument(IDocument)
161      */

162     public void setDocument(IDocument document) {
163     }
164
165     /*
166      * @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor)
167      */

168     public void setProgressMonitor(IProgressMonitor monitor) {
169         fProgressMonitor= monitor;
170     }
171
172     /*
173      * @see IReconcilingStrategyExtension#initialReconcile()
174      */

175     public void initialReconcile() {
176         reconcile(true);
177     }
178
179     /**
180      * Tells this strategy whether to inform its listeners.
181      *
182      * @param notify <code>true</code> if listeners should be notified
183      */

184     public void notifyListeners(boolean notify) {
185         fNotify= notify;
186     }
187
188     /**
189      * Called before reconciling is started.
190      *
191      * @since 3.0
192      */

193     public void aboutToBeReconciled() {
194         if (fIsJavaReconcilingListener)
195             fJavaReconcilingListener.aboutToBeReconciled();
196     }
197 }
198
Popular Tags