1600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/*
2600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Conditions Of Use
3600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *
4600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * This software was developed by employees of the National Institute of
5600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Standards and Technology (NIST), an agency of the Federal Government.
6600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pursuant to title 15 Untied States Code Section 105, works of NIST
7600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * employees are not subject to copyright protection in the United States
8600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * and are considered to be in the public domain.  As a result, a formal
9600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * license is not needed to use the software.
10600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *
11600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * This software is provided by NIST as a service and is expressly
12600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
13600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
14600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
15600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * AND DATA ACCURACY.  NIST does not warrant or make any representations
16600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * regarding the use of the software or the results thereof, including but
17600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * not limited to the correctness, accuracy, reliability or usefulness of
18600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * the software.
19600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *
20600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Permission to use this software is contingent upon your acceptance
21600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * of the terms of this agreement.
22600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *
23600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */
24600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpackage gov.nist.core;
25600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
26600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.ArrayList;
27600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.Collection;
28600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.HashMap;
29600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.Iterator;
30600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.List;
31600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.Map;
32600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.Set;
33600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
34600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpublic class MultiValueMapImpl<V> implements MultiValueMap<String, V>, Cloneable {
35600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    private HashMap<String, ArrayList<V>> map = new HashMap<String, ArrayList<V>>();
36600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
37600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    private static final long serialVersionUID = 4275505380960964605L;
38600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
39600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public MultiValueMapImpl() {
40600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        super();
41600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
42600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
43600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
44600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public List<V> put(String key, V value) {
45600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        ArrayList<V> keyList = map.get(key);
46600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        if (keyList == null) {
47600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            keyList = new ArrayList<V>(10);
48600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            map.put(key, keyList);
49600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        }
50600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
51600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        keyList.add(value);
52600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return keyList;
53600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
54600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
55600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public boolean containsValue(Object value) {
56600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Set pairs = map.entrySet();
57600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
58600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        if (pairs == null)
59600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            return false;
60600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
61600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Iterator pairsIterator = pairs.iterator();
62600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        while (pairsIterator.hasNext()) {
63600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Map.Entry keyValuePair = (Map.Entry) (pairsIterator.next());
64600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            ArrayList list = (ArrayList) (keyValuePair.getValue());
65600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            if (list.contains(value))
66600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                return true;
67600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        }
68600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return false;
69600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
70600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
71600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public void clear() {
72600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Set pairs = map.entrySet();
73600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Iterator pairsIterator = pairs.iterator();
74600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        while (pairsIterator.hasNext()) {
75600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Map.Entry keyValuePair = (Map.Entry) (pairsIterator.next());
76600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            ArrayList list = (ArrayList) (keyValuePair.getValue());
77600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            list.clear();
78600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        }
79600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        map.clear();
80600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
81600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
82600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public Collection values() {
83600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        ArrayList returnList = new ArrayList(map.size());
84600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
85600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Set pairs = map.entrySet();
86600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Iterator pairsIterator = pairs.iterator();
87600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        while (pairsIterator.hasNext()) {
88600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Map.Entry keyValuePair = (Map.Entry) (pairsIterator.next());
89600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            ArrayList list = (ArrayList) (keyValuePair.getValue());
90600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
91600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Object[] values = list.toArray();
92600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            for (int ii = 0; ii < values.length; ii++) {
93600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                returnList.add(values[ii]);
94600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            }
95600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        }
96600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return returnList;
97600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
98600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
99600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public Object clone() {
100600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        MultiValueMapImpl obj = new MultiValueMapImpl<V>();
101600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        obj.map = (HashMap<Object, ArrayList<V>>) this.map.clone();
102600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return obj;
103600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
104600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
105600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public int size() {
106600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return this.map.size();
107600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
108600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
109600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public boolean containsKey(Object key) {
110600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return map.containsKey(key);
111600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
112600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
113600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public Set entrySet() {
114600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return map.entrySet();
115600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
116600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
117600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public boolean isEmpty() {
118600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return map.isEmpty();
119600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
120600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
121600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public Set<String> keySet() {
122600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return this.map.keySet();
123600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
124600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
125600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public Object remove(String key, V item) {
126600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        ArrayList<V> list = this.map.get(key);
127600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        if (list == null) {
128600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            return null;
129600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        } else {
130600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            return list.remove(item);
131600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        }
132600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
133600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
134600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public List<V> get(Object key) {
135600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return map.get(key);
136600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
137600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
138600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public List<V> put(String key, List<V> value) {
139600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return this.map.put(key,(ArrayList<V>) value);
140600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
141600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
142600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public List<V> remove(Object key) {
143600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return map.remove(key);
144600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
145600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
146600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public void putAll(Map< ? extends String, ? extends List<V>> mapToPut) {
147600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        for (String k : mapToPut.keySet()) {
148600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            ArrayList<V> al = new ArrayList<V>();
149600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            al.addAll(mapToPut.get(k));
150600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            this.map.put(k, al);
151600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        }
152600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
153600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
154600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang}
155