KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > javaeditor > OverrideIndicatorManager


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.jdt.internal.ui.javaeditor;
13
14 import java.util.HashMap JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.Map JavaDoc;
17
18 import org.eclipse.core.runtime.Assert;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.NullProgressMonitor;
22
23 import org.eclipse.jface.dialogs.MessageDialog;
24
25 import org.eclipse.jface.text.ISynchronizable;
26 import org.eclipse.jface.text.Position;
27 import org.eclipse.jface.text.source.Annotation;
28 import org.eclipse.jface.text.source.IAnnotationModel;
29 import org.eclipse.jface.text.source.IAnnotationModelExtension;
30
31 import org.eclipse.jdt.core.IJavaElement;
32 import org.eclipse.jdt.core.dom.ASTNode;
33 import org.eclipse.jdt.core.dom.ASTVisitor;
34 import org.eclipse.jdt.core.dom.CompilationUnit;
35 import org.eclipse.jdt.core.dom.IMethodBinding;
36 import org.eclipse.jdt.core.dom.ITypeBinding;
37 import org.eclipse.jdt.core.dom.MethodDeclaration;
38 import org.eclipse.jdt.core.dom.SimpleName;
39
40 import org.eclipse.jdt.internal.corext.dom.Bindings;
41 import org.eclipse.jdt.internal.corext.util.JdtFlags;
42 import org.eclipse.jdt.internal.corext.util.Messages;
43
44 import org.eclipse.jdt.ui.JavaUI;
45
46 import org.eclipse.jdt.internal.ui.JavaPlugin;
47 import org.eclipse.jdt.internal.ui.text.java.IJavaReconcilingListener;
48 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
49
50 /**
51  * Manages the override and overwrite indicators for
52  * the given Java element and annotation model.
53  *
54  * @since 3.0
55  */

56 class OverrideIndicatorManager implements IJavaReconcilingListener {
57
58     /**
59      * Overwrite and override indicator annotation.
60      *
61      * @since 3.0
62      */

63     class OverrideIndicator extends Annotation {
64
65         private boolean fIsOverwriteIndicator;
66         private String JavaDoc fAstNodeKey;
67
68         /**
69          * Creates a new override annotation.
70          *
71          * @param isOverwriteIndicator <code>true</code> if this annotation is
72          * an overwrite indicator, <code>false</code> otherwise
73          * @param text the text associated with this annotation
74          * @param key the method binding key
75          * @since 3.0
76          */

77         OverrideIndicator(boolean isOverwriteIndicator, String JavaDoc text, String JavaDoc key) {
78             super(ANNOTATION_TYPE, false, text);
79             fIsOverwriteIndicator= isOverwriteIndicator;
80             fAstNodeKey= key;
81         }
82
83         /**
84          * Tells whether this is an overwrite or an override indicator.
85          *
86          * @return <code>true</code> if this is an overwrite indicator
87          */

88         public boolean isOverwriteIndicator() {
89             return fIsOverwriteIndicator;
90         }
91
92         /**
93          * Opens and reveals the defining method.
94          */

95         public void open() {
96             CompilationUnit ast= ASTProvider.getASTProvider().getAST(fJavaElement, ASTProvider.WAIT_ACTIVE_ONLY, null);
97             if (ast != null) {
98                 ASTNode node= ast.findDeclaringNode(fAstNodeKey);
99                 if (node instanceof MethodDeclaration) {
100                     try {
101                         IMethodBinding methodBinding= ((MethodDeclaration)node).resolveBinding();
102                         IMethodBinding definingMethodBinding= Bindings.findOverriddenMethod(methodBinding, true);
103                         if (definingMethodBinding != null) {
104                             IJavaElement definingMethod= definingMethodBinding.getJavaElement();
105                             if (definingMethod != null) {
106                                 JavaUI.openInEditor(definingMethod, true, true);
107                                 return;
108                             }
109                         }
110                     } catch (CoreException e) {
111                         ExceptionHandler.handle(e, JavaEditorMessages.OverrideIndicatorManager_open_error_title, JavaEditorMessages.OverrideIndicatorManager_open_error_messageHasLogEntry);
112                         return;
113                     }
114                 }
115             }
116             String JavaDoc title= JavaEditorMessages.OverrideIndicatorManager_open_error_title;
117             String JavaDoc message= JavaEditorMessages.OverrideIndicatorManager_open_error_message;
118             MessageDialog.openError(JavaPlugin.getActiveWorkbenchShell(), title, message);
119         }
120     }
121
122     static final String JavaDoc ANNOTATION_TYPE= "org.eclipse.jdt.ui.overrideIndicator"; //$NON-NLS-1$
123

124     private IAnnotationModel fAnnotationModel;
125     private Object JavaDoc fAnnotationModelLockObject;
126     private Annotation[] fOverrideAnnotations;
127     private IJavaElement fJavaElement;
128
129
130     public OverrideIndicatorManager(IAnnotationModel annotationModel, IJavaElement javaElement, CompilationUnit ast) {
131         Assert.isNotNull(annotationModel);
132         Assert.isNotNull(javaElement);
133
134         fJavaElement= javaElement;
135         fAnnotationModel=annotationModel;
136         fAnnotationModelLockObject= getLockObject(fAnnotationModel);
137
138         updateAnnotations(ast, new NullProgressMonitor());
139     }
140
141     /**
142      * Returns the lock object for the given annotation model.
143      *
144      * @param annotationModel the annotation model
145      * @return the annotation model's lock object
146      * @since 3.0
147      */

148     private Object JavaDoc getLockObject(IAnnotationModel annotationModel) {
149         if (annotationModel instanceof ISynchronizable) {
150             Object JavaDoc lock= ((ISynchronizable)annotationModel).getLockObject();
151             if (lock != null)
152                 return lock;
153         }
154         return annotationModel;
155     }
156
157     /**
158      * Updates the override and implements annotations based
159      * on the given AST.
160      *
161      * @param ast the compilation unit AST
162      * @param progressMonitor the progress monitor
163      * @since 3.0
164      */

165     protected void updateAnnotations(CompilationUnit ast, IProgressMonitor progressMonitor) {
166
167         if (ast == null || progressMonitor.isCanceled())
168             return;
169
170         final Map JavaDoc annotationMap= new HashMap JavaDoc(50);
171
172         ast.accept(new ASTVisitor(false) {
173             /*
174              * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
175              */

176             public boolean visit(MethodDeclaration node) {
177                 IMethodBinding binding= node.resolveBinding();
178                 if (binding != null) {
179                     IMethodBinding definingMethod= Bindings.findOverriddenMethod(binding, true);
180                     if (definingMethod != null) {
181
182                         ITypeBinding definingType= definingMethod.getDeclaringClass();
183                         String JavaDoc qualifiedMethodName= definingType.getQualifiedName() + "." + binding.getName(); //$NON-NLS-1$
184

185                         boolean isImplements= JdtFlags.isAbstract(definingMethod);
186                         String JavaDoc text;
187                         if (isImplements)
188                             text= Messages.format(JavaEditorMessages.OverrideIndicatorManager_implements, qualifiedMethodName);
189                         else
190                             text= Messages.format(JavaEditorMessages.OverrideIndicatorManager_overrides, qualifiedMethodName);
191
192                         SimpleName name= node.getName();
193                         Position position= new Position(name.getStartPosition(), name.getLength());
194
195                         annotationMap.put(
196                                 new OverrideIndicator(isImplements, text, binding.getKey()),
197                                 position);
198
199                     }
200                 }
201                 return true;
202             }
203         });
204
205         if (progressMonitor.isCanceled())
206             return;
207
208         synchronized (fAnnotationModelLockObject) {
209             if (fAnnotationModel instanceof IAnnotationModelExtension) {
210                 ((IAnnotationModelExtension)fAnnotationModel).replaceAnnotations(fOverrideAnnotations, annotationMap);
211             } else {
212                 removeAnnotations();
213                 Iterator JavaDoc iter= annotationMap.entrySet().iterator();
214                 while (iter.hasNext()) {
215                     Map.Entry JavaDoc mapEntry= (Map.Entry JavaDoc)iter.next();
216                     fAnnotationModel.addAnnotation((Annotation)mapEntry.getKey(), (Position)mapEntry.getValue());
217                 }
218             }
219             fOverrideAnnotations= (Annotation[])annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]);
220         }
221     }
222
223     /**
224      * Removes all override indicators from this manager's annotation model.
225      */

226     void removeAnnotations() {
227         if (fOverrideAnnotations == null)
228             return;
229
230         synchronized (fAnnotationModelLockObject) {
231             if (fAnnotationModel instanceof IAnnotationModelExtension) {
232                 ((IAnnotationModelExtension)fAnnotationModel).replaceAnnotations(fOverrideAnnotations, null);
233             } else {
234                 for (int i= 0, length= fOverrideAnnotations.length; i < length; i++)
235                     fAnnotationModel.removeAnnotation(fOverrideAnnotations[i]);
236             }
237             fOverrideAnnotations= null;
238         }
239     }
240
241     /*
242      * @see org.eclipse.jdt.internal.ui.text.java.IJavaReconcilingListener#aboutToBeReconciled()
243      */

244     public void aboutToBeReconciled() {
245     }
246
247     /*
248      * @see org.eclipse.jdt.internal.ui.text.java.IJavaReconcilingListener#reconciled(CompilationUnit, boolean, IProgressMonitor)
249      */

250     public void reconciled(CompilationUnit ast, boolean forced, IProgressMonitor progressMonitor) {
251         updateAnnotations(ast, progressMonitor);
252     }
253 }
254
255
Popular Tags