9a8d7a64c4ea6f7a4069dfb3b396e1ddd65f382f
[cfb.git] / prod / net / jaekl / cfb / analyze / Analyzer.java
1 package net.jaekl.cfb.analyze;
2
3 // Copyright (C) 2015 Christian Jaekl
4
5 import java.io.File;
6 import java.io.IOException;
7 import java.io.PrintWriter;
8 import java.text.MessageFormat;
9 import java.util.Locale;
10 import java.util.Locale.Category;
11
12 import org.xml.sax.SAXException;
13
14 import net.jaekl.cfb.CfbBundle;
15 import net.jaekl.cfb.util.Command;
16 import net.jaekl.qd.xml.XmlParseException;
17
18 public class Analyzer {
19         File m_findbugsDir;
20         
21         public Analyzer(File findbugsDir) {
22                 m_findbugsDir = findbugsDir;
23         }
24         
25         public Analysis analyze(PrintWriter pw, File workDir, File fbp) throws IOException, XmlParseException {
26                 Analysis result = new Analysis();
27         
28                 File fbOutput = outputWorkFile(workDir, fbp);
29                 
30                 String cmdLine = buildCommandLine(workDir, fbp, fbOutput);
31                 pw.println(cmdLine);
32                 pw.flush();
33                 Command.Result fbResult = new Command().exec(cmdLine);
34                 if (0 != fbResult.getRetCode()) {
35                         // Our attempt to execute FindBugs failed.
36                         // Report the error and return null.
37                         String cannotExecFormat = trans(CfbBundle.CANNOT_EXEC);
38                         String cannotExecMsg = MessageFormat.format(cannotExecFormat, cmdLine, fbResult.getRetCode());
39                         pw.println(cannotExecMsg);
40                         pw.println(trans(CfbBundle.STDOUT_WAS));
41                         pw.println(fbResult.getStdout());
42                         pw.println(trans(CfbBundle.STDERR_WAS));
43                         pw.println(fbResult.getStderr());
44                         return null;
45                 }
46                 
47                 result = parseFbOutput(fbOutput);
48                 result.dump(pw);                        
49                 return result;
50         }
51         
52         String trans(String key) {
53                 return CfbBundle.getInst(Locale.getDefault(Category.DISPLAY)).get(key);
54         }
55         
56         String buildCommandLine(File workDir, File fbp, File fbOutput) 
57         {
58                 assert(null != workDir);
59                 assert(null != fbp);
60                 assert(null != fbOutput);
61                 
62                 StringBuilder sb = new StringBuilder();
63                 
64                 sb.append(m_findbugsDir.getAbsolutePath())
65                   .append(File.separator)
66                   .append("bin")
67                   .append(File.separator)
68                   .append("findbugs -textui -xml -output ")
69                   .append(fbOutput.getAbsolutePath())
70                   .append(" -project ")
71                   .append(fbp.getAbsolutePath());
72                 
73                 return sb.toString();
74         }       
75         
76         // Come up with an appropriate name for the XML output file.
77         //   workDir:  place where the file should be created
78         //       fbp:  FindBugsProject file
79         File outputWorkFile(File workDir, File fbp) 
80         {
81                 assert(null != workDir);
82                 assert(null != fbp);
83                 
84                 String workPath = workDir.getAbsolutePath();
85                 
86                 String projName = fbp.getName();
87                 int len = projName.length();
88                 if (len > 4) {
89                         String extension = projName.substring(len - 4, len).toLowerCase(Locale.CANADA);
90                         if (extension.equals(".fbp")) {
91                                 projName = projName.substring(0, len - 4);
92                         }
93                 }
94                 
95                 return new File(workPath + File.separator + projName + ".xml");
96         }
97         
98         // Parse the output.xml that resulted from a FindBugs run,
99         // and store its findings into an Analysis object.
100         Analysis parseFbOutput(File fbOutput) throws XmlParseException 
101         {
102                 Analysis result = new Analysis();
103                 try {
104                         result.parse(fbOutput);
105                 } catch (IOException | SAXException exc) {
106                         throw new XmlParseException(exc);
107                 }
108                 return result;
109         }
110 }