View Javadoc
1 /*** 2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html 3 */ 4 package net.sourceforge.pmd.renderers; 5 6 import net.sourceforge.pmd.PMD; 7 import net.sourceforge.pmd.Report; 8 import net.sourceforge.pmd.RuleViolation; 9 import net.sourceforge.pmd.util.StringUtil; 10 11 import java.io.BufferedReader; 12 import java.io.File; 13 import java.io.FileReader; 14 import java.io.IOException; 15 16 import java.util.Iterator; 17 18 /*** 19 * <p>A console renderer with optional color support under *nix systems.</p> 20 * 21 * <pre> 22 * * file: ./src/gilot/Test.java 23 * src: Test.java:12 24 * rule: AtLeastOneConstructor 25 * msg: Each class should declare at least one constructor 26 * code: public class Test 27 * 28 * * file: ./src/gilot/log/format/LogInterpreter.java 29 * src: LogInterpreter.java:317 30 * rule: AvoidDuplicateLiterals 31 * msg: The same String literal appears 4 times in this file; the first occurrence is on line 317 32 * code: logger.error( "missing attribute 'app_arg' in rule '" + ((Element)element.getParent()).getAttributeValue( "name" ) + "'" ); 33 * 34 * src: LogInterpreter.java:317 35 * rule: AvoidDuplicateLiterals 36 * msg: The same String literal appears 5 times in this file; the first occurrence is on line 317 37 * code: logger.error( "missing attribute 'app_arg' in rule '" + ((Element)element.getParent()).getAttributeValue( "name" ) + "'" ); 38 * 39 * * warnings: 3 40 * 41 * </pre> 42 * 43 * <p>Colorization is turned on by supplying -D<b>pmd.color</b> - any value other than 44 * '0' or 'false', enables color - including an empty value (''). <b>Nota Bene:</b> 45 * colorization is atm only supported under *nix terminals accepting ansi escape 46 * sequences, such as xterm, rxvt et cetera.</p> 47 */ 48 public class PapariTextRenderer implements Renderer 49 { 50 /*** 51 * Directory from where java was invoked. 52 */ 53 private String pwd = null; 54 55 private String yellowBold = ""; 56 private String whiteBold = ""; 57 private String redBold = ""; 58 private String cyan = ""; 59 private String green = ""; 60 61 private String colorReset = ""; 62 63 /*** 64 * Enables colors on *nix systems - not windows. Color support depends 65 * on the pmd.color property, which should be set with the -D option 66 * during execution - a set value other than 'false' or '0' enables color. 67 * 68 * btw, is it possible to do this on windows (ie; console colors)? 69 */ 70 private void initColors() 71 { 72 if (System.getProperty("pmd.color") != null && 73 !(System.getProperty("pmd.color").equals("0") || System.getProperty("pmd.color").equals("false"))) 74 { 75 this.yellowBold = "\u001B[1;33m"; 76 this.whiteBold = "\u001B[1;37m"; 77 this.redBold = "\u001B[1;31m"; 78 this.green = "\u001B[0;32m"; 79 this.cyan = "\u001B[0;36m"; 80 81 this.colorReset = "\u001B[0m"; 82 } 83 } 84 85 public String render(Report report) 86 { 87 StringBuffer buf = new StringBuffer(PMD.EOL); 88 89 // init colors, if supported 90 this.initColors(); 91 92 // last file 93 String fileName = null; 94 95 // keeps track of violations and errors 96 int errors = 0; 97 int warnings = 0; 98 99 // iterating rule violations 100 for (Iterator i = report.iterator(); i.hasNext();) 101 { 102 warnings++; 103 104 RuleViolation rv = (RuleViolation) i.next(); 105 if (!rv.getFilename().equals(fileName)) 106 { 107 fileName = rv.getFilename(); 108 buf.append( this.yellowBold + "*" + this.colorReset + " file: " + this.whiteBold + this.getRelativePath(fileName) + this.colorReset + PMD.EOL); 109 } 110 111 buf.append(this.green + " src: " + this.cyan + fileName.substring( fileName.lastIndexOf(File.separator)+1)+ this.colorReset + ":" + this.cyan + rv.getLine() + this.colorReset + PMD.EOL); 112 buf.append(this.green + " rule: " + this.colorReset + rv.getRule().getName() + PMD.EOL); 113 buf.append(this.green + " msg: " + this.colorReset + rv.getDescription() + PMD.EOL); 114 buf.append(this.green + " code: " + this.colorReset + this.getLine( fileName, rv.getLine() ) + PMD.EOL + PMD.EOL); 115 116 } 117 118 // iterating errors 119 for (Iterator i = report.errors(); i.hasNext();) 120 { 121 errors++; 122 123 Report.ProcessingError error = (Report.ProcessingError)i.next(); 124 if (error.getFile().equals(fileName)) 125 { 126 fileName = error.getFile(); 127 buf.append( this.redBold + "*" + this.colorReset + " file: " + this.whiteBold + this.getRelativePath(fileName) + this.colorReset + PMD.EOL); 128 } 129 buf.append(this.green + " err: " + this.cyan + error.getMsg() + this.colorReset + PMD.EOL + PMD.EOL); 130 } 131 132 // adding error message count, if any 133 if ( errors > 0 ) 134 { 135 buf.append(this.redBold + "*" + this.colorReset + " errors: "+ this.whiteBold + warnings + this.colorReset + PMD.EOL); 136 } 137 buf.append(this.yellowBold + "*" + this.colorReset + " warnings: "+ this.whiteBold + warnings + this.colorReset + PMD.EOL); 138 139 return buf.toString(); 140 } 141 142 /*** 143 * Retrieves the requested line from the specified file. 144 * 145 * @param sourceFile the java or cpp source file 146 * @param line line number to extract 147 * 148 * @return a trimmed line of source code 149 */ 150 private String getLine( String sourceFile, int line ) 151 { 152 String code = null; 153 try 154 { 155 File file = new File( "." ); 156 BufferedReader br = new BufferedReader( new FileReader( new File( sourceFile ) ) ); 157 158 for ( int i = 0; line > i; i++ ) 159 { 160 code = br.readLine().trim(); 161 } 162 br.close(); 163 } 164 catch ( IOException ioErr ) 165 { 166 ioErr.printStackTrace(); 167 } 168 return code; 169 } 170 171 /*** 172 * Attempts to determine the relative path to the file. If relative path cannot be found, 173 * the original path is returnedi, ie - the current path for the supplied file. 174 * 175 * @param fileName well, the file with its original path. 176 * @return the relative path to the file 177 */ 178 private String getRelativePath( String fileName ) 179 { 180 String relativePath = null; 181 182 // check if working directory need to be assigned 183 if (pwd == null) 184 { 185 try 186 { 187 this.pwd = new File(".").getCanonicalPath(); 188 } 189 catch (IOException ioErr) 190 { 191 // to avoid further error 192 this.pwd = ""; 193 } 194 } 195 196 // make sure that strings match before doing any substring-ing 197 if (fileName.indexOf(this.pwd) == 0) 198 { 199 relativePath = "." + fileName.substring( this.pwd.length() ); 200 201 // remove current dir occuring twice - occurs if . was supplied as path 202 if ( relativePath.startsWith( "." + File.separator + "." + File.separator ) ) 203 { 204 relativePath = relativePath.substring(2); 205 } 206 } 207 else 208 { 209 // this happens when pmd's supplied argument deviates from the pwd 'branch' (god knows this terminolgy - i hope i make some sense). 210 // for instance, if supplied=/usr/lots/of/src and pwd=/usr/lots/of/shared/source 211 // TODO: a fix to get relative path? 212 relativePath = fileName; 213 } 214 215 return relativePath; 216 } 217 }

This page was automatically generated by Maven