1
2
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
24
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
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;
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
198
199
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 }