View Javadoc

1   /*
2    * $Id: CachedChildrenList.java,v 1.18 2011/06/16 09:29:41 jbmeslin Exp $
3    * 
4    */
5   package org.rcfaces.core.internal.util;
6   
7   import java.lang.reflect.Array;
8   import java.util.ArrayList;
9   import java.util.Collections;
10  import java.util.HashMap;
11  import java.util.Iterator;
12  import java.util.List;
13  import java.util.Map;
14  import java.util.NoSuchElementException;
15  
16  import javax.faces.component.UIComponent;
17  
18  import org.rcfaces.core.internal.AbstractReleasable;
19  import org.rcfaces.core.internal.manager.IContainerManager;
20  import org.rcfaces.core.internal.manager.ITransientAttributesManager;
21  
22  /**
23   * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
24   * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:41 $
25   */
26  public final class CachedChildrenList extends AbstractReleasable {
27      private static final String REVISION = "$Revision: 1.18 $";
28  
29      private static final UIComponent[] UI_COMPONENT_EMPTY_ARRAY = new UIComponent[0];
30  
31      private static final Iterator EMPTY_ITERATOR = new Iterator() {
32          private static final String REVISION = "$Revision: 1.18 $";
33  
34          public boolean hasNext() {
35              return false;
36          }
37  
38          public Object next() {
39              throw new NoSuchElementException("Empty iterator");
40          }
41  
42          public void remove() {
43          }
44      };
45  
46      // private static final Object LOCK = new Object();
47  
48      private static final Map emptyArrays = new HashMap(32);
49  
50      private Class elementClass;
51  
52      private int containerStateId;
53  
54      private UIComponent componentsArray[];
55  
56      private List components;
57  
58      private void set(IContainerManager container, Class elementClass) {
59          this.elementClass = elementClass;
60          containerStateId = -1; // getContainerStateId(container);
61      }
62  
63      private int getContainerStateId(IContainerManager container) {
64          return container.getChildrenListState();
65      }
66  
67      private void verifyList(IContainerManager container) {
68          int currentContainerStateId = getContainerStateId(container);
69  
70          if (components != null && currentContainerStateId == containerStateId) {
71              return;
72          }
73  
74          if (components == null) {
75              components = new ArrayList(container.getChildCount());
76  
77          } else {
78              components.clear();
79          }
80  
81          componentsArray = null;
82  
83          for (Iterator it = container.getChildren().iterator(); it.hasNext();) {
84              Object obj = it.next();
85  
86              if (obj == null || elementClass.isInstance(obj) == false) {
87                  continue;
88              }
89  
90              components.add(obj);
91          }
92  
93          if (components instanceof ArrayList) {
94              ((ArrayList) components).trimToSize();
95          }
96  
97          containerStateId = currentContainerStateId;
98      }
99  
100     private UIComponent[] getArray(IContainerManager container) {
101         verifyList(container);
102 
103         if (componentsArray != null) {
104             return componentsArray;
105         }
106 
107         componentsArray = getEmptyArray(elementClass);
108 
109         if (components.size() > 0) {
110             componentsArray = (UIComponent[]) components
111                     .toArray(componentsArray);
112         }
113 
114         return componentsArray;
115     }
116 
117     private int getCount(IContainerManager container) {
118         verifyList(container);
119 
120         return components.size();
121     }
122 
123     private Iterator getIterator(IContainerManager container) {
124         if (getCount(container) == 0) {
125             return EMPTY_ITERATOR;
126         }
127 
128         return components.iterator();
129     }
130 
131     private List getList(IContainerManager container) {
132         if (getCount(container) == 0) {
133             return Collections.EMPTY_LIST;
134         }
135 
136         return components;
137     }
138 
139     public static UIComponent[] getArray(IContainerManager elementContainer,
140             Class elementClass) {
141         CachedChildrenList cachedChildrenList = getCachedChildrenList(
142                 elementContainer, elementClass);
143 
144         return cachedChildrenList.getArray(elementContainer);
145     }
146 
147     public static List getList(IContainerManager elementContainer,
148             Class elementClass) {
149         CachedChildrenList cachedChildrenList = getCachedChildrenList(
150                 elementContainer, elementClass);
151 
152         return cachedChildrenList.getList(elementContainer);
153     }
154 
155     public static Iterator getIterator(IContainerManager elementContainer,
156             Class elementClass) {
157         CachedChildrenList cachedChildrenList = getCachedChildrenList(
158                 elementContainer, elementClass);
159 
160         return cachedChildrenList.getIterator(elementContainer);
161     }
162 
163     public static int getCount(IContainerManager elementContainer,
164             Class elementClass) {
165         CachedChildrenList cachedChildrenList = getCachedChildrenList(
166                 elementContainer, elementClass);
167 
168         return cachedChildrenList.getCount(elementContainer);
169     }
170 
171     private static CachedChildrenList getCachedChildrenList(
172             IContainerManager elementContainer, Class elementClass) {
173         ITransientAttributesManager transientAttributes = (ITransientAttributesManager) elementContainer;
174 
175         String key = elementClass.getName();
176 
177         CachedChildrenList cachedChildrenList = (CachedChildrenList) transientAttributes
178                 .getTransientAttribute(key);
179         if (cachedChildrenList != null) {
180             return cachedChildrenList;
181         }
182 
183         cachedChildrenList = allocateCachedChildrenList();
184 
185         cachedChildrenList.set(elementContainer, elementClass);
186 
187         transientAttributes.setTransientAttribute(key, cachedChildrenList);
188 
189         return cachedChildrenList;
190     }
191 
192     private static CachedChildrenList allocateCachedChildrenList() {
193         return new CachedChildrenList();
194     }
195 
196     /*
197      * (non-Javadoc)
198      * 
199      * @see com.vedana.adonis.Releasable#release()
200      */
201     public void release() {
202         elementClass = null;
203         if (components != null) {
204             components.clear();
205         }
206         componentsArray = null;
207         containerStateId = -1;
208 
209         super.release();
210     }
211 
212     public static UIComponent[] getEmptyArray(Class clz) {
213         synchronized (emptyArrays) {
214             UIComponent array[] = (UIComponent[]) emptyArrays.get(clz);
215             if (array != null) {
216                 return array;
217             }
218 
219             array = (UIComponent[]) Array.newInstance(clz, 0);
220 
221             emptyArrays.put(clz, array);
222 
223             return array;
224         }
225     }
226 }