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