1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.myfaces.trinidad.component;
23
24 import java.io.IOException;
25 import java.util.Iterator;
26 import java.util.Map;
27 import javax.el.MethodExpression;
28 import javax.faces.component.UIComponent;
29 import javax.faces.component.visit.VisitCallback;
30 import javax.faces.component.visit.VisitContext;
31 import javax.faces.component.visit.VisitHint;
32 import javax.faces.context.FacesContext;
33 import javax.faces.event.AbortProcessingException;
34 import javax.faces.event.FacesEvent;
35 import javax.faces.event.PhaseId;
36 import org.apache.myfaces.trinidad.bean.FacesBean;
37 import org.apache.myfaces.trinidad.bean.PropertyKey;
38 import org.apache.myfaces.trinidad.event.RowDisclosureListener;
39 import org.apache.myfaces.trinidad.model.CollectionModel;
40 import org.apache.myfaces.trinidad.model.RowKeySet;
41 import org.apache.myfaces.trinidad.model.RowKeySetTreeImpl;
42 import org.apache.myfaces.trinidad.model.TreeModel;
43 import org.apache.myfaces.trinidad.util.ComponentUtils;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class UIXPage extends UIXNavigationHierarchy
72 {
73 static public final FacesBean.Type TYPE = new FacesBean.Type(
74 UIXNavigationHierarchy.TYPE);
75 static public final PropertyKey ROW_DISCLOSURE_LISTENER_KEY =
76 TYPE.registerKey("rowDisclosureListener", MethodExpression.class);
77 static public final PropertyKey DISCLOSED_ROW_KEYS_KEY =
78 TYPE.registerKey("disclosedRowKeys", RowKeySet.class, null, 0, PropertyKey.Mutable.OFTEN);
79 static public final PropertyKey VALUE_KEY =
80 TYPE.registerKey("value", Object.class, null, 0, PropertyKey.Mutable.SOMETIMES);
81 static public final PropertyKey VAR_STATUS_KEY =
82 TYPE.registerKey("varStatus", String.class, PropertyKey.CAP_NOT_BOUND);
83 static public final PropertyKey IMMEDIATE_KEY =
84 TYPE.registerKey("immediate", Boolean.class, Boolean.FALSE);
85 static public final String NODE_STAMP_FACET = "nodeStamp";
86
87 static public final String COMPONENT_FAMILY =
88 "org.apache.myfaces.trinidad.Page";
89 static public final String COMPONENT_TYPE =
90 "org.apache.myfaces.trinidad.Page";
91
92
93
94
95 public UIXPage()
96 {
97 super("org.apache.myfaces.trinidad.BasePage");
98 }
99
100
101
102
103 @Override
104 public void queueEvent(FacesEvent event)
105 {
106 TableUtils.__handleQueueEvent(this, event);
107 super.queueEvent(event);
108 }
109
110
111
112
113
114
115 @Override
116 public void broadcast(FacesEvent event) throws AbortProcessingException
117 {
118 HierarchyUtils.__handleBroadcast(this,
119 event,
120 getDisclosedRowKeys(),
121 getRowDisclosureListener());
122 super.broadcast(event);
123 }
124
125 @Override
126 public CollectionModel createCollectionModel(CollectionModel current, Object value)
127 {
128 TreeModel model = (TreeModel)super.createCollectionModel(current, value);
129 RowKeySet treeState = getDisclosedRowKeys();
130 treeState.setCollectionModel(model);
131 return model;
132 }
133
134 @Override
135 @SuppressWarnings("unchecked")
136 protected void processFacetsAndChildren(
137 FacesContext context,
138 PhaseId phaseId)
139 {
140 Object oldPath = getRowKey();
141 setRowKey(null);
142
143 HierarchyUtils.__iterateOverTree(context,
144 phaseId,
145 this,
146 getDisclosedRowKeys(),
147 false);
148
149 setRowKey(oldPath);
150
151
152 TableUtils.__processChildren(context, this, phaseId);
153
154 Map<String, UIComponent> facets = getFacets();
155 Iterator<String> facetKeys = facets.keySet().iterator();
156
157 while(facetKeys.hasNext())
158 {
159 String facetKey = facetKeys.next();
160 if (!"nodeStamp".equals(facetKey))
161 {
162 processComponent(context, facets.get(facetKey), phaseId);
163 }
164 }
165 }
166
167 @Override
168 protected boolean visitChildren(
169 VisitContext visitContext,
170 VisitCallback callback)
171 {
172 if (ComponentUtils.isSkipIterationVisit(visitContext))
173 {
174 return visitChildrenWithoutIterating(visitContext, callback);
175 }
176 else
177 {
178 return _visitChildrenIterating(visitContext, callback);
179 }
180 }
181
182 private boolean _visitChildrenIterating(
183 VisitContext visitContext,
184 VisitCallback callback)
185 {
186 boolean done = visitData(visitContext, callback);
187
188 if (!done)
189 {
190
191 int childCount = getChildCount();
192 if (childCount > 0)
193 {
194 for (UIComponent child : getChildren())
195 {
196 done = UIXComponent.visitTree(visitContext, child, callback);
197
198 if (done)
199 break;
200 }
201 }
202
203
204 if (!done)
205 {
206
207 int facetCount = getFacetCount();
208
209 if (facetCount > 0)
210 {
211 UIComponent nodeStamp = getNodeStamp();
212
213
214 if ((facetCount > 1) || (nodeStamp == null))
215 {
216 for (UIComponent facet : getFacets().values())
217 {
218
219 if (facet != nodeStamp)
220 {
221 if (UIXComponent.visitTree(visitContext, facet, callback))
222 {
223 done = true;
224 break;
225 }
226 }
227 }
228 }
229 }
230 }
231 }
232
233 return done;
234 }
235
236 @Override
237 protected boolean visitData(
238 VisitContext visitContext,
239 VisitCallback callback)
240 {
241 Object oldPath = getRowKey();
242
243
244
245 RowKeySet disclosedRowKeys = (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED))
246 ? getDisclosedRowKeys()
247 : null;
248
249 setRowKey(null);
250
251 boolean done;
252
253 try
254 {
255 done = visitHierarchy(visitContext, callback, getStamps(), disclosedRowKeys);
256 }
257 finally
258 {
259 setRowKey(oldPath);
260 }
261
262 return done;
263 }
264
265 @Override
266 void __encodeBegin(FacesContext context) throws IOException
267 {
268 HierarchyUtils.__handleEncodeBegin(this, getDisclosedRowKeys());
269 super.__encodeBegin(context);
270 }
271
272 @Override
273 void __init()
274 {
275 super.__init();
276 if (getDisclosedRowKeys() == null)
277 setDisclosedRowKeys(new RowKeySetTreeImpl());
278 }
279
280 @Override
281 protected FacesBean createFacesBean(String rendererType)
282 {
283 return new RowKeyFacesBeanWrapper(super.createFacesBean(rendererType));
284 }
285
286 private class RowKeyFacesBeanWrapper
287 extends FacesBeanWrapper
288 {
289 private boolean _retrievingDisclosedRows = false;
290
291 RowKeyFacesBeanWrapper(FacesBean bean)
292 {
293 super(bean);
294 }
295
296 @Override
297 public Object getProperty(PropertyKey key)
298 {
299 Object value = super.getProperty(key);
300
301 if (key == DISCLOSED_ROW_KEYS_KEY && !_retrievingDisclosedRows && value instanceof RowKeySet)
302 {
303
304
305 _retrievingDisclosedRows = true;
306
307 try
308 {
309 RowKeySet rowKeys = (RowKeySet) value;
310
311
312 __flushCachedModel();
313 rowKeys.setCollectionModel(getCollectionModel());
314 }
315 finally
316 {
317 _retrievingDisclosedRows = false;
318 }
319 }
320
321 return value;
322 }
323
324 @Override
325 public Object saveState(FacesContext context)
326 {
327 RowKeySet rowKeys = (RowKeySet)super.getProperty(DISCLOSED_ROW_KEYS_KEY);
328 if (rowKeys != null)
329 {
330
331 rowKeys.setCollectionModel(null);
332 }
333 return super.saveState(context);
334 }
335 }
336
337
338
339
340
341 final public UIComponent getNodeStamp()
342 {
343 return getFacet(NODE_STAMP_FACET);
344 }
345
346
347
348
349
350 @SuppressWarnings("unchecked")
351 final public void setNodeStamp(UIComponent nodeStampFacet)
352 {
353 getFacets().put(NODE_STAMP_FACET, nodeStampFacet);
354 }
355
356
357
358
359
360
361 final public MethodExpression getRowDisclosureListener()
362 {
363 return (MethodExpression)getProperty(ROW_DISCLOSURE_LISTENER_KEY);
364 }
365
366
367
368
369
370
371 final public void setRowDisclosureListener(MethodExpression rowDisclosureListener)
372 {
373 setProperty(ROW_DISCLOSURE_LISTENER_KEY, (rowDisclosureListener));
374 }
375
376
377
378
379
380
381
382 final public RowKeySet getDisclosedRowKeys()
383 {
384 return (RowKeySet)getProperty(DISCLOSED_ROW_KEYS_KEY);
385 }
386
387
388
389
390
391
392
393 final public void setDisclosedRowKeys(RowKeySet disclosedRowKeys)
394 {
395 setProperty(DISCLOSED_ROW_KEYS_KEY, (disclosedRowKeys));
396 }
397
398
399
400
401
402
403
404 final public Object getValue()
405 {
406 return getProperty(VALUE_KEY);
407 }
408
409
410
411
412
413
414
415 final public void setValue(Object value)
416 {
417 setProperty(VALUE_KEY, (value));
418 }
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433 final public String getVarStatus()
434 {
435 return ComponentUtils.resolveString(getProperty(VAR_STATUS_KEY));
436 }
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451 final public void setVarStatus(String varStatus)
452 {
453 setProperty(VAR_STATUS_KEY, (varStatus));
454 }
455
456
457
458
459
460
461
462
463
464
465
466
467
468 final public boolean isImmediate()
469 {
470 return ComponentUtils.resolveBoolean(getProperty(IMMEDIATE_KEY), false);
471 }
472
473
474
475
476
477
478
479
480
481
482
483
484
485 final public void setImmediate(boolean immediate)
486 {
487 setProperty(IMMEDIATE_KEY, immediate ? Boolean.TRUE : Boolean.FALSE);
488 }
489
490
491
492
493
494
495 final public void addRowDisclosureListener(
496 RowDisclosureListener listener)
497 {
498 addFacesListener(listener);
499 }
500
501
502
503
504
505
506 final public void removeRowDisclosureListener(
507 RowDisclosureListener listener)
508 {
509 removeFacesListener(listener);
510 }
511
512
513
514
515
516
517 final public RowDisclosureListener[] getRowDisclosureListeners()
518 {
519 return (RowDisclosureListener[])getFacesListeners(RowDisclosureListener.class);
520 }
521
522 @Override
523 public String getFamily()
524 {
525 return COMPONENT_FAMILY;
526 }
527
528 @Override
529 protected FacesBean.Type getBeanType()
530 {
531 return TYPE;
532 }
533
534
535
536
537 protected UIXPage(
538 String rendererType
539 )
540 {
541 super(rendererType);
542 }
543
544 static
545 {
546 TYPE.lockAndRegister("org.apache.myfaces.trinidad.Page","org.apache.myfaces.trinidad.BasePage");
547 }
548 }