View Javadoc

1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.ant;
5   
6   import net.sourceforge.pmd.PMD;
7   import net.sourceforge.pmd.Report;
8   import net.sourceforge.pmd.renderers.EmacsRenderer;
9   import net.sourceforge.pmd.renderers.HTMLRenderer;
10  import net.sourceforge.pmd.renderers.PapariTextRenderer;
11  import net.sourceforge.pmd.renderers.Renderer;
12  import net.sourceforge.pmd.renderers.SummaryHTMLRenderer;
13  import net.sourceforge.pmd.renderers.TextRenderer;
14  import net.sourceforge.pmd.renderers.VBHTMLRenderer;
15  import net.sourceforge.pmd.renderers.XMLRenderer;
16  import net.sourceforge.pmd.renderers.YAHTMLRenderer;
17  import net.sourceforge.pmd.renderers.CSVRenderer;
18  import org.apache.tools.ant.BuildException;
19  
20  import java.io.BufferedWriter;
21  import java.io.File;
22  import java.io.FileWriter;
23  import java.io.IOException;
24  import java.io.OutputStreamWriter;
25  import java.io.Writer;
26  import java.util.HashMap;
27  import java.util.Iterator;
28  import java.util.Map;
29  
30  public class Formatter {
31  
32      private interface RendererBuilder {
33          Renderer build(Object[] optionalArg);
34      } // factory template
35  
36      private File toFile;
37      private String linkPrefix;
38      private String linePrefix;
39      private String type;
40      private boolean toConsole;
41      private boolean showSuppressed;
42  
43      private static final Map renderersByCode = new HashMap(8);
44  
45      static {
46          renderersByCode.put("xml", new RendererBuilder() {
47              public Renderer build(Object[] arg) { return new XMLRenderer(); }
48          });
49          renderersByCode.put("html", new RendererBuilder() {
50              public Renderer build(Object[] arg) { return new HTMLRenderer((String) arg[0], (String) arg[1]); }
51          });
52          renderersByCode.put("summaryhtml", new RendererBuilder() {
53              public Renderer build(Object[] arg) { return new SummaryHTMLRenderer((String) arg[0], (String) arg[1]); }
54          });
55          renderersByCode.put("papari", new RendererBuilder() {
56              public Renderer build(Object[] arg) { return new PapariTextRenderer(); }
57          });
58          renderersByCode.put("csv", new RendererBuilder() {
59              public Renderer build(Object[] arg) { return new CSVRenderer(); }
60          });
61          renderersByCode.put("emacs", new RendererBuilder() {
62              public Renderer build(Object[] arg) { return new EmacsRenderer(); }
63          });
64          renderersByCode.put("vbhtml", new RendererBuilder() {
65              public Renderer build(Object[] arg) { return new VBHTMLRenderer(); }
66          });
67          renderersByCode.put("yahtml", new RendererBuilder() {
68              public Renderer build(Object[] arg) { return new YAHTMLRenderer(); }
69          });
70          renderersByCode.put("text", new RendererBuilder() {
71              public Renderer build(Object[] arg) { return new TextRenderer(); }
72          });
73          // add additional codes & factories here
74      }
75  
76      public void setShowSuppressed(boolean value) {
77          this.showSuppressed = value;
78      }
79  
80      public void setType(String type) {
81          this.type = type;
82      }
83  
84      public void setLinkPrefix(String linkPrefix) {
85          this.linkPrefix = linkPrefix;
86      }
87  
88      public void setToFile(File toFile) {
89          this.toFile = toFile;
90      }
91  
92      public void setToConsole(boolean toConsole) {
93          this.toConsole = toConsole;
94      }
95  
96      public void setLinePrefix(String linePrefix) {
97          this.linePrefix = linePrefix;
98      }
99  
100     public void outputReport(Report report, String baseDir) {
101         try {
102             if (toConsole) {
103                 outputReportTo(new BufferedWriter(new OutputStreamWriter(System.out)), report, true);
104             }
105             if (toFile != null) {
106                 outputReportTo(getToFileWriter(baseDir), report, false);
107             }
108         } catch (IOException ioe) {
109             throw new BuildException(ioe.getMessage());
110         }
111     }
112 
113     public boolean isNoOutputSupplied() {
114         return toFile == null && !toConsole;
115     }
116 
117     public String toString() {
118         return "file = " + toFile + "; renderer = " + type;
119     }
120 
121     private static String[] validRendererCodes() {
122         Iterator iter = renderersByCode.keySet().iterator();
123         String[] validTypes = new String[renderersByCode.size()];
124         int i = 0;
125         while (iter.hasNext()) validTypes[i++] = (String) iter.next();
126         return validTypes;
127     }
128 
129     private void outputReportTo(Writer writer, Report report, boolean consoleRenderer) throws IOException {
130         getRenderer(consoleRenderer).render(writer, report);
131         writer.write(PMD.EOL);
132         writer.close();
133     }
134 
135 
136     private static String unknownRendererMessage(String userSpecifiedType) {
137         StringBuffer sb = new StringBuffer(100);
138         sb.append("Formatter type must be one of: '");
139         String[] typeCodes = validRendererCodes();
140         sb.append(typeCodes[0]);
141         for (int i = 1; i < typeCodes.length; i++) {
142             sb.append("', '").append(typeCodes[i]);
143         }
144         sb.append("', or a class name; you specified: ");
145         sb.append(userSpecifiedType);
146         return sb.toString();
147     }
148 
149     private Renderer fromClassname(String rendererClassname) {
150         try {
151             return (Renderer) Class.forName(rendererClassname).newInstance();
152         } catch (Exception e) {
153             throw new BuildException(unknownRendererMessage(rendererClassname));
154         }
155     }
156 
157     // FIXME - hm, what about this consoleRenderer thing... need a test for this
158     private Renderer getRenderer(boolean consoleRenderer) {
159         if ("".equals(type)) {
160             throw new BuildException(unknownRendererMessage("<unspecified>"));
161         }
162         RendererBuilder builder = (RendererBuilder) renderersByCode.get(type);
163         Renderer renderer = builder == null ? fromClassname(type) : builder.build(new String[]{linkPrefix, linePrefix});
164         renderer.showSuppressedViolations(showSuppressed);
165         return renderer;
166     }
167 
168     private Writer getToFileWriter(String baseDir) throws IOException {
169         if (!toFile.isAbsolute()) {
170             return new BufferedWriter(new FileWriter(new File(baseDir + System.getProperty("file.separator") + toFile.getPath())));
171         }
172         return new BufferedWriter(new FileWriter(toFile));
173     }
174 }