KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > editor > semantic > MarkOccurencesHighlighter


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.java.editor.semantic;
20
21 import com.sun.source.tree.ClassTree;
22 import com.sun.source.tree.CompilationUnitTree;
23 import com.sun.source.tree.IdentifierTree;
24 import com.sun.source.tree.MemberSelectTree;
25 import com.sun.source.tree.MethodTree;
26 import com.sun.source.tree.PrimitiveTypeTree;
27 import com.sun.source.tree.Tree;
28 import com.sun.source.util.SourcePositions;
29 import com.sun.source.util.TreePath;
30 import java.awt.Color JavaDoc;
31 import java.beans.PropertyChangeEvent JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.util.Collections JavaDoc;
34 import java.util.Set JavaDoc;
35 import java.util.logging.Level JavaDoc;
36 import java.util.logging.Logger JavaDoc;
37 import javax.lang.model.element.Element;
38 import javax.swing.event.CaretEvent JavaDoc;
39 import javax.swing.text.Document JavaDoc;
40 import javax.swing.text.JTextComponent JavaDoc;
41 import org.netbeans.api.java.source.CancellableTask;
42 import org.netbeans.api.java.source.CompilationInfo;
43 import org.netbeans.api.timers.TimesCollector;
44 import org.netbeans.modules.editor.highlights.spi.Highlight;
45 import org.netbeans.modules.editor.highlights.spi.Highlighter;
46 import org.openide.ErrorManager;
47 import org.openide.cookies.EditorCookie;
48 import org.openide.filesystems.FileObject;
49 import org.openide.filesystems.FileUtil;
50 import org.openide.loaders.DataObject;
51
52 /**
53  *
54  * @author Jan Lahoda
55  */

56 public class MarkOccurencesHighlighter implements CancellableTask<CompilationInfo> {
57     
58     private FileObject file;
59     
60     /** Creates a new instance of SemanticHighlighter */
61     MarkOccurencesHighlighter(FileObject file) {
62         this.file = file;
63     }
64     
65     public static final Color JavaDoc ES_COLOR = new Color JavaDoc( 175, 172, 102 ); // new Color(244, 164, 113);
66

67     public Document JavaDoc getDocument() {
68         try {
69             DataObject d = DataObject.find(file);
70             EditorCookie ec = (EditorCookie) d.getCookie(EditorCookie.class);
71             
72             if (ec == null)
73                 return null;
74             
75             return ec.getDocument();
76         } catch (IOException JavaDoc e) {
77             Logger.getLogger(MarkOccurencesHighlighter.class.getName()).log(Level.INFO, "SemanticHighlighter: Cannot find DataObject for file: " + FileUtil.getFileDisplayName(file), e);
78             return null;
79         }
80     }
81     
82     public void run(CompilationInfo info) {
83         resume();
84         
85         Document JavaDoc doc = getDocument();
86         
87         if (doc == null) {
88             Logger.getLogger(MarkOccurencesHighlighter.class.getName()).log(Level.INFO, "SemanticHighlighter: Cannot get document!");
89             return ;
90         }
91         
92         long start = System.currentTimeMillis();
93         
94         int caretPosition = MarkOccurrencesHighlighterFactory.getLastPosition(file);
95         
96         if (isCancelled())
97             return;
98         
99         Set JavaDoc<Highlight> highlights = processImpl(info, doc, caretPosition);
100         
101         if (isCancelled())
102             return;
103         
104         TimesCollector.getDefault().reportTime(((DataObject) doc.getProperty(Document.StreamDescriptionProperty)).getPrimaryFile(), "occurrences", "Occurrences", (System.currentTimeMillis() - start));
105         
106         Highlighter.getDefault().setHighlights(file, "occurrences", highlights);
107         OccurrencesMarkProvider.get(doc).setOccurrences(highlights);
108     }
109     
110     private boolean isIn(CompilationUnitTree cu, SourcePositions sp, Tree tree, int position) {
111         return sp.getStartPosition(cu, tree) <= position && position <= sp.getEndPosition(cu, tree);
112     }
113     
114     private boolean isIn(int caretPosition, int[] span) {
115 // System.err.println("caretPosition = " + caretPosition );
116
// System.err.println("span[0]= " + span[0]);
117
// System.err.println("span[1]= " + span[1]);
118
return span[0] <= caretPosition && caretPosition <= span[1];
119     }
120     
121     Set JavaDoc<Highlight> processImpl(CompilationInfo info, Document JavaDoc doc, int caretPosition) {
122         CompilationUnitTree cu = info.getCompilationUnit();
123         Tree lastTree = null;
124         Set JavaDoc<Highlight> localUsages = null;
125         TreePath tp = info.getTreeUtilities().pathFor(caretPosition);
126         while(tp != null) {
127             if (isCancelled())
128                 return Collections.emptySet();
129             
130             Tree tree = tp.getLeaf();
131             //detect caret inside the return type or throws clause:
132
if (tree instanceof MethodTree && (lastTree instanceof IdentifierTree
133                     || lastTree instanceof PrimitiveTypeTree
134                     || lastTree instanceof MemberSelectTree)) {
135                 //hopefully found something, check:
136
MethodTree decl = (MethodTree) tree;
137                 Tree type = decl.getReturnType();
138                 
139                 if (isIn(cu, info.getTrees().getSourcePositions(), type, caretPosition)) {
140                     MethodExitDetector med = new MethodExitDetector();
141                     
142                     setExitDetector(med);
143                     
144                     try {
145                         return med.process(info, doc, decl, null);
146                     } finally {
147                         setExitDetector(null);
148                     }
149                 }
150                 
151                 for (Tree exc : decl.getThrows()) {
152                     if (isIn(cu, info.getTrees().getSourcePositions(), exc, caretPosition)) {
153                         MethodExitDetector med = new MethodExitDetector();
154                         
155                         setExitDetector(med);
156                         
157                         try {
158                             return med.process(info, doc, decl, Collections.singletonList(exc));
159                         } finally {
160                             setExitDetector(null);
161                         }
162                     }
163                 }
164             }
165             
166             if (localUsages != null)
167                 return localUsages;
168             
169             //variable declaration:
170
Element el = info.getTrees().getElement(tp);
171             if ( el != null
172                     && (!(tree instanceof ClassTree) || isIn(caretPosition, Utilities.findIdentifierSpan(tp, cu, info.getTrees().getSourcePositions(), doc)))
173                     && !Utilities.isKeyword(tree)
174                     && (!(tree instanceof MethodTree) || lastTree == null)) {
175                 FindLocalUsagesQuery fluq = new FindLocalUsagesQuery();
176                 
177                 setLocalUsages(fluq);
178                 
179                 try {
180                     localUsages = fluq.findUsages(el, info, doc);
181                 } finally {
182                     setLocalUsages(null);
183                 }
184             }
185             lastTree = tree;
186             tp = tp.getParentPath();
187         }
188         
189         if (localUsages != null)
190             return localUsages;
191         
192         return Collections.emptySet();
193     }
194     
195     private boolean canceled;
196     private MethodExitDetector exitDetector;
197     private FindLocalUsagesQuery localUsages;
198     
199     private final synchronized void setExitDetector(MethodExitDetector detector) {
200         this.exitDetector = detector;
201     }
202     
203     private final synchronized void setLocalUsages(FindLocalUsagesQuery localUsages) {
204         this.localUsages = localUsages;
205     }
206     
207     public final synchronized void cancel() {
208         canceled = true;
209         
210         if (exitDetector != null) {
211             exitDetector.cancel();
212         }
213         if (localUsages != null) {
214             localUsages.cancel();
215         }
216     }
217     
218     protected final synchronized boolean isCancelled() {
219         return canceled;
220     }
221     
222     protected final synchronized void resume() {
223         canceled = false;
224     }
225     
226 }
227
Popular Tags