001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube 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 * SonarQube 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 org.apache.commons.io.FilenameUtils;
023import org.apache.commons.lang.StringUtils;
024import org.sonar.api.batch.fs.InputFile;
025import org.sonar.api.utils.WildcardPattern;
026
027public abstract class PathPattern {
028
029  final WildcardPattern pattern;
030
031  PathPattern(String pattern) {
032    this.pattern = WildcardPattern.create(pattern);
033  }
034
035  public abstract boolean match(InputFile inputFile);
036
037  public abstract boolean match(InputFile inputFile, boolean caseSensitiveFileExtension);
038
039  public static PathPattern create(String s) {
040    String trimmed = StringUtils.trim(s);
041    if (StringUtils.startsWithIgnoreCase(trimmed, "file:")) {
042      return new AbsolutePathPattern(StringUtils.substring(trimmed, "file:".length()));
043    }
044    return new RelativePathPattern(trimmed);
045  }
046
047  public static PathPattern[] create(String[] s) {
048    PathPattern[] result = new PathPattern[s.length];
049    for (int i = 0; i < s.length; i++) {
050      result[i] = create(s[i]);
051    }
052    return result;
053  }
054
055  private static class AbsolutePathPattern extends PathPattern {
056    private AbsolutePathPattern(String pattern) {
057      super(pattern);
058    }
059
060    @Override
061    public boolean match(InputFile inputFile) {
062      return match(inputFile, true);
063    }
064
065    @Override
066    public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
067      String path = inputFile.absolutePath();
068      if (!caseSensitiveFileExtension) {
069        String extension = super.sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
070        if (StringUtils.isNotBlank(extension)) {
071          path = StringUtils.removeEndIgnoreCase(path, extension);
072          path = path + extension;
073        }
074      }
075      return pattern.match(path);
076    }
077
078    @Override
079    public String toString() {
080      return "file:" + pattern.toString();
081    }
082  }
083
084  /**
085   * Path relative to module basedir
086   */
087  private static class RelativePathPattern extends PathPattern {
088    private RelativePathPattern(String pattern) {
089      super(pattern);
090    }
091
092    @Override
093    public boolean match(InputFile inputFile) {
094      return match(inputFile, true);
095    }
096
097    @Override
098    public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
099      String path = inputFile.relativePath();
100      if (!caseSensitiveFileExtension) {
101        String extension = super.sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
102        if (StringUtils.isNotBlank(extension)) {
103          path = StringUtils.removeEndIgnoreCase(path, extension);
104          path = path + extension;
105        }
106      }
107      return path != null && pattern.match(path);
108    }
109
110    @Override
111    public String toString() {
112      return pattern.toString();
113    }
114  }
115
116  static String sanitizeExtension(String suffix) {
117    return StringUtils.lowerCase(StringUtils.removeStart(suffix, "."));
118  }
119}