1 20 package org.apache.cactus.extension.jsp; 21 22 import java.io.IOException ; 23 import java.util.ArrayList ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 27 import junit.framework.Assert; 28 29 import javax.servlet.jsp.JspException ; 30 import javax.servlet.jsp.PageContext ; 31 import javax.servlet.jsp.tagext.BodyContent ; 32 import javax.servlet.jsp.tagext.BodyTag ; 33 import javax.servlet.jsp.tagext.IterationTag ; 34 import javax.servlet.jsp.tagext.Tag ; 35 import javax.servlet.jsp.tagext.TryCatchFinally ; 36 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 40 224 public final class JspTagLifecycle 225 { 226 228 235 public abstract static class Interceptor 236 { 237 238 262 public void evalBody(int theIteration, BodyContent theBody) 263 throws JspException , IOException 264 { 265 } 267 268 272 public void skipBody() 273 { 274 } 276 277 } 278 279 285 private static class ExpectBodyEvaluatedInterceptor 286 extends Interceptor 287 { 288 291 private int actualNumIterations; 292 293 296 private int expectedNumIterations; 297 298 303 public ExpectBodyEvaluatedInterceptor(int theNumIterations) 304 { 305 this.expectedNumIterations = theNumIterations; 306 } 307 308 314 public void evalBody(int theIteration, BodyContent theBody) 315 { 316 actualNumIterations++; 317 if (actualNumIterations > expectedNumIterations) 318 { 319 Assert.fail("Expected " + expectedNumIterations 320 + " iterations, but was " + actualNumIterations); 321 } 322 } 323 324 328 public void skipBody() 329 { 330 if (actualNumIterations < expectedNumIterations) 331 { 332 Assert.fail("Expected " + expectedNumIterations 333 + " iterations, but was " + actualNumIterations); 334 } 335 } 336 } 337 338 343 private static class ExpectBodySkippedInterceptor 344 extends Interceptor 345 { 346 351 public void evalBody(int theIteration, BodyContent theBody) 352 { 353 Assert.fail("Tag body should have been skipped"); 354 } 355 } 356 357 363 private class ExpectScopedVariableExposedInterceptor 364 extends Interceptor 365 { 366 369 private String name; 370 371 374 private Object [] expectedValues; 375 376 379 private int scope; 380 381 389 public ExpectScopedVariableExposedInterceptor(String theName, 390 Object [] theExpectedValues, int theScope) 391 { 392 this.name = theName; 393 this.expectedValues = theExpectedValues; 394 this.scope = theScope; 395 } 396 397 402 public void evalBody(int theIteration, BodyContent theBody) 403 { 404 Assert.assertEquals(expectedValues[theIteration], 405 pageContext.getAttribute(name, scope)); 406 } 407 } 408 409 414 private class NestedTagInterceptor 415 extends Interceptor 416 { 417 420 private JspTagLifecycle lifecycle; 421 422 428 public NestedTagInterceptor(JspTagLifecycle theLifecycle) 429 { 430 this.lifecycle = theLifecycle; 431 } 432 433 438 public void evalBody(int theIteration, BodyContent theBody) 439 throws JspException , IOException 440 { 441 lifecycle.invoke(); 442 } 443 } 444 445 451 private class NestedTextInterceptor 452 extends Interceptor 453 { 454 457 private String text; 458 459 464 public NestedTextInterceptor(String theText) 465 { 466 this.text = theText; 467 } 468 469 474 public void evalBody(int theIteration, BodyContent theBody) 475 throws IOException 476 { 477 if (theBody != null) 478 { 479 theBody.print(text); 480 } 481 else 482 { 483 pageContext.getOut().print(text); 484 } 485 } 486 } 487 488 490 493 private static Log log = LogFactory.getLog(JspTagLifecycle.class); 494 495 497 500 protected PageContext pageContext; 501 502 505 private Tag tag; 506 507 510 private List interceptors; 511 512 514 520 public JspTagLifecycle(PageContext thePageContext, Tag theTag) 521 { 522 if ((thePageContext == null) || (theTag == null)) 523 { 524 throw new NullPointerException (); 525 } 526 this.tag = theTag; 527 this.pageContext = thePageContext; 528 this.tag.setPageContext(this.pageContext); 529 } 530 531 533 538 public void addInterceptor(Interceptor theInterceptor) 539 { 540 if (theInterceptor == null) 541 { 542 throw new NullPointerException (); 543 } 544 if (this.interceptors == null) 545 { 546 this.interceptors = new ArrayList (); 547 } 548 this.interceptors.add(theInterceptor); 549 } 550 551 559 public JspTagLifecycle addNestedTag(Tag theNestedTag) 560 { 561 if (theNestedTag == null) 562 { 563 throw new NullPointerException (); 564 } 565 JspTagLifecycle lifecycle = 566 new JspTagLifecycle(this.pageContext, theNestedTag); 567 theNestedTag.setParent(this.tag); 568 addInterceptor(new NestedTagInterceptor(lifecycle)); 569 return lifecycle; 570 } 571 572 578 public void addNestedText(String theNestedText) 579 { 580 if (theNestedText == null) 581 { 582 throw new NullPointerException (); 583 } 584 addInterceptor(new NestedTextInterceptor(theNestedText)); 585 } 586 587 591 public void expectBodyEvaluated() 592 { 593 addInterceptor(new ExpectBodyEvaluatedInterceptor(1)); 594 } 595 596 603 public void expectBodyEvaluated(int theNumIterations) 604 { 605 addInterceptor(new ExpectBodyEvaluatedInterceptor(theNumIterations)); 606 } 607 608 613 public void expectBodySkipped() 614 { 615 addInterceptor(new ExpectBodySkippedInterceptor()); 616 } 617 618 627 public void expectScopedVariableExposed(String theName, 628 Object [] theExpectedValues) 629 { 630 expectScopedVariableExposed(theName, theExpectedValues, 631 PageContext.PAGE_SCOPE); 632 } 633 634 644 public void expectScopedVariableExposed(String theName, 645 Object [] theExpectedValues, int theScope) 646 { 647 if ((theName == null) || (theExpectedValues == null)) 648 { 649 throw new NullPointerException (); 650 } 651 if (theExpectedValues.length == 0) 652 { 653 throw new IllegalArgumentException (); 654 } 655 if ((theScope != PageContext.PAGE_SCOPE) 656 && (theScope != PageContext.REQUEST_SCOPE) 657 && (theScope != PageContext.SESSION_SCOPE) 658 && (theScope != PageContext.APPLICATION_SCOPE)) 659 { 660 throw new IllegalArgumentException (); 661 } 662 addInterceptor( 663 new ExpectScopedVariableExposedInterceptor(theName, 664 theExpectedValues, theScope)); 665 } 666 667 676 public void invoke() throws JspException , IOException 677 { 678 if (this.tag instanceof TryCatchFinally ) 679 { 680 TryCatchFinally tryCatchFinally = (TryCatchFinally ) this.tag; 681 try 682 { 683 invokeInternal(); 684 } 685 catch (Throwable t1) 686 { 687 try 688 { 689 tryCatchFinally.doCatch(t1); 690 } 691 catch (Throwable t2) 692 { 693 throw new JspException (t2.getMessage()); 694 } 695 } 696 finally 697 { 698 tryCatchFinally.doFinally(); 699 } 700 } 701 else 702 { 703 invokeInternal(); 704 } 705 } 706 707 709 718 private void fireEvalBody(int theIteration, BodyContent theBody) 719 throws JspException , IOException 720 { 721 if (this.interceptors != null) 722 { 723 for (Iterator i = this.interceptors.iterator(); i.hasNext();) 724 { 725 ((Interceptor) i.next()).evalBody(theIteration, theBody); 726 } 727 } 728 } 729 730 733 private void fireSkipBody() 734 { 735 if (this.interceptors != null) 736 { 737 for (Iterator i = this.interceptors.iterator(); i.hasNext();) 738 { 739 ((Interceptor) i.next()).skipBody(); 740 } 741 } 742 } 743 744 751 private void invokeInternal() 752 throws JspException , IOException 753 { 754 int status = this.tag.doStartTag(); 755 if (this.tag instanceof IterationTag ) 756 { 757 if (status != Tag.SKIP_BODY) 758 { 759 BodyContent body = null; 760 try 761 { 762 IterationTag iterationTag = (IterationTag ) this.tag; 763 if ((status == BodyTag.EVAL_BODY_BUFFERED) 764 && (this.tag instanceof BodyTag )) 765 { 766 BodyTag bodyTag = (BodyTag ) this.tag; 767 body = pageContext.pushBody(); 768 if (log.isDebugEnabled()) 769 { 770 log.debug("Pushed body content [" 771 + body.getString() + "]"); 772 } 773 bodyTag.setBodyContent(body); 774 bodyTag.doInitBody(); 775 } 776 int iteration = 0; 777 do 778 { 779 fireEvalBody(iteration, body); 780 if (log.isDebugEnabled()) 781 { 782 log.debug("Body evaluated for the [" 783 + iteration + "] time"); 784 } 785 status = iterationTag.doAfterBody(); 786 iteration++; 787 } while (status == IterationTag.EVAL_BODY_AGAIN); 788 if (log.isDebugEnabled()) 789 { 790 log.debug("Body skipped"); 791 } 792 fireSkipBody(); 793 } 794 finally 795 { 796 if (body != null) 797 { 798 if (log.isDebugEnabled()) 799 { 800 log.debug("Popping body content [" 801 + body.getString() + "]"); 802 } 803 pageContext.popBody(); 804 body = null; 805 } 806 } 807 } 808 else 809 { 810 if (log.isDebugEnabled()) 811 { 812 log.debug("Body skipped"); 813 } 814 fireSkipBody(); 815 } 816 } 817 status = tag.doEndTag(); 818 } 819 820 } 821 | Popular Tags |