View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package javax.faces.component;
20  
21  import java.io.Serializable;
22  import java.util.AbstractCollection;
23  import java.util.AbstractSet;
24  import java.util.Collection;
25  import java.util.Iterator;
26  import java.util.Map;
27  import java.util.Set;
28  
29  /**
30   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
31   * @version $Revision: 1297575 $ $Date: 2012-03-06 11:59:07 -0500 (Tue, 06 Mar 2012) $
32   */
33  class _ComponentFacetMap<V extends UIComponent> implements Map<String, V>, Serializable
34  {
35      private static final long serialVersionUID = -3456937594422167629L;
36      private UIComponent _component;
37      private Map<String, V> _map = new _ArrayMap<String, V>(0,5);
38      private Set<Entry<String, V>> _entrySet = null;
39      private Set<String> _keySet = null;
40      private Collection<V> _valueCollection = null;
41  
42      _ComponentFacetMap(UIComponent component)
43      {
44          _component = component;
45      }
46  
47      public int size()
48      {
49          return _map.size();
50      }
51  
52      public void clear()
53      {
54          UIComponent[] values = _map.values().toArray(new UIComponent[_map.size()]);
55          //remove all elements from underlying map
56          _map.clear();
57          //Set parent to null
58          for (int i = 0; i < values.length; i++)
59          {
60              values[i].setParent(null);
61          }
62      }
63  
64      public boolean isEmpty()
65      {
66          return _map.isEmpty();
67      }
68  
69      public boolean containsKey(Object key)
70      {
71          checkKey(key);
72          return _map.containsKey(key);
73      }
74  
75      public boolean containsValue(Object value)
76      {
77          checkValue(value);
78          return _map.containsValue(value);
79      }
80  
81      public Collection<V> values()
82      {
83          if (_valueCollection == null)
84          {
85              _valueCollection= new ComponentFacetValueCollection();
86          }
87          return _valueCollection;
88      }
89  
90      public void putAll(Map<? extends String, ? extends V> t)
91      {
92          for (Map.Entry<? extends String, ? extends V> entry : t.entrySet())
93          {
94              put(entry.getKey(), entry.getValue());
95          }
96      }
97  
98      public Set<Entry<String, V>> entrySet()
99      {
100         if (_entrySet == null)
101         {
102             _entrySet = new ComponentFacetEntrySet();
103         }
104         return _entrySet;
105     }
106 
107     public Set<String> keySet()
108     {
109         if (_keySet == null)
110         {
111             _keySet = new ComponentFacetKeySet();
112         }
113         return _keySet;
114     }
115 
116     public V get(Object key)
117     {
118         checkKey(key);
119         return _map.get(key);
120     }
121 
122     public V remove(Object key)
123     {
124         checkKey(key);
125         V facet = _map.remove(key);
126         if (facet != null)
127         {
128             facet.setParent(null);
129         }
130         return facet;
131     }
132 
133     public V put(String key, V value)
134     {
135         //checkKey(key);
136         if (key == null)
137         {
138             throw new NullPointerException("key");
139         }
140         //checkValue(value);
141         if (value == null)
142         {
143             throw new NullPointerException("value");
144         }
145         setNewParent(key, value);
146         V previousValue = _map.put(key, value);
147         if (previousValue != null)
148         {
149             previousValue.setParent(null);
150         }
151         return previousValue; 
152     }
153 
154     private void setNewParent(String facetName, UIComponent facet)
155     {
156         UIComponent oldParent = facet.getParent();
157         if (oldParent != null)
158         {
159             if (!oldParent.getChildren().remove(facet))
160             {
161                 // Check if the component is inside a facet and remove from there
162                 if (oldParent.getFacetCount() > 0)
163                 {
164                     for (Iterator< Map.Entry<String, UIComponent > > it = 
165                         oldParent.getFacets().entrySet().iterator() ; it.hasNext() ; )
166                     {
167                         Map.Entry<String, UIComponent > entry = it.next();
168                         
169                         if (entry.getValue().equals(facet))
170                         {
171                             it.remove();
172                             break;
173                         }
174                     }
175                 }
176             }
177         }
178         facet.setParent(_component);
179     }
180 
181     private void checkKey(Object key)
182     {
183         if (key == null)
184         {
185             throw new NullPointerException("key");
186         }
187         if (!(key instanceof String))
188         {
189             throw new ClassCastException("key is not a String");
190         }
191     }
192 
193     private void checkValue(Object value)
194     {
195         if (value == null)
196         {
197             throw new NullPointerException("value");
198         }
199         if (!(value instanceof UIComponent))
200         {
201             throw new ClassCastException("value is not a UIComponent");
202         }
203     }
204 
205     private class ComponentFacetEntrySet extends AbstractSet<Entry<String, V>>
206     {
207         public ComponentFacetEntrySet()
208         {
209         }
210         
211         public int size()
212         {
213             return _map.size();
214         }
215 
216         public boolean isEmpty()
217         {
218             return _map.isEmpty();
219         }
220 
221         public boolean contains(Object o)
222         {
223             return _map.entrySet().contains(o);
224         }
225 
226         public Iterator<java.util.Map.Entry<String, V>> iterator()
227         {
228             return new ComponentFacetEntryIterator(_map.entrySet().iterator());
229         }
230 
231         public Object[] toArray()
232         {
233             return _map.entrySet().toArray();
234         }
235 
236         public <T> T[] toArray(T[] a)
237         {
238             return _map.entrySet().toArray(a);
239         }
240 
241         public boolean add(java.util.Map.Entry<String, V> o)
242         {
243             // Add over the entry set is not allowed, because this should be done
244             // through the outer Map instance.
245             throw new UnsupportedOperationException();
246         }
247 
248         @SuppressWarnings("unchecked")
249         public boolean remove(Object o)
250         {
251             if (_map.entrySet().remove(o))
252             {
253                 if (o instanceof Map.Entry)
254                 {
255                     Object value = ((Map.Entry<String, V>) o).getValue();
256                     
257                     if (value != null && value instanceof UIComponent)
258                     {
259                         ((UIComponent) value).setParent(null);
260                     }
261                 }
262                 return true;
263             }
264             else
265             {
266                 return false;
267             }
268         }
269 
270         public boolean containsAll(Collection<?> c)
271         {
272             return _map.entrySet().containsAll(c);
273         }
274 
275         public boolean addAll(
276                 Collection<? extends java.util.Map.Entry<String, V>> c)
277         {
278             // Add over the entry set is not allowed, because this should be done
279             // through the outer Map instance.
280             throw new UnsupportedOperationException();
281         }
282 
283         @Override
284         public boolean equals(Object obj)
285         {
286             return _map.entrySet().equals(obj);
287         }
288 
289         @Override
290         public int hashCode()
291         {
292             return _map.entrySet().hashCode();
293         }
294 
295         @Override
296         public String toString()
297         {
298             return _map.entrySet().toString();
299         }
300     }
301     
302     private class ComponentFacetEntryIterator implements Iterator<Map.Entry<String, V>>
303     {
304         private Iterator<Map.Entry<String, V>> _delegate;
305         private V _currentEntryValue;
306         
307         public ComponentFacetEntryIterator(Iterator<Map.Entry<String, V>> it)
308         {
309             _delegate = it;
310             _currentEntryValue = null;
311         }
312         
313         public boolean hasNext()
314         {
315             return _delegate.hasNext();
316         }
317 
318         public java.util.Map.Entry<String, V> next()
319         {
320             java.util.Map.Entry<String, V> next = _delegate.next(); 
321             _currentEntryValue = next.getValue();
322             return new ComponentFacetEntry(next);
323         }
324 
325         public void remove()
326         {
327             _delegate.remove();
328             if (_currentEntryValue != null)
329             {
330                 _currentEntryValue.setParent(null);
331             }
332         }
333     }
334 
335     /**
336      * Wrapper used to override setValue() method
337      * 
338      */
339     private class ComponentFacetEntry implements Map.Entry<String, V>
340     {
341         private java.util.Map.Entry<String, V> _entry;
342         
343         public ComponentFacetEntry(java.util.Map.Entry<String, V> entry)
344         {
345             _entry = entry;
346         }
347 
348         public String getKey()
349         {
350             return _entry.getKey();
351         }
352 
353         public V getValue()
354         {
355             return _entry.getValue();
356         }
357 
358         public V setValue(V value)
359         {
360             setNewParent(_entry.getKey(), value);
361             V previousValue = _entry.setValue(value);
362             if (previousValue != null)
363             {
364                 previousValue.setParent(null);
365             }
366             return previousValue;
367         }
368 
369         @Override
370         public int hashCode()
371         {
372             return _entry.hashCode();
373         }
374 
375         @Override
376         public boolean equals(Object obj)
377         {
378             return _entry.equals(obj);
379         }
380 
381         @Override
382         public String toString()
383         {
384             return _entry.toString();
385         }
386     }
387     
388     private class ComponentFacetKeySet extends AbstractSet<String>
389     {
390 
391         public ComponentFacetKeySet()
392         {
393         }
394         
395         public int size()
396         {
397             return _map.keySet().size();
398         }
399 
400         public boolean isEmpty()
401         {
402             return _map.keySet().isEmpty();
403         }
404 
405         public boolean contains(Object o)
406         {
407             return _map.keySet().contains(o);
408         }
409 
410         public Iterator<String> iterator()
411         {
412             // Iterate over entrySet is equals to iterate over keySet, but
413             // in this case is better use entrySet iterator, because we can
414             // get the value directly and call setParent(null) if the entry is
415             // removed
416             return new ComponentFacetKeyIterator(_map.entrySet().iterator());
417         }
418 
419         public Object[] toArray()
420         {
421             return _map.keySet().toArray();
422         }
423 
424         public <T> T[] toArray(T[] a)
425         {
426             return _map.keySet().toArray(a);
427         }
428 
429         public boolean add(String o)
430         {
431             throw new UnsupportedOperationException();
432         }
433 
434         public boolean remove(Object o)
435         {
436             V previousValue = _map.get(o);
437             if (_map.keySet().remove(o))
438             {
439                 if (previousValue != null)
440                 {
441                     ((UIComponent) previousValue).setParent(null);
442                 }
443                 return true;
444             }
445             else
446             {
447                 return false;
448             }
449         }
450 
451         public boolean containsAll(Collection<?> c)
452         {
453             return _map.keySet().containsAll(c);
454         }
455 
456         public boolean addAll(Collection<? extends String> c)
457         {
458             throw new UnsupportedOperationException();
459         }
460 
461         @Override
462         public boolean equals(Object obj)
463         {
464             return _map.keySet().equals(obj);
465         }
466 
467         @Override
468         public int hashCode()
469         {
470             return _map.keySet().hashCode();
471         }
472 
473         @Override
474         public String toString()
475         {
476             return _map.keySet().toString();
477         }
478     }
479     
480     private class ComponentFacetKeyIterator implements Iterator<String>
481     {
482         private Iterator<Map.Entry<String, V>> _delegate;
483         private V _currentEntryValue;
484         
485         public ComponentFacetKeyIterator(Iterator<Map.Entry<String, V>> it)
486         {
487             _delegate = it;
488             _currentEntryValue = null;
489         }
490         
491         public boolean hasNext()
492         {
493             return _delegate.hasNext();
494         }
495 
496         public String next()
497         {
498             java.util.Map.Entry<String, V> next = _delegate.next(); 
499             _currentEntryValue = next.getValue();
500             return next.getKey();
501         }
502 
503         public void remove()
504         {
505             _delegate.remove();
506             if (_currentEntryValue != null)
507             {
508                 _currentEntryValue.setParent(null);
509             }
510         }
511     }
512 
513     private class ComponentFacetValueCollection extends AbstractCollection<V>
514     {
515         public ComponentFacetValueCollection()
516         {
517         }
518 
519         public int size()
520         {
521             return _map.values().size();
522         }
523 
524         public boolean isEmpty()
525         {
526             return _map.values().isEmpty();
527         }
528 
529         public boolean contains(Object o)
530         {
531             return _map.values().contains(o);
532         }
533 
534         public Iterator<V> iterator()
535         {
536             return new ComponentFacetValueIterator(_map.entrySet().iterator());
537         }
538 
539         public Object[] toArray()
540         {
541             return _map.values().toArray();
542         }
543 
544         public <T> T[] toArray(T[] a)
545         {
546             return _map.values().toArray(a);
547         }
548 
549         public boolean add(V o)
550         {
551             // Add over the entry set is not allowed, because this should be done
552             // through the outer Map instance.
553             throw new UnsupportedOperationException();
554         }
555 
556         public boolean containsAll(Collection<?> c)
557         {
558             return _map.values().containsAll(c);
559         }
560 
561         public boolean addAll(Collection<? extends V> c)
562         {
563             // Add over the entry set is not allowed, because this should be done
564             // through the outer Map instance.
565             throw new UnsupportedOperationException();
566         }
567 
568         @Override
569         public boolean equals(Object obj)
570         {
571             return _map.values().equals(obj);
572         }
573 
574         @Override
575         public int hashCode()
576         {
577             return _map.values().hashCode();
578         }
579 
580         @Override
581         public String toString()
582         {
583             return _map.values().toString();
584         }
585     }
586     
587     private class ComponentFacetValueIterator implements Iterator<V>
588     {
589         private Iterator<Map.Entry<String, V>> _delegate;
590         private V _currentEntryValue;
591         
592         public ComponentFacetValueIterator(Iterator<Map.Entry<String, V>> it)
593         {
594             _delegate = it;
595             _currentEntryValue = null;
596         }
597         
598         public boolean hasNext()
599         {
600             return _delegate.hasNext();
601         }
602 
603         public V next()
604         {
605             java.util.Map.Entry<String, V> next = _delegate.next(); 
606             _currentEntryValue = next.getValue();
607             return next.getValue();
608         }
609 
610         public void remove()
611         {
612             _delegate.remove();
613             if (_currentEntryValue != null)
614             {
615                 _currentEntryValue.setParent(null);
616             }
617         }
618     }
619 }