001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2014 Oliver Burn 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019package com.puppycrawl.tools.checkstyle.checks.coding; 020 021import com.puppycrawl.tools.checkstyle.api.DetailAST; 022import com.puppycrawl.tools.checkstyle.api.TokenTypes; 023import com.puppycrawl.tools.checkstyle.checks.AbstractFormatCheck; 024import java.util.Set; 025import java.util.regex.Pattern; 026 027/** 028 * <p> 029 * Checks for illegal token text. 030 * </p> 031 * <p> An example of how to configure the check to forbid String literals 032 * containing <code>"a href"</code> is: 033 * </p> 034 * <pre> 035 * <module name="IllegalTokenText"> 036 * <property name="tokens" value="STRING_LITERAL"/> 037 * <property name="format" value="a href"/> 038 * </module> 039 * </pre> 040 * <p> An example of how to configure the check to forbid leading zeros in an 041 * integer literal, other than zero and a hex literal is: 042 * </p> 043 * <pre> 044 * <module name="IllegalTokenText"> 045 * <property name="tokens" value="NUM_INT,NUM_LONG"/> 046 * <property name="format" value="^0[^lx]"/> 047 * <property name="ignoreCase" value="true"/> 048 * </module> 049 * </pre> 050 * @author Rick Giles 051 */ 052public class IllegalTokenTextCheck 053 extends AbstractFormatCheck 054{ 055 /** 056 * Custom message for report if illegal regexp found 057 * ignored if empty. 058 */ 059 private String message = ""; 060 061 /** 062 * Instantiates a new instance. 063 */ 064 public IllegalTokenTextCheck() 065 { 066 super("$^"); // the empty language 067 } 068 069 @Override 070 public void beginTree(DetailAST rootAST) 071 { 072 } 073 074 @Override 075 public int[] getDefaultTokens() 076 { 077 return new int[0]; 078 } 079 080 @Override 081 public int[] getAcceptableTokens() 082 { 083 // Any tokens set by property 'tokens' are acceptable 084 final Set<String> tokenNames = getTokenNames(); 085 final int[] result = new int[tokenNames.size()]; 086 int i = 0; 087 for (final String name : tokenNames) { 088 result[i] = TokenTypes.getTokenId(name); 089 i++; 090 } 091 return result; 092 } 093 094 @Override 095 public void visitToken(DetailAST ast) 096 { 097 final String text = ast.getText(); 098 if (getRegexp().matcher(text).find()) { 099 String message = getMessage(); 100 if ("".equals(message)) { 101 message = "illegal.token.text"; 102 } 103 log( 104 ast.getLineNo(), 105 ast.getColumnNo(), 106 message, 107 getFormat()); 108 } 109 } 110 111 /** 112 * Setter for message property. 113 * @param message custom message which should be used 114 * to report about violations. 115 */ 116 public void setMessage(String message) 117 { 118 this.message = (null == message) ? "" : message; 119 } 120 121 /** 122 * Getter for message property. 123 * @return custom message which should be used 124 * to report about violations. 125 */ 126 public String getMessage() 127 { 128 return message; 129 } 130 131 /** 132 * Set whether or not the match is case sensitive. 133 * @param caseInsensitive true if the match is case insensitive. 134 */ 135 public void setIgnoreCase(boolean caseInsensitive) 136 { 137 if (caseInsensitive) { 138 setCompileFlags(Pattern.CASE_INSENSITIVE); 139 } 140 } 141}