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);
+    }
+}