d272d06d9404dd5e6946f8cf140835ec3fbc89a2
[netconf.git] / restconf / restconf-common / src / main / java / org / opendaylight / restconf / common / util / MultivaluedHashMap.java
1 /*
2  * Copyright (c) 2017 Inocybe Technologies and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.restconf.common.util;
9
10 import java.util.Arrays;
11 import java.util.Collection;
12 import java.util.HashMap;
13 import java.util.LinkedList;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Objects;
17 import java.util.Set;
18 import javax.ws.rs.core.MultivaluedMap;
19
20 /**
21  * A hash table based implementation of {@link MultivaluedMap} interface.
22  *
23  * @author Thomas Pantelis
24  */
25 public class MultivaluedHashMap<K, V> implements MultivaluedMap<K, V> {
26     private final Map<K, List<V>> store = new HashMap<>();
27
28     @Override
29     public final void putSingle(K key, V value) {
30         List<V> values = getValues(key);
31
32         values.clear();
33         if (value != null) {
34             values.add(value);
35         }
36     }
37
38     @Override
39     public void add(K key, V value) {
40         List<V> values = getValues(key);
41
42         if (value != null) {
43             values.add(value);
44         }
45     }
46
47     @Override
48     @SafeVarargs
49     public final void addAll(K key, V... newValues) {
50         addAll(key, Arrays.asList(newValues));
51     }
52
53     @Override
54     public void addAll(K key, List<V> valueList) {
55         Objects.requireNonNull(valueList, "Supplied list of values must not be null.");
56
57         if (valueList.isEmpty()) {
58             return;
59         }
60
61         List<V> values = getValues(key);
62         for (V value : valueList) {
63             if (value != null) {
64                 values.add(value);
65             }
66         }
67     }
68
69     @Override
70     public void addFirst(K key, V value) {
71         List<V> values = getValues(key);
72
73         if (value != null) {
74             values.add(0, value);
75         }
76     }
77
78     @Override
79     public V getFirst(K key) {
80         List<V> values = store.get(key);
81         return values == null || values.isEmpty() ? null : values.get(0);
82     }
83
84     @Override
85     public boolean equalsIgnoreValueOrder(MultivaluedMap<K, V> omap) {
86         if (this == omap) {
87             return true;
88         }
89         if (!keySet().equals(omap.keySet())) {
90             return false;
91         }
92         for (Entry<K, List<V>> e : entrySet()) {
93             List<V> olist = omap.get(e.getKey());
94             if (e.getValue().size() != olist.size()) {
95                 return false;
96             }
97             for (V v : e.getValue()) {
98                 if (!olist.contains(v)) {
99                     return false;
100                 }
101             }
102         }
103         return true;
104     }
105
106     @Override
107     public Collection<List<V>> values() {
108         return store.values();
109     }
110
111     @Override
112     public int size() {
113         return store.size();
114     }
115
116     @Override
117     public List<V> remove(Object key) {
118         return store.remove(key);
119     }
120
121     @Override
122     public void putAll(Map<? extends K, ? extends List<V>> map) {
123         store.putAll(map);
124     }
125
126     @Override
127     public List<V> put(K key, List<V> value) {
128         return store.put(key, value);
129     }
130
131     @Override
132     public Set<K> keySet() {
133         return store.keySet();
134     }
135
136     @Override
137     public boolean isEmpty() {
138         return store.isEmpty();
139     }
140
141     @Override
142     public List<V> get(Object key) {
143         return store.get(key);
144     }
145
146     @Override
147     public Set<Entry<K, List<V>>> entrySet() {
148         return store.entrySet();
149     }
150
151     @Override
152     public boolean containsValue(Object value) {
153         return store.containsValue(value);
154     }
155
156     @Override
157     public boolean containsKey(Object key) {
158         return store.containsKey(key);
159     }
160
161     @Override
162     public void clear() {
163         store.clear();
164     }
165
166     private List<V> getValues(K key) {
167         return store.computeIfAbsent(key, k -> new LinkedList<>());
168     }
169 }