    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     */
    017    package org.apache.commons.io.filefilter;
    018
    019    import java.io.File;
    020    import java.io.Serializable;
    021    import java.util.List;
    022
    023    import org.apache.commons.io.FilenameUtils;
    024    import org.apache.commons.io.IOCase;
    025
    026    /**
    027     * Filters files using the supplied wildcards.
    028     * <p>
    029     * This filter selects files and directories based on one or more wildcards.
    030     * Testing is case-sensitive by default, but this can be configured.
    031     * <p>
    032     * The wildcard matcher uses the characters '?' and '*' to represent a
    033     * single or multiple wildcard characters.
    034     * This is the same as often found on Dos/Unix command lines.
    035     * The extension check is case-sensitive by .
    036     * See {@link FilenameUtils#wildcardMatchOnSystem} for more information.
    037     * <p>
    038     * For example:
    039     * <pre>
    040     * File dir = new File(".");
    041     * FileFilter fileFilter = new WildcardFileFilter("*test*.java~*~");
    042     * File[] files = dir.listFiles(fileFilter);
    043     * for (int i = 0; i < files.length; i++) {
    044     *   System.out.println(files[i]);
    045     * }
    046     * </pre>
    047     *
    048     * @author Jason Anderson
    049     * @version $Revision: 1004077 $ $Date: 2010-10-04 01:58:42 +0100 (Mon, 04 Oct 2010) $
    050     * @since Commons IO 1.3
    051     */
    052    public class WildcardFileFilter extends AbstractFileFilter implements Serializable {
    053
    054        /** The wildcards that will be used to match filenames. */
    055        private final String[] wildcards;
    056        /** Whether the comparison is case sensitive. */
    057        private final IOCase caseSensitivity;
    058
    059        /**
    060         * Construct a new case-sensitive wildcard filter for a single wildcard.
    061         *
    062         * @param wildcard  the wildcard to match
    063         * @throws IllegalArgumentException if the pattern is null
    064         */
    065        public WildcardFileFilter(String wildcard) {
    066            this(wildcard, null);
    067        }
    068
    069        /**
    070         * Construct a new wildcard filter for a single wildcard specifying case-sensitivity.
    071         *
    072         * @param wildcard  the wildcard to match, not null
    073         * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
    074         * @throws IllegalArgumentException if the pattern is null
    075         */
    076        public WildcardFileFilter(String wildcard, IOCase caseSensitivity) {
    077            if (wildcard == null) {
    078                throw new IllegalArgumentException("The wildcard must not be null");
    079            }
    080            this.wildcards = new String[] { wildcard };
    081            this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
    082        }
    083
    084        /**
    085         * Construct a new case-sensitive wildcard filter for an array of wildcards.
    086         * <p>
    087         * The array is not cloned, so could be changed after constructing the
    088         * instance. This would be inadvisable however.
    089         *
    090         * @param wildcards  the array of wildcards to match
    091         * @throws IllegalArgumentException if the pattern array is null
    092         */
    093        public WildcardFileFilter(String[] wildcards) {
    094            this(wildcards, null);
    095        }
    096
    097        /**
    098         * Construct a new wildcard filter for an array of wildcards specifying case-sensitivity.
    099         * <p>
    100         * The array is not cloned, so could be changed after constructing the
    101         * instance. This would be inadvisable however.
    102         *
    103         * @param wildcards  the array of wildcards to match, not null
    104         * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
    105         * @throws IllegalArgumentException if the pattern array is null
    106         */
    107        public WildcardFileFilter(String[] wildcards, IOCase caseSensitivity) {
    108            if (wildcards == null) {
    109                throw new IllegalArgumentException("The wildcard array must not be null");
    110            }
    111            this.wildcards = new String[wildcards.length];
    112            System.arraycopy(wildcards, 0, this.wildcards, 0, wildcards.length);
    113            this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
    114        }
    115
    116        /**
    117         * Construct a new case-sensitive wildcard filter for a list of wildcards.
    118         *
    119         * @param wildcards  the list of wildcards to match, not null
    120         * @throws IllegalArgumentException if the pattern list is null
    121         * @throws ClassCastException if the list does not contain Strings
    122         */
    123        public WildcardFileFilter(List<String> wildcards) {
    124            this(wildcards, null);
    125        }
    126
    127        /**
    128         * Construct a new wildcard filter for a list of wildcards specifying case-sensitivity.
    129         *
    130         * @param wildcards  the list of wildcards to match, not null
    131         * @param caseSensitivity  how to handle case sensitivity, null means case-sensitive
    132         * @throws IllegalArgumentException if the pattern list is null
    133         * @throws ClassCastException if the list does not contain Strings
    134         */
    135        public WildcardFileFilter(List<String> wildcards, IOCase caseSensitivity) {
    136            if (wildcards == null) {
    137                throw new IllegalArgumentException("The wildcard list must not be null");
    138            }
    139            this.wildcards = wildcards.toArray(new String[wildcards.size()]);
    140            this.caseSensitivity = (caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity);
    141        }
    142
    143        //-----------------------------------------------------------------------
    144        /**
    145         * Checks to see if the filename matches one of the wildcards.
    146         *
    147         * @param dir  the file directory
    148         * @param name  the filename
    149         * @return true if the filename matches one of the wildcards
    150         */
    151        @Override
    152        public boolean accept(File dir, String name) {
    153            for (String wildcard : wildcards) {
    154                if (FilenameUtils.wildcardMatch(name, wildcard, caseSensitivity)) {
    155                    return true;
    156                }
    157            }
    158            return false;
    159        }
    160
    161        /**
    162         * Checks to see if the filename matches one of the wildcards.
    163         *
    164         * @param file  the file to check
    165         * @return true if the filename matches one of the wildcards
    166         */
    167        @Override
    168        public boolean accept(File file) {
    169            String name = file.getName();
    170            for (String wildcard : wildcards) {
    171                if (FilenameUtils.wildcardMatch(name, wildcard, caseSensitivity)) {
    172                    return true;
    173                }
    174            }
    175            return false;
    176        }
    177
    178        /**
    179         * Provide a String representaion of this file filter.
    180         *
    181         * @return a String representaion
    182         */
    183        @Override
    184        public String toString() {
    185            StringBuilder buffer = new StringBuilder();
    186            buffer.append(super.toString());
    187            buffer.append("(");
    188            if (wildcards != null) {
    189                for (int i = 0; i < wildcards.length; i++) {
    190                    if (i > 0) {
    191                        buffer.append(",");
    192                    }
    193                    buffer.append(wildcards[i]);
    194                }
    195            }
    196            buffer.append(")");
    197            return buffer.toString();
    198        }
    199
    200    }