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