001: /**
002: * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003: */package net.sourceforge.pmd.ant;
004:
005: import net.sourceforge.pmd.PMD;
006: import net.sourceforge.pmd.Report;
007: import net.sourceforge.pmd.renderers.EmacsRenderer;
008: import net.sourceforge.pmd.renderers.HTMLRenderer;
009: import net.sourceforge.pmd.renderers.PapariTextRenderer;
010: import net.sourceforge.pmd.renderers.Renderer;
011: import net.sourceforge.pmd.renderers.SummaryHTMLRenderer;
012: import net.sourceforge.pmd.renderers.TextRenderer;
013: import net.sourceforge.pmd.renderers.VBHTMLRenderer;
014: import net.sourceforge.pmd.renderers.XMLRenderer;
015: import net.sourceforge.pmd.renderers.XSLTRenderer;
016: import net.sourceforge.pmd.renderers.YAHTMLRenderer;
017: import net.sourceforge.pmd.renderers.CSVRenderer;
018: import org.apache.tools.ant.BuildException;
019:
020: import java.io.BufferedWriter;
021: import java.io.File;
022: import java.io.FileWriter;
023: import java.io.IOException;
024: import java.io.OutputStreamWriter;
025: import java.io.Writer;
026: import java.util.HashMap;
027: import java.util.Map;
028:
029: public class Formatter {
030:
031: private interface RendererBuilder {
032: Renderer build(Object[] optionalArg);
033: } // factory template
034:
035: private File toFile;
036: private String linkPrefix;
037: private String linePrefix;
038: private String type;
039: private boolean toConsole;
040: private boolean showSuppressed;
041:
042: private static final Map<String, RendererBuilder> renderersByCode = new HashMap<String, RendererBuilder>(
043: 8);
044:
045: static {
046: renderersByCode.put("xml", new RendererBuilder() {
047: public Renderer build(Object[] arg) {
048: return new XMLRenderer();
049: }
050: });
051: renderersByCode.put("betterhtml", new RendererBuilder() {
052: public Renderer build(Object[] arg) {
053: return new XSLTRenderer();
054: }
055: });
056: renderersByCode.put("html", new RendererBuilder() {
057: public Renderer build(Object[] arg) {
058: return new HTMLRenderer((String) arg[0],
059: (String) arg[1]);
060: }
061: });
062: renderersByCode.put("summaryhtml", new RendererBuilder() {
063: public Renderer build(Object[] arg) {
064: return new SummaryHTMLRenderer((String) arg[0],
065: (String) arg[1]);
066: }
067: });
068: renderersByCode.put("papari", new RendererBuilder() {
069: public Renderer build(Object[] arg) {
070: return new PapariTextRenderer();
071: }
072: });
073: renderersByCode.put("csv", new RendererBuilder() {
074: public Renderer build(Object[] arg) {
075: return new CSVRenderer();
076: }
077: });
078: renderersByCode.put("emacs", new RendererBuilder() {
079: public Renderer build(Object[] arg) {
080: return new EmacsRenderer();
081: }
082: });
083: renderersByCode.put("vbhtml", new RendererBuilder() {
084: public Renderer build(Object[] arg) {
085: return new VBHTMLRenderer();
086: }
087: });
088: renderersByCode.put("yahtml", new RendererBuilder() {
089: public Renderer build(Object[] arg) {
090: return new YAHTMLRenderer();
091: }
092: });
093: renderersByCode.put("text", new RendererBuilder() {
094: public Renderer build(Object[] arg) {
095: return new TextRenderer();
096: }
097: });
098: // add additional codes & factories here
099: }
100:
101: public void setShowSuppressed(boolean value) {
102: this .showSuppressed = value;
103: }
104:
105: public void setType(String type) {
106: this .type = type;
107: }
108:
109: public void setLinkPrefix(String linkPrefix) {
110: this .linkPrefix = linkPrefix;
111: }
112:
113: public void setToFile(File toFile) {
114: this .toFile = toFile;
115: }
116:
117: public void setToConsole(boolean toConsole) {
118: this .toConsole = toConsole;
119: }
120:
121: public void setLinePrefix(String linePrefix) {
122: this .linePrefix = linePrefix;
123: }
124:
125: private Writer writer;
126:
127: private Renderer renderer;
128:
129: public Renderer getRenderer() {
130: return renderer;
131: }
132:
133: public void start(String baseDir) {
134: try {
135: if (toConsole) {
136: writer = new BufferedWriter(new OutputStreamWriter(
137: System.out));
138: }
139: if (toFile != null) {
140: writer = getToFileWriter(baseDir);
141: }
142: renderer = getRenderer(toConsole);
143: renderer.setWriter(writer);
144: renderer.start();
145: } catch (IOException ioe) {
146: throw new BuildException(ioe.getMessage());
147: }
148: }
149:
150: public void end(Report errorReport) {
151: try {
152: renderer.renderFileReport(errorReport);
153: renderer.end();
154: writer.write(PMD.EOL);
155: if (toConsole) {
156: writer.flush();
157: } else {
158: writer.close();
159: }
160: } catch (IOException ioe) {
161: throw new BuildException(ioe.getMessage());
162: }
163: }
164:
165: public boolean isNoOutputSupplied() {
166: return toFile == null && !toConsole;
167: }
168:
169: public String toString() {
170: return "file = " + toFile + "; renderer = " + type;
171: }
172:
173: private static String[] validRendererCodes() {
174: return renderersByCode.keySet().toArray(
175: new String[renderersByCode.size()]);
176: }
177:
178: private static String unknownRendererMessage(
179: String userSpecifiedType) {
180: StringBuffer sb = new StringBuffer(100);
181: sb.append("Formatter type must be one of: '");
182: String[] typeCodes = validRendererCodes();
183: sb.append(typeCodes[0]);
184: for (int i = 1; i < typeCodes.length; i++) {
185: sb.append("', '").append(typeCodes[i]);
186: }
187: sb.append("', or a class name; you specified: ");
188: sb.append(userSpecifiedType);
189: return sb.toString();
190: }
191:
192: private Renderer fromClassname(String rendererClassname) {
193: try {
194: return (Renderer) Class.forName(rendererClassname)
195: .newInstance();
196: } catch (Exception e) {
197: throw new BuildException(
198: unknownRendererMessage(rendererClassname));
199: }
200: }
201:
202: // FIXME - hm, what about this consoleRenderer thing... need a test for this
203: private Renderer getRenderer(boolean consoleRenderer) {
204: if ("".equals(type)) {
205: throw new BuildException(
206: unknownRendererMessage("<unspecified>"));
207: }
208: RendererBuilder builder = renderersByCode.get(type);
209: Renderer renderer = builder == null ? fromClassname(type)
210: : builder
211: .build(new String[] { linkPrefix, linePrefix });
212: renderer.showSuppressedViolations(showSuppressed);
213: return renderer;
214: }
215:
216: private Writer getToFileWriter(String baseDir) throws IOException {
217: if (!toFile.isAbsolute()) {
218: return new BufferedWriter(new FileWriter(new File(baseDir
219: + System.getProperty("file.separator")
220: + toFile.getPath())));
221: }
222: return new BufferedWriter(new FileWriter(toFile));
223: }
224: }
|