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.functor.core.collection;
018    
019    import java.io.Serializable;
020    import java.lang.reflect.Array;
021    import java.util.Collection;
022    
023    import org.apache.commons.functor.BinaryPredicate;
024    import org.apache.commons.functor.UnaryPredicate;
025    import org.apache.commons.functor.adapter.RightBoundPredicate;
026    
027    /**
028     * A {@link BinaryPredicate} that checks to see if the
029     * specified object is an element of the specified
030     * Collection.
031     *
032     * @since 1.0
033     * @version $Revision: 1170771 $ $Date: 2011-09-14 21:07:22 +0200 (Wed, 14 Sep 2011) $
034     * @author  Jason Horman (jason@jhorman.org)
035     * @author  Rodney Waldhoff
036     */
037    public final class IsElementOf<L, R> implements BinaryPredicate<L, R>, Serializable {
038        // static members
039        //---------------------------------------------------------------
040    
041        /**
042         * serialVersionUID declaration.
043         */
044        private static final long serialVersionUID = -7639051806015321070L;
045        private static final IsElementOf<Object, Object> INSTANCE = new IsElementOf<Object, Object>();
046    
047        // constructors
048        //---------------------------------------------------------------
049        /**
050         * Create a new IsElementOf.
051         */
052        public IsElementOf() {
053        }
054    
055        // instance methods
056        //---------------------------------------------------------------
057        /**
058         * {@inheritDoc}
059         */
060        public boolean test(L obj, R col) {
061            if (col instanceof Collection<?>) {
062                return testCollection(obj, (Collection<?>) col);
063            }
064            if (null != col && col.getClass().isArray()) {
065                return testArray(obj, col);
066            }
067            if (null == col) {
068                throw new IllegalArgumentException("Right side argument must not be null.");
069            }
070            throw new IllegalArgumentException("Expected Collection or Array, found " + col.getClass());
071        }
072    
073        /**
074         * {@inheritDoc}
075         */
076        public boolean equals(Object obj) {
077            return (obj instanceof IsElementOf<?, ?>);
078        }
079    
080        /**
081         * {@inheritDoc}
082         */
083        public int hashCode() {
084            return "IsElementOf".hashCode();
085        }
086    
087        /**
088         * {@inheritDoc}
089         */
090        public String toString() {
091            return "IsElementOf";
092        }
093    
094        /**
095         * Test a collection.
096         * @param obj to find
097         * @param col to search
098         * @return boolean
099         */
100        private boolean testCollection(Object obj, Collection<?> col) {
101            return col.contains(obj);
102        }
103    
104        /**
105         * Test an array.
106         * @param obj to find
107         * @param array to search
108         * @return boolean
109         */
110        private boolean testArray(Object obj, Object array) {
111            for (int i = 0, m = Array.getLength(array); i < m; i++) {
112                Object value = Array.get(array, i);
113                if (obj == value) {
114                    return true;
115                }
116                if (obj != null && obj.equals(value)) {
117                    return true;
118                }
119            }
120            return false;
121        }
122    
123        // static methods
124        //---------------------------------------------------------------
125        /**
126         * Get an IsElementOf instance.
127         * @return IsElementOf
128         */
129        public static IsElementOf<Object, Object> instance() {
130            return INSTANCE;
131        }
132    
133        /**
134         * Get an IsElementOf(collection|array) UnaryPredicate.
135         * @param obj collection/array to search
136         * @return UnaryPredicate
137         */
138        public static <A> UnaryPredicate<A> instance(Object obj) {
139            if (null == obj) {
140                throw new NullPointerException("Argument must not be null");
141            } else if (obj instanceof Collection<?>) {
142                return new RightBoundPredicate<A>(new IsElementOf<A, Object>(), obj);
143            } else if (obj.getClass().isArray()) {
144                return new RightBoundPredicate<A>(new IsElementOf<A, Object>(), obj);
145            } else {
146                throw new IllegalArgumentException("Expected Collection or Array, found " + obj.getClass());
147            }
148        }
149    
150    }