001    /* JAPI - (Yet another (hopefully) useful) Java API
002     *
003     * Copyright (C) 2004-2006 Christian Hujer
004     *
005     * This program is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU General Public License as
007     * published by the Free Software Foundation; either version 2 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful, but
011     * WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     * General Public License for more details.
014     *
015     * You should have received a copy of the GNU General Public License
016     * along with this program; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018     * 02111-1307, USA.
019     */
020    
021    package net.sf.japi.util.filter;
022    
023    import java.util.Collection;
024    
025    /** This interface servers as a common interface for filters.
026     * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a>
027     */
028    public interface Filter<T> {
029    
030        /** Tests whether or not the specified object should be included.
031         * @param o object to be tested
032         * @return <code>true</code> if and only if <code>o</code> should be included
033         */
034        boolean accept(T o);
035    
036        /** Factory for useful filters.
037         * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a>
038         */
039        @SuppressWarnings({"StaticMethodNamingConvention", "UtilityClass", "InnerClassOfInterface"})
040        final class Factory {
041    
042            /** Utility class, must not be instantiated. */
043            private Factory() {
044            }
045    
046            /** Create a Filter that is the opposite of another filter.
047             * @param filter Filter to negate
048             * @return negated version of <var>filter</var>
049             */
050            public static <T> Filter<T> not(final Filter<T> filter) {
051                return new NotFilter<T>(filter);
052            }
053    
054            /** Create a Filter that is the AND combination of several other filters.
055             * @param filters Filters to AND
056             * @return AND version of <var>filters</var>
057             */
058            public static <T> Filter<T> and(final Iterable<Filter<T>> filters) {
059                return new AndFilterForIterable<T>(filters);
060            }
061    
062            /** Create a Filter that is the AND combination of several other filters.
063             * @param filters Filters to AND
064             * @return AND version of <var>filters</var>
065             */
066            public static <T> Filter<T> and(final Filter<T>... filters) {
067                return new AndFilterForArray<T>(filters);
068            }
069    
070            /** Create a Filter that is the OR combination of several other filters.
071             * @param filters Filters to OR
072             * @return OR version of <var>filters</var>
073             */
074            public static <T> Filter<T> or(final Iterable<Filter<T>> filters) {
075                return new OrFilterForIterable<T>(filters);
076            }
077    
078            /** Create a Filter that is the OR combination of several other filters.
079             * @param filters Filters to OR
080             * @return OR version of <var>filters</var>
081             */
082            public static <T> Filter<T> or(final Filter<T>... filters) {
083                return new OrFilterForArray<T>(filters);
084            }
085    
086            /** Create a Filter that returns whether an element is contained in a collection.
087             * Note: The collection is not cloned.
088             * Changes to the underlying collection will affect the filter behaviour.
089             * If you need a stable filter, you have to clone the collection before invoking this method
090             * @param collection Collection to use as a base
091             * @return Filter that returns whether an element is contained in a collection
092             */
093            public static <T> Filter<T> contained(final Collection<T> collection) {
094                return new CollectionFilter<T>(collection);
095            }
096    
097        } // class FilterFactory
098    
099    } // interface Filter