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.ArrayList;
022    import java.util.Collections;
023    import java.util.List;
024    
025    /**
026     * A {@link java.io.FileFilter} providing conditional OR logic across a list of
027     * file filters. This filter returns {@code true} if any filters in the
028     * list return {@code true}. Otherwise, it returns {@code false}.
029     * Checking of the file filter list stops when the first filter returns
030     * {@code true}.
031     *
032     * @since 1.0
033     * @version $Id: OrFileFilter.java 1307462 2012-03-30 15:13:11Z ggregory $
034     * @see FileFilterUtils#or(IOFileFilter...)
035     */
036    public class OrFileFilter
037            extends AbstractFileFilter
038            implements ConditionalFileFilter, Serializable {
039    
040        /** The list of file filters. */
041        private final List<IOFileFilter> fileFilters;
042    
043        /**
044         * Constructs a new instance of <code>OrFileFilter</code>.
045         *
046         * @since 1.1
047         */
048        public OrFileFilter() {
049            this.fileFilters = new ArrayList<IOFileFilter>();
050        }
051    
052        /**
053         * Constructs a new instance of <code>OrFileFilter</code>
054         * with the specified filters.
055         *
056         * @param fileFilters  the file filters for this filter, copied, null ignored
057         * @since 1.1
058         */
059        public OrFileFilter(final List<IOFileFilter> fileFilters) {
060            if (fileFilters == null) {
061                this.fileFilters = new ArrayList<IOFileFilter>();
062            } else {
063                this.fileFilters = new ArrayList<IOFileFilter>(fileFilters);
064            }
065        }
066    
067        /**
068         * Constructs a new file filter that ORs the result of two other filters.
069         * 
070         * @param filter1  the first filter, must not be null
071         * @param filter2  the second filter, must not be null
072         * @throws IllegalArgumentException if either filter is null
073         */
074        public OrFileFilter(IOFileFilter filter1, IOFileFilter filter2) {
075            if (filter1 == null || filter2 == null) {
076                throw new IllegalArgumentException("The filters must not be null");
077            }
078            this.fileFilters = new ArrayList<IOFileFilter>(2);
079            addFileFilter(filter1);
080            addFileFilter(filter2);
081        }
082    
083        /**
084         * {@inheritDoc}
085         */
086        public void addFileFilter(final IOFileFilter ioFileFilter) {
087            this.fileFilters.add(ioFileFilter);
088        }
089    
090        /**
091         * {@inheritDoc}
092         */
093        public List<IOFileFilter> getFileFilters() {
094            return Collections.unmodifiableList(this.fileFilters);
095        }
096    
097        /**
098         * {@inheritDoc}
099         */
100        public boolean removeFileFilter(IOFileFilter ioFileFilter) {
101            return this.fileFilters.remove(ioFileFilter);
102        }
103    
104        /**
105         * {@inheritDoc}
106         */
107        public void setFileFilters(final List<IOFileFilter> fileFilters) {
108            this.fileFilters.clear();
109            this.fileFilters.addAll(fileFilters);
110        }
111    
112        /**
113         * {@inheritDoc}
114         */
115        @Override
116        public boolean accept(final File file) {
117            for (IOFileFilter fileFilter : fileFilters) {
118                if (fileFilter.accept(file)) {
119                    return true;
120                }
121            }
122            return false;
123        }
124    
125        /**
126         * {@inheritDoc}
127         */
128        @Override
129        public boolean accept(final File file, final String name) {
130            for (IOFileFilter fileFilter : fileFilters) {
131                if (fileFilter.accept(file, name)) {
132                    return true;
133                }
134            }
135            return false;
136        }
137    
138        /**
139         * Provide a String representaion of this file filter.
140         *
141         * @return a String representaion
142         */
143        @Override
144        public String toString() {
145            StringBuilder buffer = new StringBuilder();
146            buffer.append(super.toString());
147            buffer.append("(");
148            if (fileFilters != null) {
149                for (int i = 0; i < fileFilters.size(); i++) {
150                    if (i > 0) {
151                        buffer.append(",");
152                    }
153                    Object filter = fileFilters.get(i);
154                    buffer.append(filter == null ? "null" : filter.toString());
155                }
156            }
157            buffer.append(")");
158            return buffer.toString();
159        }
160    
161    }