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
039        if (elements.length == 1) {
040            return Collections.singleton(elements[0]);
041        }
042
043        LinkedHashSet<E> set = new LinkedHashSet<E>(elements.length * 4 / 3 + 1);
044        Collections.addAll(set, elements);
045        return set;
046    }
047
048    /**
049     * Returns {@code true} if the specified {@code Collection} is {@code null} or {@link Collection#isEmpty empty},
050     * {@code false} otherwise.
051     *
052     * @param c the collection to check
053     * @return {@code true} if the specified {@code Collection} is {@code null} or {@link Collection#isEmpty empty},
054     *         {@code false} otherwise.
055     * @since 1.0
056     */
057    public static boolean isEmpty(Collection c) {
058        return c == null || c.isEmpty();
059    }
060
061    /**
062     * Returns {@code true} if the specified {@code Map} is {@code null} or {@link Map#isEmpty empty},
063     * {@code false} otherwise.
064     *
065     * @param m the {@code Map} to check
066     * @return {@code true} if the specified {@code Map} is {@code null} or {@link Map#isEmpty empty},
067     *         {@code false} otherwise.
068     * @since 1.0
069     */
070    public static boolean isEmpty(Map m) {
071        return m == null || m.isEmpty();
072    }
073
074    /**
075     * Returns the size of the specified collection or {@code 0} if the collection is {@code null}.
076     *
077     * @param c the collection to check
078     * @return the size of the specified collection or {@code 0} if the collection is {@code null}.
079     * @since 1.2
080     */
081    public static int size(Collection c) {
082        return c != null ? c.size() : 0;
083    }
084
085    /**
086     * Returns the size of the specified map or {@code 0} if the map is {@code null}.
087     *
088     * @param m the map to check
089     * @return the size of the specified map or {@code 0} if the map is {@code null}.
090     * @since 1.2
091     */
092    public static int size(Map m) {
093        return m != null ? m.size() : 0;
094    }
095
096
097    /**
098     * Returns {@code true} if the specified {@code PrincipalCollection} is {@code null} or
099     * {@link PrincipalCollection#isEmpty empty}, {@code false} otherwise.
100     *
101     * @param principals the principals to check.
102     * @return {@code true} if the specified {@code PrincipalCollection} is {@code null} or
103     *         {@link PrincipalCollection#isEmpty empty}, {@code false} otherwise.
104     * @since 1.0
105     */
106    public static boolean isEmpty(PrincipalCollection principals) {
107        return principals == null || principals.isEmpty();
108    }
109
110    public static <E> List<E> asList(E... elements) {
111        if (elements == null || elements.length == 0) {
112            return Collections.emptyList();
113        }
114
115        // Integer overflow does not occur when a large array is passed in because the list array already exists
116        return Arrays.asList(elements);
117    }
118
119    /*public static <E> Deque<E> asDeque(E... elements) {
120        if (elements == null || elements.length == 0) {
121            return new ArrayDeque<E>();
122        }
123        // Avoid integer overflow when a large array is passed in
124        int capacity = computeListCapacity(elements.length);
125        ArrayDeque<E> deque = new ArrayDeque<E>(capacity);
126        Collections.addAll(deque, elements);
127        return deque;
128    }*/
129
130    static int computeListCapacity(int arraySize) {
131        return (int) Math.min(5L + arraySize + (arraySize / 10), Integer.MAX_VALUE);
132    }
133}