PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/checkstyle-5.6/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/RegexpCheck.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 256 lines | 138 code | 27 blank | 91 comment | 23 complexity | 1ec9debe7f409f5b64c56950c78076f2 MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////
  2. // checkstyle: Checks Java source code for adherence to a set of rules.
  3. // Copyright (C) 2001-2012 Oliver Burn
  4. //
  5. // This library is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU Lesser General Public
  7. // License as published by the Free Software Foundation; either
  8. // version 2.1 of the License, or (at your option) any later version.
  9. //
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. // Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public
  16. // License along with this library; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. ////////////////////////////////////////////////////////////////////////////////
  19. package com.puppycrawl.tools.checkstyle.checks;
  20. import com.google.common.collect.Lists;
  21. import com.puppycrawl.tools.checkstyle.api.DetailAST;
  22. import com.puppycrawl.tools.checkstyle.api.FileContents;
  23. import java.util.List;
  24. import java.util.regex.Matcher;
  25. import java.util.regex.Pattern;
  26. /**
  27. * <p>
  28. * A check that makes sure that a specified pattern exists (or not) in the file.
  29. * </p>
  30. * <p>
  31. * An example of how to configure the check to make sure a copyright statement
  32. * is included in the file (but without requirements on where in the file
  33. * it should be):
  34. * </p>
  35. * <pre>
  36. * &lt;module name="RequiredRegexp"&gt;
  37. * &lt;property name="format" value="This code is copyrighted"/&gt;
  38. * &lt;/module&gt;
  39. * </pre>
  40. * <p>
  41. * And to make sure the same statement appears at the beginning of the file.
  42. * </p>
  43. * <pre>
  44. * &lt;module name="RequiredRegexp"&gt;
  45. * &lt;property name="format" value="\AThis code is copyrighted"/&gt;
  46. * &lt;/module&gt;
  47. * </pre>
  48. * @author Stan Quinn
  49. */
  50. public class RegexpCheck extends AbstractFormatCheck
  51. {
  52. /** Default duplicate limit */
  53. private static final int DEFAULT_DUPLICATE_LIMIT = -1;
  54. /** Default error report limit */
  55. private static final int DEFAULT_ERROR_LIMIT = 100;
  56. /** Error count exceeded message */
  57. private static final String ERROR_LIMIT_EXCEEDED_MESSAGE =
  58. "The error limit has been exceeded, "
  59. + "the check is aborting, there may be more unreported errors.";
  60. /** Custom message for report. */
  61. private String mMessage = "";
  62. /** Ignore matches within comments? **/
  63. private boolean mIgnoreComments;
  64. /** Pattern illegal? */
  65. private boolean mIllegalPattern;
  66. /** Error report limit */
  67. private int mErrorLimit = DEFAULT_ERROR_LIMIT;
  68. /** Disallow more than x duplicates? */
  69. private int mDuplicateLimit;
  70. /** Boolean to say if we should check for duplicates. */
  71. private boolean mCheckForDuplicates;
  72. /** Tracks number of matches made */
  73. private int mMatchCount;
  74. /** Tracks number of errors */
  75. private int mErrorCount;
  76. /** Relates StringBuffer positions to line # and column */
  77. private final List<Integer[]> mCharacters = Lists.newArrayList();
  78. /** The mMatcher */
  79. private Matcher mMatcher;
  80. /**
  81. * Instantiates an new RegexpCheck.
  82. */
  83. public RegexpCheck()
  84. {
  85. super("$^", Pattern.MULTILINE); // the empty language
  86. }
  87. /**
  88. * Setter for message property.
  89. * @param aMessage custom message which should be used in report.
  90. */
  91. public void setMessage(String aMessage)
  92. {
  93. mMessage = (aMessage == null) ? "" : aMessage;
  94. }
  95. /**
  96. * Getter for message property.
  97. * I'm not sure if this gets used by anything outside,
  98. * I just included it because GenericIllegalRegexp had it,
  99. * it's being used in logMessage() so it's covered in EMMA.
  100. * @return custom message to be used in report.
  101. */
  102. public String getMessage()
  103. {
  104. return mMessage;
  105. }
  106. /**
  107. * Sets if matches within comments should be ignored.
  108. * @param aIgnoreComments True if comments should be ignored.
  109. */
  110. public void setIgnoreComments(boolean aIgnoreComments)
  111. {
  112. mIgnoreComments = aIgnoreComments;
  113. }
  114. /**
  115. * Sets if pattern is illegal, otherwise pattern is required.
  116. * @param aIllegalPattern True if pattern is not allowed.
  117. */
  118. public void setIllegalPattern(boolean aIllegalPattern)
  119. {
  120. mIllegalPattern = aIllegalPattern;
  121. }
  122. /**
  123. * Sets the limit on the number of errors to report.
  124. * @param aErrorLimit the number of errors to report.
  125. */
  126. public void setErrorLimit(int aErrorLimit)
  127. {
  128. mErrorLimit = aErrorLimit;
  129. }
  130. /**
  131. * Sets the maximum number of instances of required pattern allowed.
  132. * @param aDuplicateLimit negative values mean no duplicate checking,
  133. * any positive value is used as the limit.
  134. */
  135. public void setDuplicateLimit(int aDuplicateLimit)
  136. {
  137. mDuplicateLimit = aDuplicateLimit;
  138. mCheckForDuplicates = (mDuplicateLimit > DEFAULT_DUPLICATE_LIMIT);
  139. }
  140. @Override
  141. public int[] getDefaultTokens()
  142. {
  143. return new int[0];
  144. }
  145. @Override
  146. public void beginTree(DetailAST aRootAST)
  147. {
  148. mCharacters.clear();
  149. final Pattern pattern = getRegexp();
  150. final String[] lines = getLines();
  151. final StringBuffer sb = new StringBuffer();
  152. for (int i = 0; i < lines.length; i++) {
  153. sb.append(lines[i]);
  154. sb.append('\n');
  155. for (int j = 0; j < (lines[i].length() + 1); j++) {
  156. mCharacters.add(new Integer[] {i + 1, j});
  157. }
  158. }
  159. mMatcher = pattern.matcher(sb.toString());
  160. mMatchCount = 0;
  161. mErrorCount = 0;
  162. findMatch();
  163. }
  164. /** recursive method that finds the matches. */
  165. private void findMatch()
  166. {
  167. int startLine;
  168. int startColumn;
  169. int endLine;
  170. int endColumn;
  171. boolean foundMatch;
  172. boolean ignore = false;
  173. foundMatch = mMatcher.find();
  174. if (!foundMatch && !mIllegalPattern && (mMatchCount == 0)) {
  175. logMessage(0);
  176. }
  177. else if (foundMatch) {
  178. startLine = (mCharacters.get(mMatcher.start()))[0].
  179. intValue();
  180. startColumn = (mCharacters.get(mMatcher.start()))[1].
  181. intValue();
  182. endLine = (mCharacters.get(mMatcher.end() - 1))[0].
  183. intValue();
  184. endColumn = (mCharacters.get(mMatcher.end() - 1))[1].
  185. intValue();
  186. if (mIgnoreComments) {
  187. final FileContents theFileContents = getFileContents();
  188. ignore = theFileContents.hasIntersectionWithComment(startLine,
  189. startColumn, endLine, endColumn);
  190. }
  191. if (!ignore) {
  192. mMatchCount++;
  193. if (mIllegalPattern || (mCheckForDuplicates
  194. && ((mMatchCount - 1) > mDuplicateLimit)))
  195. {
  196. mErrorCount++;
  197. logMessage(startLine);
  198. }
  199. }
  200. if ((mErrorCount < mErrorLimit)
  201. && (ignore || mIllegalPattern || mCheckForDuplicates))
  202. {
  203. findMatch();
  204. }
  205. }
  206. }
  207. /**
  208. * Displays the right message.
  209. * @param aLineNumber the line number the message relates to.
  210. */
  211. private void logMessage(int aLineNumber)
  212. {
  213. String message = "".equals(getMessage()) ? getFormat() : mMessage;
  214. if (mErrorCount >= mErrorLimit) {
  215. message = ERROR_LIMIT_EXCEEDED_MESSAGE + message;
  216. }
  217. if (mIllegalPattern) {
  218. log(aLineNumber, "illegal.regexp", message);
  219. }
  220. else {
  221. if (aLineNumber > 0) {
  222. log(aLineNumber, "duplicate.regexp", message);
  223. }
  224. else {
  225. log(aLineNumber, "required.regexp", message);
  226. }
  227. }
  228. }
  229. }