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.vfs2.filter;
018
019import java.io.Serializable;
020import java.util.ArrayList;
021import java.util.Arrays;
022import java.util.List;
023
024import org.apache.commons.vfs2.FileFilter;
025import org.apache.commons.vfs2.FileSelectInfo;
026
027/**
028 * Filters files based on the suffix (what the file name ends with). This is used
029 * in retrieving all the files of a particular type.
030 * <p>
031 * For example, to retrieve and print all {@code *.java} files in the
032 * current directory:
033 * </p>
034 *
035 * <pre>
036 * FileSystemManager fsManager = VFS.getManager();
037 * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
038 * FileObject[] files = dir.findFiles(new FileFilterSelector(new SuffixFileFilter(&quot;.java&quot;)));
039 * for (int i = 0; i &lt; files.length; i++) {
040 *     System.out.println(files[i]);
041 * }
042 * </pre>
043 *
044 * @author This code was originally ported from Apache Commons IO File Filter
045 * @see "https://commons.apache.org/proper/commons-io/"
046 * @since 2.4
047 */
048public class SuffixFileFilter implements FileFilter, Serializable {
049
050    private static final long serialVersionUID = 1L;
051
052    /** Whether the comparison is case-sensitive. */
053    private final IOCase caseSensitivity;
054
055    /** The file name suffixes to search for. */
056    private final List<String> suffixes;
057
058    /**
059     * Constructs a new Suffix file filter for a list of suffixes specifying
060     * case-sensitivity.
061     *
062     * @param suffixes        the suffixes to allow, must not be null
063     * @param caseSensitivity how to handle case sensitivity, null means
064     *                        case-sensitive
065     */
066    public SuffixFileFilter(final IOCase caseSensitivity, final List<String> suffixes) {
067        if (suffixes == null) {
068            throw new IllegalArgumentException("The list of suffixes must not be null");
069        }
070        this.suffixes = new ArrayList<>(suffixes);
071        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
072    }
073
074    /**
075     * Constructs a new Suffix file filter for an array of suffixes specifying
076     * case-sensitivity.
077     *
078     * @param suffixes        the suffixes to allow, must not be null
079     * @param caseSensitivity how to handle case sensitivity, null means
080     *                        case-sensitive
081     */
082    public SuffixFileFilter(final IOCase caseSensitivity, final String... suffixes) {
083        if (suffixes == null) {
084            throw new IllegalArgumentException("The array of suffixes must not be null");
085        }
086        this.suffixes = new ArrayList<>(Arrays.asList(suffixes));
087        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
088    }
089
090    /**
091     * Constructs a new Suffix file filter for a list of suffixes.
092     *
093     * @param suffixes the suffixes to allow, must not be null
094     */
095    public SuffixFileFilter(final List<String> suffixes) {
096        this(IOCase.SENSITIVE, suffixes);
097    }
098
099    /**
100     * Constructs a new Suffix file filter for an array of suffixes.
101     *
102     * @param suffixes the suffixes to allow, must not be null
103     */
104    public SuffixFileFilter(final String... suffixes) {
105        this(IOCase.SENSITIVE, suffixes);
106    }
107
108    /**
109     * Checks to see if the file name ends with the suffix.
110     *
111     * @param fileSelectInfo the File to check
112     * @return true if the file name ends with one of our suffixes
113     */
114    @Override
115    public boolean accept(final FileSelectInfo fileSelectInfo) {
116        final String name = fileSelectInfo.getFile().getName().getBaseName();
117        return suffixes.stream().anyMatch(suffix -> caseSensitivity.checkEndsWith(name, suffix));
118    }
119
120    /**
121     * Provides a String representation of this file filter.
122     *
123     * @return a String representation
124     */
125    @Override
126    public String toString() {
127        final StringBuilder buffer = new StringBuilder();
128        buffer.append(super.toString());
129        buffer.append("(");
130        if (suffixes != null) {
131            buffer.append(String.join(",", suffixes));
132        }
133        buffer.append(")");
134        return buffer.toString();
135    }
136
137}