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.Arrays;
024import java.util.Collection;
025import java.util.Collections;
026import java.util.LinkedHashSet;
027import java.util.List;
028import java.util.Map;
029import java.util.Set;
030
031/**
032 * Static helper class for use dealing with Collections.
033 *
034 * @since 0.9
035 */
036public final class CollectionUtils {
037
038    private CollectionUtils() {
039    }
040
041    @SafeVarargs
042    public static <E> Set<E> asSet(E... elements) {
043        if (elements == null || elements.length == 0) {
044            return Collections.emptySet();
045        }
046
047        if (elements.length == 1) {
048            return Collections.singleton(elements[0]);
049        }
050
051        LinkedHashSet<E> set = new LinkedHashSet<E>(elements.length * 4 / 3 + 1);
052        Collections.addAll(set, elements);
053        return set;
054    }
055
056    /**
057     * Returns {@code true} if the specified {@code Collection} is {@code null} or {@link Collection#isEmpty empty},
058     * {@code false} otherwise.
059     *
060     * @param c the collection to check
061     * @return {@code true} if the specified {@code Collection} is {@code null} or {@link Collection#isEmpty empty},
062     * {@code false} otherwise.
063     * @since 1.0
064     */
065    public static boolean isEmpty(Collection c) {
066        return c == null || c.isEmpty();
067    }
068
069    /**
070     * Returns {@code true} if the specified {@code Map} is {@code null} or {@link Map#isEmpty empty},
071     * {@code false} otherwise.
072     *
073     * @param m the {@code Map} to check
074     * @return {@code true} if the specified {@code Map} is {@code null} or {@link Map#isEmpty empty},
075     * {@code false} otherwise.
076     * @since 1.0
077     */
078    public static boolean isEmpty(Map m) {
079        return m == null || m.isEmpty();
080    }
081
082    /**
083     * Returns the size of the specified collection or {@code 0} if the collection is {@code null}.
084     *
085     * @param c the collection to check
086     * @return the size of the specified collection or {@code 0} if the collection is {@code null}.
087     * @since 1.2
088     */
089    public static int size(Collection c) {
090        return c != null ? c.size() : 0;
091    }
092
093    /**
094     * Returns the size of the specified map or {@code 0} if the map is {@code null}.
095     *
096     * @param m the map to check
097     * @return the size of the specified map or {@code 0} if the map is {@code null}.
098     * @since 1.2
099     */
100    public static int size(Map m) {
101        return m != null ? m.size() : 0;
102    }
103
104
105    /**
106     * Returns {@code true} if the specified {@code PrincipalCollection} is {@code null} or
107     * {@link PrincipalCollection#isEmpty empty}, {@code false} otherwise.
108     *
109     * @param principals the principals to check.
110     * @return {@code true} if the specified {@code PrincipalCollection} is {@code null} or
111     * {@link PrincipalCollection#isEmpty empty}, {@code false} otherwise.
112     * @since 1.0
113     * @deprecated Use PrincipalCollection.isEmpty() directly.
114     */
115    @Deprecated
116    public static boolean isEmpty(PrincipalCollection principals) {
117        return principals == null || principals.isEmpty();
118    }
119
120    @SafeVarargs
121    public static <E> List<E> asList(E... elements) {
122        if (elements == null || elements.length == 0) {
123            return Collections.emptyList();
124        }
125
126        // Integer overflow does not occur when a large array is passed in because the list array already exists
127        return Arrays.asList(elements);
128    }
129
130    /*public static <E> Deque<E> asDeque(E... elements) {
131        if (elements == null || elements.length == 0) {
132            return new ArrayDeque<E>();
133        }
134        // Avoid integer overflow when a large array is passed in
135        int capacity = computeListCapacity(elements.length);
136        ArrayDeque<E> deque = new ArrayDeque<E>(capacity);
137        Collections.addAll(deque, elements);
138        return deque;
139    }*/
140    @SuppressWarnings("checkstyle:MagicNumber")
141    static int computeListCapacity(int arraySize) {
142        return (int) Math.min(5L + arraySize + (arraySize / 10), Integer.MAX_VALUE);
143    }
144}