001/* 002 * SonarQube 003 * Copyright (C) 2009-2018 SonarSource SA 004 * mailto:info AT sonarsource DOT com 005 * 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020package org.sonar.api.batch.fs.internal; 021 022import java.nio.file.Path; 023import javax.annotation.concurrent.ThreadSafe; 024import org.apache.commons.io.FilenameUtils; 025import org.apache.commons.lang.StringUtils; 026import org.sonar.api.utils.PathUtils; 027import org.sonar.api.utils.WildcardPattern; 028import org.sonar.api.utils.log.Logger; 029import org.sonar.api.utils.log.Loggers; 030 031@ThreadSafe 032public abstract class PathPattern { 033 034 private static final Logger LOG = Loggers.get(PathPattern.class); 035 036 /** 037 * @deprecated since 6.6 038 */ 039 @Deprecated 040 private static final String ABSOLUTE_PATH_PATTERN_PREFIX = "file:"; 041 final WildcardPattern pattern; 042 043 PathPattern(String pattern) { 044 this.pattern = WildcardPattern.create(pattern); 045 } 046 047 public abstract boolean match(Path absolutePath, Path relativePath); 048 049 public abstract boolean match(Path absolutePath, Path relativePath, boolean caseSensitiveFileExtension); 050 051 public static PathPattern create(String s) { 052 String trimmed = StringUtils.trim(s); 053 if (StringUtils.startsWithIgnoreCase(trimmed, ABSOLUTE_PATH_PATTERN_PREFIX)) { 054 LOG.warn("Using absolute path pattern is deprecated. Please use relative path instead of '" + trimmed + "'"); 055 return new AbsolutePathPattern(StringUtils.substring(trimmed, ABSOLUTE_PATH_PATTERN_PREFIX.length())); 056 } 057 return new RelativePathPattern(trimmed); 058 } 059 060 public static PathPattern[] create(String[] s) { 061 PathPattern[] result = new PathPattern[s.length]; 062 for (int i = 0; i < s.length; i++) { 063 result[i] = create(s[i]); 064 } 065 return result; 066 } 067 068 /** 069 * @deprecated since 6.6 070 */ 071 @Deprecated 072 private static class AbsolutePathPattern extends PathPattern { 073 private AbsolutePathPattern(String pattern) { 074 super(pattern); 075 } 076 077 @Override 078 public boolean match(Path absolutePath, Path relativePath) { 079 return match(absolutePath, relativePath, true); 080 } 081 082 @Override 083 public boolean match(Path absolutePath, Path relativePath, boolean caseSensitiveFileExtension) { 084 String path = PathUtils.sanitize(absolutePath.toString()); 085 if (!caseSensitiveFileExtension) { 086 String extension = sanitizeExtension(FilenameUtils.getExtension(path)); 087 if (StringUtils.isNotBlank(extension)) { 088 path = StringUtils.removeEndIgnoreCase(path, extension); 089 path = path + extension; 090 } 091 } 092 return pattern.match(path); 093 } 094 095 @Override 096 public String toString() { 097 return ABSOLUTE_PATH_PATTERN_PREFIX + pattern.toString(); 098 } 099 } 100 101 /** 102 * Path relative to module basedir 103 */ 104 private static class RelativePathPattern extends PathPattern { 105 private RelativePathPattern(String pattern) { 106 super(pattern); 107 } 108 109 @Override 110 public boolean match(Path absolutePath, Path relativePath) { 111 return match(absolutePath, relativePath, true); 112 } 113 114 @Override 115 public boolean match(Path absolutePath, Path relativePath, boolean caseSensitiveFileExtension) { 116 String path = PathUtils.sanitize(relativePath.toString()); 117 if (!caseSensitiveFileExtension) { 118 String extension = sanitizeExtension(FilenameUtils.getExtension(path)); 119 if (StringUtils.isNotBlank(extension)) { 120 path = StringUtils.removeEndIgnoreCase(path, extension); 121 path = path + extension; 122 } 123 } 124 return path != null && pattern.match(path); 125 } 126 127 @Override 128 public String toString() { 129 return pattern.toString(); 130 } 131 } 132 133 static String sanitizeExtension(String suffix) { 134 return StringUtils.lowerCase(StringUtils.removeStart(suffix, ".")); 135 } 136}