001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.oauth2.sdk.util;
019
020
021import java.util.*;
022
023
024/**
025 * Multi-valued map utilities.
026 */
027public final class MultivaluedMapUtils {
028        
029        
030        /**
031         * Converts the specified multi-valued map to a single-valued map by
032         * taking the first value in the list.
033         *
034         * @param map The multi-valued map, {@code null} if not specified.
035         *
036         * @return The single-valued map, {@code null} if no map was specified.
037         */
038        public static <K,V> Map<K,V> toSingleValuedMap(final Map<K,List<V>> map) {
039                
040                if (map == null)
041                        return null;
042                
043                Map<K,V> out = new HashMap<>();
044                
045                for (Map.Entry<K,List<V>> en: map.entrySet()) {
046                        
047                        if (en.getValue() == null || en.getValue().isEmpty()) {
048                                out.put(en.getKey(), null);
049                        } else {
050                                out.put(en.getKey(), en.getValue().get(0));
051                        }
052                }
053                
054                return out;
055        }
056        
057        
058        /**
059         * Gets the first value for the specified key.
060         *
061         * @param map The multi-valued map. Must not be {@code null}.
062         * @param key The key. Must not be {@code null}.
063         *
064         * @return The first value, {@code null} if not set.
065         */
066        public static <K,V> V getFirstValue(final Map<K,List<V>> map, final K key) {
067                
068                List<V> valueList = map.get(key);
069                
070                if (valueList == null || valueList.isEmpty()) {
071                        return null;
072                }
073                
074                return valueList.get(0);
075        }
076        
077        
078        /**
079         * Removes the entry for the specified key and returns its first value.
080         *
081         * @param map The multi-valued map. Must not be {@code null}.
082         * @param key The key. Must not be {@code null}.
083         *
084         * @return The first value, {@code null} if not set.
085         */
086        public static <K,V> V removeAndReturnFirstValue(final Map<K,List<V>> map, final String key) {
087                
088                List<V> valueList = map.remove(key);
089                
090                if (valueList == null || valueList.isEmpty()) {
091                        return null;
092                }
093                
094                return valueList.get(0);
095        }
096        
097        
098        /**
099         * Returns the keys with more than one value.
100         *
101         * @param map      The multi-valued map, {@code null} if not specified.
102         * @param excepted The excepted keys, {@code null} or empty if none.
103         *
104         * @return The keys with more than one value, empty set if none.
105         */
106        public static <K,V> Set<K> getKeysWithMoreThanOneValue(final Map<K,List<V>> map, final Set<K> excepted) {
107                
108                if (map == null || map.isEmpty()) {
109                        return Collections.emptySet();
110                }
111                
112                Set<K> found = new HashSet<>();
113                for (Map.Entry<K,List<V>> en: map.entrySet()) {
114                        if (CollectionUtils.contains(excepted, en.getKey())) {
115                                continue;
116                        }
117                        
118                        if (en.getValue() != null && en.getValue().size() > 1) {
119                                found.add(en.getKey());
120                        }
121                }
122                return found;
123        }
124        
125        
126        /**
127         * Prevents public instantiation.
128         */
129        private MultivaluedMapUtils() {}
130}