    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.io.filefilter;
    018
    019import java.io.File;
    020import java.io.Serializable;
    021import java.nio.file.FileVisitResult;
    022import java.nio.file.Path;
    023import java.nio.file.attribute.BasicFileAttributes;
    024import java.util.regex.Pattern;
    025
    026import org.apache.commons.io.IOCase;
    027
    028/**
    029 * Filters files using supplied regular expression(s).
    030 * <p>
    031 * See java.util.regex.Pattern for regex matching rules.
    032 * </p>
    033 * <h2>Using Classic IO</h2>
    034 * <p>
    035 * e.g.
    036 *
    037 * <pre>
    038 * File dir = new File(".");
    039 * FileFilter fileFilter = new RegexFileFilter("^.*[tT]est(-\\d+)?\\.java$");
    040 * File[] files = dir.listFiles(fileFilter);
    041 * for (String file : files) {
    042 *     System.out.println(file);
    043 * }
    044 * </pre>
    045 *
    046 * <h2>Using NIO</h2>
    047 *
    048 * <pre>
    049 * final Path dir = Paths.get("");
    050 * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new RegexFileFilter("^.*[tT]est(-\\d+)?\\.java$"));
    051 * //
    052 * // Walk one dir
    053 * Files.<b>walkFileTree</b>(dir, Collections.emptySet(), 1, visitor);
    054 * System.out.println(visitor.getPathCounters());
    055 * System.out.println(visitor.getFileList());
    056 * //
    057 * visitor.getPathCounters().reset();
    058 * //
    059 * // Walk dir tree
    060 * Files.<b>walkFileTree</b>(dir, visitor);
    061 * System.out.println(visitor.getPathCounters());
    062 * System.out.println(visitor.getDirList());
    063 * System.out.println(visitor.getFileList());
    064 * </pre>
    065 *
    066 * @since 1.4
    067 */
    068public class RegexFileFilter extends AbstractFileFilter implements Serializable {
    069
    070    private static final long serialVersionUID = 4269646126155225062L;
    071    /** The regular expression pattern that will be used to match file names */
    072    private final Pattern pattern;
    073
    074    /**
    075     * Construct a new regular expression filter for a compiled regular expression
    076     *
    077     * @param pattern regular expression to match
    078     * @throws IllegalArgumentException if the pattern is null
    079     */
    080    public RegexFileFilter(final Pattern pattern) {
    081        if (pattern == null) {
    082            throw new IllegalArgumentException("Pattern is missing");
    083        }
    084
    085        this.pattern = pattern;
    086    }
    087
    088    /**
    089     * Construct a new regular expression filter.
    090     *
    091     * @param pattern regular string expression to match
    092     * @throws IllegalArgumentException if the pattern is null
    093     */
    094    public RegexFileFilter(final String pattern) {
    095        if (pattern == null) {
    096            throw new IllegalArgumentException("Pattern is missing");
    097        }
    098
    099        this.pattern = Pattern.compile(pattern);
    100    }
    101
    102    /**
    103     * Construct a new regular expression filter with the specified flags.
    104     *
    105     * @param pattern regular string expression to match
    106     * @param flags pattern flags - e.g. {@link Pattern#CASE_INSENSITIVE}
    107     * @throws IllegalArgumentException if the pattern is null
    108     */
    109    public RegexFileFilter(final String pattern, final int flags) {
    110        if (pattern == null) {
    111            throw new IllegalArgumentException("Pattern is missing");
    112        }
    113        this.pattern = Pattern.compile(pattern, flags);
    114    }
    115
    116    /**
    117     * Construct a new regular expression filter with the specified flags case sensitivity.
    118     *
    119     * @param pattern regular string expression to match
    120     * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
    121     * @throws IllegalArgumentException if the pattern is null
    122     */
    123    public RegexFileFilter(final String pattern, final IOCase caseSensitivity) {
    124        if (pattern == null) {
    125            throw new IllegalArgumentException("Pattern is missing");
    126        }
    127        int flags = 0;
    128        if (caseSensitivity != null && !caseSensitivity.isCaseSensitive()) {
    129            flags = Pattern.CASE_INSENSITIVE;
    130        }
    131        this.pattern = Pattern.compile(pattern, flags);
    132    }
    133
    134    /**
    135     * Checks to see if the file name matches one of the regular expressions.
    136     *
    137     * @param dir the file directory (ignored)
    138     * @param name the file name
    139     * @return true if the file name matches one of the regular expressions
    140     */
    141    @Override
    142    public boolean accept(final File dir, final String name) {
    143        return pattern.matcher(name).matches();
    144    }
    145
    146    /**
    147     * Checks to see if the file name matches one of the regular expressions.
    148     *
    149     * @param path the path
    150     * @param attributes the path attributes
    151     * @return true if the file name matches one of the regular expressions
    152     */
    153    @Override
    154    public FileVisitResult accept(final Path path, final BasicFileAttributes attributes) {
    155        return toFileVisitResult(pattern.matcher(path.toString()).matches(), path);
    156    }
    157
    158}