KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > gui2 > SourceCodeDisplay


1 /*
2  * FindBugs - Find Bugs in Java programs
3  * Copyright (C) 2006, University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307, USA
18  */

19
20 package edu.umd.cs.findbugs.gui2;
21
22 import java.awt.Color JavaDoc;
23 import java.io.FileReader JavaDoc;
24 import java.io.InputStream JavaDoc;
25 import java.io.InputStreamReader JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.LinkedList JavaDoc;
29 import java.util.Map JavaDoc;
30
31 import javax.swing.JTextPane JavaDoc;
32 import javax.swing.text.DefaultStyledDocument JavaDoc;
33 import javax.swing.text.Document JavaDoc;
34 import javax.swing.text.Element JavaDoc;
35 import javax.swing.text.StyledDocument JavaDoc;
36 import javax.swing.text.BadLocationException JavaDoc;
37
38 import edu.umd.cs.findbugs.BugAnnotation;
39 import edu.umd.cs.findbugs.BugInstance;
40 import edu.umd.cs.findbugs.SourceLineAnnotation;
41 import edu.umd.cs.findbugs.annotations.CheckForNull;
42 import edu.umd.cs.findbugs.annotations.NonNull;
43 import edu.umd.cs.findbugs.ba.SourceFile;
44 import edu.umd.cs.findbugs.sourceViewer.JavaSourceDocument;
45
46 public final class SourceCodeDisplay implements Runnable JavaDoc {
47     final MainFrame frame;
48
49     private static final Color JavaDoc MAIN_HIGHLIGHT = new Color JavaDoc(1f, 1f, 0.5f);
50     private static final Color JavaDoc MAIN_HIGHLIGHT_MORE = MAIN_HIGHLIGHT.brighter();
51     private static final Color JavaDoc ALTERNATIVE_HIGHLIGHT = new Color JavaDoc(0.86f, 0.90f, 1.0f);
52     private static final Color JavaDoc FOUND_HIGHLIGHT = new Color JavaDoc(0.75f, 0.75f, 1f);
53
54     static final Document JavaDoc SOURCE_NOT_RELEVANT = new DefaultStyledDocument JavaDoc();;
55     
56     public JavaSourceDocument myDocument;
57     private int currentChar = -1; //for find
58

59     private final Map JavaDoc<String JavaDoc, JavaSourceDocument> map = new HashMap JavaDoc<String JavaDoc, JavaSourceDocument>();
60
61     SourceCodeDisplay(MainFrame frame) {
62         this.frame = frame;
63         Thread JavaDoc t = new Thread JavaDoc(this, "Source code display thread");
64         t.setDaemon(true);
65         t.start();
66     }
67
68     private boolean pendingUpdate;
69
70     @CheckForNull private BugInstance bugToDisplay;
71
72     private SourceLineAnnotation sourceToHighlight;
73
74     public synchronized void displaySource(BugInstance bug,
75             SourceLineAnnotation source) {
76         bugToDisplay = bug;
77         sourceToHighlight = source;
78         pendingUpdate = true;
79         notifyAll();
80     }
81
82     public void clearCache() {
83         map.clear();
84     }
85     
86     @NonNull
87     private JavaSourceDocument getDocument(SourceLineAnnotation source) {
88         try {
89             SourceFile sourceFile = frame.sourceFinder.findSourceFile(source);
90             String JavaDoc fullFileName = sourceFile.getFullFileName();
91             JavaSourceDocument result = map.get(fullFileName);
92             if (result != null)
93                 return result;
94             try {
95                 InputStream JavaDoc in = sourceFile.getInputStream();
96                 result = new JavaSourceDocument(source.getClassName(),
97                         new InputStreamReader JavaDoc(in), sourceFile);
98             } catch (Exception JavaDoc e) {
99                 result = JavaSourceDocument.UNKNOWNSOURCE;
100                 Debug.println(e); // e.printStackTrace();
101
}
102             map.put(fullFileName, result);
103             return result;
104         } catch (Exception JavaDoc e) {
105             Debug.println(e); // e.printStackTrace();
106
return JavaSourceDocument.UNKNOWNSOURCE;
107         
108         }
109     }
110
111     public void run() {
112         while (true) {
113             BugInstance myBug;
114             SourceLineAnnotation mySourceLine;
115             synchronized (this) {
116                 while (!pendingUpdate) {
117                     try {
118                         wait();
119                     } catch (InterruptedException JavaDoc e) {
120                         // we don't use these
121
}
122                 }
123                 myBug = bugToDisplay;
124                 mySourceLine = sourceToHighlight;
125                 bugToDisplay = null;
126                 sourceToHighlight = null;
127                 pendingUpdate = false;
128             }
129             if (myBug == null) {
130                 frame.clearSourcePane();
131                 continue;
132             }
133             
134             try {
135             final JavaSourceDocument src = getDocument(mySourceLine);
136             this.myDocument = src;
137             src.getHighlightInformation().clear();
138             String JavaDoc primaryKind = mySourceLine.getDescription();
139             // Display myBug and mySourceLine
140
for(Iterator JavaDoc<BugAnnotation> i = myBug.annotationIterator(); i.hasNext(); ) {
141                 BugAnnotation annotation = i.next();
142                 if (annotation instanceof SourceLineAnnotation) {
143                     SourceLineAnnotation sourceAnnotation = (SourceLineAnnotation) annotation;
144                     if (sourceAnnotation == mySourceLine) continue;
145                     if (sourceAnnotation.getDescription().equals(primaryKind))
146                         highlight(src, sourceAnnotation, MAIN_HIGHLIGHT_MORE);
147                     else
148                         highlight(src, sourceAnnotation, ALTERNATIVE_HIGHLIGHT);
149                 }
150             }
151             highlight(src, mySourceLine, MAIN_HIGHLIGHT);
152             final BugInstance thisBug = myBug;
153             final SourceLineAnnotation thisSource = mySourceLine;
154             javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc() {
155                 public void run() {
156                     frame.sourceCodeTextPane.setEditorKit(src.getEditorKit());
157                     StyledDocument JavaDoc document = src.getDocument();
158                     frame.sourceCodeTextPane.setDocument(document);
159                     frame.setSourceTabTitle(thisSource.getSourceFile() + " in " + thisSource.getPackageName());
160                     int startLine = thisSource.getStartLine();
161                     int endLine = thisSource.getEndLine();
162                     int originLine = (startLine + endLine) / 2;
163                     LinkedList JavaDoc<Integer JavaDoc> otherLines = new LinkedList JavaDoc<Integer JavaDoc>();
164                     //show(frame.sourceCodeTextPane, document, thisSource);
165
for(Iterator JavaDoc<BugAnnotation> i = thisBug.annotationIterator(); i.hasNext(); ) {
166                         BugAnnotation annotation = i.next();
167                         if (annotation instanceof SourceLineAnnotation) {
168                             SourceLineAnnotation sourceAnnotation = (SourceLineAnnotation) annotation;
169                             if (sourceAnnotation != thisSource) {
170                                 //show(frame.sourceCodeTextPane, document, sourceAnnotation);
171
int otherLine = sourceAnnotation.getStartLine();
172                                 if (otherLine > originLine) otherLine = sourceAnnotation.getEndLine();
173                                 otherLines.add(otherLine);
174                             }
175                         }
176                     }
177                     //show(frame.sourceCodeTextPane, document, thisSource);
178
if (startLine >= 0 && endLine >= 0)
179                     frame.sourceCodeTextPane.scrollLinesToVisible(startLine, endLine, otherLines);
180                 }
181             });
182         } catch (Exception JavaDoc e) {
183             Debug.println(e); // e.printStackTrace();
184
}
185         }
186     }
187
188     /**
189      * @param src
190      * @param sourceAnnotation
191      */

192     private void highlight(JavaSourceDocument src, SourceLineAnnotation sourceAnnotation, Color JavaDoc color) {
193
194         int startLine = sourceAnnotation.getStartLine();
195         if (startLine == -1) return;
196         if (!sourceAnnotation.getClassName().equals(src.getTitle())) return;
197         src.getHighlightInformation().setHighlight(startLine, sourceAnnotation.getEndLine(), color);
198     }
199     
200     public void foundItem(int lineNum) {
201         myDocument.getHighlightInformation().updateFoundLineNum(lineNum);
202         myDocument.getHighlightInformation().setHighlight(lineNum, FOUND_HIGHLIGHT);
203         frame.sourceCodeTextPane.scrollLineToVisible(lineNum);
204         frame.sourceCodeTextPane.updateUI();
205     }
206     
207     private int search(JavaSourceDocument document, String JavaDoc target, int start, Boolean JavaDoc backwards)
208     {
209         String JavaDoc docContent = null;
210         try{
211         docContent = document.getDocument().getText(0, document.getDocument().getLength());
212         }
213         catch(BadLocationException JavaDoc ble){System.out.println("Bad location exception");}
214         catch(NullPointerException JavaDoc npe){return -1;}
215         if(docContent == null) return -1;
216         int targetLen = target.length();
217         int sourceLen = docContent.length();
218         if(targetLen > sourceLen)
219             return -1;
220         else if(backwards)
221         {
222             for(int i=start; i>=0; i--)
223                 if(docContent.substring(i, i+targetLen).equals(target))
224                     return i;
225             for(int i=(sourceLen-targetLen); i>start; i--)
226                 if(docContent.substring(i, i+targetLen).equals(target))
227                     return i;
228             return -1;
229         }
230         else
231         {
232             for(int i=start; i<=(sourceLen-targetLen); i++)
233                 if(docContent.substring(i, i+targetLen).equals(target))
234                     return i;
235             for(int i=0; i<start; i++)
236                 if(docContent.substring(i, i+targetLen).equals(target))
237                     return i;
238             return -1;
239         }
240     }
241     
242     private int charToLineNum(int charNum)
243     {
244         if(charNum==-1) return -1;
245         try
246         {
247             for(int i=1; true; i++){
248                 if(frame.sourceCodeTextPane.getLineOffset(i) > charNum)
249                     return i-1;
250                 else if(frame.sourceCodeTextPane.getLineOffset(i) == -1)
251                     return -1;
252             }
253         }
254         catch(BadLocationException JavaDoc ble){return -1;}
255     }
256     
257     public int find(String JavaDoc target)
258     {
259         int charFoundAt = search(myDocument, target, 0, false);
260         currentChar = charFoundAt;
261         //System.out.println(currentChar);
262
//System.out.println(charToLineNum(currentChar));
263
return charToLineNum(currentChar);
264     }
265     
266     public int findNext(String JavaDoc target)
267     {
268         int charFoundAt = search(myDocument, target, currentChar+1, false);
269         currentChar = charFoundAt;
270         //System.out.println(currentChar);
271
//System.out.println(charToLineNum(currentChar));
272
return charToLineNum(currentChar);
273     }
274     
275     public int findPrevious(String JavaDoc target)
276     {
277         int charFoundAt = search(myDocument, target, currentChar-1, true);
278         currentChar = charFoundAt;
279         //System.out.println(currentChar);
280
//System.out.println(charToLineNum(currentChar));
281
return charToLineNum(currentChar);
282     }
283     
284     private void show(JTextPane JavaDoc pane, Document JavaDoc src, SourceLineAnnotation sourceAnnotation) {
285
286         int startLine = sourceAnnotation.getStartLine();
287         if (startLine == -1) return;
288         frame.sourceCodeTextPane.scrollLineToVisible(startLine);
289         /*
290         Element element = src.getDefaultRootElement().getElement(sourceAnnotation.getStartLine()-1);
291         if (element == null) {
292             if (MainFrame.DEBUG) {
293             System.out.println("Couldn't display line " + sourceAnnotation.getStartLine() + " of " + sourceAnnotation.getSourceFile());
294             System.out.println("It only seems to have " + src.getDefaultRootElement().getElementCount() + " lines");
295             }
296             return;
297         }
298         pane.setCaretPosition(element.getStartOffset());
299         */

300     }
301
302     public void showLine(int line) {
303         frame.sourceCodeTextPane.scrollLineToVisible(line);
304         /*
305         JTextPane pane = frame.sourceCodeTextPane;
306         Document doc = pane.getDocument();
307         Element element = doc.getDefaultRootElement().getElement(line-1);
308         pane.setCaretPosition(element.getStartOffset());
309         */

310     }
311 }
312
Popular Tags