1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.component;
20
21 import java.util.List;
22 import java.util.Map;
23
24 import javax.faces.component.UIComponent;
25 import javax.faces.context.FacesContext;
26 import javax.faces.event.FacesEvent;
27 import javax.faces.event.PhaseId;
28
29 import org.apache.myfaces.trinidad.event.DisclosureEvent;
30 import org.apache.myfaces.trinidad.event.FocusEvent;
31 import org.apache.myfaces.trinidad.event.RangeChangeEvent;
32 import org.apache.myfaces.trinidad.event.RowDisclosureEvent;
33 import org.apache.myfaces.trinidad.event.SelectionEvent;
34 import org.apache.myfaces.trinidad.event.SortEvent;
35 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
36 import org.apache.myfaces.trinidad.model.ModelUtils;
37 import org.apache.myfaces.trinidad.model.RowKeySet;
38 import org.apache.myfaces.trinidad.model.SortStrength;
39 import org.apache.myfaces.trinidad.model.TreeModel;
40
41
42
43
44 public final class TableUtils
45 {
46
47
48
49
50
51
52
53
54
55
56
57 public static int getLast(CollectionComponent table)
58 {
59 return getLast(table, table.getFirst());
60 }
61
62
63
64
65
66
67
68
69
70
71
72 public static int getLast(CollectionComponent table, int rangeStart)
73 {
74 final int rangeEnd;
75 int blockSize = table.getRows();
76
77 if (blockSize <= 0)
78 {
79 rangeEnd = Integer.MAX_VALUE;
80 }
81 else
82 {
83 rangeEnd = rangeStart + blockSize;
84 }
85 return ModelUtils.findLastIndex(table, rangeStart, rangeEnd) - 1;
86 }
87
88
89
90
91
92
93
94
95 @SuppressWarnings("unchecked")
96 public static Object setupELVariable(FacesContext context, String name, Object value)
97 {
98 Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
99 if (value == null)
100 return requestMap.remove(name);
101 else
102 return requestMap.put(name, value);
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116
117 static void __doSafeExpandAll(
118 TreeModel model,
119 RowKeySet state,
120 int maxSize)
121 {
122 int size = _getSizeOfTree(model, maxSize);
123 if ((size < 0) || (size > maxSize))
124 {
125
126
127 state.add();
128
129
130 model.enterContainer();
131 int i=0;
132 while(true)
133 {
134 model.setRowIndex(i++);
135 if (!model.isRowAvailable())
136 break;
137 state.add();
138 }
139 model.exitContainer();
140 }
141 else
142 state.addAll();
143 }
144
145
146
147
148
149
150
151
152
153
154
155 static int _getSizeOfTree(TreeModel model, int maxSize)
156 {
157 if (model.isRowAvailable() && model.isContainer())
158 {
159 model.enterContainer();
160 try
161 {
162 int size = model.getRowCount();
163 for(int i=0, sz=size; i<sz; i++)
164 {
165 if (size > maxSize)
166 return size;
167 model.setRowIndex(i);
168 int kidSize = _getSizeOfTree(model, maxSize - size);
169 if (kidSize < 0)
170 return -1;
171 size += kidSize;
172 }
173 return size;
174 }
175 finally
176 {
177 model.exitContainer();
178 }
179 }
180 return 0;
181 }
182
183
184
185
186
187
188
189
190 static void __handleQueueEvent(UIComponent comp, FacesEvent event)
191 {
192 if (_isImmediateEvent(comp, event))
193 {
194 String immediateAttr = UIXTree.IMMEDIATE_KEY.getName();
195 Object isImmediate = comp.getAttributes().get(immediateAttr);
196 if (Boolean.TRUE.equals(isImmediate))
197 {
198 event.setPhaseId(PhaseId.ANY_PHASE);
199 FacesContext context = FacesContext.getCurrentInstance();
200 context.renderResponse();
201 }
202 else
203 {
204
205
206
207
208
209
210 event.setPhaseId(PhaseId.INVOKE_APPLICATION);
211 }
212 }
213 }
214
215
216
217
218
219
220
221 @SuppressWarnings("unchecked")
222 public static void processFacets(
223 FacesContext context,
224 final UIXCollection table,
225 UIComponent component,
226 final PhaseId phaseId,
227 String skipFacet)
228 {
229 Map<String, UIComponent> facets = component.getFacets();
230 final UIComponent skip = (skipFacet != null)
231 ? (UIComponent) facets.get(skipFacet)
232 : null;
233
234 new ChildLoop()
235 {
236 @Override
237 protected void process(FacesContext context, UIComponent facet, ComponentProcessingContext cpContext)
238 {
239 if (facet != skip)
240 table.processComponent(context, facet, phaseId);
241 }
242 }.runAlways(context, facets.values());
243 }
244
245
246
247
248
249 public static void processColumnFacets(
250 FacesContext context,
251 final UIXCollection table,
252 UIComponent column,
253 final PhaseId phaseId)
254 {
255 new ChildLoop()
256 {
257 @Override
258 protected void process(FacesContext context, UIComponent child, ComponentProcessingContext cpContext)
259 {
260 if (child instanceof UIXColumn && child.isRendered())
261 {
262
263 processFacets(context, table, child, phaseId, null);
264
265 processColumnFacets(context, table, child, phaseId);
266 }
267 }
268 }.runAlways(context, column);
269 }
270
271
272
273
274 public static void processStampedChildren(
275 FacesContext context,
276 final UIXCollection table,
277 final PhaseId phaseId)
278 {
279 new ChildLoop()
280 {
281 @Override
282 protected void process(FacesContext context, UIComponent child, ComponentProcessingContext cpContext)
283 {
284
285
286 UIXComponent.clearCachedClientIds(child);
287 table.processComponent(context, child, phaseId);
288 }
289 }.runAlways(context, table);
290 }
291
292
293
294
295
296
297
298
299 public static SortStrength findSortStrength(UIXCollection parent, String sortProperty)
300 {
301 SortStrength sortStrength = null;
302
303 if (sortProperty == null || sortProperty.isEmpty())
304 return null;
305
306 List<UIComponent> children = parent.getChildren();
307 for (UIComponent child : children)
308 {
309 if (child instanceof UIXColumn)
310 {
311 UIXColumn targetColumn = (UIXColumn)child;
312 if (sortProperty.equals(targetColumn.getSortProperty()))
313 {
314 String strength = targetColumn.getSortStrength();
315 sortStrength = _toSortStrength(strength);
316 break;
317 }
318 }
319 }
320
321 return sortStrength;
322 }
323
324
325
326
327 private static SortStrength _toSortStrength(String strength)
328 {
329 SortStrength sortStrength = null;
330
331 if (strength != null && !strength.isEmpty())
332 {
333 try
334 {
335 sortStrength = SortStrength.valueOf(strength.toUpperCase());
336 }
337 catch (IllegalArgumentException iae)
338 {
339 _LOG.warning("INVALID_SORT_STRENGTH_PROPERTY", strength);
340 }
341 }
342
343 return sortStrength;
344 }
345
346
347
348
349 @SuppressWarnings("unchecked")
350 static void __processChildren(
351 FacesContext context,
352 final UIXCollection comp,
353 final PhaseId phaseId)
354 {
355
356
357 int childCount = comp.getChildCount();
358 if (childCount != 0)
359 {
360 List<UIComponent> children = comp.getChildren();
361
362 for (int i = 0; i < childCount; i++)
363 {
364 UIComponent child = children.get(i);
365 comp.processComponent(context, child, phaseId);
366 }
367 }
368 }
369
370 static void cacheHeaderFooterFacets(UIComponent parent, Map<UIComponent, Boolean> cache)
371 {
372
373 UIComponent headerFacet = parent.getFacets().get("header");
374 if (headerFacet != null)
375 {
376 _cacheDescendants(headerFacet, cache, true);
377 }
378
379
380 UIComponent footerFacet = parent.getFacets().get("footer");
381 if (footerFacet != null)
382 {
383 _cacheDescendants(footerFacet, cache, true);
384 }
385 }
386
387 static void cacheColumnHeaderFooterFacets(UIComponent parent, Map<UIComponent, Boolean> cache)
388 {
389 List<UIComponent> children = parent.getChildren();
390 for (UIComponent child : children)
391 {
392 if (child instanceof UIXColumn)
393 {
394 cacheHeaderFooterFacets(child, cache);
395 cacheColumnHeaderFooterFacets(child, cache);
396 }
397 }
398 }
399
400
401 private static void _cacheDescendants(UIComponent parent, Map<UIComponent, Boolean> cache, boolean inclusive)
402 {
403 if(inclusive)
404 cache.put(parent, Boolean.TRUE);
405
406 List<UIComponent> children = parent.getChildren();
407 for (UIComponent child : children)
408 {
409 _cacheDescendants(child, cache, true);
410 }
411 }
412
413
414
415
416
417 private static boolean _isImmediateEvent(UIComponent comp, FacesEvent event)
418 {
419 if (event.getComponent() == comp)
420 {
421 return
422 (event instanceof RangeChangeEvent) ||
423 (event instanceof DisclosureEvent) ||
424 (event instanceof RowDisclosureEvent) ||
425 (event instanceof SelectionEvent) ||
426 (event instanceof SortEvent) ||
427 (event instanceof FocusEvent);
428 }
429 return false;
430 }
431
432 private TableUtils()
433 {
434 }
435
436 private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(TableUtils.class);
437 }