103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.util; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.Serializable; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Arrays; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Collection; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashMap; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.List; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Map; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Set; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.ConcurrentHashMap; 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.ConcurrentMap; 3003928aee4356845252ac6b662d5c72c29903813eJake Slack 3103928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */ 3203928aee4356845252ac6b662d5c72c29903813eJake Slack/** A multi valued Map. 3303928aee4356845252ac6b662d5c72c29903813eJake Slack * This Map specializes HashMap and provides methods 3403928aee4356845252ac6b662d5c72c29903813eJake Slack * that operate on multi valued items. 3503928aee4356845252ac6b662d5c72c29903813eJake Slack * <P> 3603928aee4356845252ac6b662d5c72c29903813eJake Slack * Implemented as a map of LazyList values 3703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param <K> The key type of the map. 3803928aee4356845252ac6b662d5c72c29903813eJake Slack * 3903928aee4356845252ac6b662d5c72c29903813eJake Slack * @see LazyList 4003928aee4356845252ac6b662d5c72c29903813eJake Slack * 4103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 4203928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class MultiMap<K> implements ConcurrentMap<K,Object>, Serializable 4303928aee4356845252ac6b662d5c72c29903813eJake Slack{ 4403928aee4356845252ac6b662d5c72c29903813eJake Slack private static final long serialVersionUID = -6878723138353851005L; 4503928aee4356845252ac6b662d5c72c29903813eJake Slack Map<K,Object> _map; 4603928aee4356845252ac6b662d5c72c29903813eJake Slack ConcurrentMap<K, Object> _cmap; 4703928aee4356845252ac6b662d5c72c29903813eJake Slack 4803928aee4356845252ac6b662d5c72c29903813eJake Slack public MultiMap() 4903928aee4356845252ac6b662d5c72c29903813eJake Slack { 5003928aee4356845252ac6b662d5c72c29903813eJake Slack _map=new HashMap<K, Object>(); 5103928aee4356845252ac6b662d5c72c29903813eJake Slack } 5203928aee4356845252ac6b662d5c72c29903813eJake Slack 5303928aee4356845252ac6b662d5c72c29903813eJake Slack public MultiMap(Map<K,Object> map) 5403928aee4356845252ac6b662d5c72c29903813eJake Slack { 5503928aee4356845252ac6b662d5c72c29903813eJake Slack if (map instanceof ConcurrentMap) 5603928aee4356845252ac6b662d5c72c29903813eJake Slack _map=_cmap=new ConcurrentHashMap<K, Object>(map); 5703928aee4356845252ac6b662d5c72c29903813eJake Slack else 5803928aee4356845252ac6b662d5c72c29903813eJake Slack _map=new HashMap<K, Object>(map); 5903928aee4356845252ac6b662d5c72c29903813eJake Slack } 6003928aee4356845252ac6b662d5c72c29903813eJake Slack 6103928aee4356845252ac6b662d5c72c29903813eJake Slack public MultiMap(MultiMap<K> map) 6203928aee4356845252ac6b662d5c72c29903813eJake Slack { 6303928aee4356845252ac6b662d5c72c29903813eJake Slack if (map._cmap!=null) 6403928aee4356845252ac6b662d5c72c29903813eJake Slack _map=_cmap=new ConcurrentHashMap<K, Object>(map._cmap); 6503928aee4356845252ac6b662d5c72c29903813eJake Slack else 6603928aee4356845252ac6b662d5c72c29903813eJake Slack _map=new HashMap<K,Object>(map._map); 6703928aee4356845252ac6b662d5c72c29903813eJake Slack } 6803928aee4356845252ac6b662d5c72c29903813eJake Slack 6903928aee4356845252ac6b662d5c72c29903813eJake Slack public MultiMap(int capacity) 7003928aee4356845252ac6b662d5c72c29903813eJake Slack { 7103928aee4356845252ac6b662d5c72c29903813eJake Slack _map=new HashMap<K, Object>(capacity); 7203928aee4356845252ac6b662d5c72c29903813eJake Slack } 7303928aee4356845252ac6b662d5c72c29903813eJake Slack 7403928aee4356845252ac6b662d5c72c29903813eJake Slack public MultiMap(boolean concurrent) 7503928aee4356845252ac6b662d5c72c29903813eJake Slack { 7603928aee4356845252ac6b662d5c72c29903813eJake Slack if (concurrent) 7703928aee4356845252ac6b662d5c72c29903813eJake Slack _map=_cmap=new ConcurrentHashMap<K, Object>(); 7803928aee4356845252ac6b662d5c72c29903813eJake Slack else 7903928aee4356845252ac6b662d5c72c29903813eJake Slack _map=new HashMap<K, Object>(); 8003928aee4356845252ac6b662d5c72c29903813eJake Slack } 8103928aee4356845252ac6b662d5c72c29903813eJake Slack 8203928aee4356845252ac6b662d5c72c29903813eJake Slack 8303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 8403928aee4356845252ac6b662d5c72c29903813eJake Slack /** Get multiple values. 8503928aee4356845252ac6b662d5c72c29903813eJake Slack * Single valued entries are converted to singleton lists. 8603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 8703928aee4356845252ac6b662d5c72c29903813eJake Slack * @return Unmodifieable List of values. 8803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 8903928aee4356845252ac6b662d5c72c29903813eJake Slack public List getValues(Object name) 9003928aee4356845252ac6b662d5c72c29903813eJake Slack { 9103928aee4356845252ac6b662d5c72c29903813eJake Slack return LazyList.getList(_map.get(name),true); 9203928aee4356845252ac6b662d5c72c29903813eJake Slack } 9303928aee4356845252ac6b662d5c72c29903813eJake Slack 9403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 9503928aee4356845252ac6b662d5c72c29903813eJake Slack /** Get a value from a multiple value. 9603928aee4356845252ac6b662d5c72c29903813eJake Slack * If the value is not a multivalue, then index 0 retrieves the 9703928aee4356845252ac6b662d5c72c29903813eJake Slack * value or null. 9803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 9903928aee4356845252ac6b662d5c72c29903813eJake Slack * @param i Index of element to get. 10003928aee4356845252ac6b662d5c72c29903813eJake Slack * @return Unmodifieable List of values. 10103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 10203928aee4356845252ac6b662d5c72c29903813eJake Slack public Object getValue(Object name,int i) 10303928aee4356845252ac6b662d5c72c29903813eJake Slack { 10403928aee4356845252ac6b662d5c72c29903813eJake Slack Object l=_map.get(name); 10503928aee4356845252ac6b662d5c72c29903813eJake Slack if (i==0 && LazyList.size(l)==0) 10603928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 10703928aee4356845252ac6b662d5c72c29903813eJake Slack return LazyList.get(l,i); 10803928aee4356845252ac6b662d5c72c29903813eJake Slack } 10903928aee4356845252ac6b662d5c72c29903813eJake Slack 11003928aee4356845252ac6b662d5c72c29903813eJake Slack 11103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 11203928aee4356845252ac6b662d5c72c29903813eJake Slack /** Get value as String. 11303928aee4356845252ac6b662d5c72c29903813eJake Slack * Single valued items are converted to a String with the toString() 11403928aee4356845252ac6b662d5c72c29903813eJake Slack * Object method. Multi valued entries are converted to a comma separated 11503928aee4356845252ac6b662d5c72c29903813eJake Slack * List. No quoting of commas within values is performed. 11603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 11703928aee4356845252ac6b662d5c72c29903813eJake Slack * @return String value. 11803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 11903928aee4356845252ac6b662d5c72c29903813eJake Slack public String getString(Object name) 12003928aee4356845252ac6b662d5c72c29903813eJake Slack { 12103928aee4356845252ac6b662d5c72c29903813eJake Slack Object l=_map.get(name); 12203928aee4356845252ac6b662d5c72c29903813eJake Slack switch(LazyList.size(l)) 12303928aee4356845252ac6b662d5c72c29903813eJake Slack { 12403928aee4356845252ac6b662d5c72c29903813eJake Slack case 0: 12503928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 12603928aee4356845252ac6b662d5c72c29903813eJake Slack case 1: 12703928aee4356845252ac6b662d5c72c29903813eJake Slack Object o=LazyList.get(l,0); 12803928aee4356845252ac6b662d5c72c29903813eJake Slack return o==null?null:o.toString(); 12903928aee4356845252ac6b662d5c72c29903813eJake Slack default: 13003928aee4356845252ac6b662d5c72c29903813eJake Slack { 13103928aee4356845252ac6b662d5c72c29903813eJake Slack StringBuilder values=new StringBuilder(128); 13203928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0; i<LazyList.size(l); i++) 13303928aee4356845252ac6b662d5c72c29903813eJake Slack { 13403928aee4356845252ac6b662d5c72c29903813eJake Slack Object e=LazyList.get(l,i); 13503928aee4356845252ac6b662d5c72c29903813eJake Slack if (e!=null) 13603928aee4356845252ac6b662d5c72c29903813eJake Slack { 13703928aee4356845252ac6b662d5c72c29903813eJake Slack if (values.length()>0) 13803928aee4356845252ac6b662d5c72c29903813eJake Slack values.append(','); 13903928aee4356845252ac6b662d5c72c29903813eJake Slack values.append(e.toString()); 14003928aee4356845252ac6b662d5c72c29903813eJake Slack } 14103928aee4356845252ac6b662d5c72c29903813eJake Slack } 14203928aee4356845252ac6b662d5c72c29903813eJake Slack return values.toString(); 14303928aee4356845252ac6b662d5c72c29903813eJake Slack } 14403928aee4356845252ac6b662d5c72c29903813eJake Slack } 14503928aee4356845252ac6b662d5c72c29903813eJake Slack } 14603928aee4356845252ac6b662d5c72c29903813eJake Slack 14703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 14803928aee4356845252ac6b662d5c72c29903813eJake Slack public Object get(Object name) 14903928aee4356845252ac6b662d5c72c29903813eJake Slack { 15003928aee4356845252ac6b662d5c72c29903813eJake Slack Object l=_map.get(name); 15103928aee4356845252ac6b662d5c72c29903813eJake Slack switch(LazyList.size(l)) 15203928aee4356845252ac6b662d5c72c29903813eJake Slack { 15303928aee4356845252ac6b662d5c72c29903813eJake Slack case 0: 15403928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 15503928aee4356845252ac6b662d5c72c29903813eJake Slack case 1: 15603928aee4356845252ac6b662d5c72c29903813eJake Slack Object o=LazyList.get(l,0); 15703928aee4356845252ac6b662d5c72c29903813eJake Slack return o; 15803928aee4356845252ac6b662d5c72c29903813eJake Slack default: 15903928aee4356845252ac6b662d5c72c29903813eJake Slack return LazyList.getList(l,true); 16003928aee4356845252ac6b662d5c72c29903813eJake Slack } 16103928aee4356845252ac6b662d5c72c29903813eJake Slack } 16203928aee4356845252ac6b662d5c72c29903813eJake Slack 16303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 16403928aee4356845252ac6b662d5c72c29903813eJake Slack /** Put and entry into the map. 16503928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 16603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param value The entry value. 16703928aee4356845252ac6b662d5c72c29903813eJake Slack * @return The previous value or null. 16803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 16903928aee4356845252ac6b662d5c72c29903813eJake Slack public Object put(K name, Object value) 17003928aee4356845252ac6b662d5c72c29903813eJake Slack { 17103928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.put(name,LazyList.add(null,value)); 17203928aee4356845252ac6b662d5c72c29903813eJake Slack } 17303928aee4356845252ac6b662d5c72c29903813eJake Slack 17403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 17503928aee4356845252ac6b662d5c72c29903813eJake Slack /** Put multi valued entry. 17603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 17703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param values The List of multiple values. 17803928aee4356845252ac6b662d5c72c29903813eJake Slack * @return The previous value or null. 17903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 18003928aee4356845252ac6b662d5c72c29903813eJake Slack public Object putValues(K name, List<? extends Object> values) 18103928aee4356845252ac6b662d5c72c29903813eJake Slack { 18203928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.put(name,values); 18303928aee4356845252ac6b662d5c72c29903813eJake Slack } 18403928aee4356845252ac6b662d5c72c29903813eJake Slack 18503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 18603928aee4356845252ac6b662d5c72c29903813eJake Slack /** Put multi valued entry. 18703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 18803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param values The String array of multiple values. 18903928aee4356845252ac6b662d5c72c29903813eJake Slack * @return The previous value or null. 19003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 19103928aee4356845252ac6b662d5c72c29903813eJake Slack public Object putValues(K name, String... values) 19203928aee4356845252ac6b662d5c72c29903813eJake Slack { 19303928aee4356845252ac6b662d5c72c29903813eJake Slack Object list=null; 19403928aee4356845252ac6b662d5c72c29903813eJake Slack for (int i=0;i<values.length;i++) 19503928aee4356845252ac6b662d5c72c29903813eJake Slack list=LazyList.add(list,values[i]); 19603928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.put(name,list); 19703928aee4356845252ac6b662d5c72c29903813eJake Slack } 19803928aee4356845252ac6b662d5c72c29903813eJake Slack 19903928aee4356845252ac6b662d5c72c29903813eJake Slack 20003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 20103928aee4356845252ac6b662d5c72c29903813eJake Slack /** Add value to multi valued entry. 20203928aee4356845252ac6b662d5c72c29903813eJake Slack * If the entry is single valued, it is converted to the first 20303928aee4356845252ac6b662d5c72c29903813eJake Slack * value of a multi valued entry. 20403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 20503928aee4356845252ac6b662d5c72c29903813eJake Slack * @param value The entry value. 20603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 20703928aee4356845252ac6b662d5c72c29903813eJake Slack public void add(K name, Object value) 20803928aee4356845252ac6b662d5c72c29903813eJake Slack { 20903928aee4356845252ac6b662d5c72c29903813eJake Slack Object lo = _map.get(name); 21003928aee4356845252ac6b662d5c72c29903813eJake Slack Object ln = LazyList.add(lo,value); 21103928aee4356845252ac6b662d5c72c29903813eJake Slack if (lo!=ln) 21203928aee4356845252ac6b662d5c72c29903813eJake Slack _map.put(name,ln); 21303928aee4356845252ac6b662d5c72c29903813eJake Slack } 21403928aee4356845252ac6b662d5c72c29903813eJake Slack 21503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 21603928aee4356845252ac6b662d5c72c29903813eJake Slack /** Add values to multi valued entry. 21703928aee4356845252ac6b662d5c72c29903813eJake Slack * If the entry is single valued, it is converted to the first 21803928aee4356845252ac6b662d5c72c29903813eJake Slack * value of a multi valued entry. 21903928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 22003928aee4356845252ac6b662d5c72c29903813eJake Slack * @param values The List of multiple values. 22103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 22203928aee4356845252ac6b662d5c72c29903813eJake Slack public void addValues(K name, List<? extends Object> values) 22303928aee4356845252ac6b662d5c72c29903813eJake Slack { 22403928aee4356845252ac6b662d5c72c29903813eJake Slack Object lo = _map.get(name); 22503928aee4356845252ac6b662d5c72c29903813eJake Slack Object ln = LazyList.addCollection(lo,values); 22603928aee4356845252ac6b662d5c72c29903813eJake Slack if (lo!=ln) 22703928aee4356845252ac6b662d5c72c29903813eJake Slack _map.put(name,ln); 22803928aee4356845252ac6b662d5c72c29903813eJake Slack } 22903928aee4356845252ac6b662d5c72c29903813eJake Slack 23003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 23103928aee4356845252ac6b662d5c72c29903813eJake Slack /** Add values to multi valued entry. 23203928aee4356845252ac6b662d5c72c29903813eJake Slack * If the entry is single valued, it is converted to the first 23303928aee4356845252ac6b662d5c72c29903813eJake Slack * value of a multi valued entry. 23403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 23503928aee4356845252ac6b662d5c72c29903813eJake Slack * @param values The String array of multiple values. 23603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 23703928aee4356845252ac6b662d5c72c29903813eJake Slack public void addValues(K name, String[] values) 23803928aee4356845252ac6b662d5c72c29903813eJake Slack { 23903928aee4356845252ac6b662d5c72c29903813eJake Slack Object lo = _map.get(name); 24003928aee4356845252ac6b662d5c72c29903813eJake Slack Object ln = LazyList.addCollection(lo,Arrays.asList(values)); 24103928aee4356845252ac6b662d5c72c29903813eJake Slack if (lo!=ln) 24203928aee4356845252ac6b662d5c72c29903813eJake Slack _map.put(name,ln); 24303928aee4356845252ac6b662d5c72c29903813eJake Slack } 24403928aee4356845252ac6b662d5c72c29903813eJake Slack 24503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 24603928aee4356845252ac6b662d5c72c29903813eJake Slack /** Remove value. 24703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param name The entry key. 24803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param value The entry value. 24903928aee4356845252ac6b662d5c72c29903813eJake Slack * @return true if it was removed. 25003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 25103928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean removeValue(K name,Object value) 25203928aee4356845252ac6b662d5c72c29903813eJake Slack { 25303928aee4356845252ac6b662d5c72c29903813eJake Slack Object lo = _map.get(name); 25403928aee4356845252ac6b662d5c72c29903813eJake Slack Object ln=lo; 25503928aee4356845252ac6b662d5c72c29903813eJake Slack int s=LazyList.size(lo); 25603928aee4356845252ac6b662d5c72c29903813eJake Slack if (s>0) 25703928aee4356845252ac6b662d5c72c29903813eJake Slack { 25803928aee4356845252ac6b662d5c72c29903813eJake Slack ln=LazyList.remove(lo,value); 25903928aee4356845252ac6b662d5c72c29903813eJake Slack if (ln==null) 26003928aee4356845252ac6b662d5c72c29903813eJake Slack _map.remove(name); 26103928aee4356845252ac6b662d5c72c29903813eJake Slack else 26203928aee4356845252ac6b662d5c72c29903813eJake Slack _map.put(name, ln); 26303928aee4356845252ac6b662d5c72c29903813eJake Slack } 26403928aee4356845252ac6b662d5c72c29903813eJake Slack return LazyList.size(ln)!=s; 26503928aee4356845252ac6b662d5c72c29903813eJake Slack } 26603928aee4356845252ac6b662d5c72c29903813eJake Slack 26703928aee4356845252ac6b662d5c72c29903813eJake Slack 26803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 26903928aee4356845252ac6b662d5c72c29903813eJake Slack /** Put all contents of map. 27003928aee4356845252ac6b662d5c72c29903813eJake Slack * @param m Map 27103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 27203928aee4356845252ac6b662d5c72c29903813eJake Slack public void putAll(Map<? extends K, ? extends Object> m) 27303928aee4356845252ac6b662d5c72c29903813eJake Slack { 27403928aee4356845252ac6b662d5c72c29903813eJake Slack boolean multi = (m instanceof MultiMap); 27503928aee4356845252ac6b662d5c72c29903813eJake Slack 27603928aee4356845252ac6b662d5c72c29903813eJake Slack if (multi) 27703928aee4356845252ac6b662d5c72c29903813eJake Slack { 27803928aee4356845252ac6b662d5c72c29903813eJake Slack for (Map.Entry<? extends K, ? extends Object> entry : m.entrySet()) 27903928aee4356845252ac6b662d5c72c29903813eJake Slack { 28003928aee4356845252ac6b662d5c72c29903813eJake Slack _map.put(entry.getKey(),LazyList.clone(entry.getValue())); 28103928aee4356845252ac6b662d5c72c29903813eJake Slack } 28203928aee4356845252ac6b662d5c72c29903813eJake Slack } 28303928aee4356845252ac6b662d5c72c29903813eJake Slack else 28403928aee4356845252ac6b662d5c72c29903813eJake Slack { 28503928aee4356845252ac6b662d5c72c29903813eJake Slack _map.putAll(m); 28603928aee4356845252ac6b662d5c72c29903813eJake Slack } 28703928aee4356845252ac6b662d5c72c29903813eJake Slack } 28803928aee4356845252ac6b662d5c72c29903813eJake Slack 28903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 29003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 29103928aee4356845252ac6b662d5c72c29903813eJake Slack * @return Map of String arrays 29203928aee4356845252ac6b662d5c72c29903813eJake Slack */ 29303928aee4356845252ac6b662d5c72c29903813eJake Slack public Map<K,String[]> toStringArrayMap() 29403928aee4356845252ac6b662d5c72c29903813eJake Slack { 29503928aee4356845252ac6b662d5c72c29903813eJake Slack HashMap<K,String[]> map = new HashMap<K,String[]>(_map.size()*3/2) 29603928aee4356845252ac6b662d5c72c29903813eJake Slack { 29703928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString() 29803928aee4356845252ac6b662d5c72c29903813eJake Slack { 29903928aee4356845252ac6b662d5c72c29903813eJake Slack StringBuilder b=new StringBuilder(); 30003928aee4356845252ac6b662d5c72c29903813eJake Slack b.append('{'); 30103928aee4356845252ac6b662d5c72c29903813eJake Slack for (K k:keySet()) 30203928aee4356845252ac6b662d5c72c29903813eJake Slack { 30303928aee4356845252ac6b662d5c72c29903813eJake Slack if(b.length()>1) 30403928aee4356845252ac6b662d5c72c29903813eJake Slack b.append(','); 30503928aee4356845252ac6b662d5c72c29903813eJake Slack b.append(k); 30603928aee4356845252ac6b662d5c72c29903813eJake Slack b.append('='); 30703928aee4356845252ac6b662d5c72c29903813eJake Slack b.append(Arrays.asList(get(k))); 30803928aee4356845252ac6b662d5c72c29903813eJake Slack } 30903928aee4356845252ac6b662d5c72c29903813eJake Slack 31003928aee4356845252ac6b662d5c72c29903813eJake Slack b.append('}'); 31103928aee4356845252ac6b662d5c72c29903813eJake Slack return b.toString(); 31203928aee4356845252ac6b662d5c72c29903813eJake Slack } 31303928aee4356845252ac6b662d5c72c29903813eJake Slack }; 31403928aee4356845252ac6b662d5c72c29903813eJake Slack 31503928aee4356845252ac6b662d5c72c29903813eJake Slack for(Map.Entry<K,Object> entry: _map.entrySet()) 31603928aee4356845252ac6b662d5c72c29903813eJake Slack { 31703928aee4356845252ac6b662d5c72c29903813eJake Slack String[] a = LazyList.toStringArray(entry.getValue()); 31803928aee4356845252ac6b662d5c72c29903813eJake Slack map.put(entry.getKey(),a); 31903928aee4356845252ac6b662d5c72c29903813eJake Slack } 32003928aee4356845252ac6b662d5c72c29903813eJake Slack return map; 32103928aee4356845252ac6b662d5c72c29903813eJake Slack } 32203928aee4356845252ac6b662d5c72c29903813eJake Slack 32303928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 32403928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString() 32503928aee4356845252ac6b662d5c72c29903813eJake Slack { 32603928aee4356845252ac6b662d5c72c29903813eJake Slack return _cmap==null?_map.toString():_cmap.toString(); 32703928aee4356845252ac6b662d5c72c29903813eJake Slack } 32803928aee4356845252ac6b662d5c72c29903813eJake Slack 32903928aee4356845252ac6b662d5c72c29903813eJake Slack public void clear() 33003928aee4356845252ac6b662d5c72c29903813eJake Slack { 33103928aee4356845252ac6b662d5c72c29903813eJake Slack _map.clear(); 33203928aee4356845252ac6b662d5c72c29903813eJake Slack } 33303928aee4356845252ac6b662d5c72c29903813eJake Slack 33403928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean containsKey(Object key) 33503928aee4356845252ac6b662d5c72c29903813eJake Slack { 33603928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.containsKey(key); 33703928aee4356845252ac6b662d5c72c29903813eJake Slack } 33803928aee4356845252ac6b662d5c72c29903813eJake Slack 33903928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean containsValue(Object value) 34003928aee4356845252ac6b662d5c72c29903813eJake Slack { 34103928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.containsValue(value); 34203928aee4356845252ac6b662d5c72c29903813eJake Slack } 34303928aee4356845252ac6b662d5c72c29903813eJake Slack 34403928aee4356845252ac6b662d5c72c29903813eJake Slack public Set<Entry<K, Object>> entrySet() 34503928aee4356845252ac6b662d5c72c29903813eJake Slack { 34603928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.entrySet(); 34703928aee4356845252ac6b662d5c72c29903813eJake Slack } 34803928aee4356845252ac6b662d5c72c29903813eJake Slack 34903928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 35003928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean equals(Object o) 35103928aee4356845252ac6b662d5c72c29903813eJake Slack { 35203928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.equals(o); 35303928aee4356845252ac6b662d5c72c29903813eJake Slack } 35403928aee4356845252ac6b662d5c72c29903813eJake Slack 35503928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 35603928aee4356845252ac6b662d5c72c29903813eJake Slack public int hashCode() 35703928aee4356845252ac6b662d5c72c29903813eJake Slack { 35803928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.hashCode(); 35903928aee4356845252ac6b662d5c72c29903813eJake Slack } 36003928aee4356845252ac6b662d5c72c29903813eJake Slack 36103928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean isEmpty() 36203928aee4356845252ac6b662d5c72c29903813eJake Slack { 36303928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.isEmpty(); 36403928aee4356845252ac6b662d5c72c29903813eJake Slack } 36503928aee4356845252ac6b662d5c72c29903813eJake Slack 36603928aee4356845252ac6b662d5c72c29903813eJake Slack public Set<K> keySet() 36703928aee4356845252ac6b662d5c72c29903813eJake Slack { 36803928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.keySet(); 36903928aee4356845252ac6b662d5c72c29903813eJake Slack } 37003928aee4356845252ac6b662d5c72c29903813eJake Slack 37103928aee4356845252ac6b662d5c72c29903813eJake Slack public Object remove(Object key) 37203928aee4356845252ac6b662d5c72c29903813eJake Slack { 37303928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.remove(key); 37403928aee4356845252ac6b662d5c72c29903813eJake Slack } 37503928aee4356845252ac6b662d5c72c29903813eJake Slack 37603928aee4356845252ac6b662d5c72c29903813eJake Slack public int size() 37703928aee4356845252ac6b662d5c72c29903813eJake Slack { 37803928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.size(); 37903928aee4356845252ac6b662d5c72c29903813eJake Slack } 38003928aee4356845252ac6b662d5c72c29903813eJake Slack 38103928aee4356845252ac6b662d5c72c29903813eJake Slack public Collection<Object> values() 38203928aee4356845252ac6b662d5c72c29903813eJake Slack { 38303928aee4356845252ac6b662d5c72c29903813eJake Slack return _map.values(); 38403928aee4356845252ac6b662d5c72c29903813eJake Slack } 38503928aee4356845252ac6b662d5c72c29903813eJake Slack 38603928aee4356845252ac6b662d5c72c29903813eJake Slack 38703928aee4356845252ac6b662d5c72c29903813eJake Slack 38803928aee4356845252ac6b662d5c72c29903813eJake Slack public Object putIfAbsent(K key, Object value) 38903928aee4356845252ac6b662d5c72c29903813eJake Slack { 39003928aee4356845252ac6b662d5c72c29903813eJake Slack if (_cmap==null) 39103928aee4356845252ac6b662d5c72c29903813eJake Slack throw new UnsupportedOperationException(); 39203928aee4356845252ac6b662d5c72c29903813eJake Slack return _cmap.putIfAbsent(key,value); 39303928aee4356845252ac6b662d5c72c29903813eJake Slack } 39403928aee4356845252ac6b662d5c72c29903813eJake Slack 39503928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean remove(Object key, Object value) 39603928aee4356845252ac6b662d5c72c29903813eJake Slack { 39703928aee4356845252ac6b662d5c72c29903813eJake Slack if (_cmap==null) 39803928aee4356845252ac6b662d5c72c29903813eJake Slack throw new UnsupportedOperationException(); 39903928aee4356845252ac6b662d5c72c29903813eJake Slack return _cmap.remove(key,value); 40003928aee4356845252ac6b662d5c72c29903813eJake Slack } 40103928aee4356845252ac6b662d5c72c29903813eJake Slack 40203928aee4356845252ac6b662d5c72c29903813eJake Slack public boolean replace(K key, Object oldValue, Object newValue) 40303928aee4356845252ac6b662d5c72c29903813eJake Slack { 40403928aee4356845252ac6b662d5c72c29903813eJake Slack if (_cmap==null) 40503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new UnsupportedOperationException(); 40603928aee4356845252ac6b662d5c72c29903813eJake Slack return _cmap.replace(key,oldValue,newValue); 40703928aee4356845252ac6b662d5c72c29903813eJake Slack } 40803928aee4356845252ac6b662d5c72c29903813eJake Slack 40903928aee4356845252ac6b662d5c72c29903813eJake Slack public Object replace(K key, Object value) 41003928aee4356845252ac6b662d5c72c29903813eJake Slack { 41103928aee4356845252ac6b662d5c72c29903813eJake Slack if (_cmap==null) 41203928aee4356845252ac6b662d5c72c29903813eJake Slack throw new UnsupportedOperationException(); 41303928aee4356845252ac6b662d5c72c29903813eJake Slack return _cmap.replace(key,value); 41403928aee4356845252ac6b662d5c72c29903813eJake Slack } 41503928aee4356845252ac6b662d5c72c29903813eJake Slack} 416