📄 avoidduplicateliteralsrule.java
字号:
/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html*/package net.sourceforge.pmd.rules;import net.sourceforge.pmd.AbstractRule;import net.sourceforge.pmd.RuleContext;import net.sourceforge.pmd.ast.ASTArgumentList;import net.sourceforge.pmd.ast.ASTCompilationUnit;import net.sourceforge.pmd.ast.ASTLiteral;import net.sourceforge.pmd.ast.ASTVariableInitializer;import net.sourceforge.pmd.ast.Node;import net.sourceforge.pmd.ast.SimpleNode;import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.IOException;import java.io.LineNumberReader;import java.text.MessageFormat;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;public class AvoidDuplicateLiteralsRule extends AbstractRule { public static class ExceptionParser { private static final char ESCAPE_CHAR = '\\'; private char delimiter; public ExceptionParser(char delimiter) { this.delimiter = delimiter; } public Set parse(String in) { Set result = new HashSet(); StringBuffer currentToken = new StringBuffer(); boolean inEscapeMode = false; for (int i=0; i<in.length(); i++) { if (inEscapeMode) { inEscapeMode = false; currentToken.append(in.charAt(i)); continue; } if (!inEscapeMode && in.charAt(i) == ESCAPE_CHAR) { inEscapeMode = true; continue; } if (in.charAt(i) == delimiter) { result.add(currentToken.toString()); currentToken = new StringBuffer(); } else { currentToken.append(in.charAt(i)); } } if (currentToken.length()>0) { result.add(currentToken.toString()); currentToken = new StringBuffer(); } return result; } } private static final char DEFAULT_SEPARATOR = ','; private static final String EXCEPTION_LIST_PROPERTY = "exceptionlist"; private static final String SEPARATOR_PROPERTY = "separator"; private static final String EXCEPTION_FILE_NAME_PROPERTY = "exceptionfile"; private Map literals = new HashMap(); private Set exceptions = new HashSet(); public Object visit(ASTCompilationUnit node, Object data) { literals.clear(); if (hasProperty(EXCEPTION_LIST_PROPERTY)) { ExceptionParser p; if (hasProperty(SEPARATOR_PROPERTY)) { p = new ExceptionParser(getStringProperty(SEPARATOR_PROPERTY).charAt(0)); } else { p = new ExceptionParser(DEFAULT_SEPARATOR); } exceptions = p.parse(getStringProperty(EXCEPTION_LIST_PROPERTY)); } else if (hasProperty(EXCEPTION_FILE_NAME_PROPERTY)) { exceptions = new HashSet(); try { LineNumberReader reader = new LineNumberReader(new BufferedReader(new FileReader(new File(getStringProperty(EXCEPTION_FILE_NAME_PROPERTY))))); String line = null; while ((line = reader.readLine()) != null) { exceptions.add(line); } reader.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } super.visit(node, data); int threshold = getIntProperty("threshold"); for (Iterator i = literals.keySet().iterator(); i.hasNext();) { String key = (String) i.next(); List occurrences = (List) literals.get(key); if (occurrences.size() >= threshold) { Object[] args = new Object[]{new Integer(occurrences.size()), new Integer(((SimpleNode) occurrences.get(0)).getBeginLine())}; String msg = MessageFormat.format(getMessage(), args); RuleContext ctx = (RuleContext) data; ctx.getReport().addRuleViolation(createRuleViolation(ctx, ((SimpleNode) occurrences.get(0)).getBeginLine(), msg)); } } return data; } public Object visit(ASTLiteral node, Object data) { if (!hasAtLeastSevenParents(node) || (!seventhParentIsAnArgList(node) && !seventhParentIsAVariableInitializer(node))) { return data; } // just catching strings of 3 chars or more for now - no numbers if (node.getImage() == null || node.getImage().indexOf('\"') == -1 || node.getImage().length() < 3) { return data; } // skip any exceptions if (exceptions.contains(node.getImage().substring(1, node.getImage().length()-1))) { return data; } if (literals.containsKey(node.getImage())) { List occurrences = (List) literals.get(node.getImage()); occurrences.add(node); } else { List occurrences = new ArrayList(); occurrences.add(node); literals.put(node.getImage(), occurrences); } return data; } private boolean seventhParentIsAVariableInitializer(ASTLiteral node) { return node.jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTVariableInitializer; } private boolean seventhParentIsAnArgList(ASTLiteral node) { return node.jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTArgumentList; } private boolean hasAtLeastSevenParents(Node node) { Node currentNode = node; for (int i = 0; i < 7; i++) { if (currentNode instanceof ASTCompilationUnit) { return false; } currentNode = currentNode.jjtGetParent(); } return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -