001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2022 the original author or authors. 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//////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.checks.imports; 021 022import java.util.regex.Pattern; 023 024/** 025 * Represents an import rules for a specific file. Only the file name is 026 * considered and only files processed by TreeWalker. The file's 027 * extension is ignored. 028 */ 029class FileImportControl extends AbstractImportControl { 030 /** The name for the file. */ 031 private final String name; 032 /** The regex pattern for exact matches - only not null if regex is true. */ 033 private final Pattern patternForExactMatch; 034 /** If this file name represents a regular expression. */ 035 private final boolean regex; 036 037 /** 038 * Construct a file node. 039 * 040 * @param parent the parent node. 041 * @param name the name of the file. 042 * @param regex flags interpretation of name as regex pattern. 043 */ 044 /* package */ FileImportControl(PkgImportControl parent, String name, boolean regex) { 045 super(parent, MismatchStrategy.DELEGATE_TO_PARENT); 046 047 this.regex = regex; 048 if (regex) { 049 this.name = encloseInGroup(name); 050 patternForExactMatch = createPatternForExactMatch(this.name); 051 } 052 else { 053 this.name = name; 054 patternForExactMatch = null; 055 } 056 } 057 058 /** 059 * Enclose {@code expression} in a (non-capturing) group. 060 * 061 * @param expression the input regular expression 062 * @return a grouped pattern. 063 */ 064 private static String encloseInGroup(String expression) { 065 return "(?:" + expression + ")"; 066 } 067 068 /** 069 * Creates a Pattern from {@code expression}. 070 * 071 * @param expression a self-contained regular expression matching the full 072 * file name exactly. 073 * @return a Pattern. 074 */ 075 private static Pattern createPatternForExactMatch(String expression) { 076 return Pattern.compile(expression); 077 } 078 079 @Override 080 public AbstractImportControl locateFinest(String forPkg, String forFileName) { 081 AbstractImportControl finestMatch = null; 082 // Check if we are a match. 083 if (matchesExactly(forPkg, forFileName)) { 084 finestMatch = this; 085 } 086 return finestMatch; 087 } 088 089 @Override 090 protected boolean matchesExactly(String pkg, String fileName) { 091 final boolean result; 092 if (fileName == null) { 093 result = false; 094 } 095 else if (regex) { 096 result = patternForExactMatch.matcher(fileName).matches(); 097 } 098 else { 099 result = name.equals(fileName); 100 } 101 return result; 102 } 103}