org.mortbay.util.MultiMap Maven / Gradle / Ivy
// ========================================================================
// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.util;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/* ------------------------------------------------------------ */
/** A multi valued Map.
* This Map specializes HashMap and provides methods
* that operate on multi valued items.
*
* Implemented as a map of LazyList values
*
* @see LazyList
* @author Greg Wilkins (gregw)
*/
public class MultiMap extends HashMap
implements Cloneable
{
/* ------------------------------------------------------------ */
/** Constructor.
*/
public MultiMap()
{}
/* ------------------------------------------------------------ */
/** Constructor.
* @param size Capacity of the map
*/
public MultiMap(int size)
{
super(size);
}
/* ------------------------------------------------------------ */
/** Constructor.
* @param map
*/
public MultiMap(Map map)
{
super((map.size()*3)/2);
putAll(map);
}
/* ------------------------------------------------------------ */
/** 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(super.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=super.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=super.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:
StringBuffer values=new StringBuffer(128);
synchronized(values)
{
for (int i=0; i0)
values.append(',');
values.append(e.toString());
}
}
return values.toString();
}
}
}
/* ------------------------------------------------------------ */
public Object get(Object name)
{
Object l=super.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(Object name, Object value)
{
return super.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(Object name, List values)
{
return super.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(Object name, String[] values)
{
Object list=null;
for (int i=0;i0)
{
ln=LazyList.remove(lo,value);
if (ln==null)
super.remove(name);
else
super.put(name, ln);
}
return LazyList.size(ln)!=s;
}
/* ------------------------------------------------------------ */
/** Put all contents of map.
* @param m Map
*/
public void putAll(Map m)
{
Iterator i = m.entrySet().iterator();
boolean multi=m instanceof MultiMap;
while(i.hasNext())
{
Map.Entry entry =
(Map.Entry)i.next();
if (multi)
super.put(entry.getKey(),LazyList.clone(entry.getValue()));
else
put(entry.getKey(),entry.getValue());
}
}
/* ------------------------------------------------------------ */
/**
* @return Map of String arrays
*/
public Map toStringArrayMap()
{
HashMap map = new HashMap(size()*3/2);
Iterator i = super.entrySet().iterator();
while(i.hasNext())
{
Map.Entry entry = (Map.Entry)i.next();
Object l = entry.getValue();
String[] a = LazyList.toStringArray(l);
// for (int j=a.length;j-->0;)
// if (a[j]==null)
// a[j]="";
map.put(entry.getKey(),a);
}
return map;
}
/* ------------------------------------------------------------ */
public Object clone()
{
MultiMap mm = (MultiMap) super.clone();
Iterator iter = mm.entrySet().iterator();
while (iter.hasNext())
{
Map.Entry entry = (Map.Entry)iter.next();
entry.setValue(LazyList.clone(entry.getValue()));
}
return mm;
}
}