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.functor.core.collection;
018
019import java.io.Serializable;
020import java.lang.reflect.Array;
021import java.util.Collection;
022
023import org.apache.commons.functor.UnaryFunction;
024import org.apache.commons.lang3.Validate;
025
026/**
027 * Returns the size of the specified Collection, or the length
028 * of the specified array or String.
029 *
030 * @param <A> the function argument type.
031 * @version $Revision: 1345136 $ $Date: 2012-06-01 08:47:06 -0400 (Fri, 01 Jun 2012) $
032 */
033public final class Size<A> implements UnaryFunction<A, Integer>, Serializable {
034
035    /**
036     * serialVersionUID declaration.
037     */
038    private static final long serialVersionUID = -12374650738412129L;
039    /**
040     * A static {@code Size} instance reference.
041     */
042    private static final Size<Object> INSTANCE = new Size<Object>();
043
044    // constructor
045    // ------------------------------------------------------------------------
046    /**
047     * Create a new Size.
048     */
049    public Size() { }
050
051    /**
052     * {@inheritDoc}
053     */
054    public Integer evaluate(Object obj) {
055        Validate.notNull(obj, "Argument must not be null");
056        if (obj instanceof Collection<?>) {
057            return evaluate((Collection<?>) obj);
058        }
059        if (obj instanceof String) {
060            return evaluate((String) obj);
061        }
062        if (obj.getClass().isArray()) {
063            return evaluateArray(obj);
064        }
065        throw new IllegalArgumentException("Expected Collection, String or Array, found " + obj);
066    }
067
068    /**
069     * {@inheritDoc}
070     */
071    @Override
072    public boolean equals(Object that) {
073        return that instanceof Size<?>;
074    }
075
076    /**
077     * {@inheritDoc}
078     */
079    @Override
080    public int hashCode() {
081        return "Size".hashCode();
082    }
083
084    /**
085     * {@inheritDoc}
086     */
087    @Override
088    public String toString() {
089        return "Size()";
090    }
091
092    /**
093     * Get a Size instance.
094     * @return Size
095     */
096    public static Size<Object> instance() {
097        return INSTANCE;
098    }
099
100    /**
101     * Evaluate a Collection.
102     * @param col to evaluate
103     * @return Integer
104     */
105    private Integer evaluate(Collection<?> col) {
106        return Integer.valueOf(col.size());
107    }
108
109    /**
110     * Evaluate a String.
111     * @param str to evaluate
112     * @return Integer
113     */
114    private Integer evaluate(String str) {
115        return Integer.valueOf(str.length());
116    }
117
118    /**
119     * Evaluate an array.
120     * @param array to evaluate
121     * @return Integer
122     */
123    private Integer evaluateArray(Object array) {
124        return Integer.valueOf(Array.getLength(array));
125    }
126
127}