KickJava   Java API By Example, From Geeks To Geeks.

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


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.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31
32 import javax.swing.JFileChooser JavaDoc;
33 import javax.swing.JOptionPane JavaDoc;
34
35 import org.dom4j.DocumentException;
36
37 import edu.umd.cs.findbugs.AbstractBugReporter;
38 import edu.umd.cs.findbugs.BugCollection;
39 import edu.umd.cs.findbugs.BugInstance;
40 import edu.umd.cs.findbugs.BugReporter;
41 import edu.umd.cs.findbugs.BugReporterObserver;
42 import edu.umd.cs.findbugs.DetectorFactoryCollection;
43 import edu.umd.cs.findbugs.FindBugs;
44 import edu.umd.cs.findbugs.FindBugs2;
45 import edu.umd.cs.findbugs.FindBugsProgress;
46 import edu.umd.cs.findbugs.IFindBugsEngine;
47 import edu.umd.cs.findbugs.Priorities;
48 import edu.umd.cs.findbugs.Project;
49 import edu.umd.cs.findbugs.ProjectStats;
50 import edu.umd.cs.findbugs.SortedBugCollection;
51 import edu.umd.cs.findbugs.annotations.NonNull;
52 import edu.umd.cs.findbugs.ba.JavaClassAndMethod;
53 import edu.umd.cs.findbugs.ba.MissingClassException;
54 import edu.umd.cs.findbugs.ba.SourceFinder;
55 import edu.umd.cs.findbugs.classfile.ClassDescriptor;
56 import edu.umd.cs.findbugs.classfile.MethodDescriptor;
57 import edu.umd.cs.findbugs.config.UserPreferences;
58 import edu.umd.cs.findbugs.workflow.Update;
59
60 /**
61  * Everything having to do with loading bugs should end up here.
62  * @author Dan
63  *
64  */

65 public class BugLoader {
66     
67     public static BugCollection mainBugCollection = null; //this is so the Sortables can look up AppVersions; this probably isn't the right place to put it
68

69     private static Project loadedProject;
70     
71     /**
72      * This is how we attach to a FindBugs analysis, the PrintCallBack ignores most things FindBugs returns to us, implementing things like showing what classes were missing might be done here.
73      * This just adds all the bugs FindBugs finds to our BugSet.
74      * @author Dan
75      *
76      */

77     private static class PrintCallBack implements edu.umd.cs.findbugs.BugReporter
78     {
79         FindBugs fb;
80         ArrayList JavaDoc<BugLeafNode> bugs;
81         ArrayList JavaDoc<BugReporterObserver> bros;
82         ArrayList JavaDoc<String JavaDoc> errorLog;
83         boolean done;
84         int priorityThreadhold = Priorities.LOW_PRIORITY;
85         
86         PrintCallBack()
87         {
88             bros=new ArrayList JavaDoc<BugReporterObserver>();
89             errorLog=new ArrayList JavaDoc<String JavaDoc>();
90             bugs=new ArrayList JavaDoc<BugLeafNode>();
91             done=false;
92         }
93         
94         public void setEngine(FindBugs engine) {
95             if (done==true)
96             {
97                 throw new IllegalStateException JavaDoc("This PrintCallBack has already finished its analysis, create a new callback if you want another analysis done");
98             }
99             if (fb!=null)
100             {
101                 throw new IllegalStateException JavaDoc("The engine has already been set, but the analysis was not finished, create a new callback instead of running multiple analyses from this one");
102             }
103             fb=engine;
104 // System.out.println("Engine Set!");
105
}
106
107         public void setErrorVerbosity(int level) {
108 // System.out.println("Error Verbosity set at " + level);
109
}
110
111         public void setPriorityThreshold(int threshold) {
112             priorityThreadhold = Math.min(Priorities.EXP_PRIORITY, threshold);
113         }
114
115         public void reportBug(BugInstance bugInstance) {
116             if (bugInstance.getPriority() > priorityThreadhold) return;
117             BugLeafNode b = new BugLeafNode(bugInstance);
118             bugs.add(b);
119         }
120
121         public void finish() {
122 // System.out.println("All Done!");
123
for (String JavaDoc s: errorLog)
124             {
125                 System.err.println(s);
126             }
127             done=true;
128         }
129
130         public void reportQueuedErrors() {
131 // System.out.println("We are supposed to report queued errors, whatever that means.");
132
// System.out.println(errorLog);
133
}
134
135         public void addObserver(BugReporterObserver observer) {
136             bros.add(observer);
137         }
138
139         public ProjectStats getProjectStats() {
140 // System.out.println("Oh noes, look out for null pointers!");
141
return null;
142         }
143
144         public BugReporter getRealBugReporter() {
145             return this;
146         }
147
148         public void reportMissingClass(ClassNotFoundException JavaDoc ex) {
149             Debug.println(ex);
150         }
151
152         public void reportSkippedAnalysis(JavaClassAndMethod method) {
153 // System.out.println("we skipped something" + method);
154
}
155
156         public void logError(String JavaDoc message) {
157 // System.out.println("logging an error");
158
errorLog.add(message);
159         }
160
161         public void logError(String JavaDoc message, Throwable JavaDoc e) {
162             if (e instanceof MissingClassException) {
163                 reportMissingClass(((MissingClassException)e).getClassNotFoundException());
164                 return;
165             }
166 // System.out.println("logging an error with stack trace");
167
// e.printStackTrace();
168
errorLog.add(message);
169         }
170
171         public void observeClass(ClassDescriptor classDescriptor) {
172 // System.out.println("I am now observing ClassDescriptor " + classDescriptor);
173
}
174
175         public BugSet getBugs()
176         {
177             return new BugSet(bugs);
178         }
179
180         public void reportSkippedAnalysis(MethodDescriptor method) {
181 // System.out.println("method " + method.getMethodName() + " of class " + method.getClassName() + " was skipped");
182
}
183
184         /* (non-Javadoc)
185          * @see edu.umd.cs.findbugs.classfile.IErrorLogger#reportMissingClass(edu.umd.cs.findbugs.classfile.ClassDescriptor)
186          */

187         public void reportMissingClass(ClassDescriptor classDescriptor) {
188             // TODO Auto-generated method stub
189

190         }
191
192         
193     }
194     
195     /**
196      * Performs an analysis and returns the BugSet created
197      *
198      * @param p The Project to run the analysis on
199      * @param progressCallback the progressCallBack is supposed to be supplied by analyzing dialog, FindBugs supplies progress information while it runs the analysis
200      * @return the bugs found
201      */

202     public static BugSet doAnalysis(@NonNull Project p, FindBugsProgress progressCallback)
203     {
204         PrintCallBack pcb=new PrintCallBack();
205         IFindBugsEngine fb=createEngine(p, pcb);
206         fb.setUserPreferences(UserPreferences.getUserPreferences());
207         fb.setProgressCallback(progressCallback);
208         try {
209             fb.execute();
210             List JavaDoc<String JavaDoc> possibleDirectories=p.getSourceDirList();
211 // System.out.println("List of directories: "+p.getSourceDirList());
212
MainFrame.getInstance().setSourceFinder(new SourceFinder());
213             MainFrame.getInstance().getSourceFinder().setSourceBaseList(possibleDirectories);
214
215             return pcb.getBugs();
216         } catch (IOException JavaDoc e) {
217             Debug.println(e);
218         } catch (InterruptedException JavaDoc e) {
219             // Do nothing
220
}
221         
222         
223         return null;
224         
225     }
226
227     /**
228      * Create the IFindBugsEngine that will be used to
229      * analyze the application.
230      *
231      * @param p the Project
232      * @param pcb the PrintCallBack
233      * @return the IFindBugsEngine
234      */

235     private static IFindBugsEngine createEngine(@NonNull Project p, PrintCallBack pcb)
236     {
237         if (false) {
238             // Old driver - don't use
239
return new FindBugs(pcb, p);
240         } else {
241             FindBugs2 engine = new FindBugs2();
242             engine.setBugReporter(pcb);
243             engine.setProject(p);
244             
245             engine.setDetectorFactoryCollection(DetectorFactoryCollection.instance());
246             
247             return engine;
248         }
249     }
250     
251     public static BugSet loadBugsHelper(BugCollection collection)
252     {
253         mainBugCollection = collection;
254         ArrayList JavaDoc<BugLeafNode> bugList=new ArrayList JavaDoc<BugLeafNode>();
255         Iterator JavaDoc<BugInstance> i=collection.iterator();
256         while (i.hasNext())
257         {
258             bugList.add(new BugLeafNode(i.next()));
259         }
260         
261         return new BugSet(bugList);
262         
263     }
264     
265     public static BugSet loadBugs(Project project, URL JavaDoc url){
266         try {
267             return loadBugs(project, url.openConnection().getInputStream());
268         } catch (IOException JavaDoc e) {
269             JOptionPane.showMessageDialog(null,"This file contains no bug data");
270         }
271         return null;
272     }
273     public static BugSet loadBugs(Project project, File JavaDoc file){
274         try {
275             return loadBugs(project, new FileInputStream JavaDoc(file));
276         } catch (IOException JavaDoc e) {
277             JOptionPane.showMessageDialog(null,"This file contains no bug data");
278         }
279         return null;
280     }
281     public static BugSet loadBugs(Project project, InputStream JavaDoc in)
282     {
283             try
284             {
285                 SortedBugCollection col=new SortedBugCollection();
286                 col.readXML(in, project);
287                 List JavaDoc<String JavaDoc> possibleDirectories=project.getSourceDirList();
288                 MainFrame.getInstance().setSourceFinder(new SourceFinder());
289                 MainFrame.getInstance().getSourceFinder().setSourceBaseList(possibleDirectories);
290
291                 return loadBugsHelper(col);
292             } catch (IOException JavaDoc e) {
293                 JOptionPane.showMessageDialog(null,"This file contains no bug data");
294             } catch (DocumentException e) {
295                 JOptionPane.showMessageDialog(null,"This file does not have the correct format; it may be corrupt.");
296             }
297             return null;
298     }
299
300
301     public static Project getLoadedProject()
302     {
303         return loadedProject;
304     }
305     
306     private BugLoader()
307     {
308         //NO.
309
}
310     
311     /**
312      * TODO: This really needs to be rewritten such that they don't have to choose ALL xmls in one fel swoop. I'm thinking something more like new project wizard's functionality. -Dan
313      *
314      * Merges bug collection histories from xmls selected by the user. Right now all xmls must be in the same folder and he must select all of them at once
315      * Makes use of FindBugs's mergeCollection method in the Update class of the workflow package
316      * @return the merged collecction of bugs
317      */

318     public static BugSet combineBugHistories()
319     {
320         try
321         {
322             FBFileChooser chooser=new FBFileChooser();
323             chooser.setFileFilter(new FindBugsAnalysisFileFilter());
324 // chooser.setCurrentDirectory(GUISaveState.getInstance().getStarterDirectoryForLoadBugs()); This is done by FBFileChooser.
325
chooser.setMultiSelectionEnabled(true);
326             chooser.setDialogTitle(edu.umd.cs.findbugs.L10N.getLocalString("dlg.choose_xmls_ttl", "Choose All XML's To Combine"));
327             if (chooser.showOpenDialog(MainFrame.getInstance())==JFileChooser.CANCEL_OPTION)
328                 return null;
329             
330             loadedProject=new Project();
331             SortedBugCollection conglomeration=new SortedBugCollection();
332             conglomeration.readXML(chooser.getSelectedFiles()[0],loadedProject);
333             Update update = new Update();
334             for (int x=1; x<chooser.getSelectedFiles().length;x++)
335             {
336                 File JavaDoc f=chooser.getSelectedFiles()[x];
337                 Project p=new Project();
338                 SortedBugCollection col=new SortedBugCollection();
339                 col.readXML(f,p);
340                 conglomeration=(SortedBugCollection) update.mergeCollections(conglomeration, col, false);//False means dont show dead bugs
341
}
342             
343             return loadBugsHelper(conglomeration);
344         } catch (IOException JavaDoc e) {
345             Debug.println(e);
346             return null;
347         } catch (DocumentException e) {
348             Debug.println(e);
349             return null;
350         }
351
352     }
353     
354     /**
355      * Does what it says it does, hit apple r (control r on pc) and the analysis is redone using the current project
356      * @param p
357      * @return the bugs from the reanalysis, or null if cancelled
358      */

359     public static BugSet redoAnalysisKeepComments(@NonNull Project p)
360     {
361         BugSet oldSet=BugSet.getMainBugSet();
362         SortedBugCollection current=new SortedBugCollection();
363         
364         for (BugLeafNode node: oldSet)
365         {
366             BugInstance bug=node.getBug();
367             current.add(bug);
368         }
369         Update update = new Update();
370         final SortedBugCollection justAnalyzed=new SortedBugCollection();
371         
372         RedoAnalysisCallback ac= new RedoAnalysisCallback(justAnalyzed);
373         
374         new AnalyzingDialog(p,ac,true);
375         
376         if (ac.finished)
377             return loadBugsHelper(update.mergeCollections(current, justAnalyzed, false));
378         else
379             return null;
380         
381     }
382     
383     /** just used to know how the new analysis went*/
384     private static class RedoAnalysisCallback implements AnalysisCallback
385     {
386         public RedoAnalysisCallback(SortedBugCollection collection)
387         {
388             justAnalyzed=collection;
389         }
390         
391         SortedBugCollection justAnalyzed;
392         boolean finished;
393         public void analysisFinished(BugSet b)
394         {
395             for(BugLeafNode node: b)
396             {
397                 BugInstance bug=node.getBug();
398                 justAnalyzed.add(bug);
399             }
400             finished=true;
401         }
402
403         public void analysisInterrupted()
404         {
405             finished=false;
406         }
407     }
408 }
Popular Tags