View Javadoc
1   /*
2    * Copyright (c) 2011-2025 Yegor Bugayenko
3    *
4    * All rights reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions
8    * are met: 1) Redistributions of source code must retain the above
9    * copyright notice, this list of conditions and the following
10   * disclaimer. 2) Redistributions in binary form must reproduce the above
11   * copyright notice, this list of conditions and the following
12   * disclaimer in the documentation and/or other materials provided
13   * with the distribution. 3) Neither the name of the Qulice.com nor
14   * the names of its contributors may be used to endorse or promote
15   * products derived from this software without specific prior written
16   * permission.
17   *
18   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
20   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29   * OF THE POSSIBILITY OF SUCH DAMAGE.
30   */
31  package com.qulice.checkstyle;
32  
33  import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
34  import com.puppycrawl.tools.checkstyle.api.DetailAST;
35  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
36  import java.util.regex.Matcher;
37  import java.util.regex.Pattern;
38  
39  /**
40   * Multi line comment checker.
41   * Used by the checkstyle process multiple times as a singleton.
42   * @since 0.23.1
43   */
44  public final class MultiLineCommentCheck extends AbstractCheck {
45      /**
46       * Pattern for check.
47       * It is not final as it is initialized from the configuration.
48       */
49      private Pattern format = Pattern.compile("^$");
50  
51      /**
52       * The message to report for a match.
53       * It is not final as it is initialized from the configuration.
54       */
55      private String message = "";
56  
57      /**
58       * Comment line.
59       * It is not final because the visitToken method is called many times
60       * during the class under test and the field is reinitialized with a new object.
61       */
62      @SuppressWarnings("PMD.AvoidStringBufferField")
63      private StringBuilder text;
64  
65      @Override
66      public boolean isCommentNodesRequired() {
67          return true;
68      }
69  
70      @Override
71      public int[] getDefaultTokens() {
72          return new int[]{
73              TokenTypes.BLOCK_COMMENT_BEGIN,
74              TokenTypes.COMMENT_CONTENT,
75              TokenTypes.BLOCK_COMMENT_END,
76          };
77      }
78  
79      @Override
80      public int[] getAcceptableTokens() {
81          return this.getDefaultTokens();
82      }
83  
84      @Override
85      public int[] getRequiredTokens() {
86          return this.getDefaultTokens();
87      }
88  
89      @Override
90      public void visitToken(final DetailAST ast) {
91          if (ast.getType() == TokenTypes.BLOCK_COMMENT_BEGIN) {
92              this.text = new StringBuilder(ast.getText());
93          } else if (ast.getType() == TokenTypes.COMMENT_CONTENT) {
94              this.text.append(ast.getText());
95          } else {
96              this.text.append(ast.getText());
97              final Matcher matcher = this.format.matcher(this.text.toString());
98              if (matcher.matches()) {
99                  this.log(ast, this.message);
100             }
101         }
102     }
103 
104     /**
105      * The method is called from checkstyle to configure this class.
106      * The parameter is set from the checks.xml file
107      * <module name="com.qulice.checkstyle.MultiLineCommentCheck"/> and
108      * <property name="format" value=" this regexp "/> property
109      *
110      * @param fmt Validatig regexp.
111      */
112     public void setFormat(final String fmt) {
113         this.format = Pattern.compile(fmt);
114     }
115 
116     /**
117      * The method is called from checkstyle to configure this class.
118      * The parameter is set from the checks.xml file
119      * <module name="com.qulice.checkstyle.MultiLineCommentCheck"/> and
120      * <property name="message" value="First sentence in a comment should start with ....."/>
121      * property
122      *
123      * @param msg Error message.
124      */
125     public void setMessage(final String msg) {
126         this.message = msg;
127     }
128 }