Add local MultivaluedHashMap implementation
[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.Collection;
11 import java.util.HashMap;
12 import java.util.LinkedList;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Objects;
16 import java.util.Set;
17 import javax.ws.rs.core.MultivaluedMap;
18
19 /**
20  * A hash table based implementation of {@link MultivaluedMap} interface.
21  *
22  * @author Thomas Pantelis
23  */
24 public class MultivaluedHashMap<K, V> implements MultivaluedMap<K, V> {
25     private final Map<K, List<V>> store = new HashMap<>();
26
27     @Override
28     public final void putSingle(K key, V value) {
29         List<V> values = getValues(key);
30
31         values.clear();
32         if (value != null) {
33             values.add(value);
34         }
35     }
36
37     @Override
38     public void add(K key, V value) {
39         List<V> values = getValues(key);
40
41         if (value != null) {
42             values.add(value);
43         }
44     }
45
46     @Override
47     public void addAll(K key, V... newValues) {
48         Objects.requireNonNull(newValues, "Supplied array of values must not be null.");
49
50         if (newValues.length == 0) {
51             return;
52         }
53
54         List<V> values = getValues(key);
55         for (V value : newValues) {
56             if (value != null) {
57                 values.add(value);
58             }
59         }
60     }
61
62     @Override
63     public void addAll(K key, List<V> valueList) {
64         Objects.requireNonNull(valueList, "Supplied list of values must not be null.");
65
66         if (valueList.isEmpty()) {
67             return;
68         }
69
70         List<V> values = getValues(key);
71         for (V value : valueList) {
72             if (value != null) {
73                 values.add(value);
74             }
75         }
76     }
77
78     @Override
79     public void addFirst(K key, V value) {
80         List<V> values = getValues(key);
81
82         if (value != null) {
83             values.add(0, value);
84         }
85     }
86
87     @Override
88     public V getFirst(K key) {
89         List<V> values = store.get(key);
90         if (values != null && values.size() > 0) {
91             return values.get(0);
92         } else {
93             return null;
94         }
95     }
96
97     @Override
98     public boolean equalsIgnoreValueOrder(MultivaluedMap<K, V> omap) {
99         if (this == omap) {
100             return true;
101         }
102         if (!keySet().equals(omap.keySet())) {
103             return false;
104         }
105         for (Entry<K, List<V>> e : entrySet()) {
106             List<V> olist = omap.get(e.getKey());
107             if (e.getValue().size() != olist.size()) {
108                 return false;
109             }
110             for (V v : e.getValue()) {
111                 if (!olist.contains(v)) {
112                     return false;
113                 }
114             }
115         }
116         return true;
117     }
118
119     @Override
120     public Collection<List<V>> values() {
121         return store.values();
122     }
123
124     @Override
125     public int size() {
126         return store.size();
127     }
128
129     @Override
130     public List<V> remove(Object key) {
131         return store.remove(key);
132     }
133
134     @Override
135     public void putAll(Map<? extends K, ? extends List<V>> map) {
136         store.putAll(map);
137     }
138
139     @Override
140     public List<V> put(K key, List<V> value) {
141         return store.put(key, value);
142     }
143
144     @Override
145     public Set<K> keySet() {
146         return store.keySet();
147     }
148
149     @Override
150     public boolean isEmpty() {
151         return store.isEmpty();
152     }
153
154     @Override
155     public List<V> get(Object key) {
156         return store.get(key);
157     }
158
159     @Override
160     public Set<Entry<K, List<V>>> entrySet() {
161         return store.entrySet();
162     }
163
164     @Override
165     public boolean containsValue(Object value) {
166         return store.containsValue(value);
167     }
168
169     @Override
170     public boolean containsKey(Object key) {
171         return store.containsKey(key);
172     }
173
174     @Override
175     public void clear() {
176         store.clear();
177     }
178
179     private List<V> getValues(K key) {
180         List<V> list = store.get(key);
181         if (list == null) {
182             list = new LinkedList<>();
183             store.put(key, list);
184         }
185
186         return list;
187     }
188 }