View Javadoc

1   /*
2    * $Id:  $
3    * -------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  package org.mule.transport.http.multipart;
11  
12  // ========================================================================
13  // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
14  // ------------------------------------------------------------------------
15  // All rights reserved. This program and the accompanying materials
16  // are made available under the terms of the Eclipse Public License v1.0
17  // and Apache License v2.0 which accompanies this distribution.
18  // The Eclipse Public License is available at
19  // http://www.eclipse.org/legal/epl-v10.html
20  // The Apache License v2.0 is available at
21  // http://www.opensource.org/licenses/apache2.0.php
22  // You may elect to redistribute this code under either of these licenses.
23  // ========================================================================
24  
25  
26  import java.util.Arrays;
27  import java.util.Collection;
28  import java.util.HashMap;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Set;
33  import java.util.concurrent.ConcurrentHashMap;
34  import java.util.concurrent.ConcurrentMap;
35  
36  /* ------------------------------------------------------------ */
37  /** A multi valued Map.
38   * This Map specializes HashMap and provides methods
39   * that operate on multi valued items.
40   * <P>
41   * Implemented as a map of LazyList values
42   *
43   * @see LazyList
44   *
45   */
46  public class MultiMap<K> implements ConcurrentMap<K,Object>
47  {
48      Map<K,Object> _map;
49      ConcurrentMap<K, Object> _cmap;
50  
51      public MultiMap()
52      {
53          _map=new HashMap<K, Object>();
54      }
55  
56      public MultiMap(Map map)
57      {
58          if (map instanceof ConcurrentMap)
59              _map=_cmap=new ConcurrentHashMap<K, Object>(map);
60          else
61              _map=new HashMap<K, Object>(map);
62      }
63  
64      public MultiMap(int capacity)
65      {
66          _map=new HashMap<K, Object>(capacity);
67      }
68  
69      public MultiMap(boolean concurrent)
70      {
71          if (concurrent)
72              _map=_cmap=new ConcurrentHashMap<K, Object>();
73          else
74              _map=new HashMap<K, Object>();
75      }
76  
77  
78      /* ------------------------------------------------------------ */
79      /** Get multiple values.
80       * Single valued entries are converted to singleton lists.
81       * @param name The entry key.
82       * @return Unmodifieable List of values.
83       */
84      public List getValues(Object name)
85      {
86          return LazyList.getList(_map.get(name),true);
87      }
88  
89      /* ------------------------------------------------------------ */
90      /** Get a value from a multiple value.
91       * If the value is not a multivalue, then index 0 retrieves the
92       * value or null.
93       * @param name The entry key.
94       * @param i Index of element to get.
95       * @return Unmodifieable List of values.
96       */
97      public Object getValue(Object name,int i)
98      {
99          Object l=_map.get(name);
100         if (i==0 && LazyList.size(l)==0)
101             return null;
102         return LazyList.get(l,i);
103     }
104 
105 
106     /* ------------------------------------------------------------ */
107     /** Get value as String.
108      * Single valued items are converted to a String with the toString()
109      * Object method. Multi valued entries are converted to a comma separated
110      * List.  No quoting of commas within values is performed.
111      * @param name The entry key.
112      * @return String value.
113      */
114     public String getString(Object name)
115     {
116         Object l=_map.get(name);
117         switch(LazyList.size(l))
118         {
119           case 0:
120               return null;
121           case 1:
122               Object o=LazyList.get(l,0);
123               return o==null?null:o.toString();
124           default:
125           {
126               StringBuilder values=new StringBuilder(128);
127               for (int i=0; i<LazyList.size(l); i++)
128               {
129                   Object e=LazyList.get(l,i);
130                   if (e!=null)
131                   {
132                       if (values.length()>0)
133                           values.append(',');
134                       values.append(e.toString());
135                   }
136               }
137               return values.toString();
138           }
139         }
140     }
141 
142     /* ------------------------------------------------------------ */
143     public Object get(Object name)
144     {
145         Object l=_map.get(name);
146         switch(LazyList.size(l))
147         {
148           case 0:
149               return null;
150           case 1:
151               Object o=LazyList.get(l,0);
152               return o;
153           default:
154               return LazyList.getList(l,true);
155         }
156     }
157 
158     /* ------------------------------------------------------------ */
159     /** Put and entry into the map.
160      * @param name The entry key.
161      * @param value The entry value.
162      * @return The previous value or null.
163      */
164     public Object put(K name, Object value)
165     {
166         return _map.put(name,LazyList.add(null,value));
167     }
168 
169     /* ------------------------------------------------------------ */
170     /** Put multi valued entry.
171      * @param name The entry key.
172      * @param values The List of multiple values.
173      * @return The previous value or null.
174      */
175     public Object putValues(K name, List values)
176     {
177         return _map.put(name,values);
178     }
179 
180     /* ------------------------------------------------------------ */
181     /** Put multi valued entry.
182      * @param name The entry key.
183      * @param values The String array of multiple values.
184      * @return The previous value or null.
185      */
186     public Object putValues(K name, String[] values)
187     {
188         Object list=null;
189         for (int i=0;i<values.length;i++)
190             list=LazyList.add(list,values[i]);
191         return put(name,list);
192     }
193 
194 
195     /* ------------------------------------------------------------ */
196     /** Add value to multi valued entry.
197      * If the entry is single valued, it is converted to the first
198      * value of a multi valued entry.
199      * @param name The entry key.
200      * @param value The entry value.
201      */
202     public void add(K name, Object value)
203     {
204         Object lo = _map.get(name);
205         Object ln = LazyList.add(lo,value);
206         if (lo!=ln)
207             _map.put(name,ln);
208     }
209 
210     /* ------------------------------------------------------------ */
211     /** Add values to multi valued entry.
212      * If the entry is single valued, it is converted to the first
213      * value of a multi valued entry.
214      * @param name The entry key.
215      * @param values The List of multiple values.
216      */
217     public void addValues(K name, List values)
218     {
219         Object lo = _map.get(name);
220         Object ln = LazyList.addCollection(lo,values);
221         if (lo!=ln)
222             _map.put(name,ln);
223     }
224 
225     /* ------------------------------------------------------------ */
226     /** Add values to multi valued entry.
227      * If the entry is single valued, it is converted to the first
228      * value of a multi valued entry.
229      * @param name The entry key.
230      * @param values The String array of multiple values.
231      */
232     public void addValues(K name, String[] values)
233     {
234         Object lo = _map.get(name);
235         Object ln = LazyList.addCollection(lo,Arrays.asList(values));
236         if (lo!=ln)
237             _map.put(name,ln);
238     }
239 
240     /* ------------------------------------------------------------ */
241     /** Remove value.
242      * @param name The entry key.
243      * @param value The entry value.
244      * @return true if it was removed.
245      */
246     public boolean removeValue(K name,Object value)
247     {
248         Object lo = _map.get(name);
249         Object ln=lo;
250         int s=LazyList.size(lo);
251         if (s>0)
252         {
253             ln=LazyList.remove(lo,value);
254             if (ln==null)
255                 _map.remove(name);
256             else
257                 _map.put(name, ln);
258         }
259         return LazyList.size(ln)!=s;
260     }
261 
262     /* ------------------------------------------------------------ */
263     /** Put all contents of map.
264      * @param m Map
265      */
266     public void putAll(Map m)
267     {
268         Iterator i = m.entrySet().iterator();
269         boolean multi=m instanceof MultiMap;
270         while(i.hasNext())
271         {
272             Map.Entry entry = (Map.Entry)i.next();
273             if (multi)
274                 _map.put((K)(entry.getKey()),LazyList.clone(entry.getValue()));
275             else
276                 put((K)(entry.getKey()),entry.getValue());
277         }
278     }
279 
280     /* ------------------------------------------------------------ */
281     /**
282      * @return Map of String arrays
283      */
284     public Map toStringArrayMap()
285     {
286         HashMap map = new HashMap(_map.size()*3/2);
287 
288         Iterator i = _map.entrySet().iterator();
289         while(i.hasNext())
290         {
291             Map.Entry entry = (Map.Entry)i.next();
292             Object l = entry.getValue();
293             String[] a = LazyList.toStringArray(l);
294             // for (int j=a.length;j-->0;)
295             //    if (a[j]==null)
296             //         a[j]="";
297             map.put(entry.getKey(),a);
298         }
299         return map;
300     }
301 
302     public void clear()
303     {
304         _map.clear();
305     }
306 
307     public boolean containsKey(Object key)
308     {
309         return _map.containsKey(key);
310     }
311 
312     public boolean containsValue(Object value)
313     {
314         return _map.containsValue(value);
315     }
316 
317     public Set<Entry<K, Object>> entrySet()
318     {
319         return _map.entrySet();
320     }
321 
322     @Override
323     public boolean equals(Object o)
324     {
325         return _map.equals(o);
326     }
327 
328     @Override
329     public int hashCode()
330     {
331         return _map.hashCode();
332     }
333 
334     public boolean isEmpty()
335     {
336         return _map.isEmpty();
337     }
338 
339     public Set<K> keySet()
340     {
341         return _map.keySet();
342     }
343 
344     public Object remove(Object key)
345     {
346         return _map.remove(key);
347     }
348 
349     public int size()
350     {
351         return _map.size();
352     }
353 
354     public Collection<Object> values()
355     {
356         return _map.values();
357     }
358 
359 
360 
361     public Object putIfAbsent(K key, Object value)
362     {
363         if (_cmap==null)
364             throw new UnsupportedOperationException();
365         return _cmap.putIfAbsent(key,value);
366     }
367 
368     public boolean remove(Object key, Object value)
369     {
370         if (_cmap==null)
371             throw new UnsupportedOperationException();
372         return _cmap.remove(key,value);
373     }
374 
375     public boolean replace(K key, Object oldValue, Object newValue)
376     {
377         if (_cmap==null)
378             throw new UnsupportedOperationException();
379         return _cmap.replace(key,oldValue,newValue);
380     }
381 
382     public Object replace(K key, Object value)
383     {
384         if (_cmap==null)
385             throw new UnsupportedOperationException();
386         return _cmap.replace(key,value);
387     }
388 
389 
390 }