KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > form > TestFormSupport


1 // Copyright 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.tapestry.form;
16
17 import org.apache.hivemind.ApplicationRuntimeException;
18 import org.apache.hivemind.Location;
19 import org.apache.hivemind.test.HiveMindTestCase;
20 import org.apache.hivemind.util.ClasspathResource;
21 import org.apache.tapestry.IEngine;
22 import org.apache.tapestry.IMarkupWriter;
23 import org.apache.tapestry.IRender;
24 import org.apache.tapestry.IRequestCycle;
25 import org.apache.tapestry.NestedMarkupWriter;
26 import org.apache.tapestry.PageRenderSupport;
27 import org.apache.tapestry.StaleLinkException;
28 import org.apache.tapestry.TapestryUtils;
29 import org.apache.tapestry.engine.ILink;
30 import org.apache.tapestry.valid.IValidationDelegate;
31 import org.easymock.MockControl;
32
33 /**
34  * Tests for {@link org.apache.tapestry.form.FormSupportImpl}.
35  *
36  * @author Howard M. Lewis Ship
37  * @since 4.0
38  */

39 public class TestFormSupport extends HiveMindTestCase
40 {
41
42     private IRender newComponentRenderBody(final FormSupport fs, final IFormComponent component,
43             final IMarkupWriter nested)
44     {
45         return newComponentsRenderBody(fs, new IFormComponent[]
46         { component }, nested);
47     }
48
49     private IRender newComponentsRenderBody(final FormSupport fs, final IFormComponent[] component,
50             final IMarkupWriter nested)
51     {
52         return new IRender()
53         {
54             public void render(IMarkupWriter writer, IRequestCycle cycle)
55             {
56                 assertEquals("Writer argument must be nested instance.", nested, writer);
57
58                 for (int i = 0; i < component.length; i++)
59                     fs.getElementId(component[i]);
60             }
61         };
62     }
63
64     private IFormComponent newFormComponent(String JavaDoc id, String JavaDoc name)
65     {
66         MockControl componentc = newControl(IFormComponent.class);
67         final IFormComponent component = (IFormComponent) componentc.getMock();
68
69         component.getId();
70         componentc.setReturnValue(id);
71
72         component.setName(name);
73
74         return component;
75     }
76
77     private IFormComponent newFormComponent(String JavaDoc id, String JavaDoc extendedId, Location location)
78     {
79         MockControl componentc = newControl(IFormComponent.class);
80         final IFormComponent component = (IFormComponent) componentc.getMock();
81
82         component.getId();
83         componentc.setReturnValue(id);
84
85         component.getExtendedId();
86         componentc.setReturnValue(extendedId);
87
88         component.getLocation();
89         componentc.setReturnValue(location);
90
91         return component;
92     }
93
94     private IValidationDelegate newDelegate()
95     {
96         return (IValidationDelegate) newMock(IValidationDelegate.class);
97     }
98
99     private IMarkupWriter newWriter()
100     {
101         return (IMarkupWriter) newMock(IMarkupWriter.class);
102     }
103
104     private NestedMarkupWriter newNestedWriter()
105     {
106         return (NestedMarkupWriter) newMock(NestedMarkupWriter.class);
107     }
108
109     public void testComplexRender()
110     {
111         MockControl writerc = newControl(IMarkupWriter.class);
112         IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
113
114         NestedMarkupWriter nested = newNestedWriter();
115
116         MockControl cyclec = newControl(IRequestCycle.class);
117         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
118
119         MockControl enginec = newControl(IEngine.class);
120         IEngine engine = (IEngine) enginec.getMock();
121
122         MockForm form = new MockForm();
123
124         cycle.isRewound(form);
125         cyclec.setReturnValue(false);
126
127         cycle.getEngine();
128         cyclec.setReturnValue(engine);
129
130         engine.getClassResolver();
131         enginec.setReturnValue(getClassResolver());
132
133         replayControls();
134
135         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
136
137         verifyControls();
138
139         final IFormComponent barney1 = newFormComponent("barney", "barney");
140         final IFormComponent wilma = newFormComponent("wilma", "wilma");
141         final IFormComponent barney2 = newFormComponent("barney", "barney$0");
142
143         IRender body = newComponentsRenderBody(fs, new IFormComponent[]
144         { barney1, wilma, barney2 }, nested);
145
146         form.setBody(body);
147
148         MockControl linkc = newControl(ILink.class);
149         ILink link = (ILink) linkc.getMock();
150
151         IRender render = (IRender) newMock(IRender.class);
152
153         MockControl supportc = newControl(PageRenderSupport.class);
154         PageRenderSupport support = (PageRenderSupport) supportc.getMock();
155
156         cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
157         cyclec.setReturnValue(support);
158
159         support.addExternalScript(new ClasspathResource(getClassResolver(),
160                 "/org/apache/tapestry/form/Form.js"));
161
162         support
163                 .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
164
165         link.getParameterNames();
166         linkc.setReturnValue(new String JavaDoc[]
167         { "service" });
168
169         link.getParameterValues("service");
170         linkc.setReturnValue(new String JavaDoc[]
171         { "fred" });
172
173         writer.getNestedWriter();
174         writerc.setReturnValue(nested);
175
176         link.getURL(null, false);
177         linkc.setReturnValue("/app");
178
179         writer.begin("form");
180         writer.attribute("method", "post");
181         writer.attribute("action", "/app");
182
183         writer.attribute("name", "myform");
184
185         render.render(writer, cycle);
186
187         writer.println();
188
189         trainHidden(writer, "formids", "barney,wilma,barney$0");
190         trainHidden(writer, "service", "fred");
191         trainHidden(writer, "submitmode", "");
192
193         nested.close();
194
195         writer.end();
196
197         replayControls();
198
199         fs.render("post", render, link);
200
201         verifyControls();
202     }
203
204     public void testComplexRewind()
205     {
206         IMarkupWriter writer = newWriter();
207
208         MockControl cyclec = newControl(IRequestCycle.class);
209         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
210
211         IValidationDelegate delegate = newDelegate();
212
213         MockControl enginec = newControl(IEngine.class);
214         IEngine engine = (IEngine) enginec.getMock();
215
216         MockForm form = new MockForm(delegate);
217
218         cycle.isRewound(form);
219         cyclec.setReturnValue(true);
220
221         cycle.getEngine();
222         cyclec.setReturnValue(engine);
223
224         engine.getClassResolver();
225         enginec.setReturnValue(getClassResolver());
226
227         replayControls();
228
229         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
230
231         verifyControls();
232
233         delegate.clear();
234
235         trainCycleForRewind(cyclec, cycle, "barney,wilma,barney$0", null);
236
237         final IFormComponent barney1 = newFormComponent("barney", "barney");
238         final IFormComponent wilma = newFormComponent("wilma", "wilma");
239         final IFormComponent barney2 = newFormComponent("barney", "barney$0");
240
241         IRender body = newComponentsRenderBody(fs, new IFormComponent[]
242         { barney1, wilma, barney2 }, writer);
243
244         form.setBody(body);
245
246         replayControls();
247
248         assertEquals(FormConstants.SUBMIT_NORMAL, fs.rewind());
249
250         verifyControls();
251     }
252
253     public void testComplexSubmitEventHandler()
254     {
255         MockControl writerc = newControl(IMarkupWriter.class);
256         IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
257
258         NestedMarkupWriter nested = newNestedWriter();
259
260         MockControl cyclec = newControl(IRequestCycle.class);
261         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
262
263         MockControl enginec = newControl(IEngine.class);
264         IEngine engine = (IEngine) enginec.getMock();
265
266         MockForm form = new MockForm();
267
268         cycle.isRewound(form);
269         cyclec.setReturnValue(false);
270
271         cycle.getEngine();
272         cyclec.setReturnValue(engine);
273
274         engine.getClassResolver();
275         enginec.setReturnValue(getClassResolver());
276
277         replayControls();
278
279         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
280
281         verifyControls();
282
283         form.setBody(new IRender()
284         {
285             public void render(IMarkupWriter writer, IRequestCycle cycle)
286             {
287                 fs.addEventHandler(FormEventType.SUBMIT, "mySubmit1");
288                 fs.addEventHandler(FormEventType.SUBMIT, "mySubmit2");
289                 fs.addEventHandler(FormEventType.SUBMIT, "mySubmit3");
290             }
291         });
292
293         MockControl linkc = newControl(ILink.class);
294         ILink link = (ILink) linkc.getMock();
295
296         IRender render = (IRender) newMock(IRender.class);
297
298         MockControl supportc = newControl(PageRenderSupport.class);
299         PageRenderSupport support = (PageRenderSupport) supportc.getMock();
300
301         cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
302         cyclec.setReturnValue(support);
303
304         support.addExternalScript(new ClasspathResource(getClassResolver(),
305                 "/org/apache/tapestry/form/Form.js"));
306
307         support
308                 .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
309
310         link.getParameterNames();
311         linkc.setReturnValue(new String JavaDoc[]
312         { "service" });
313
314         link.getParameterValues("service");
315         linkc.setReturnValue(new String JavaDoc[]
316         { "fred" });
317
318         writer.getNestedWriter();
319         writerc.setReturnValue(nested);
320
321         link.getURL(null, false);
322         linkc.setReturnValue("/app");
323
324         writer.begin("form");
325         writer.attribute("method", "post");
326         writer.attribute("action", "/app");
327
328         writer.attribute("name", "myform");
329
330         render.render(writer, cycle);
331
332         writer.println();
333
334         trainHidden(writer, "formids", "");
335         trainHidden(writer, "service", "fred");
336         trainHidden(writer, "submitmode", "");
337
338         nested.close();
339
340         writer.end();
341
342         trainForPageSupport(
343                 cyclec,
344                 cycle,
345                 "myform_events.addSubmitListener(function (event)\n{\n mySubmit1();\n mySubmit2();\n mySubmit3();\n});\n");
346
347         replayControls();
348
349         fs.render("post", render, link);
350
351         verifyControls();
352     }
353
354     public void testEncodingType()
355     {
356         MockControl writerc = newControl(IMarkupWriter.class);
357         IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
358
359         NestedMarkupWriter nested = newNestedWriter();
360
361         MockControl cyclec = newControl(IRequestCycle.class);
362         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
363
364         MockControl enginec = newControl(IEngine.class);
365         IEngine engine = (IEngine) enginec.getMock();
366
367         MockForm form = new MockForm();
368
369         cycle.isRewound(form);
370         cyclec.setReturnValue(false);
371
372         cycle.getEngine();
373         cyclec.setReturnValue(engine);
374
375         engine.getClassResolver();
376         enginec.setReturnValue(getClassResolver());
377
378         replayControls();
379
380         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
381
382         verifyControls();
383
384         form.setBody(new IRender()
385         {
386             public void render(IMarkupWriter writer, IRequestCycle cycle)
387             {
388                 fs.setEncodingType("foo/bar");
389             }
390         });
391
392         MockControl linkc = newControl(ILink.class);
393         ILink link = (ILink) linkc.getMock();
394
395         IRender render = (IRender) newMock(IRender.class);
396
397         MockControl supportc = newControl(PageRenderSupport.class);
398         PageRenderSupport support = (PageRenderSupport) supportc.getMock();
399
400         cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
401         cyclec.setReturnValue(support);
402
403         support.addExternalScript(new ClasspathResource(getClassResolver(),
404                 "/org/apache/tapestry/form/Form.js"));
405
406         support
407                 .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
408
409         link.getParameterNames();
410         linkc.setReturnValue(new String JavaDoc[]
411         { "service" });
412
413         link.getParameterValues("service");
414         linkc.setReturnValue(new String JavaDoc[]
415         { "fred" });
416
417         writer.getNestedWriter();
418         writerc.setReturnValue(nested);
419
420         link.getURL(null, false);
421         linkc.setReturnValue("/app");
422
423         writer.begin("form");
424         writer.attribute("method", "post");
425         writer.attribute("action", "/app");
426         writer.attribute("name", "myform");
427         writer.attribute("enctype", "foo/bar");
428
429         render.render(writer, cycle);
430
431         writer.println();
432
433         trainHidden(writer, "formids", "");
434         trainHidden(writer, "service", "fred");
435         trainHidden(writer, "submitmode", "");
436
437         nested.close();
438
439         writer.end();
440
441         replayControls();
442
443         fs.render("post", render, link);
444
445         verifyControls();
446     }
447
448     public void testHiddenValues()
449     {
450         MockControl writerc = newControl(IMarkupWriter.class);
451         IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
452
453         NestedMarkupWriter nested = newNestedWriter();
454
455         MockControl cyclec = newControl(IRequestCycle.class);
456         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
457
458         MockControl enginec = newControl(IEngine.class);
459         IEngine engine = (IEngine) enginec.getMock();
460
461         MockForm form = new MockForm();
462
463         cycle.isRewound(form);
464         cyclec.setReturnValue(false);
465
466         cycle.getEngine();
467         cyclec.setReturnValue(engine);
468
469         engine.getClassResolver();
470         enginec.setReturnValue(getClassResolver());
471
472         replayControls();
473
474         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
475
476         verifyControls();
477
478         form.setBody(new IRender()
479         {
480             public void render(IMarkupWriter writer, IRequestCycle cycle)
481             {
482                 fs.addHiddenValue("hidden1", "value1");
483                 fs.addHiddenValue("hidden2", "id2", "value2");
484             }
485         });
486
487         MockControl linkc = newControl(ILink.class);
488         ILink link = (ILink) linkc.getMock();
489
490         IRender render = (IRender) newMock(IRender.class);
491
492         MockControl supportc = newControl(PageRenderSupport.class);
493         PageRenderSupport support = (PageRenderSupport) supportc.getMock();
494
495         cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
496         cyclec.setReturnValue(support);
497
498         support.addExternalScript(new ClasspathResource(getClassResolver(),
499                 "/org/apache/tapestry/form/Form.js"));
500
501         support
502                 .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
503
504         link.getParameterNames();
505         linkc.setReturnValue(new String JavaDoc[]
506         { "service" });
507
508         link.getParameterValues("service");
509         linkc.setReturnValue(new String JavaDoc[]
510         { "fred" });
511
512         writer.getNestedWriter();
513         writerc.setReturnValue(nested);
514
515         link.getURL(null, false);
516         linkc.setReturnValue("/app");
517
518         writer.begin("form");
519         writer.attribute("method", "post");
520         writer.attribute("action", "/app");
521
522         writer.attribute("name", "myform");
523
524         render.render(writer, cycle);
525
526         writer.println();
527
528         trainHidden(writer, "formids", "");
529         trainHidden(writer, "service", "fred");
530         trainHidden(writer, "submitmode", "");
531         trainHidden(writer, "hidden1", "value1");
532         trainHidden(writer, "hidden2", "id2", "value2");
533
534         nested.close();
535
536         writer.end();
537
538         replayControls();
539
540         fs.render("post", render, link);
541
542         verifyControls();
543     }
544
545     public void testInvalidEncodingType()
546     {
547         MockControl writerc = newControl(IMarkupWriter.class);
548         IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
549
550         NestedMarkupWriter nested = newNestedWriter();
551
552         MockControl cyclec = newControl(IRequestCycle.class);
553         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
554
555         MockControl enginec = newControl(IEngine.class);
556         IEngine engine = (IEngine) enginec.getMock();
557
558         MockForm form = new MockForm();
559
560         cycle.isRewound(form);
561         cyclec.setReturnValue(false);
562
563         cycle.getEngine();
564         cyclec.setReturnValue(engine);
565
566         engine.getClassResolver();
567         enginec.setReturnValue(getClassResolver());
568
569         replayControls();
570
571         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
572
573         verifyControls();
574
575         form.setBody(new IRender()
576         {
577             public void render(IMarkupWriter writer, IRequestCycle cycle)
578             {
579                 fs.setEncodingType("foo/bar");
580                 fs.setEncodingType("zip/zap");
581             }
582         });
583
584         MockControl linkc = newControl(ILink.class);
585         ILink link = (ILink) linkc.getMock();
586
587         IRender render = (IRender) newMock(IRender.class);
588
589         MockControl supportc = newControl(PageRenderSupport.class);
590         PageRenderSupport support = (PageRenderSupport) supportc.getMock();
591
592         cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
593         cyclec.setReturnValue(support);
594
595         support.addExternalScript(new ClasspathResource(getClassResolver(),
596                 "/org/apache/tapestry/form/Form.js"));
597
598         support
599                 .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
600
601         link.getParameterNames();
602         linkc.setReturnValue(new String JavaDoc[]
603         { "service" });
604
605         link.getParameterValues("service");
606         linkc.setReturnValue(new String JavaDoc[]
607         { "fred" });
608
609         writer.getNestedWriter();
610         writerc.setReturnValue(nested);
611
612         replayControls();
613
614         try
615         {
616             fs.render("post", render, link);
617             unreachable();
618         }
619         catch (ApplicationRuntimeException ex)
620         {
621             assertEquals(
622                     "Components within form SomePage/myform have requested conflicting encoding types 'foo/bar' and 'zip/zap'.",
623                     ex.getMessage());
624             assertSame(form, ex.getComponent());
625         }
626
627         verifyControls();
628     }
629
630     public void testRenderExtraReservedIds()
631     {
632         MockControl writerc = newControl(IMarkupWriter.class);
633         IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
634
635         NestedMarkupWriter nested = newNestedWriter();
636
637         MockControl cyclec = newControl(IRequestCycle.class);
638         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
639
640         MockControl enginec = newControl(IEngine.class);
641         IEngine engine = (IEngine) enginec.getMock();
642
643         MockForm form = new MockForm();
644
645         cycle.isRewound(form);
646         cyclec.setReturnValue(false);
647
648         cycle.getEngine();
649         cyclec.setReturnValue(engine);
650
651         engine.getClassResolver();
652         enginec.setReturnValue(getClassResolver());
653
654         replayControls();
655
656         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
657
658         verifyControls();
659
660         final IFormComponent component = newFormComponent("action", "action$0");
661
662         IRender body = newComponentRenderBody(fs, component, nested);
663
664         form.setBody(body);
665
666         MockControl linkc = newControl(ILink.class);
667         ILink link = (ILink) linkc.getMock();
668
669         IRender render = (IRender) newMock(IRender.class);
670
671         MockControl supportc = newControl(PageRenderSupport.class);
672         PageRenderSupport support = (PageRenderSupport) supportc.getMock();
673
674         cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
675         cyclec.setReturnValue(support);
676
677         support.addExternalScript(new ClasspathResource(getClassResolver(),
678                 "/org/apache/tapestry/form/Form.js"));
679
680         support
681                 .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
682
683         link.getParameterNames();
684         linkc.setReturnValue(new String JavaDoc[]
685         { "action" });
686
687         link.getParameterValues("action");
688         linkc.setReturnValue(new String JavaDoc[]
689         { "fred" });
690
691         writer.getNestedWriter();
692         writerc.setReturnValue(nested);
693
694         link.getURL(null, false);
695         linkc.setReturnValue("/app");
696
697         writer.begin("form");
698         writer.attribute("method", "post");
699         writer.attribute("action", "/app");
700
701         writer.attribute("name", "myform");
702
703         render.render(writer, cycle);
704
705         writer.println();
706
707         trainHidden(writer, "formids", "action$0");
708         trainHidden(writer, "action", "fred");
709         trainHidden(writer, "reservedids", "action");
710         trainHidden(writer, "submitmode", "");
711
712         nested.close();
713
714         writer.end();
715
716         replayControls();
717
718         fs.render("post", render, link);
719
720         verifyControls();
721     }
722
723     public void testResetEventHandler()
724     {
725         MockControl writerc = newControl(IMarkupWriter.class);
726         IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
727
728         NestedMarkupWriter nested = newNestedWriter();
729
730         MockControl cyclec = newControl(IRequestCycle.class);
731         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
732
733         MockControl enginec = newControl(IEngine.class);
734         IEngine engine = (IEngine) enginec.getMock();
735
736         MockForm form = new MockForm();
737
738         cycle.isRewound(form);
739         cyclec.setReturnValue(false);
740
741         cycle.getEngine();
742         cyclec.setReturnValue(engine);
743
744         engine.getClassResolver();
745         enginec.setReturnValue(getClassResolver());
746
747         replayControls();
748
749         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
750
751         verifyControls();
752
753         form.setBody(new IRender()
754         {
755             public void render(IMarkupWriter writer, IRequestCycle cycle)
756             {
757                 fs.addEventHandler(FormEventType.RESET, "myReset1");
758                 fs.addEventHandler(FormEventType.RESET, "myReset2");
759             }
760         });
761
762         MockControl linkc = newControl(ILink.class);
763         ILink link = (ILink) linkc.getMock();
764
765         IRender render = (IRender) newMock(IRender.class);
766
767         MockControl supportc = newControl(PageRenderSupport.class);
768         PageRenderSupport support = (PageRenderSupport) supportc.getMock();
769
770         cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
771         cyclec.setReturnValue(support);
772
773         support.addExternalScript(new ClasspathResource(getClassResolver(),
774                 "/org/apache/tapestry/form/Form.js"));
775
776         support
777                 .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
778
779         link.getParameterNames();
780         linkc.setReturnValue(new String JavaDoc[]
781         { "service" });
782
783         link.getParameterValues("service");
784         linkc.setReturnValue(new String JavaDoc[]
785         { "fred" });
786
787         writer.getNestedWriter();
788         writerc.setReturnValue(nested);
789
790         link.getURL(null, false);
791         linkc.setReturnValue("/app");
792
793         writer.begin("form");
794         writer.attribute("method", "post");
795         writer.attribute("action", "/app");
796
797         writer.attribute("name", "myform");
798
799         render.render(writer, cycle);
800
801         writer.println();
802
803         trainHidden(writer, "formids", "");
804         trainHidden(writer, "service", "fred");
805         trainHidden(writer, "submitmode", "");
806
807         nested.close();
808
809         writer.end();
810
811         trainForPageSupport(
812                 cyclec,
813                 cycle,
814                 "myform_events.addResetListener(function (event)\n{\n myReset1();\n myReset2();\n});\n");
815
816         replayControls();
817
818         fs.render("post", render, link);
819
820         verifyControls();
821     }
822
823     public void testRewindExtraReservedIds()
824     {
825         IMarkupWriter writer = newWriter();
826
827         MockControl cyclec = newControl(IRequestCycle.class);
828         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
829         IValidationDelegate delegate = newDelegate();
830
831         MockControl enginec = newControl(IEngine.class);
832         IEngine engine = (IEngine) enginec.getMock();
833
834         MockForm form = new MockForm(delegate);
835
836         cycle.isRewound(form);
837         cyclec.setReturnValue(true);
838
839         cycle.getEngine();
840         cyclec.setReturnValue(engine);
841
842         engine.getClassResolver();
843         enginec.setReturnValue(getClassResolver());
844
845         replayControls();
846
847         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
848
849         verifyControls();
850
851         delegate.clear();
852
853         trainCycleForRewind(cyclec, cycle, "action$0", "action");
854
855         final IFormComponent component = newFormComponent("action", "action$0");
856
857         IRender body = newComponentRenderBody(fs, component, writer);
858
859         form.setBody(body);
860
861         replayControls();
862
863         assertEquals(FormConstants.SUBMIT_NORMAL, fs.rewind());
864
865         verifyControls();
866     }
867
868     public void testRewindMismatch()
869     {
870
871         IMarkupWriter writer = newWriter();
872
873         MockControl cyclec = newControl(IRequestCycle.class);
874         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
875
876         IValidationDelegate delegate = newDelegate();
877
878         MockControl enginec = newControl(IEngine.class);
879         IEngine engine = (IEngine) enginec.getMock();
880
881         MockForm form = new MockForm(delegate);
882
883         cycle.isRewound(form);
884         cyclec.setReturnValue(true);
885
886         cycle.getEngine();
887         cyclec.setReturnValue(engine);
888
889         engine.getClassResolver();
890         enginec.setReturnValue(getClassResolver());
891
892         replayControls();
893
894         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
895
896         verifyControls();
897
898         Location l = newLocation();
899
900         delegate.clear();
901
902         // So, the scenario here is that component "pebbles" was inside
903
// some kind of conditional that evaluated to true during the render,
904
// but is now false on the rewind.
905

906         trainCycleForRewind(cyclec, cycle, "barney,wilma,pebbles,barney$0", null);
907
908         final IFormComponent barney1 = newFormComponent("barney", "barney");
909         final IFormComponent wilma = newFormComponent("wilma", "wilma");
910         final IFormComponent barney2 = newFormComponent("barney", "SomePage/barney", l);
911
912         IRender body = newComponentsRenderBody(fs, new IFormComponent[]
913         { barney1, wilma, barney2 }, writer);
914
915         form.setBody(body);
916
917         replayControls();
918
919         try
920         {
921             fs.rewind();
922             unreachable();
923         }
924         catch (StaleLinkException ex)
925         {
926             assertEquals(
927                     "Rewind of form SomePage/myform expected allocated id #3 to be 'pebbles', but was 'barney$0' (requested by component SomePage/barney).",
928                     ex.getMessage());
929             assertSame(barney2, ex.getComponent());
930             assertSame(l, ex.getLocation());
931         }
932
933         verifyControls();
934     }
935
936     public void testRewindTooLong()
937     {
938         IMarkupWriter writer = newWriter();
939
940         MockControl cyclec = newControl(IRequestCycle.class);
941         IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
942
943         IValidationDelegate delegate = newDelegate();
944
945         MockControl enginec = newControl(IEngine.class);
946         IEngine engine = (IEngine) enginec.getMock();
947
948         MockForm form = new MockForm(delegate);
949
950         cycle.isRewound(form);
951         cyclec.setReturnValue(true);
952
953         cycle.getEngine();
954         cyclec.setReturnValue(engine);
955
956         engine.getClassResolver();
957         enginec.setReturnValue(getClassResolver());
958
959         replayControls();
960
961         final FormSupport fs = new FormSupportImpl(writer, cycle, form);
962
963         verifyControls();
964
965         Location l = newLocation();
966
967         delegate.clear();
968
969         // So, the scenario here is that component "barney" was inside
970
// some kind of loop that executed once on the render, but twice
971
// on the rewind (i.e., an additional object was added in between).
972

973         trainCycleForRewind(cyclec, cycle, "barney,wilma", null);
974
975         final IFormComponent barney1 = newFormComponent("barney", "barney");
976         final IFormComponent wilma = newFormComponent("wilma", "wilma");
977         final IFormComponent barney2 = newFormComponent("barney", "SomePage/barney", l);
978
979         IRender body = newComponentsRenderBody(fs, new IFormComponent[]
980         { barney1, wilma, barney2 }, writer);
981
982         form.setBody(body);
983
984         replayControls();
985
986         try
987         {
988             fs.rewind();
989             unreachable();
990         }
991         catch (StaleLinkException ex)
992         {
993             assertEquals(
994                     "Rewind of form SomePage/myform expected only 2 form elements, but an additional id was requested by component SomePage/barney.",
995                     ex.getMessage());
996             assertSame(barney2, ex.getComponent());
997             assertSame(l, ex.getLocation());
998         }
999
1000        verifyControls();
1001    }
1002
1003    public void testRewindTooShort()
1004    {
1005        Location l = newLocation();
1006        IMarkupWriter writer = newWriter();
1007
1008        MockControl cyclec = newControl(IRequestCycle.class);
1009        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
1010
1011        IValidationDelegate delegate = newDelegate();
1012
1013        MockControl enginec = newControl(IEngine.class);
1014        IEngine engine = (IEngine) enginec.getMock();
1015
1016        MockForm form = new MockForm(delegate, l);
1017
1018        cycle.isRewound(form);
1019        cyclec.setReturnValue(true);
1020
1021        cycle.getEngine();
1022        cyclec.setReturnValue(engine);
1023
1024        engine.getClassResolver();
1025        enginec.setReturnValue(getClassResolver());
1026
1027        replayControls();
1028
1029        final FormSupport fs = new FormSupportImpl(writer, cycle, form);
1030
1031        verifyControls();
1032
1033        delegate.clear();
1034
1035        // So, the scenario here is that component "barney" was inside
1036
// some kind of loop that executed twice on the render, but only once
1037
// on the rewind (i.e., the object was deleted in between).
1038

1039        trainCycleForRewind(cyclec, cycle, "barney,wilma,barney$0", null);
1040
1041        final IFormComponent barney1 = newFormComponent("barney", "barney");
1042        final IFormComponent wilma = newFormComponent("wilma", "wilma");
1043
1044        IRender body = newComponentsRenderBody(fs, new IFormComponent[]
1045        { barney1, wilma }, writer);
1046
1047        form.setBody(body);
1048
1049        replayControls();
1050
1051        try
1052        {
1053            fs.rewind();
1054            unreachable();
1055        }
1056        catch (StaleLinkException ex)
1057        {
1058            assertEquals(
1059                    "Rewind of form SomePage/myform expected 1 more form elements, starting with id 'barney$0'.",
1060                    ex.getMessage());
1061            assertSame(form, ex.getComponent());
1062            assertSame(l, ex.getLocation());
1063        }
1064
1065        verifyControls();
1066    }
1067
1068    public void testSimpleRender()
1069    {
1070        MockControl writerc = newControl(IMarkupWriter.class);
1071        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
1072
1073        NestedMarkupWriter nested = newNestedWriter();
1074
1075        MockControl cyclec = newControl(IRequestCycle.class);
1076        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
1077
1078        MockControl enginec = newControl(IEngine.class);
1079        IEngine engine = (IEngine) enginec.getMock();
1080
1081        MockForm form = new MockForm();
1082
1083        cycle.isRewound(form);
1084        cyclec.setReturnValue(false);
1085
1086        cycle.getEngine();
1087        cyclec.setReturnValue(engine);
1088
1089        engine.getClassResolver();
1090        enginec.setReturnValue(getClassResolver());
1091
1092        replayControls();
1093
1094        final FormSupport fs = new FormSupportImpl(writer, cycle, form);
1095
1096        verifyControls();
1097
1098        final IFormComponent component = newFormComponent("barney", "barney");
1099
1100        IRender body = newComponentRenderBody(fs, component, nested);
1101
1102        form.setBody(body);
1103
1104        MockControl linkc = newControl(ILink.class);
1105        ILink link = (ILink) linkc.getMock();
1106
1107        IRender render = (IRender) newMock(IRender.class);
1108
1109        MockControl supportc = newControl(PageRenderSupport.class);
1110        PageRenderSupport support = (PageRenderSupport) supportc.getMock();
1111
1112        cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
1113        cyclec.setReturnValue(support);
1114
1115        support.addExternalScript(new ClasspathResource(getClassResolver(),
1116                "/org/apache/tapestry/form/Form.js"));
1117
1118        support
1119                .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
1120
1121        link.getParameterNames();
1122        linkc.setReturnValue(new String JavaDoc[]
1123        { "service" });
1124
1125        link.getParameterValues("service");
1126        linkc.setReturnValue(new String JavaDoc[]
1127        { "fred" });
1128
1129        writer.getNestedWriter();
1130        writerc.setReturnValue(nested);
1131
1132        link.getURL(null, false);
1133        linkc.setReturnValue("/app");
1134
1135        writer.begin("form");
1136        writer.attribute("method", "post");
1137        writer.attribute("action", "/app");
1138
1139        writer.attribute("name", "myform");
1140
1141        render.render(writer, cycle);
1142
1143        writer.println();
1144
1145        trainHidden(writer, "formids", "barney");
1146        trainHidden(writer, "service", "fred");
1147        trainHidden(writer, "submitmode", "");
1148
1149        nested.close();
1150
1151        writer.end();
1152
1153        replayControls();
1154
1155        fs.render("post", render, link);
1156
1157        verifyControls();
1158    }
1159
1160    public void testSimpleRenderWithDeferredRunnable()
1161    {
1162        MockControl writerc = newControl(IMarkupWriter.class);
1163        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
1164
1165        NestedMarkupWriter nested = newNestedWriter();
1166
1167        MockControl cyclec = newControl(IRequestCycle.class);
1168        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
1169
1170        MockControl enginec = newControl(IEngine.class);
1171        IEngine engine = (IEngine) enginec.getMock();
1172
1173        MockForm form = new MockForm();
1174
1175        cycle.isRewound(form);
1176        cyclec.setReturnValue(false);
1177
1178        cycle.getEngine();
1179        cyclec.setReturnValue(engine);
1180
1181        engine.getClassResolver();
1182        enginec.setReturnValue(getClassResolver());
1183
1184        replayControls();
1185
1186        final FormSupport fs = new FormSupportImpl(writer, cycle, form);
1187
1188        verifyControls();
1189
1190        IRender body = new IRender()
1191        {
1192
1193            public void render(final IMarkupWriter writer, IRequestCycle cycle)
1194            {
1195                fs.addDeferredRunnable(new Runnable JavaDoc()
1196                {
1197
1198                    public void run()
1199                    {
1200                        writer.print("DEFERRED");
1201                    }
1202
1203                });
1204            }
1205
1206        };
1207
1208        form.setBody(body);
1209
1210        MockControl linkc = newControl(ILink.class);
1211        ILink link = (ILink) linkc.getMock();
1212
1213        IRender render = (IRender) newMock(IRender.class);
1214
1215        MockControl supportc = newControl(PageRenderSupport.class);
1216        PageRenderSupport support = (PageRenderSupport) supportc.getMock();
1217
1218        cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
1219        cyclec.setReturnValue(support);
1220
1221        support.addExternalScript(new ClasspathResource(getClassResolver(),
1222                "/org/apache/tapestry/form/Form.js"));
1223
1224        support
1225                .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
1226
1227        link.getParameterNames();
1228        linkc.setReturnValue(new String JavaDoc[]
1229        { "service" });
1230
1231        link.getParameterValues("service");
1232        linkc.setReturnValue(new String JavaDoc[]
1233        { "fred" });
1234
1235        writer.getNestedWriter();
1236        writerc.setReturnValue(nested);
1237
1238        link.getURL(null, false);
1239        linkc.setReturnValue("/app");
1240
1241        writer.begin("form");
1242        writer.attribute("method", "post");
1243        writer.attribute("action", "/app");
1244
1245        writer.attribute("name", "myform");
1246
1247        render.render(writer, cycle);
1248
1249        writer.println();
1250
1251        trainHidden(writer, "formids", "");
1252        trainHidden(writer, "service", "fred");
1253        trainHidden(writer, "submitmode", "");
1254
1255        // EasyMock can't fully verify that this gets called at the right moment, nor can we truly
1256
// prove (well, except by looking at the code), that the deferred runnables execute at the
1257
// right time.
1258

1259        nested.print("DEFERRED");
1260
1261        nested.close();
1262
1263        writer.end();
1264
1265        replayControls();
1266
1267        fs.render("post", render, link);
1268
1269        verifyControls();
1270    }
1271
1272    public void testSimpleRewind()
1273    {
1274        IMarkupWriter writer = newWriter();
1275
1276        MockControl cyclec = newControl(IRequestCycle.class);
1277        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
1278
1279        IValidationDelegate delegate = newDelegate();
1280
1281        MockControl enginec = newControl(IEngine.class);
1282        IEngine engine = (IEngine) enginec.getMock();
1283
1284        MockForm form = new MockForm(delegate);
1285
1286        cycle.isRewound(form);
1287        cyclec.setReturnValue(true);
1288
1289        cycle.getEngine();
1290        cyclec.setReturnValue(engine);
1291
1292        engine.getClassResolver();
1293        enginec.setReturnValue(getClassResolver());
1294
1295        replayControls();
1296
1297        final FormSupport fs = new FormSupportImpl(writer, cycle, form);
1298
1299        verifyControls();
1300
1301        delegate.clear();
1302
1303        trainCycleForRewind(cyclec, cycle, "barney", null);
1304
1305        final IFormComponent component = newFormComponent("barney", "barney");
1306
1307        IRender body = newComponentRenderBody(fs, component, writer);
1308
1309        form.setBody(body);
1310
1311        replayControls();
1312
1313        assertEquals(FormConstants.SUBMIT_NORMAL, fs.rewind());
1314
1315        verifyControls();
1316    }
1317
1318    public void testRefreshRewind()
1319    {
1320        IMarkupWriter writer = newWriter();
1321
1322        MockControl cyclec = newControl(IRequestCycle.class);
1323        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
1324
1325        IValidationDelegate delegate = newDelegate();
1326
1327        MockControl enginec = newControl(IEngine.class);
1328        IEngine engine = (IEngine) enginec.getMock();
1329
1330        MockForm form = new MockForm(delegate);
1331
1332        cycle.isRewound(form);
1333        cyclec.setReturnValue(true);
1334
1335        cycle.getEngine();
1336        cyclec.setReturnValue(engine);
1337
1338        engine.getClassResolver();
1339        enginec.setReturnValue(getClassResolver());
1340
1341        replayControls();
1342
1343        final FormSupport fs = new FormSupportImpl(writer, cycle, form);
1344
1345        verifyControls();
1346
1347        delegate.clear();
1348
1349        trainCycleForRewind(cyclec, cycle, "refresh", "barney", null);
1350
1351        final IFormComponent component = newFormComponent("barney", "barney");
1352
1353        IRender body = newComponentRenderBody(fs, component, writer);
1354
1355        form.setBody(body);
1356
1357        replayControls();
1358
1359        assertEquals(FormConstants.SUBMIT_REFRESH, fs.rewind());
1360
1361        verifyControls();
1362    }
1363
1364    public void testCancelRewind()
1365    {
1366        IMarkupWriter writer = newWriter();
1367
1368        MockControl cyclec = newControl(IRequestCycle.class);
1369        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
1370
1371        IValidationDelegate delegate = newDelegate();
1372
1373        MockControl enginec = newControl(IEngine.class);
1374        IEngine engine = (IEngine) enginec.getMock();
1375
1376        MockForm form = new MockForm(delegate);
1377
1378        cycle.isRewound(form);
1379        cyclec.setReturnValue(true);
1380
1381        cycle.getEngine();
1382        cyclec.setReturnValue(engine);
1383
1384        engine.getClassResolver();
1385        enginec.setReturnValue(getClassResolver());
1386
1387        replayControls();
1388
1389        final FormSupport fs = new FormSupportImpl(writer, cycle, form);
1390
1391        verifyControls();
1392
1393        delegate.clear();
1394
1395        trainGetParameter(cyclec, cycle, FormSupportImpl.SUBMIT_MODE, "cancel");
1396
1397        // Create a body, just to provie it doesn't get invoked.
1398

1399        IRender body = (IRender) newMock(IRender.class);
1400
1401        form.setBody(body);
1402
1403        replayControls();
1404
1405        assertEquals(FormConstants.SUBMIT_CANCEL, fs.rewind());
1406
1407        verifyControls();
1408    }
1409
1410    public void testSimpleRewindWithDeferredRunnable()
1411    {
1412        IMarkupWriter writer = newWriter();
1413
1414        MockControl cyclec = newControl(IRequestCycle.class);
1415        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
1416
1417        IValidationDelegate delegate = newDelegate();
1418
1419        MockControl enginec = newControl(IEngine.class);
1420        IEngine engine = (IEngine) enginec.getMock();
1421
1422        MockForm form = new MockForm(delegate);
1423
1424        cycle.isRewound(form);
1425        cyclec.setReturnValue(true);
1426
1427        cycle.getEngine();
1428        cyclec.setReturnValue(engine);
1429
1430        engine.getClassResolver();
1431        enginec.setReturnValue(getClassResolver());
1432
1433        replayControls();
1434
1435        final FormSupport fs = new FormSupportImpl(writer, cycle, form);
1436
1437        verifyControls();
1438
1439        delegate.clear();
1440
1441        trainCycleForRewind(cyclec, cycle, "", null);
1442
1443        writer.print("DEFERRED");
1444
1445        replayControls();
1446
1447        IRender body = new IRender()
1448        {
1449
1450            public void render(final IMarkupWriter writer, IRequestCycle cycle)
1451            {
1452                fs.addDeferredRunnable(new Runnable JavaDoc()
1453                {
1454                    public void run()
1455                    {
1456                        writer.print("DEFERRED");
1457                    }
1458
1459                });
1460            }
1461
1462        };
1463
1464        form.setBody(body);
1465
1466        assertEquals(FormConstants.SUBMIT_NORMAL, fs.rewind());
1467
1468        verifyControls();
1469    }
1470
1471    public void testSimpleSubmitEventHandler()
1472    {
1473        MockControl writerc = newControl(IMarkupWriter.class);
1474        IMarkupWriter writer = (IMarkupWriter) writerc.getMock();
1475
1476        NestedMarkupWriter nested = newNestedWriter();
1477
1478        MockControl cyclec = newControl(IRequestCycle.class);
1479        IRequestCycle cycle = (IRequestCycle) cyclec.getMock();
1480
1481        MockControl enginec = newControl(IEngine.class);
1482        IEngine engine = (IEngine) enginec.getMock();
1483
1484        MockForm form = new MockForm();
1485
1486        cycle.isRewound(form);
1487        cyclec.setReturnValue(false);
1488
1489        cycle.getEngine();
1490        cyclec.setReturnValue(engine);
1491
1492        engine.getClassResolver();
1493        enginec.setReturnValue(getClassResolver());
1494
1495        replayControls();
1496
1497        final FormSupport fs = new FormSupportImpl(writer, cycle, form);
1498
1499        verifyControls();
1500
1501        form.setBody(new IRender()
1502        {
1503            public void render(IMarkupWriter writer, IRequestCycle cycle)
1504            {
1505                fs.addEventHandler(FormEventType.SUBMIT, "mySubmit()");
1506            }
1507        });
1508
1509        MockControl linkc = newControl(ILink.class);
1510        ILink link = (ILink) linkc.getMock();
1511
1512        IRender render = (IRender) newMock(IRender.class);
1513
1514        MockControl supportc = newControl(PageRenderSupport.class);
1515        PageRenderSupport support = (PageRenderSupport) supportc.getMock();
1516
1517        cycle.getAttribute("org.apache.tapestry.PageRenderSupport");
1518        cyclec.setReturnValue(support);
1519
1520        support.addExternalScript(new ClasspathResource(getClassResolver(),
1521                "/org/apache/tapestry/form/Form.js"));
1522
1523        support
1524                .addInitializationScript("var myform_events = new FormEventManager(document.myform);");
1525
1526        link.getParameterNames();
1527        linkc.setReturnValue(new String JavaDoc[]
1528        { "service" });
1529
1530        link.getParameterValues("service");
1531        linkc.setReturnValue(new String JavaDoc[]
1532        { "fred" });
1533
1534        writer.getNestedWriter();
1535        writerc.setReturnValue(nested);
1536
1537        link.getURL(null, false);
1538        linkc.setReturnValue("/app");
1539
1540        writer.begin("form");
1541        writer.attribute("method", "post");
1542        writer.attribute("action", "/app");
1543
1544        writer.attribute("name", "myform");
1545
1546        render.render(writer, cycle);
1547
1548        writer.println();
1549
1550        trainHidden(writer, "formids", "");
1551        trainHidden(writer, "service", "fred");
1552        trainHidden(writer, "submitmode", "");
1553
1554        nested.close();
1555
1556        writer.end();
1557
1558        trainForPageSupport(
1559                cyclec,
1560                cycle,
1561                "myform_events.addSubmitListener(function (event)\n{\n mySubmit();\n});\n");
1562        replayControls();
1563
1564        fs.render("post", render, link);
1565
1566        verifyControls();
1567    }
1568
1569    private void trainCycleForRewind(MockControl cyclec, IRequestCycle cycle, String JavaDoc allocatedIds,
1570            String JavaDoc reservedIds)
1571    {
1572        trainCycleForRewind(cyclec, cycle, "submit", allocatedIds, reservedIds);
1573    }
1574
1575    private void trainCycleForRewind(MockControl cyclec, IRequestCycle cycle, String JavaDoc submitMode,
1576            String JavaDoc allocatedIds, String JavaDoc reservedIds)
1577    {
1578        trainGetParameter(cyclec, cycle, FormSupportImpl.SUBMIT_MODE, submitMode);
1579        trainGetParameter(cyclec, cycle, FormSupportImpl.FORM_IDS, allocatedIds);
1580        trainGetParameter(cyclec, cycle, FormSupportImpl.RESERVED_FORM_IDS, reservedIds);
1581    }
1582
1583    private void trainGetParameter(MockControl cyclec, IRequestCycle cycle, String JavaDoc parameterName,
1584            String JavaDoc value)
1585    {
1586        cycle.getParameter(parameterName);
1587        cyclec.setReturnValue(value);
1588    }
1589
1590    private void trainForPageSupport(MockControl cyclec, IRequestCycle cycle, String JavaDoc initialization)
1591    {
1592        PageRenderSupport prs = (PageRenderSupport) newMock(PageRenderSupport.class);
1593
1594        prs.addInitializationScript(initialization);
1595
1596        cycle.getAttribute(TapestryUtils.PAGE_RENDER_SUPPORT_ATTRIBUTE);
1597        cyclec.setReturnValue(prs);
1598    }
1599
1600    private void trainHidden(IMarkupWriter writer, String JavaDoc name, String JavaDoc value)
1601    {
1602        writer.beginEmpty("input");
1603        writer.attribute("type", "hidden");
1604        writer.attribute("name", name);
1605        writer.attribute("value", value);
1606        writer.println();
1607    }
1608
1609    private void trainHidden(IMarkupWriter writer, String JavaDoc name, String JavaDoc id, String JavaDoc value)
1610    {
1611        writer.beginEmpty("input");
1612        writer.attribute("type", "hidden");
1613        writer.attribute("name", name);
1614        writer.attribute("id", id);
1615        writer.attribute("value", value);
1616        writer.println();
1617    }
1618}
Popular Tags