1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
|
package test.utils;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import java.io.File;
import java.io.FileInputStream;
/**
* This TestCase verifies that content of the source files adheres
* to certain coding practices by matching regular expressions
* (string patterns):
*
* - Verify that Log4J logger is not being used directly
* ("org.apache.log4j" is not in source files).
*
* - Verify that System.out.println is not used except
* in wsdl to/from java tooling.
*
* - Verify that log.info(), log.warn(), log.error(), and log.fatal()
* use Messages.getMessage() (i18n).
*
* - Verify that exceptions are created with Messages.getMessage() (i18n).
*
* To add new patterns, search for and append to the
* private attribute 'avoidPatterns'.
*
* Based on code in TestMessages.java.
*/
public class TestSrcContent extends TestCase {
public TestSrcContent(String name) {
super(name);
} // ctor
public static Test suite() {
return new TestSuite(TestSrcContent.class);
}
private static final String LS = System.getProperty("line.separator");
private String errors = "";
/**
* If this test is run from xml-axis/java, then walk through the source
* tree (xml-axis/java/src), calling checkFile for each file.
*/
public void testSourceFiles() {
String baseDir = System.getProperty("user.dir");
File srcDir = new File(baseDir, "src");
if (srcDir.exists()) {
walkTree(srcDir);
}
if (!errors.equals("")) {
throw new AssertionFailedError(errors);
}
} // testSourceFiles
/**
* Walk the source tree
*/
private void walkTree(File srcDir) {
File[] files = srcDir.listFiles();
for (int i = 0; i < files.length; ++i) {
if (files[i].isDirectory()) {
walkTree(files[i]);
}
else {
checkFile(files[i]);
}
}
} // walkTree
static private class FileNameContentPattern
{
private PatternCompiler compiler = new Perl5Compiler();
private PatternMatcher matcher = new Perl5Matcher();
private Pattern namePattern = null;
private Pattern contentPattern = null;
private boolean expectContent = true;
FileNameContentPattern(String namePattern,
String contentPattern,
boolean expectContentInFile)
{
try {
this.namePattern = compiler.compile(namePattern);
this.contentPattern = compiler.compile(contentPattern);
this.expectContent = expectContentInFile;
}
catch (MalformedPatternException e) {
throw new AssertionFailedError(e.getMessage());
}
}
/**
* This is not a match IFF
* - the name matches, AND
* - the content is not as expected
*/
boolean noMatch(String name, String content)
{
return
matcher.matches(name, namePattern) &&
matcher.contains(content, contentPattern) != expectContent;
}
String getContentPattern() { return contentPattern.getPattern(); }
boolean getExpectContent() { return expectContent; }
};
/**
* Patterns to be checked. Each pattern has three parameters:
* (i) a pattern that matches filenames that are to be checked,
* (ii) a pattern to be searched for in the chosen files
* (iii) whether the pattern is to be allowed (typically false indicating
* not allowed)
* See the Axis Developer's Guide for more information.
*/
private static final FileNameContentPattern avoidPatterns[] =
{
//**
//** For escape ('\'), remember that Java gets first dibs..
//** so double-escape for pattern-matcher to see it.
//**
// Verify that java files do not use Log4j
//
//new FileNameContentPattern(".+\\.java",
// "org\\.apache\\.log4j", false),
new FileNameContentPattern(".+([\\\\/])"
+ "java\\1"
// + "(?!src\\1org\\1apache\\1axis\\1client\\1HappyClient\\.java)"
+ "([a-zA-Z0-9_]+\\1)*"
+ "[^\\\\/]+\\.java",
"org\\.apache\\.log4j", false),
// Verify that axis java files do not use System.out.println
// or System.err.println, except:
// - utils/tcpmon.java
// - providers/BSFProvider.java
// - utils/CLArgsParser.java
// - Version.java
// - tooling in 'org/apache/axis/wsdl'
// - client/AdminClient.java
// - utils/Admin.java
new FileNameContentPattern(".+([\\\\/])"
+ "java\\1src\\1org\\1apache\\1axis\\1"
+ "(?!utils\\1tcpmon\\.java"
+ "|client\\1AdminClient\\.java"
+ "|utils\\1Admin\\.java"
+ "|utils\\1SOAPMonitor\\.java"
+ "|providers\\1BSFProvider\\.java"
+ "|utils\\1CLArgsParser\\.java"
+ "|transport\\1jms\\1SimpleJMSListener\\.java"
+ "|Version\\.java"
+ "|wsdl\\1)"
+ "([a-zA-Z0-9_]+\\1)*"
+ "[^\\\\/]+\\.java",
"System\\.(out|err)\\.println", false),
// Verify that internationalization is being used properly
// with logger. Exceptions:
// - all log.debug calls
// - client/AdminClient.java
// - utils/tcpmon.java
// - utils/Admin.java
// - handlers/LogMessage.java
// - tooling in 'org/apache/axis/wsdl'
//
new FileNameContentPattern(".+([\\\\/])"
+ "java\\1src\\1org\\1apache\\1axis\\1"
+ "(?!utils\\1tcpmon\\.java"
+ "|client\\1AdminClient\\.java"
+ "|utils\\1Admin\\.java"
+ "|utils\\1SOAPMonitor\\.java"
+ "|handlers\\1LogMessage\\.java"
+ "|wsdl\\1)"
+ "([a-zA-Z0-9_]+\\1)*"
+ "[^\\\\/]+\\.java",
"log\\.(info|warn|error|fatal)"
+ "[ \\t]*\\("
+ "(?=[ \\t]*\\\")",
false),
// Verify that exceptions are built with messages.
new FileNameContentPattern(".+([\\\\/])"
+ "java\\1src\\1org\\1apache\\1axis\\1"
+ "([a-zA-Z0-9_]+\\1)*"
+ "[^\\\\/]+\\.java",
"new[ \\t]+[a-zA-Z0-9_]*"
+ "Exception\\(\\)",
false),
// Verify that we don't explicitly create NPEs.
new FileNameContentPattern(".+([\\\\/])"
+ "java\\1src\\1org\\1apache\\1axis\\1"
+ "([a-zA-Z0-9_]+\\1)*"
+ "[^\\\\/]+\\.java",
"new[ \\t]+"
+ "NullPointerException",
false),
};
private void checkFile(File file) {
try {
FileInputStream fis = new FileInputStream(file);
byte[] bytes = new byte[fis.available()];
fis.read(bytes);
String content = new String(bytes);
for (int i = 0; i < avoidPatterns.length; i++) {
if (avoidPatterns[i].noMatch(file.getPath(), content)) {
// if (content.indexOf(avoidStrings[i]) >= 0) {
errors = errors
+ "File: " + file.getPath() + ": "
+ (avoidPatterns[i].getExpectContent()
? "Expected: "
: "Unexpected: ")
+ avoidPatterns[i].getContentPattern()
+ LS;
}
}
}
catch (Throwable t) {
errors = errors
+ "File: " + file.getPath()
+ ": " + t.getMessage()
+ LS;
}
} // checkFile
}
|