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