1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.component;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.EnumSet;
26 import java.util.List;
27
28 import javax.faces.application.StateManager;
29 import javax.faces.component.html.HtmlPanelGroup;
30 import javax.faces.component.visit.VisitCallback;
31 import javax.faces.component.visit.VisitContext;
32 import javax.faces.component.visit.VisitHint;
33 import javax.faces.component.visit.VisitResult;
34 import javax.faces.context.FacesContext;
35 import javax.faces.event.AbortProcessingException;
36 import javax.faces.event.FacesEvent;
37 import javax.faces.event.PhaseId;
38 import javax.faces.render.Renderer;
39
40 import org.apache.myfaces.Assert;
41 import org.apache.myfaces.TestRunner;
42 import org.apache.myfaces.mock.MockRenderedValueExpression;
43 import org.apache.myfaces.test.base.AbstractJsfTestCase;
44 import org.apache.myfaces.test.mock.visit.MockVisitContext;
45 import org.easymock.classextension.EasyMock;
46 import org.easymock.classextension.IMocksControl;
47
48
49
50
51
52 public class UIDataTest extends AbstractJsfTestCase
53 {
54
55 public UIDataTest(String name)
56 {
57 super(name);
58 }
59
60 private IMocksControl _mocksControl;
61 private UIData _testImpl;
62
63 @Override
64 protected void setUp() throws Exception
65 {
66 super.setUp();
67 _mocksControl = EasyMock.createControl();
68 _testImpl = new UIData();
69 }
70
71
72
73
74
75 public void testValueExpression()
76 {
77 assertSetValueExpressionException(IllegalArgumentException.class, "rowIndex");
78 assertSetValueExpressionException(NullPointerException.class, null);
79 }
80
81 private void assertSetValueExpressionException(Class<? extends Throwable> expected, final String name)
82 {
83 Assert.assertException(expected, new TestRunner()
84 {
85 public void run() throws Throwable
86 {
87 _testImpl.setValueExpression(name, null);
88 }
89 });
90 }
91
92
93
94
95 public void testGetClientId()
96 {
97 _testImpl.setId("xxx");
98 Renderer renderer = _mocksControl.createMock(Renderer.class);
99 renderKit.addRenderer(UIData.COMPONENT_FAMILY, UIData.COMPONENT_TYPE, renderer);
100 assertEquals("xxx", _testImpl.getClientId(facesContext));
101 _testImpl.setRowIndex(99);
102
103 assertEquals("xxx", _testImpl.getClientId(facesContext));
104 assertEquals("xxx:99", _testImpl.getContainerClientId(facesContext));
105 }
106
107
108
109
110
111
112
113 public void testInvokeOnComponentFacesContextStringContextCallback()
114 {
115
116
117
118
119 final class MyContextCallback implements ContextCallback
120 {
121
122 private boolean invoked = false;
123
124 public void invokeContextCallback(FacesContext context,
125 UIComponent target)
126 {
127 this.invoked = true;
128 }
129
130 }
131
132 UIComponent facet = new UIOutput();
133 facet.setId("facet");
134 UIColumn column = new UIColumn();
135 column.setId("column");
136 column.getFacets().put("header", facet);
137 _testImpl.setId("uidata");
138 _testImpl.getChildren().add(column);
139
140 MyContextCallback callback = new MyContextCallback();
141 _testImpl.invokeOnComponent(facesContext, facet.getClientId(facesContext), callback);
142
143 assertTrue(callback.invoked);
144 }
145
146
147
148
149 public void testBroadcastFacesEvent()
150 {
151
152 final FacesEvent originalEvent = _mocksControl.createMock(FacesEvent.class);
153
154
155 UIComponent eventComponent = new UICommand()
156 {
157
158 @Override
159 public void broadcast(FacesEvent event)
160 throws AbortProcessingException
161 {
162
163 assertEquals(originalEvent, event);
164
165
166 assertEquals(5, _testImpl.getRowIndex());
167
168
169 assertEquals(this, UIComponent.getCurrentComponent(facesContext));
170
171
172 getAttributes().put("broadcastCalled", Boolean.TRUE);
173 }
174
175 };
176
177
178 EasyMock.expect(originalEvent.getComponent()).andReturn(eventComponent).anyTimes();
179
180 EasyMock.expect(originalEvent.getPhaseId()).andReturn(PhaseId.INVOKE_APPLICATION).anyTimes();
181 _mocksControl.replay();
182
183
184 facesContext.setCurrentPhaseId(PhaseId.INVOKE_APPLICATION);
185
186 _testImpl.setRowIndex(5);
187
188 facesContext.getViewRoot().getChildren().add(_testImpl);
189
190 _testImpl.queueEvent(originalEvent);
191
192 _testImpl.setRowIndex(0);
193
194 facesContext.getViewRoot().broadcastEvents(facesContext, PhaseId.INVOKE_APPLICATION);
195
196
197
198
199 assertNull(UIComponent.getCurrentComponent(facesContext));
200
201
202 assertEquals(0, _testImpl.getRowIndex());
203
204
205 _mocksControl.verify();
206
207
208 assertEquals(Boolean.TRUE, eventComponent.getAttributes().get("broadcastCalled"));
209 }
210
211
212
213
214 public void testEncodeBeginFacesContext()
215 {
216
217 }
218
219
220
221
222 public void testEncodeEndFacesContext()
223 {
224
225 }
226
227
228
229
230 public void testQueueEventFacesEvent()
231 {
232
233 }
234
235
236
237
238 public void testProcessDecodesFacesContext()
239 {
240
241 }
242
243
244
245
246 public void testProcessValidatorsFacesContext()
247 {
248
249 }
250
251
252
253
254 public void testProcessUpdatesFacesContext()
255 {
256
257 }
258
259
260
261
262 public void testSaveState()
263 {
264
265 }
266
267
268
269
270
271 public void testRestoreState()
272 {
273
274 }
275
276
277
278
279 public void testUIData()
280 {
281
282 }
283
284
285
286
287 public void testSetFooter()
288 {
289
290 }
291
292
293
294
295 public void testGetFooter()
296 {
297
298 }
299
300
301
302
303 public void testSetHeader()
304 {
305
306 }
307
308
309
310
311 public void testGetHeader()
312 {
313
314 }
315
316
317
318
319 public void testIsRowAvailable()
320 {
321
322 }
323
324
325
326
327 public void testGetRowCount()
328 {
329
330 }
331
332
333
334
335 public void testGetRowData()
336 {
337
338 }
339
340
341
342
343 public void testGetRowIndex()
344 {
345
346 }
347
348
349
350
351 public void testSetRowIndex()
352 {
353
354 }
355
356
357
358
359 public void testGetDataModel()
360 {
361
362 }
363
364
365
366
367 public void testSetDataModel()
368 {
369
370 }
371
372
373
374
375 public void testSetValue()
376 {
377
378 }
379
380
381
382
383 public void testSetRows()
384 {
385
386 }
387
388
389
390
391 public void testSetFirst()
392 {
393
394 }
395
396
397
398
399 public void testGetValue()
400 {
401
402 }
403
404
405
406
407 public void testGetVar()
408 {
409
410 }
411
412
413
414
415 public void testSetVar()
416 {
417
418 }
419
420
421
422
423 public void testGetRows()
424 {
425
426 }
427
428
429
430
431 public void testGetFirst()
432 {
433
434 }
435
436
437
438
439 public void testGetFamily()
440 {
441
442 }
443
444
445
446
447
448 public void testVisitTree() {
449 UIData uidata = new UIData();
450
451 Collection<String> value = new ArrayList<String>();
452 value.add("value#1");
453 value.add("value#2");
454 uidata.setValue(value);
455
456 UIComponent headerFacet = new HtmlPanelGroup();
457 headerFacet.setId("headerFacet");
458 uidata.setHeader(headerFacet);
459
460 UIComponent footerFacet = new HtmlPanelGroup();
461 footerFacet.setId("footerFacet");
462 uidata.setFooter(footerFacet);
463
464 UIComponent child1 = new UIColumn();
465
466 UIComponent facetOfChild1 = new HtmlPanelGroup();
467 child1.getFacets().put("someFacet", facetOfChild1);
468
469 UIOutput childOfChild1 = new UIOutput();
470 childOfChild1.setId("childOfColumn");
471 child1.getChildren().add(childOfChild1);
472 uidata.getChildren().add(child1);
473
474 UIComponent child2 = new HtmlPanelGroup();
475 uidata.getChildren().add(child2);
476 VisitCallback callback = null;
477
478 IMocksControl control = EasyMock.createControl();
479 VisitContext visitContextMock = control.createMock(VisitContext.class);
480 EasyMock.expect(visitContextMock.getFacesContext()).andReturn(facesContext).anyTimes();
481 EasyMock.expect(visitContextMock.getHints()).andReturn(Collections.<VisitHint>emptySet()).anyTimes();
482 Collection<String> subtreeIdsToVisit = new ArrayList<String>();
483 subtreeIdsToVisit.add("1");
484 EasyMock.expect(visitContextMock.getSubtreeIdsToVisit(uidata)).andReturn(subtreeIdsToVisit);
485 EasyMock.expect(visitContextMock.invokeVisitCallback(uidata, callback)).andReturn(VisitResult.ACCEPT);
486 EasyMock.expect(visitContextMock.invokeVisitCallback(headerFacet, callback)).andReturn(VisitResult.ACCEPT);
487 EasyMock.expect(visitContextMock.invokeVisitCallback(footerFacet, callback)).andReturn(VisitResult.ACCEPT);
488 EasyMock.expect(visitContextMock.invokeVisitCallback(facetOfChild1, callback)).andReturn(VisitResult.ACCEPT);
489 EasyMock.expect(visitContextMock.invokeVisitCallback(child1, callback)).andReturn(VisitResult.ACCEPT);
490 EasyMock.expect(visitContextMock.invokeVisitCallback(childOfChild1, callback)).andReturn(VisitResult.ACCEPT).times(2);
491 control.replay();
492
493 uidata.visitTree(visitContextMock, callback);
494
495 control.verify();
496
497
498
499
500 MockVisitContext mockVisitContext = new MockVisitContext(facesContext, null);
501 CountingVisitCallback countingVisitCallback = new CountingVisitCallback(2);
502 uidata.visitTree(mockVisitContext, countingVisitCallback);
503 countingVisitCallback.verify();
504
505
506 mockVisitContext = new MockVisitContext(facesContext, EnumSet.of(VisitHint.SKIP_ITERATION));
507 countingVisitCallback = new CountingVisitCallback(1);
508 uidata.visitTree(mockVisitContext, countingVisitCallback);
509 countingVisitCallback.verify();
510
511
512 value = new ArrayList<String>();
513 value.add("1");
514 value.add("2");
515 value.add("3");
516 value.add("4");
517 value.add("5");
518 uidata.setValue(value);
519 mockVisitContext = new MockVisitContext(facesContext, null);
520 countingVisitCallback = new CountingVisitCallback(5);
521 uidata.visitTree(mockVisitContext, countingVisitCallback);
522 countingVisitCallback.verify();
523
524
525 mockVisitContext = new MockVisitContext(facesContext, EnumSet.of(VisitHint.SKIP_ITERATION));
526 countingVisitCallback = new CountingVisitCallback(1);
527 uidata.visitTree(mockVisitContext, countingVisitCallback);
528 countingVisitCallback.verify();
529 }
530
531
532 public static class RowData
533 {
534 private String text;
535
536 public RowData(String text, String style)
537 {
538 super();
539 this.text = text;
540 this.style = style;
541 }
542
543 private String style;
544
545 public String getText()
546 {
547 return text;
548 }
549
550 public void setText(String text)
551 {
552 this.text = text;
553 }
554
555 public String getStyle()
556 {
557 return style;
558 }
559
560 public void setStyle(String style)
561 {
562 this.style = style;
563 }
564 }
565
566 public void testPreserveRowComponentState1() throws Exception
567 {
568 List<RowData> model = new ArrayList<RowData>();
569 model.add(new RowData("text1","style1"));
570 model.add(new RowData("text1","style2"));
571 model.add(new RowData("text1","style3"));
572 model.add(new RowData("text1","style4"));
573
574
575 request.setAttribute("list", model);
576
577 UIViewRoot root = facesContext.getViewRoot();
578 UIData table = new UIData();
579 UIColumn column = new UIColumn();
580 UIOutput text = new UIOutput();
581
582
583 root.setId(root.createUniqueId());
584 table.setId(root.createUniqueId());
585 column.setId(root.createUniqueId());
586 text.setId(root.createUniqueId());
587
588 table.setVar("row");
589 table.setRowStatePreserved(true);
590 table.setValueExpression("value", application.
591 getExpressionFactory().createValueExpression(
592 facesContext.getELContext(),"#{list}",List.class));
593
594 text.setValueExpression("value", application.
595 getExpressionFactory().createValueExpression(
596 facesContext.getELContext(),"#{row.text}",String.class));
597
598 root.getChildren().add(table);
599 table.getChildren().add(column);
600 column.getChildren().add(text);
601
602
603 facesContext.getAttributes().put(StateManager.IS_BUILDING_INITIAL_STATE, Boolean.TRUE);
604 root.markInitialState();
605 table.markInitialState();
606 column.markInitialState();
607 text.markInitialState();
608 facesContext.getAttributes().remove(StateManager.IS_BUILDING_INITIAL_STATE);
609
610
611 for (int i = 0; i < model.size(); i++)
612 {
613 RowData rowData = model.get(i);
614 table.setRowIndex(i);
615 assertEquals(rowData.getText(), text.getValue());
616 text.getAttributes().put("style", rowData.getStyle());
617 }
618
619
620 table.setRowIndex(-1);
621
622
623 for (int i = 0; i < model.size(); i++)
624 {
625 table.setRowIndex(i);
626 assertEquals(model.get(i).getStyle(), text.getAttributes().get("style"));
627 }
628
629 }
630
631 private final class CountingVisitCallback implements VisitCallback {
632
633 public final int expectedVisits;
634
635 public CountingVisitCallback(int expectedRowVisits) {
636 super();
637 this.expectedVisits = expectedRowVisits;
638 }
639
640 public int headerFacetVisits = 0;
641 public int footerFacetVisits = 0;
642 public int rowVisits = 0;
643
644 public VisitResult visit(VisitContext context, UIComponent target) {
645
646 if ("headerFacet".equals(target.getId())) {
647 headerFacetVisits++;
648 } else if ("footerFacet".equals(target.getId())) {
649 footerFacetVisits++;
650 } else if ("childOfColumn".equals(target.getId())) {
651 rowVisits++;
652 }
653 return VisitResult.ACCEPT;
654 }
655
656 public void verify() {
657 assertEquals("header facet must be visited only ones", 1, headerFacetVisits);
658 assertEquals("footer facet must be visited only ones", 1, footerFacetVisits);
659 assertEquals("Expected row visit does not match", expectedVisits, rowVisits);
660 }
661 }
662
663 public void testProcessDecodesRenderedFalse() throws Exception {
664 UIData uiData = new VerifyNoLifecycleMethodComponent();
665 UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, uiData, false);
666
667 uiData.processDecodes(facesContext);
668
669 assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
670
671 }
672
673 public void testProcessDecodesRenderedTrue() throws Exception {
674
675 UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, _testImpl, true);
676 _addColumn();
677
678 _testImpl.processDecodes(facesContext);
679
680 assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
681 }
682
683
684 public void testProcessValidatorsRenderedFalse() throws Exception {
685 UIData uiData = new VerifyNoLifecycleMethodComponent();
686 UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, uiData, false);
687
688 uiData.processValidators(facesContext);
689
690 assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
691
692 }
693
694 public void testProcessValidatorsRenderedTrue() throws Exception {
695
696 UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, _testImpl, true);
697 _addColumn();
698
699 _testImpl.processValidators(facesContext);
700
701 assertEquals("processValidators must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
702 }
703
704 public void testProcessUpdatesRenderedFalse() throws Exception {
705 UIData uiData = new VerifyNoLifecycleMethodComponent();
706 UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, uiData, false);
707
708 uiData.processUpdates(facesContext);
709
710 assertEquals("processUpdates must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
711
712 }
713
714 public void testProcessUpdatesRenderedTrue() throws Exception {
715
716 UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, _testImpl, true);
717 _addColumn();
718
719 _testImpl.processUpdates(facesContext);
720
721 assertEquals("processUpdates must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
722 }
723
724 private void _addColumn() {
725 UIColumn uiColumn = new UIColumn();
726 uiColumn.setId("testId");
727 _testImpl.getChildren().add(uiColumn);
728 MockRenderedValueExpression ve = new MockRenderedValueExpression("#{component.is eq 'testId'}", Boolean.class, uiColumn, true);
729 uiColumn.setValueExpression("rendered", ve);
730 }
731
732
733
734 public class VerifyNoLifecycleMethodComponent extends UIData
735 {
736 public void setRowIndex(int rowIndex) {
737 fail();
738 }
739 public void decode(FacesContext context) {
740 fail();
741 }
742 public void validate(FacesContext context) {
743 fail();
744 }
745 public void updateModel(FacesContext context) {
746 fail();
747 }
748 public void encodeBegin(FacesContext context) throws IOException {
749 fail();
750 }
751 public void encodeChildren(FacesContext context) throws IOException {
752 fail();
753 }
754 public void encodeEnd(FacesContext context) throws IOException {
755 fail();
756 }
757 }
758 }