001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.shiro.util;
020
021import org.apache.shiro.subject.PrincipalCollection;
022
023import java.util.*;
024
025/**
026 * Static helper class for use dealing with Collections.
027 *
028 * @since 0.9
029 */
030public class CollectionUtils {
031
032    //TODO - complete JavaDoc
033
034    public static <E> Set<E> asSet(E... elements) {
035        if (elements == null || elements.length == 0) {
036            return Collections.emptySet();
037        }
038        LinkedHashSet<E> set = new LinkedHashSet<E>(elements.length * 4 / 3 + 1);
039        Collections.addAll(set, elements);
040        return set;
041    }
042
043    /**
044     * Returns {@code true} if the specified {@code Collection} is {@code null} or {@link Collection#isEmpty empty},
045     * {@code false} otherwise.
046     *
047     * @param c the collection to check
048     * @return {@code true} if the specified {@code Collection} is {@code null} or {@link Collection#isEmpty empty},
049     *         {@code false} otherwise.
050     * @since 1.0
051     */
052    public static boolean isEmpty(Collection c) {
053        return c == null || c.isEmpty();
054    }
055
056    /**
057     * Returns {@code true} if the specified {@code Map} is {@code null} or {@link Map#isEmpty empty},
058     * {@code false} otherwise.
059     *
060     * @param m the {@code Map} to check
061     * @return {@code true} if the specified {@code Map} is {@code null} or {@link Map#isEmpty empty},
062     *         {@code false} otherwise.
063     * @since 1.0
064     */
065    public static boolean isEmpty(Map m) {
066        return m == null || m.isEmpty();
067    }
068
069    /**
070     * Returns the size of the specified collection or {@code 0} if the collection is {@code null}.
071     *
072     * @param c the collection to check
073     * @return the size of the specified collection or {@code 0} if the collection is {@code null}.
074     * @since 1.2
075     */
076    public static int size(Collection c) {
077        return c != null ? c.size() : 0;
078    }
079
080    /**
081     * Returns the size of the specified map or {@code 0} if the map is {@code null}.
082     *
083     * @param m the map to check
084     * @return the size of the specified map or {@code 0} if the map is {@code null}.
085     * @since 1.2
086     */
087    public static int size(Map m) {
088        return m != null ? m.size() : 0;
089    }
090
091
092    /**
093     * Returns {@code true} if the specified {@code PrincipalCollection} is {@code null} or
094     * {@link PrincipalCollection#isEmpty empty}, {@code false} otherwise.
095     *
096     * @param principals the principals to check.
097     * @return {@code true} if the specified {@code PrincipalCollection} is {@code null} or
098     *         {@link PrincipalCollection#isEmpty empty}, {@code false} otherwise.
099     * @since 1.0
100     */
101    public static boolean isEmpty(PrincipalCollection principals) {
102        return principals == null || principals.isEmpty();
103    }
104
105    public static <E> List<E> asList(E... elements) {
106        if (elements == null || elements.length == 0) {
107            return Collections.emptyList();
108        }
109        // Avoid integer overflow when a large array is passed in
110        int capacity = computeListCapacity(elements.length);
111        ArrayList<E> list = new ArrayList<E>(capacity);
112        Collections.addAll(list, elements);
113        return list;
114    }
115
116    /*public static <E> Deque<E> asDeque(E... elements) {
117        if (elements == null || elements.length == 0) {
118            return new ArrayDeque<E>();
119        }
120        // Avoid integer overflow when a large array is passed in
121        int capacity = computeListCapacity(elements.length);
122        ArrayDeque<E> deque = new ArrayDeque<E>(capacity);
123        Collections.addAll(deque, elements);
124        return deque;
125    }*/
126
127    static int computeListCapacity(int arraySize) {
128        return (int) Math.min(5L + arraySize + (arraySize / 10), Integer.MAX_VALUE);
129    }
130}