View Javadoc
1   package org.apache.maven.plugin.checkstyle;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import com.puppycrawl.tools.checkstyle.api.AuditEvent;
23  
24  /**
25   * Tooling for Checkstyle rules conventions: names, categories.
26   *
27   * @author Hervé Boutemy
28   * @since 2.13
29   */
30  public final class RuleUtil
31  {
32      private RuleUtil()
33      {
34          // hide utility class constructor
35      }
36      
37      private static final String CHECKSTYLE_PACKAGE = "com.puppycrawl.tools.checkstyle.checks";
38  
39      /**
40       * Get the rule name from an audit event.
41       *
42       * @param event the audit event
43       * @return the rule name, which is the class name without package and removed eventual "Check" suffix
44       */
45      public static String getName( AuditEvent event )
46      {
47          return getName( event.getSourceName() );
48      }
49      /**
50       * Get the rule name from an audit event source name.
51       *
52       * @param eventSrcName the audit event source name
53       * @return the rule name, which is the class name without package and removed eventual "Check" suffix
54       */
55      public static String getName( String eventSrcName )
56      {
57          if ( eventSrcName == null )
58          {
59              return null;
60          }
61  
62          if ( eventSrcName.endsWith( "Check" ) )
63          {
64              eventSrcName = eventSrcName.substring( 0, eventSrcName.length() - 5 );
65          }
66  
67          return eventSrcName.substring( eventSrcName.lastIndexOf( '.' ) + 1 );
68      }
69  
70      /**
71       * Get the rule category from an audit event.
72       *
73       * @param event the audit event
74       * @return the rule category, which is the last package name or "misc" or "extension"
75       */
76      public static String getCategory( AuditEvent event )
77      {
78          return getCategory( event.getSourceName() );
79      }
80  
81      /**
82       * Get the rule category from an audit event source name.
83       *
84       * @param eventSrcName the audit event source name
85       * @return the rule category, which is the last package name or "misc" or "extension"
86       */
87      public static String getCategory( String eventSrcName )
88      {
89          if ( eventSrcName == null )
90          {
91              return null;
92          }
93  
94          int end = eventSrcName.lastIndexOf( '.' );
95          eventSrcName = eventSrcName.substring( 0,  end );
96  
97          if ( CHECKSTYLE_PACKAGE.equals( eventSrcName ) )
98          {
99              return "misc";
100         }
101         else if ( !eventSrcName.startsWith( CHECKSTYLE_PACKAGE ) )
102         {
103             return "extension";
104         }
105 
106         return eventSrcName.substring( eventSrcName.lastIndexOf( '.' ) + 1 );
107     }
108 
109     public static Matcher[] parseMatchers( String[] specs )
110     {
111         Matcher[] matchers = new Matcher[specs.length];
112         int i = 0;
113         for ( String spec: specs )
114         {
115             spec = spec.trim();
116             Matcher matcher;
117             if ( Character.isUpperCase( spec.charAt( 0 ) ) )
118             {
119                 // spec starting with uppercase is a rule name
120                 matcher = new RuleMatcher( spec );
121             }
122             else if ( "misc".equals( spec ) )
123             {
124                 // "misc" is a special case
125                 matcher = new PackageMatcher( CHECKSTYLE_PACKAGE );
126             }
127             else if ( "extension".equals( spec ) )
128             {
129                 // "extension" is a special case
130                 matcher = new ExtensionMatcher();
131             }
132             else if ( !spec.contains( "." ) )
133             {
134                 matcher = new PackageMatcher( CHECKSTYLE_PACKAGE + '.' + spec );
135             }
136             else
137             {
138                 // by default, spec is a package name
139                 matcher = new PackageMatcher( spec );
140             }
141             matchers[i++] = matcher;
142         }
143         return matchers;
144     }
145 
146     /**
147      * Audit event source name matcher.
148      */
149     public static interface Matcher
150     {
151         /**
152          * Does the event source name match?
153          * @param eventSrcName the event source name
154          * @return boolean
155          */
156         boolean match( String eventSrcName );
157     }
158 
159     private static class RuleMatcher
160         implements Matcher
161     {
162         private final String rule;
163 
164         public RuleMatcher( String rule )
165         {
166             this.rule = rule;
167         }
168 
169         public boolean match( String eventSrcName )
170         {
171             return rule.equals( getName( eventSrcName ) );
172         }
173     }
174 
175     private static class PackageMatcher
176         implements Matcher
177     {
178         private final String packageName;
179 
180         public PackageMatcher( String packageName )
181         {
182             this.packageName = packageName;
183         }
184 
185         public boolean match( String eventSrcName )
186         {
187             return eventSrcName.startsWith( packageName )
188                 && !eventSrcName.substring( packageName.length() + 1 ).contains( "." );
189         }
190     }
191 
192     /**
193      * An extension does not start with Checkstyle package.
194      */
195     private static class ExtensionMatcher
196         implements Matcher
197     {
198         public boolean match( String eventSrcName )
199         {
200             return !eventSrcName.startsWith( CHECKSTYLE_PACKAGE );
201         }
202     }
203 }