1
2
3
4 package net.sourceforge.pmd.renderers;
5
6 import java.io.IOException;
7 import java.io.Writer;
8 import java.util.HashSet;
9 import java.util.Iterator;
10 import java.util.Set;
11 import java.util.StringTokenizer;
12
13 import net.sourceforge.pmd.PMD;
14 import net.sourceforge.pmd.RuleViolation;
15 import net.sourceforge.pmd.lang.rule.properties.StringProperty;
16
17
18
19
20 public class IDEAJRenderer extends AbstractIncrementingRenderer {
21
22 private String classAndMethodName;
23 private String fileName;
24
25 public static final String NAME = "ideaj";
26
27 public static final StringProperty FILE_NAME = new StringProperty("fileName", "File name.", "", 0);
28 public static final StringProperty SOURCE_PATH = new StringProperty("sourcePath", "Source path.", "", 1);
29 public static final StringProperty CLASS_AND_METHOD_NAME = new StringProperty("classAndMethodName", "Class and Method name, pass '.method' when processing a directory.", "", 2);
30
31 private static final String FILE_SEPARATOR = System.getProperty("file.separator");
32 private static final String PATH_SEPARATOR = System.getProperty("path.separator");
33
34 public IDEAJRenderer() {
35 super(NAME, "IntelliJ IDEA integration.");
36 definePropertyDescriptor(FILE_NAME);
37 definePropertyDescriptor(SOURCE_PATH);
38 definePropertyDescriptor(CLASS_AND_METHOD_NAME);
39 }
40
41 public String defaultFileExtension() { return "txt"; }
42
43
44
45
46 @Override
47 public void renderFileViolations(Iterator<RuleViolation> violations) throws IOException {
48 classAndMethodName = getProperty(CLASS_AND_METHOD_NAME);
49 fileName = getProperty(FILE_NAME);
50
51 Writer writer = getWriter();
52 if (".method".equals(classAndMethodName)) {
53
54 renderDirectoy(writer, violations);
55 } else {
56
57 renderFile(writer, violations);
58 }
59 }
60
61 private void renderDirectoy(Writer writer, Iterator<RuleViolation> violations) throws IOException {
62 SourcePath sourcePath = new SourcePath(getProperty(SOURCE_PATH));
63 StringBuilder buf = new StringBuilder();
64 while (violations.hasNext()) {
65 buf.setLength(0);
66 RuleViolation rv = violations.next();
67 buf.append(rv.getDescription() + PMD.EOL);
68 buf.append(" at ").append(
69 getFullyQualifiedClassName(rv.getFilename(), sourcePath)).append(".method(");
70 buf.append(getSimpleFileName(rv.getFilename())).append(':')
71 .append(rv.getBeginLine()).append(')').append(PMD.EOL);
72 writer.write(buf.toString());
73 }
74 }
75
76 private void renderFile(Writer writer, Iterator<RuleViolation> violations) throws IOException {
77 StringBuilder buf = new StringBuilder();
78 while (violations.hasNext()) {
79 buf.setLength(0);
80 RuleViolation rv = violations.next();
81 buf.append(rv.getDescription()).append(PMD.EOL);
82 buf.append(" at ").append(classAndMethodName).append('(')
83 .append(fileName).append(':')
84 .append(rv.getBeginLine()).append(')').append(PMD.EOL);
85 writer.write(buf.toString());
86 }
87 }
88
89 private String getFullyQualifiedClassName(String fileName, SourcePath sourcePath) {
90 String classNameWithSlashes = sourcePath.clipPath(fileName);
91 String className = classNameWithSlashes.replace(FILE_SEPARATOR.charAt(0), '.');
92 return className.substring(0, className.length() - 5);
93 }
94
95 private String getSimpleFileName(String fileName) {
96 return fileName.substring(fileName.lastIndexOf(FILE_SEPARATOR) + 1);
97 }
98
99 private static class SourcePath {
100
101 private Set<String> paths = new HashSet<String>();
102
103 public SourcePath(String sourcePathString) {
104 for (StringTokenizer st = new StringTokenizer(sourcePathString,
105 PATH_SEPARATOR); st.hasMoreTokens();) {
106 paths.add(st.nextToken());
107 }
108 }
109
110 public String clipPath(String fullFilename) {
111 for (String path : paths) {
112 if (fullFilename.startsWith(path)) {
113 return fullFilename.substring(path.length() + 1);
114 }
115 }
116 throw new RuntimeException("Couldn't find src path for " + fullFilename);
117 }
118 }
119 }