Mercurial Hosting > luan
diff src/org/eclipse/jetty/util/MultiMap.java @ 802:3428c60d7cfc
replace jetty jars with source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 07 Sep 2016 21:15:48 -0600 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/eclipse/jetty/util/MultiMap.java Wed Sep 07 21:15:48 2016 -0600 @@ -0,0 +1,415 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/* ------------------------------------------------------------ */ +/** A multi valued Map. + * This Map specializes HashMap and provides methods + * that operate on multi valued items. + * <P> + * Implemented as a map of LazyList values + * @param <K> The key type of the map. + * + * @see LazyList + * + */ +public class MultiMap<K> implements ConcurrentMap<K,Object>, Serializable +{ + private static final long serialVersionUID = -6878723138353851005L; + Map<K,Object> _map; + ConcurrentMap<K, Object> _cmap; + + public MultiMap() + { + _map=new HashMap<K, Object>(); + } + + public MultiMap(Map<K,Object> map) + { + if (map instanceof ConcurrentMap) + _map=_cmap=new ConcurrentHashMap<K, Object>(map); + else + _map=new HashMap<K, Object>(map); + } + + public MultiMap(MultiMap<K> map) + { + if (map._cmap!=null) + _map=_cmap=new ConcurrentHashMap<K, Object>(map._cmap); + else + _map=new HashMap<K,Object>(map._map); + } + + public MultiMap(int capacity) + { + _map=new HashMap<K, Object>(capacity); + } + + public MultiMap(boolean concurrent) + { + if (concurrent) + _map=_cmap=new ConcurrentHashMap<K, Object>(); + else + _map=new HashMap<K, Object>(); + } + + + /* ------------------------------------------------------------ */ + /** Get multiple values. + * Single valued entries are converted to singleton lists. + * @param name The entry key. + * @return Unmodifieable List of values. + */ + public List getValues(Object name) + { + return LazyList.getList(_map.get(name),true); + } + + /* ------------------------------------------------------------ */ + /** Get a value from a multiple value. + * If the value is not a multivalue, then index 0 retrieves the + * value or null. + * @param name The entry key. + * @param i Index of element to get. + * @return Unmodifieable List of values. + */ + public Object getValue(Object name,int i) + { + Object l=_map.get(name); + if (i==0 && LazyList.size(l)==0) + return null; + return LazyList.get(l,i); + } + + + /* ------------------------------------------------------------ */ + /** Get value as String. + * Single valued items are converted to a String with the toString() + * Object method. Multi valued entries are converted to a comma separated + * List. No quoting of commas within values is performed. + * @param name The entry key. + * @return String value. + */ + public String getString(Object name) + { + Object l=_map.get(name); + switch(LazyList.size(l)) + { + case 0: + return null; + case 1: + Object o=LazyList.get(l,0); + return o==null?null:o.toString(); + default: + { + StringBuilder values=new StringBuilder(128); + for (int i=0; i<LazyList.size(l); i++) + { + Object e=LazyList.get(l,i); + if (e!=null) + { + if (values.length()>0) + values.append(','); + values.append(e.toString()); + } + } + return values.toString(); + } + } + } + + /* ------------------------------------------------------------ */ + public Object get(Object name) + { + Object l=_map.get(name); + switch(LazyList.size(l)) + { + case 0: + return null; + case 1: + Object o=LazyList.get(l,0); + return o; + default: + return LazyList.getList(l,true); + } + } + + /* ------------------------------------------------------------ */ + /** Put and entry into the map. + * @param name The entry key. + * @param value The entry value. + * @return The previous value or null. + */ + public Object put(K name, Object value) + { + return _map.put(name,LazyList.add(null,value)); + } + + /* ------------------------------------------------------------ */ + /** Put multi valued entry. + * @param name The entry key. + * @param values The List of multiple values. + * @return The previous value or null. + */ + public Object putValues(K name, List<? extends Object> values) + { + return _map.put(name,values); + } + + /* ------------------------------------------------------------ */ + /** Put multi valued entry. + * @param name The entry key. + * @param values The String array of multiple values. + * @return The previous value or null. + */ + public Object putValues(K name, String... values) + { + Object list=null; + for (int i=0;i<values.length;i++) + list=LazyList.add(list,values[i]); + return _map.put(name,list); + } + + + /* ------------------------------------------------------------ */ + /** Add value to multi valued entry. + * If the entry is single valued, it is converted to the first + * value of a multi valued entry. + * @param name The entry key. + * @param value The entry value. + */ + public void add(K name, Object value) + { + Object lo = _map.get(name); + Object ln = LazyList.add(lo,value); + if (lo!=ln) + _map.put(name,ln); + } + + /* ------------------------------------------------------------ */ + /** Add values to multi valued entry. + * If the entry is single valued, it is converted to the first + * value of a multi valued entry. + * @param name The entry key. + * @param values The List of multiple values. + */ + public void addValues(K name, List<? extends Object> values) + { + Object lo = _map.get(name); + Object ln = LazyList.addCollection(lo,values); + if (lo!=ln) + _map.put(name,ln); + } + + /* ------------------------------------------------------------ */ + /** Add values to multi valued entry. + * If the entry is single valued, it is converted to the first + * value of a multi valued entry. + * @param name The entry key. + * @param values The String array of multiple values. + */ + public void addValues(K name, String[] values) + { + Object lo = _map.get(name); + Object ln = LazyList.addCollection(lo,Arrays.asList(values)); + if (lo!=ln) + _map.put(name,ln); + } + + /* ------------------------------------------------------------ */ + /** Remove value. + * @param name The entry key. + * @param value The entry value. + * @return true if it was removed. + */ + public boolean removeValue(K name,Object value) + { + Object lo = _map.get(name); + Object ln=lo; + int s=LazyList.size(lo); + if (s>0) + { + ln=LazyList.remove(lo,value); + if (ln==null) + _map.remove(name); + else + _map.put(name, ln); + } + return LazyList.size(ln)!=s; + } + + + /* ------------------------------------------------------------ */ + /** Put all contents of map. + * @param m Map + */ + public void putAll(Map<? extends K, ? extends Object> m) + { + boolean multi = (m instanceof MultiMap); + + if (multi) + { + for (Map.Entry<? extends K, ? extends Object> entry : m.entrySet()) + { + _map.put(entry.getKey(),LazyList.clone(entry.getValue())); + } + } + else + { + _map.putAll(m); + } + } + + /* ------------------------------------------------------------ */ + /** + * @return Map of String arrays + */ + public Map<K,String[]> toStringArrayMap() + { + HashMap<K,String[]> map = new HashMap<K,String[]>(_map.size()*3/2) + { + public String toString() + { + StringBuilder b=new StringBuilder(); + b.append('{'); + for (K k:keySet()) + { + if(b.length()>1) + b.append(','); + b.append(k); + b.append('='); + b.append(Arrays.asList(get(k))); + } + + b.append('}'); + return b.toString(); + } + }; + + for(Map.Entry<K,Object> entry: _map.entrySet()) + { + String[] a = LazyList.toStringArray(entry.getValue()); + map.put(entry.getKey(),a); + } + return map; + } + + @Override + public String toString() + { + return _cmap==null?_map.toString():_cmap.toString(); + } + + public void clear() + { + _map.clear(); + } + + public boolean containsKey(Object key) + { + return _map.containsKey(key); + } + + public boolean containsValue(Object value) + { + return _map.containsValue(value); + } + + public Set<Entry<K, Object>> entrySet() + { + return _map.entrySet(); + } + + @Override + public boolean equals(Object o) + { + return _map.equals(o); + } + + @Override + public int hashCode() + { + return _map.hashCode(); + } + + public boolean isEmpty() + { + return _map.isEmpty(); + } + + public Set<K> keySet() + { + return _map.keySet(); + } + + public Object remove(Object key) + { + return _map.remove(key); + } + + public int size() + { + return _map.size(); + } + + public Collection<Object> values() + { + return _map.values(); + } + + + + public Object putIfAbsent(K key, Object value) + { + if (_cmap==null) + throw new UnsupportedOperationException(); + return _cmap.putIfAbsent(key,value); + } + + public boolean remove(Object key, Object value) + { + if (_cmap==null) + throw new UnsupportedOperationException(); + return _cmap.remove(key,value); + } + + public boolean replace(K key, Object oldValue, Object newValue) + { + if (_cmap==null) + throw new UnsupportedOperationException(); + return _cmap.replace(key,oldValue,newValue); + } + + public Object replace(K key, Object value) + { + if (_cmap==null) + throw new UnsupportedOperationException(); + return _cmap.replace(key,value); + } +}