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.Collections;
023import java.util.List;
024import java.util.Objects;
025
026import org.apache.commons.vfs2.FileFilter;
027import org.apache.commons.vfs2.FileSelectInfo;
028import org.apache.commons.vfs2.FileSystemException;
029
030/**
031 * A {@link FileFilter} providing conditional OR logic across a list of
032 * file filters. This filter returns {@code true} if any filters in the list
033 * return {@code true}. Otherwise, it returns {@code false}. Checking of the
034 * file filter list stops when the first filter returns {@code true}.
035 *
036 * @author This code was originally ported from Apache Commons IO File Filter
037 * @see "https://commons.apache.org/proper/commons-io/"
038 * @since 2.4
039 */
040public class OrFileFilter implements FileFilter, ConditionalFileFilter, Serializable {
041
042    private static final long serialVersionUID = 1L;
043
044    /** The list of file filters. */
045    private final List<FileFilter> fileFilters;
046
047    /**
048     * Default constructor.
049     */
050    public OrFileFilter() {
051        fileFilters = new ArrayList<>();
052    }
053
054    /**
055     * Constructs a new file filter that ORs the result of other filters.
056     *
057     * @param filters array of filters, must not be null or empty
058     */
059    public OrFileFilter(final FileFilter... filters) {
060        if (filters == null || filters.length == 0) {
061            throw new IllegalArgumentException("The filters must not be null or empty");
062        }
063        for (final FileFilter filter : filters) {
064            if (filter == null) {
065                throw new IllegalArgumentException("Null filters are not allowed");
066            }
067        }
068        fileFilters = new ArrayList<>(Arrays.asList(filters));
069    }
070
071    /**
072     * Constructs a new instance of {@code OrFileFilter} with the specified
073     * filters.
074     *
075     * @param fileFilters the file filters for this filter, copied, null ignored
076     */
077    public OrFileFilter(final List<FileFilter> fileFilters) {
078        if (fileFilters == null) {
079            this.fileFilters = new ArrayList<>();
080        } else {
081            this.fileFilters = new ArrayList<>(fileFilters);
082        }
083    }
084
085    @Override
086    public boolean accept(final FileSelectInfo fileSelectInfo) throws FileSystemException {
087        for (final FileFilter fileFilter : fileFilters) {
088            if (fileFilter.accept(fileSelectInfo)) {
089                return true;
090            }
091        }
092        return false;
093    }
094
095    @Override
096    public void addFileFilter(final FileFilter fileFilter) {
097        fileFilters.add(fileFilter);
098    }
099
100    @Override
101    public List<FileFilter> getFileFilters() {
102        return Collections.unmodifiableList(fileFilters);
103    }
104
105    @Override
106    public boolean removeFileFilter(final FileFilter fileFilter) {
107        return fileFilters.remove(fileFilter);
108    }
109
110    @Override
111    public void setFileFilters(final List<FileFilter> fileFilters) {
112        this.fileFilters.clear();
113        this.fileFilters.addAll(fileFilters);
114    }
115
116    /**
117     * Provide a String representation of this file filter.
118     *
119     * @return a String representation
120     */
121    @Override
122    public String toString() {
123        final StringBuilder buffer = new StringBuilder();
124        buffer.append(super.toString());
125        buffer.append("(");
126        if (fileFilters != null) {
127            for (int i = 0; i < fileFilters.size(); i++) {
128                if (i > 0) {
129                    buffer.append(",");
130                }
131                buffer.append(Objects.toString(fileFilters.get(i)));
132            }
133        }
134        buffer.append(")");
135        return buffer.toString();
136    }
137
138}