1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2019 the original author or authors.
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  
20  package com.puppycrawl.tools.checkstyle.checks.imports;
21  
22  import java.util.regex.Pattern;
23  
24  /**
25   * Represents an import rules for a specific file. Only the file name is
26   * considered and only files processed by TreeWalker. The file's
27   * extension is ignored.
28   */
29  class FileImportControl extends AbstractImportControl {
30      /** The name for the file. */
31      private final String name;
32      /** The regex pattern for exact matches - only not null if regex is true. */
33      private final Pattern patternForExactMatch;
34      /** If this file name represents a regular expression. */
35      private final boolean regex;
36  
37      /**
38       * Construct a file node.
39       * @param parent the parent node.
40       * @param name the name of the file.
41       * @param regex flags interpretation of name as regex pattern.
42       */
43      /* package */ FileImportControl(PkgImportControl parent, String name, boolean regex) {
44          super(parent, MismatchStrategy.DELEGATE_TO_PARENT);
45  
46          this.regex = regex;
47          if (regex) {
48              this.name = encloseInGroup(name);
49              patternForExactMatch = createPatternForExactMatch(this.name);
50          }
51          else {
52              this.name = name;
53              patternForExactMatch = null;
54          }
55      }
56  
57      /**
58       * Enclose {@code expression} in a (non-capturing) group.
59       * @param expression the input regular expression
60       * @return a grouped pattern.
61       */
62      private static String encloseInGroup(String expression) {
63          return "(?:" + expression + ")";
64      }
65  
66      /**
67       * Creates a Pattern from {@code expression}.
68       * @param expression a self-contained regular expression matching the full
69       *     file name exactly.
70       * @return a Pattern.
71       */
72      private static Pattern createPatternForExactMatch(String expression) {
73          return Pattern.compile(expression);
74      }
75  
76      @Override
77      public AbstractImportControl locateFinest(String forPkg, String forFileName) {
78          AbstractImportControl finestMatch = null;
79          // Check if we are a match.
80          if (matchesExactly(forPkg, forFileName)) {
81              finestMatch = this;
82          }
83          return finestMatch;
84      }
85  
86      @Override
87      protected boolean matchesExactly(String pkg, String fileName) {
88          final boolean result;
89          if (fileName == null) {
90              result = false;
91          }
92          else if (regex) {
93              result = patternForExactMatch.matcher(fileName).matches();
94          }
95          else {
96              result = name.equals(fileName);
97          }
98          return result;
99      }
100 }