IDEAJRenderer.java
001 /**
002  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003  */
004 package net.sourceforge.pmd.renderers;
005 
006 import java.io.IOException;
007 import java.io.Writer;
008 import java.util.HashSet;
009 import java.util.Iterator;
010 import java.util.Properties;
011 import java.util.Set;
012 import java.util.StringTokenizer;
013 
014 import net.sourceforge.pmd.PMD;
015 import net.sourceforge.pmd.RuleViolation;
016 
017 /**
018  * Renderer for IntelliJ IDEA integration.
019  */
020 public class IDEAJRenderer extends AbstractIncrementingRenderer {
021 
022     public static final String NAME = "ideaj";
023 
024     public static final String SOURCE_PATH = "sourcePath";
025     public static final String CLASS_AND_METHOD_NAME = "classAndMethodName";
026     public static final String FILE_NAME = "fileName";
027 
028     private static final String FILE_SEPARATOR = System.getProperty("file.separator");
029     private static final String PATH_SEPARATOR = System.getProperty("path.separator");
030 
031     private final String sourcePath;
032     private final String classAndMethodName;
033     private final String fileName;
034 
035     public IDEAJRenderer(Properties properties) {
036   super(NAME, "IntelliJ IDEA integration.", properties);
037   super.defineProperty(SOURCE_PATH, "Source path.");
038   super.defineProperty(CLASS_AND_METHOD_NAME,
039     "Class and Method name, pass '.method' when processing a directory.");
040   super.defineProperty(FILE_NAME, "File name.");
041 
042   this.sourcePath = properties.getProperty(SOURCE_PATH);
043   this.classAndMethodName = properties.getProperty(CLASS_AND_METHOD_NAME);
044   this.fileName = properties.getProperty(FILE_NAME);
045     }
046 
047     /**
048      * {@inheritDoc}
049      */
050     @Override
051     public void renderFileViolations(Iterator<RuleViolation> violationsthrows IOException {
052   Writer writer = getWriter();
053   if (classAndMethodName.equals(".method")) {
054       // working on a directory tree
055       renderDirectoy(writer, violations);
056   else {
057       // working on one file
058       renderFile(writer, violations);
059   }
060     }
061 
062     private void renderDirectoy(Writer writer, Iterator<RuleViolation> violationsthrows IOException {
063   SourcePath sourcePath = new SourcePath(this.sourcePath);
064   StringBuffer buf = new StringBuffer();
065   while (violations.hasNext()) {
066       buf.setLength(0);
067       RuleViolation rv = violations.next();
068       buf.append(rv.getDescription() + PMD.EOL);
069       buf.append(" at ").append(getFullyQualifiedClassName(rv.getFilename(), sourcePath)).append(".method(");
070       buf.append(getSimpleFileName(rv.getFilename())).append(':').append(rv.getBeginLine()).append(')').append(
071         PMD.EOL);
072       writer.write(buf.toString());
073   }
074     }
075 
076     private void renderFile(Writer writer, Iterator<RuleViolation> violationsthrows IOException {
077   StringBuffer buf = new StringBuffer();
078   while (violations.hasNext()) {
079       buf.setLength(0);
080       RuleViolation rv = violations.next();
081       buf.append(rv.getDescription()).append(PMD.EOL);
082       buf.append(" at ").append(this.classAndMethodName).append('(').append(this.fileName).append(':').append(
083         rv.getBeginLine()).append(')').append(PMD.EOL);
084       writer.write(buf.toString());
085   }
086     }
087 
088     private String getFullyQualifiedClassName(String fileName, SourcePath sourcePath) {
089   String classNameWithSlashes = sourcePath.clipPath(fileName);
090   String className = classNameWithSlashes.replace(FILE_SEPARATOR.charAt(0)'.');
091   return className.substring(0, className.length() 5);
092     }
093 
094     private String getSimpleFileName(String fileName) {
095   return fileName.substring(fileName.lastIndexOf(FILE_SEPARATOR1);
096     }
097 
098     private static class SourcePath {
099 
100   private Set<String> paths = new HashSet<String>();
101 
102   public SourcePath(String sourcePathString) {
103       for (StringTokenizer st = new StringTokenizer(sourcePathString, PATH_SEPARATOR); st.hasMoreTokens();) {
104     paths.add(st.nextToken());
105       }
106   }
107 
108   public String clipPath(String fullFilename) {
109       for (String path : paths) {
110     if (fullFilename.startsWith(path)) {
111         return fullFilename.substring(path.length() 1);
112     }
113       }
114       throw new RuntimeException("Couldn't find src path for " + fullFilename);
115   }
116     }
117 }