1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.datalist;
20
21 import java.util.Iterator;
22 import java.util.Map;
23
24 import javax.el.ValueExpression;
25 import javax.faces.FacesException;
26 import javax.faces.component.ContextCallback;
27 import javax.faces.component.UIComponent;
28 import javax.faces.component.UINamingContainer;
29 import javax.faces.context.FacesContext;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.myfaces.component.UserRoleAware;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public abstract class AbstractHtmlDataList
51 extends org.apache.myfaces.component.html.ext.HtmlDataTableHack
52 implements UserRoleAware
53 {
54 public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlDataList";
55 private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.List";
56
57 private static Log log = LogFactory.getLog(AbstractHtmlDataList.class);
58 private static final int PROCESS_DECODES = 1;
59 private static final int PROCESS_VALIDATORS = 2;
60 private static final int PROCESS_UPDATES = 3;
61
62 private transient FacesContext _facesContext;
63
64
65
66
67
68
69 public void processDecodes(FacesContext context)
70 {
71
72 if (context == null)
73 throw new NullPointerException("context");
74 if (!isRendered())
75 return;
76
77 setRowIndex(-1);
78 processChildren(context, PROCESS_DECODES);
79 setRowIndex(-1);
80 try
81 {
82 decode(context);
83 }
84 catch (RuntimeException e)
85 {
86 context.renderResponse();
87 throw e;
88 }
89 }
90
91 public void processUpdates(FacesContext context)
92 {
93 if (context == null)
94 throw new NullPointerException("context");
95 if (!isRendered())
96 return;
97
98 setRowIndex(-1);
99 processChildren(context, PROCESS_UPDATES);
100 setRowIndex(-1);
101 checkUpdateModelError(context);
102 }
103
104 public void processValidators(FacesContext context)
105 {
106 if (context == null)
107 throw new NullPointerException("context");
108 if (!isRendered())
109 return;
110
111 setRowIndex(-1);
112 processChildren(context, PROCESS_VALIDATORS);
113 setRowIndex(-1);
114 checkUpdateModelError(context);
115 }
116
117
118
119
120
121
122 public void processChildren(FacesContext context, int processAction)
123 {
124
125 int first = getFirst();
126 int rows = getRows();
127 int last = rows == 0 ? getRowCount() : first + rows;
128
129 if (log.isTraceEnabled())
130 {
131 log.trace("processing " + getChildCount()
132 + " children: starting at " + first
133 + ", ending at " + last);
134 }
135
136 for (int rowIndex = first; last == -1 || rowIndex < last; rowIndex++)
137 {
138
139 setRowIndex(rowIndex);
140
141 if (!isRowAvailable())
142 {
143 if (log.isTraceEnabled())
144 {
145 log.trace("scrolled past the last row, aborting");
146 }
147 break;
148 }
149
150 for (Iterator it = getChildren().iterator(); it.hasNext();)
151 {
152 UIComponent child = (UIComponent) it.next();
153 if (child.isRendered())
154 process(context, child, processAction);
155 }
156 }
157 }
158
159
160
161
162
163 private void process(FacesContext context, UIComponent component,
164 int processAction)
165 {
166 switch (processAction)
167 {
168 case PROCESS_DECODES:
169 component.processDecodes(context);
170 break;
171 case PROCESS_VALIDATORS:
172 component.processValidators(context);
173 break;
174 case PROCESS_UPDATES:
175 component.processUpdates(context);
176 break;
177 }
178 }
179
180 public void setRowIndex(int rowIndex)
181 {
182 super.setRowIndex(rowIndex);
183 String rowIndexVar = getRowIndexVar();
184 String rowCountVar = getRowCountVar();
185 if (rowIndexVar != null || rowCountVar != null)
186 {
187 Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
188 if (rowIndex >= 0)
189 {
190
191 if (rowIndexVar != null)
192 {
193 requestMap.put(getRowIndexVar(), new Integer(rowIndex));
194 }
195 if (rowCountVar != null)
196 {
197 requestMap.put(getRowCountVar(), new Integer(getRowCount()));
198 }
199 }
200 else
201 {
202
203 if (rowIndexVar != null)
204 {
205 requestMap.remove(getRowIndexVar());
206 }
207 if (rowCountVar != null)
208 {
209 requestMap.remove(getRowCountVar());
210 }
211 }
212 }
213 }
214
215 @Override
216 protected void restoreDescendantComponentStates(Object state)
217 {
218 restoreDescendantComponentStates(getChildren().iterator(), state, true);
219 }
220
221 @Override
222 protected Object saveDescendantComponentStates()
223 {
224 return saveDescendantComponentStates(getChildren().iterator(), true);
225 }
226
227 @Override
228 public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
229 throws FacesException
230 {
231 if (context == null || clientId == null || callback == null)
232 {
233 throw new NullPointerException();
234 }
235
236 final String baseClientId = getClientId(context);
237
238
239 boolean returnValue = baseClientId.equals(clientId);
240
241 boolean isCachedFacesContext = isTemporalFacesContext();
242 if (!isCachedFacesContext)
243 {
244 setTemporalFacesContext(context);
245 }
246
247 try
248 {
249 if (returnValue)
250 {
251 try
252 {
253 callback.invokeContextCallback(context, this);
254 return true;
255 }
256 catch (Exception e)
257 {
258 throw new FacesException(e);
259 }
260 }
261
262
263 for (Iterator<UIComponent> it = this.getFacets().values().iterator(); !returnValue && it.hasNext();)
264 {
265 returnValue = it.next().invokeOnComponent(context, clientId, callback);
266 }
267
268 if (returnValue)
269 {
270 return returnValue;
271 }
272
273
274 if (clientId.startsWith(baseClientId))
275 {
276
277
278 char separator = UINamingContainer.SEPARATOR_CHAR;
279 ValueExpression rowKeyVE = getValueExpression("rowKey");
280 boolean rowKeyFound = false;
281
282 if (rowKeyVE != null)
283 {
284 int oldRow = this.getRowIndex();
285 try
286 {
287
288 int rowsToProcess = getRows();
289
290 if (rowsToProcess == 0)
291 {
292 rowsToProcess = getRowCount();
293 }
294 int rowIndex = getFirst();
295 for (int rowsProcessed = 0; rowsProcessed < rowsToProcess; rowsProcessed++, rowIndex++)
296 {
297 setRowIndex(rowIndex);
298 if (!isRowAvailable())
299 {
300 break;
301 }
302
303 if (clientId.startsWith(getContainerClientId(context)))
304 {
305 rowKeyFound = true;
306 break;
307 }
308 }
309
310 if (rowKeyFound)
311 {
312 for (Iterator<UIComponent> it1 = getChildren().iterator();
313 !returnValue && it1.hasNext();)
314 {
315
316 returnValue = it1.next().invokeOnComponent(context, clientId, callback);
317 }
318 }
319 }
320 finally
321 {
322 this.setRowIndex(oldRow);
323 }
324 }
325
326
327 if (rowKeyVE == null && clientId.matches(baseClientId + separator+"[0-9]+"+separator+".*"))
328 {
329 String subId = clientId.substring(baseClientId.length() + 1);
330 String clientRow = subId.substring(0, subId.indexOf(separator));
331
332
333 int oldRow = this.getRowIndex();
334
335
336 try
337 {
338
339
340 this.setRowIndex(Integer.parseInt(clientRow));
341
342
343 if (!isRowAvailable())
344 {
345 return false;
346 }
347
348 for (Iterator<UIComponent> it1 = getChildren().iterator();
349 !returnValue && it1.hasNext();)
350 {
351
352 returnValue = it1.next().invokeOnComponent(context, clientId, callback);
353 }
354 }
355 finally
356 {
357
358
359 this.setRowIndex(oldRow);
360 }
361 }
362 }
363 }
364 finally
365 {
366 if (!isCachedFacesContext)
367 {
368 setTemporalFacesContext(null);
369 }
370 }
371
372 return returnValue;
373 }
374
375 @Override
376 protected FacesContext getFacesContext()
377 {
378 if (_facesContext == null)
379 {
380 return super.getFacesContext();
381 }
382 else
383 {
384 return _facesContext;
385 }
386 }
387
388 private boolean isTemporalFacesContext()
389 {
390 return _facesContext != null;
391 }
392
393 private void setTemporalFacesContext(FacesContext facesContext)
394 {
395 _facesContext = facesContext;
396 }
397
398
399
400
401
402
403
404 public abstract String getRowCountVar();
405
406
407
408
409
410
411
412 public abstract String getRowIndexVar();
413
414
415
416
417
418
419
420
421
422
423
424
425 public abstract String getLayout();
426
427
428
429
430
431
432 public abstract String getItemStyleClass();
433
434
435
436
437
438
439 public abstract String getItemOnClick();
440 }