    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.List;
    025import java.util.Objects;
    026
    027import org.apache.commons.io.IOCase;
    028
    029/**
    030 * Filters file names for a certain name.
    031 * <p>
    032 * For example, to print all files and directories in the
    033 * current directory whose name is {@code Test}:
    034 * </p>
    035 * <h2>Using Classic IO</h2>
    036 * <pre>
    037 * File dir = new File(".");
    038 * String[] files = dir.list(new NameFileFilter("Test"));
    039 * for (String file : files) {
    040 *     System.out.println(file);
    041 * }
    042 * </pre>
    043 *
    044 * <h2>Using NIO</h2>
    045 * <pre>
    046 * final Path dir = Paths.get("");
    047 * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new NameFileFilter("Test"));
    048 * //
    049 * // Walk one dir
    050 * Files.<b>walkFileTree</b>(dir, Collections.emptySet(), 1, visitor);
    051 * System.out.println(visitor.getPathCounters());
    052 * System.out.println(visitor.getFileList());
    053 * //
    054 * visitor.getPathCounters().reset();
    055 * //
    056 * // Walk dir tree
    057 * Files.<b>walkFileTree</b>(dir, visitor);
    058 * System.out.println(visitor.getPathCounters());
    059 * System.out.println(visitor.getDirList());
    060 * System.out.println(visitor.getFileList());
    061 * </pre>
    062 *
    063 * @since 1.0
    064 * @see FileFilterUtils#nameFileFilter(String)
    065 * @see FileFilterUtils#nameFileFilter(String, IOCase)
    066 */
    067public class NameFileFilter extends AbstractFileFilter implements Serializable {
    068
    069    private static final long serialVersionUID = 176844364689077340L;
    070
    071    /** The file names to search for */
    072    private final String[] names;
    073
    074    /** Whether the comparison is case sensitive. */
    075    private final IOCase caseSensitivity;
    076
    077    /**
    078     * Constructs a new case-sensitive name file filter for a list of names.
    079     *
    080     * @param names  the names to allow, must not be null
    081     * @throws IllegalArgumentException if the name list is null
    082     * @throws ClassCastException if the list does not contain Strings
    083     */
    084    public NameFileFilter(final List<String> names) {
    085        this(names, null);
    086    }
    087
    088    /**
    089     * Constructs a new name file filter for a list of names specifying case-sensitivity.
    090     *
    091     * @param names  the names to allow, must not be null
    092     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
    093     * @throws IllegalArgumentException if the name list is null
    094     * @throws ClassCastException if the list does not contain Strings
    095     */
    096    public NameFileFilter(final List<String> names, final IOCase caseSensitivity) {
    097        if (names == null) {
    098            throw new IllegalArgumentException("The list of names must not be null");
    099        }
    100        this.names = names.toArray(EMPTY_STRING_ARRAY);
    101        this.caseSensitivity = toIOCase(caseSensitivity);
    102    }
    103
    104    /**
    105     * Constructs a new case-sensitive name file filter for a single name.
    106     *
    107     * @param name  the name to allow, must not be null
    108     * @throws IllegalArgumentException if the name is null
    109     */
    110    public NameFileFilter(final String name) {
    111        this(name, IOCase.SENSITIVE);
    112    }
    113
    114    /**
    115     * Constructs a new case-sensitive name file filter for an array of names.
    116     * <p>
    117     * The array is not cloned, so could be changed after constructing the
    118     * instance. This would be inadvisable however.
    119     * </p>
    120     *
    121     * @param names  the names to allow, must not be null
    122     * @throws IllegalArgumentException if the names array is null
    123     */
    124    public NameFileFilter(final String... names) {
    125        this(names, IOCase.SENSITIVE);
    126    }
    127
    128    /**
    129     * Construct a new name file filter specifying case-sensitivity.
    130     *
    131     * @param name  the name to allow, must not be null
    132     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
    133     * @throws IllegalArgumentException if the name is null
    134     */
    135    public NameFileFilter(final String name, final IOCase caseSensitivity) {
    136        if (name == null) {
    137            throw new IllegalArgumentException("The wildcard must not be null");
    138        }
    139        this.names = new String[] {name};
    140        this.caseSensitivity = toIOCase(caseSensitivity);
    141    }
    142
    143    /**
    144     * Constructs a new name file filter for an array of names specifying case-sensitivity.
    145     *
    146     * @param names  the names to allow, must not be null
    147     * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
    148     * @throws IllegalArgumentException if the names array is null
    149     */
    150    public NameFileFilter(final String[] names, final IOCase caseSensitivity) {
    151        if (names == null) {
    152            throw new IllegalArgumentException("The array of names must not be null");
    153        }
    154        this.names = new String[names.length];
    155        System.arraycopy(names, 0, this.names, 0, names.length);
    156        this.caseSensitivity = toIOCase(caseSensitivity);
    157    }
    158
    159    /**
    160     * Checks to see if the file name matches.
    161     *
    162     * @param file  the File to check
    163     * @return true if the file name matches
    164     */
    165    @Override
    166    public boolean accept(final File file) {
    167        return acceptBaseName(file.getName());
    168    }
    169
    170    /**
    171     * Checks to see if the file name matches.
    172     *
    173     * @param dir  the File directory (ignored)
    174     * @param name  the file name
    175     * @return true if the file name matches
    176     */
    177    @Override
    178    public boolean accept(final File dir, final String name) {
    179        return acceptBaseName(name);
    180    }
    181
    182    /**
    183     * Checks to see if the file name matches.
    184     * @param file  the File to check
    185     *
    186     * @return true if the file name matches
    187     * @since 2.9.0
    188     */
    189    @Override
    190    public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
    191        return toFileVisitResult(acceptBaseName(Objects.toString(file.getFileName(), null)), file);
    192    }
    193
    194    private boolean acceptBaseName(final String baseName) {
    195        for (final String testName : names) {
    196            if (caseSensitivity.checkEquals(baseName, testName)) {
    197                return true;
    198            }
    199        }
    200        return false;
    201    }
    202
    203    private IOCase toIOCase(final IOCase caseSensitivity) {
    204        return caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
    205    }
    206
    207    /**
    208     * Provide a String representation of this file filter.
    209     *
    210     * @return a String representation
    211     */
    212    @Override
    213    public String toString() {
    214        final StringBuilder buffer = new StringBuilder();
    215        buffer.append(super.toString());
    216        buffer.append("(");
    217        if (names != null) {
    218            for (int i = 0; i < names.length; i++) {
    219                if (i > 0) {
    220                    buffer.append(",");
    221                }
    222                buffer.append(names[i]);
    223            }
    224        }
    225        buffer.append(")");
    226        return buffer.toString();
    227    }
    228
    229}