This project has retired. For details please refer to its Attic page.
HeaderValuesMap xref
View Javadoc

1   /*
2    * $Id: HeaderValuesMap.java 1229087 2012-01-09 10:35:14Z mck $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.tiles.request.collection;
22  
23  import static org.apache.tiles.request.collection.CollectionUtil.*;
24  
25  import java.util.ArrayList;
26  import java.util.Collection;
27  import java.util.Enumeration;
28  import java.util.HashSet;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Set;
33  
34  import org.apache.tiles.request.attribute.EnumeratedValuesExtractor;
35  
36  
37  /**
38   * Exposes an {@link EnumeratedValuesExtractor} object as a read-only map.
39   *
40   * @version $Rev: 1229087 $ $Date: 2012-01-09 21:35:14 +1100 (Mon, 09 Jan 2012) $
41   */
42  public class HeaderValuesMap implements Map<String, String[]> {
43  
44      /**
45       * The request.
46       */
47      private EnumeratedValuesExtractor request;
48  
49      /**
50       * Constructor.
51       *
52       * @param request The request object to use.
53       */
54      public HeaderValuesMap(EnumeratedValuesExtractor request) {
55          this.request = request;
56      }
57  
58  
59      /** {@inheritDoc} */
60      public void clear() {
61          throw new UnsupportedOperationException();
62      }
63  
64  
65      /** {@inheritDoc} */
66      public boolean containsKey(Object key) {
67          return (request.getValue(key(key)) != null);
68      }
69  
70  
71      /** {@inheritDoc} */
72      public boolean containsValue(Object value) {
73          if (!(value instanceof String[])) {
74              return (false);
75          }
76          String[] test = (String[]) value;
77          Enumeration<String> names = request.getKeys();
78          while (names.hasMoreElements()) {
79              String name = names.nextElement();
80              if (compareHeaders(name, array2set(test))) {
81                  return true;
82              }
83          }
84          return false;
85      }
86  
87  
88      /** {@inheritDoc} */
89      public Set<Map.Entry<String, String[]>> entrySet() {
90          return new HeadersEntrySet();
91      }
92  
93  
94      /** {@inheritDoc} */
95      @Override
96      public boolean equals(Object o) {
97          EnumeratedValuesExtractor otherRequest = ((HeaderValuesMap) o).request;
98          boolean retValue = true;
99          for (Enumeration<String> attribs = request.getKeys(); attribs
100                 .hasMoreElements()
101                 && retValue;) {
102             String parameterName = attribs.nextElement();
103             Set<String> valueSet = enumeration2set(otherRequest.getValues(parameterName));
104             retValue = compareHeaders(parameterName, valueSet);
105         }
106 
107         return retValue;
108     }
109 
110 
111     /** {@inheritDoc} */
112     public String[] get(Object key) {
113         return getHeaderValues(key(key));
114     }
115 
116     /** {@inheritDoc} */
117     @Override
118     public int hashCode() {
119         int retValue = 0;
120         for (Enumeration<String> attribs = request.getKeys(); attribs
121                 .hasMoreElements();) {
122             String parameterName = attribs.nextElement();
123             Enumeration<String> values = request.getValues(parameterName);
124             int valueHash = 0;
125             while (values.hasMoreElements()) {
126                 valueHash += values.nextElement().hashCode();
127             }
128             retValue += parameterName.hashCode() ^ valueHash;
129         }
130         return retValue;
131     }
132 
133 
134     /** {@inheritDoc} */
135     public boolean isEmpty() {
136         return !request.getKeys().hasMoreElements();
137     }
138 
139 
140     /** {@inheritDoc} */
141     public Set<String> keySet() {
142         return new KeySet(request);
143     }
144 
145 
146     /** {@inheritDoc} */
147     public String[] put(String key, String[] value) {
148         throw new UnsupportedOperationException();
149     }
150 
151 
152     /** {@inheritDoc} */
153     public void putAll(Map<? extends String, ? extends String[]> map) {
154         throw new UnsupportedOperationException();
155     }
156 
157 
158     /** {@inheritDoc} */
159     public String[] remove(Object key) {
160         throw new UnsupportedOperationException();
161     }
162 
163 
164 
165     /** {@inheritDoc} */
166     public int size() {
167         return enumerationSize(request.getKeys());
168     }
169 
170 
171     /** {@inheritDoc} */
172     public Collection<String[]> values() {
173         return new HeaderValuesCollection();
174     }
175 
176     /**
177      * Extracts values enumeration of an attribute and returns the corresponding array of values.
178      *
179      * @param key The key of the attribute.
180      * @return The values of the attribute.
181      */
182     private String[] getHeaderValues(String key) {
183         List<String> list = new ArrayList<String>();
184         Enumeration<String> values = request.getValues(key);
185         while (values.hasMoreElements()) {
186             list.add(values.nextElement());
187         }
188         String[] retValue = list.toArray(new String[list.size()]);
189         return retValue;
190     }
191 
192     /**
193      * Converts the content of a string enumeration to an array of strings.
194      *
195      * @param enumeration The enumeration to convert.
196      * @return The corresponding array.
197      */
198     private Set<String> enumeration2set(Enumeration<String> enumeration) {
199         Set<String> retValue = new HashSet<String>();
200         while (enumeration.hasMoreElements()) {
201             retValue.add(enumeration.nextElement());
202         }
203         return retValue;
204     }
205 
206     /**
207      * Transforms a string array in a string set.
208      *
209      * @param valueArray The array to convert.
210      * @return The corresponding set.
211      */
212     private Set<String> array2set(String[] valueArray) {
213         Set<String> values = new HashSet<String>();
214         for (int i = 0; i < valueArray.length; i++) {
215             values.add(valueArray[i]);
216         }
217         return values;
218     }
219 
220     /**
221      * Checks if values of a header attribute are the same as the one passed in
222      * the set.
223      *
224      * @param name The name of the header.
225      * @param testSet The set of values it must contain.
226      * @return <code>true</code> if all the values, and only them, are present
227      * in the header values.
228      */
229     private boolean compareHeaders(String name, Set<String> testSet) {
230         Enumeration<String> values = request.getValues(name);
231         boolean matched = true;
232         while (values.hasMoreElements() && matched) {
233             String currentValue = values.nextElement();
234             matched = testSet.remove(currentValue);
235         }
236         matched = matched && testSet.isEmpty();
237         return matched;
238     }
239 
240     /**
241      * Entry set implementation for {@link HeaderValuesMap}.
242      */
243     private class HeadersEntrySet implements Set<Map.Entry<String, String[]>> {
244 
245         @Override
246         public boolean add(java.util.Map.Entry<String, String[]> e) {
247             throw new UnsupportedOperationException();
248         }
249 
250         @Override
251         public boolean addAll(
252                 Collection<? extends java.util.Map.Entry<String, String[]>> c) {
253             throw new UnsupportedOperationException();
254         }
255 
256         @Override
257         public void clear() {
258             throw new UnsupportedOperationException();
259         }
260 
261         @SuppressWarnings("unchecked")
262         @Override
263         public boolean contains(Object o) {
264             return containsEntry((java.util.Map.Entry<String, String[]>) o);
265         }
266 
267         @SuppressWarnings("unchecked")
268         @Override
269         public boolean containsAll(Collection<?> c) {
270             Collection<Map.Entry<String, String[]>> realCollection =
271                 (Collection<Map.Entry<String, String[]>>) c;
272             for (Map.Entry<String, String[]> entry : realCollection) {
273                 if (!containsEntry(entry)) {
274                     return false;
275                 }
276             }
277             return true;
278         }
279 
280         @Override
281         public boolean isEmpty() {
282             return HeaderValuesMap.this.isEmpty();
283         }
284 
285         @Override
286         public Iterator<java.util.Map.Entry<String, String[]>> iterator() {
287             return new HeadersEntrySetIterator();
288         }
289 
290         @Override
291         public boolean remove(Object o) {
292             throw new UnsupportedOperationException();
293         }
294 
295         @Override
296         public boolean removeAll(Collection<?> c) {
297             throw new UnsupportedOperationException();
298         }
299 
300         @Override
301         public boolean retainAll(Collection<?> c) {
302             throw new UnsupportedOperationException();
303         }
304 
305         @Override
306         public int size() {
307             return HeaderValuesMap.this.size();
308         }
309 
310         @Override
311         public Object[] toArray() {
312             return toList().toArray();
313         }
314 
315         @Override
316         public <T> T[] toArray(T[] a) {
317             return toList().toArray(a);
318         }
319 
320         /**
321          * Checks whether the given entry is present in the headers.
322          *
323          * @param entry The entry to check.
324          * @return <code></code> if the key and the values of the entry are present.
325          */
326         private boolean containsEntry(Map.Entry<String, String[]> entry) {
327             Enumeration<String> entryValues = request.getValues(key(entry.getKey()));
328             String[] valueArray = entry.getValue();
329             Set<String> values = array2set(valueArray);
330             while (entryValues.hasMoreElements()) {
331                 if (!values.remove(entryValues.nextElement())) {
332                     return false;
333                 }
334             }
335             return values.isEmpty();
336         }
337 
338         /**
339          * Turns this entry set into a list.
340          *
341          * @return The collection, turned into a list.
342          */
343         private List<Map.Entry<String, String[]>> toList() {
344             List<Map.Entry<String, String[]>> entries = new ArrayList<Map.Entry<String, String[]>>();
345             Enumeration<String> names = request.getKeys();
346             while (names.hasMoreElements()) {
347                 entries.add(extractNextEntry(names));
348             }
349             return entries;
350         }
351 
352         /**
353          * Returns the next entry, by getting the next element in the given enumeration.
354          *
355          * @param names The enumeration to get the next name from..
356          * @return The next map entry.
357          */
358         private MapEntry<String, String[]> extractNextEntry(
359                 Enumeration<String> names) {
360             String name = names.nextElement();
361             return new MapEntryArrayValues<String, String>(name, getHeaderValues(name), false);
362         }
363 
364         /**
365          * Iterates {@link HeadersEntrySet} elements.
366          */
367         private class HeadersEntrySetIterator implements Iterator<Map.Entry<String, String[]>> {
368 
369             /**
370              * The enumeration to use.
371              */
372             private Enumeration<String> namesEnumeration = request.getKeys();
373 
374             @Override
375             public boolean hasNext() {
376                 return namesEnumeration.hasMoreElements();
377             }
378 
379             @Override
380             public Map.Entry<String, String[]> next() {
381                 return extractNextEntry(namesEnumeration);
382             }
383 
384             @Override
385             public void remove() {
386                 throw new UnsupportedOperationException();
387             }
388 
389         }
390     }
391 
392     /**
393      * It is a collection of all values of the header. Each element is an array
394      * of values of a single header.
395      */
396     private class HeaderValuesCollection implements Collection<String[]> {
397 
398         @Override
399         public boolean add(String[] e) {
400             throw new UnsupportedOperationException();
401         }
402 
403         @Override
404         public boolean addAll(Collection<? extends String[]> c) {
405             throw new UnsupportedOperationException();
406         }
407 
408         @Override
409         public void clear() {
410             throw new UnsupportedOperationException();
411         }
412 
413         @Override
414         public boolean contains(Object o) {
415             return containsValue(o);
416         }
417 
418         @SuppressWarnings("unchecked")
419         @Override
420         public boolean containsAll(Collection<?> c) {
421             Collection<String[]> realCollection = (Collection<String[]>) c;
422             for (String[] value : realCollection) {
423                 if (!containsValue(value)) {
424                     return false;
425                 }
426             }
427             return true;
428         }
429 
430         @Override
431         public boolean isEmpty() {
432             return HeaderValuesMap.this.isEmpty();
433         }
434 
435         @Override
436         public Iterator<String[]> iterator() {
437             return new HeaderValuesCollectionIterator();
438         }
439 
440         @Override
441         public boolean remove(Object o) {
442             throw new UnsupportedOperationException();
443         }
444 
445         @Override
446         public boolean removeAll(Collection<?> c) {
447             throw new UnsupportedOperationException();
448         }
449 
450         @Override
451         public boolean retainAll(Collection<?> c) {
452             throw new UnsupportedOperationException();
453         }
454 
455         @Override
456         public int size() {
457             return HeaderValuesMap.this.size();
458         }
459 
460         @Override
461         public Object[] toArray() {
462             return toList().toArray();
463         }
464 
465         @Override
466         public <T> T[] toArray(T[] a) {
467             return toList().toArray(a);
468         }
469 
470         /**
471          * Turns this collection into a list.
472          *
473          * @return The list.
474          */
475         private List<String[]> toList() {
476             List<String[]> entries = new ArrayList<String[]>();
477             Enumeration<String> names = request.getKeys();
478             while (names.hasMoreElements()) {
479                 entries.add(enumeration2array(request.getValues(names.nextElement())));
480             }
481             return entries;
482         }
483 
484         /**
485          * Converts the content of a string enumeration to an array of strings.
486          *
487          * @param enumeration The enumeration to convert.
488          * @return The corresponding array.
489          */
490         private String[] enumeration2array(Enumeration<String> enumeration) {
491             List<String> list1 = new ArrayList<String>();
492             while (enumeration.hasMoreElements()) {
493                 list1.add(enumeration.nextElement());
494             }
495 
496             return list1.toArray(new String[list1.size()]);
497         }
498 
499         /**
500          * Iterates elements of {@link HeaderValuesCollection}.
501          */
502         private class HeaderValuesCollectionIterator implements Iterator<String[]> {
503 
504             /**
505              * The enumeration of the name of header attributes.
506              */
507             private Enumeration<String> namesEnumeration = request.getKeys();
508 
509             @Override
510             public boolean hasNext() {
511                 return namesEnumeration.hasMoreElements();
512             }
513 
514             @Override
515             public String[] next() {
516                 return enumeration2array(request.getValues(namesEnumeration.nextElement()));
517             }
518 
519             @Override
520             public void remove() {
521                 throw new UnsupportedOperationException();
522             }
523         }
524     }
525 }