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