1 17 package org.apache.jasper.compiler; 18 19 import java.io.CharArrayWriter ; 20 import java.io.FileNotFoundException ; 21 import java.net.URL ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 25 import javax.servlet.jsp.tagext.TagAttributeInfo ; 26 import javax.servlet.jsp.tagext.TagFileInfo ; 27 import javax.servlet.jsp.tagext.TagInfo ; 28 import javax.servlet.jsp.tagext.TagLibraryInfo ; 29 30 import org.apache.jasper.Constants; 31 import org.apache.jasper.JasperException; 32 import org.apache.jasper.JspCompilationContext; 33 import org.xml.sax.Attributes ; 34 import org.xml.sax.helpers.AttributesImpl ; 35 36 45 46 class Parser implements TagConstants { 47 48 private ParserController parserController; 49 50 private JspCompilationContext ctxt; 51 52 private JspReader reader; 53 54 private String currentFile; 55 56 private Mark start; 57 58 private ErrorDispatcher err; 59 60 private int scriptlessCount; 61 62 private boolean isTagFile; 63 64 private boolean directivesOnly; 65 66 private URL jarFileUrl; 67 68 private PageInfo pageInfo; 69 70 private static final String JAVAX_BODY_CONTENT_PARAM = "JAVAX_BODY_CONTENT_PARAM"; 73 74 private static final String JAVAX_BODY_CONTENT_PLUGIN = "JAVAX_BODY_CONTENT_PLUGIN"; 75 76 private static final String JAVAX_BODY_CONTENT_TEMPLATE_TEXT = "JAVAX_BODY_CONTENT_TEMPLATE_TEXT"; 77 78 81 private Parser(ParserController pc, JspReader reader, boolean isTagFile, 82 boolean directivesOnly, URL jarFileUrl) { 83 this.parserController = pc; 84 this.ctxt = pc.getJspCompilationContext(); 85 this.pageInfo = pc.getCompiler().getPageInfo(); 86 this.err = pc.getCompiler().getErrorDispatcher(); 87 this.reader = reader; 88 this.currentFile = reader.mark().getFile(); 89 this.scriptlessCount = 0; 90 this.isTagFile = isTagFile; 91 this.directivesOnly = directivesOnly; 92 this.jarFileUrl = jarFileUrl; 93 start = reader.mark(); 94 } 95 96 108 public static Node.Nodes parse(ParserController pc, JspReader reader, 109 Node parent, boolean isTagFile, boolean directivesOnly, 110 URL jarFileUrl, String pageEnc, String jspConfigPageEnc, 111 boolean isDefaultPageEncoding, boolean isBomPresent) throws JasperException { 112 113 Parser parser = new Parser(pc, reader, isTagFile, directivesOnly, 114 jarFileUrl); 115 116 Node.Root root = new Node.Root(reader.mark(), parent, false); 117 root.setPageEncoding(pageEnc); 118 root.setJspConfigPageEncoding(jspConfigPageEnc); 119 root.setIsDefaultPageEncoding(isDefaultPageEncoding); 120 root.setIsBomPresent(isBomPresent); 121 122 if (directivesOnly) { 123 parser.parseTagFileDirectives(root); 124 return new Node.Nodes(root); 125 } 126 127 PageInfo pageInfo = pc.getCompiler().getPageInfo(); 129 if (parent == null) { 130 parser.addInclude(root, pageInfo.getIncludePrelude()); 131 } 132 while (reader.hasMoreInput()) { 133 parser.parseElements(root); 134 } 135 if (parent == null) { 136 parser.addInclude(root, pageInfo.getIncludeCoda()); 137 } 138 139 Node.Nodes page = new Node.Nodes(root); 140 return page; 141 } 142 143 146 Attributes parseAttributes() throws JasperException { 147 AttributesImpl attrs = new AttributesImpl (); 148 149 reader.skipSpaces(); 150 while (parseAttribute(attrs)) 151 reader.skipSpaces(); 152 153 return attrs; 154 } 155 156 159 public static Attributes parseAttributes(ParserController pc, 160 JspReader reader) throws JasperException { 161 Parser tmpParser = new Parser(pc, reader, false, false, null); 162 return tmpParser.parseAttributes(); 163 } 164 165 172 private boolean parseAttribute(AttributesImpl attrs) throws JasperException { 173 174 String qName = parseName(); 176 if (qName == null) 177 return false; 178 179 String localName = qName; 181 String uri = ""; 182 int index = qName.indexOf(':'); 183 if (index != -1) { 184 String prefix = qName.substring(0, index); 185 uri = pageInfo.getURI(prefix); 186 if (uri == null) { 187 err.jspError(reader.mark(), 188 "jsp.error.attribute.invalidPrefix", prefix); 189 } 190 localName = qName.substring(index + 1); 191 } 192 193 reader.skipSpaces(); 194 if (!reader.matches("=")) 195 err.jspError(reader.mark(), "jsp.error.attribute.noequal"); 196 197 reader.skipSpaces(); 198 char quote = (char) reader.nextChar(); 199 if (quote != '\'' && quote != '"') 200 err.jspError(reader.mark(), "jsp.error.attribute.noquote"); 201 202 String watchString = ""; 203 if (reader.matches("<%=")) 204 watchString = "%>"; 205 watchString = watchString + quote; 206 207 String attrValue = parseAttributeValue(watchString); 208 attrs.addAttribute(uri, localName, qName, "CDATA", attrValue); 209 return true; 210 } 211 212 215 private String parseName() throws JasperException { 216 char ch = (char) reader.peekChar(); 217 if (Character.isLetter(ch) || ch == '_' || ch == ':') { 218 StringBuffer buf = new StringBuffer (); 219 buf.append(ch); 220 reader.nextChar(); 221 ch = (char) reader.peekChar(); 222 while (Character.isLetter(ch) || Character.isDigit(ch) || ch == '.' 223 || ch == '_' || ch == '-' || ch == ':') { 224 buf.append(ch); 225 reader.nextChar(); 226 ch = (char) reader.peekChar(); 227 } 228 return buf.toString(); 229 } 230 return null; 231 } 232 233 238 private String parseAttributeValue(String watch) throws JasperException { 239 Mark start = reader.mark(); 240 Mark stop = reader.skipUntilIgnoreEsc(watch); 241 if (stop == null) { 242 err.jspError(start, "jsp.error.attribute.unterminated", watch); 243 } 244 245 String ret = parseQuoted(reader.getText(start, stop)); 246 if (watch.length() == 1) return ret; 248 249 return "<%=" + ret + "%>"; 252 } 253 254 258 private String parseQuoted(String tx) { 259 StringBuffer buf = new StringBuffer (); 260 int size = tx.length(); 261 int i = 0; 262 while (i < size) { 263 char ch = tx.charAt(i); 264 if (ch == '&') { 265 if (i + 5 < size && tx.charAt(i + 1) == 'a' 266 && tx.charAt(i + 2) == 'p' && tx.charAt(i + 3) == 'o' 267 && tx.charAt(i + 4) == 's' && tx.charAt(i + 5) == ';') { 268 buf.append('\''); 269 i += 6; 270 } else if (i + 5 < size && tx.charAt(i + 1) == 'q' 271 && tx.charAt(i + 2) == 'u' && tx.charAt(i + 3) == 'o' 272 && tx.charAt(i + 4) == 't' && tx.charAt(i + 5) == ';') { 273 buf.append('"'); 274 i += 6; 275 } else { 276 buf.append(ch); 277 ++i; 278 } 279 } else if (ch == '\\' && i + 1 < size) { 280 ch = tx.charAt(i + 1); 281 if (ch == '\\' || ch == '\"' || ch == '\'' || ch == '>') { 282 buf.append(ch); 283 i += 2; 284 } else if (ch == '$') { 285 buf.append(Constants.ESC); 287 i += 2; 288 } else { 289 buf.append('\\'); 290 ++i; 291 } 292 } else { 293 buf.append(ch); 294 ++i; 295 } 296 } 297 return buf.toString(); 298 } 299 300 private String parseScriptText(String tx) { 301 CharArrayWriter cw = new CharArrayWriter (); 302 int size = tx.length(); 303 int i = 0; 304 while (i < size) { 305 char ch = tx.charAt(i); 306 if (i + 2 < size && ch == '%' && tx.charAt(i + 1) == '\\' 307 && tx.charAt(i + 2) == '>') { 308 cw.write('%'); 309 cw.write('>'); 310 i += 3; 311 } else { 312 cw.write(ch); 313 ++i; 314 } 315 } 316 cw.close(); 317 return cw.toString(); 318 } 319 320 323 private void processIncludeDirective(String file, Node parent) 324 throws JasperException { 325 if (file == null) { 326 return; 327 } 328 329 try { 330 parserController.parse(file, parent, jarFileUrl); 331 } catch (FileNotFoundException ex) { 332 err.jspError(start, "jsp.error.file.not.found", file); 333 } catch (Exception ex) { 334 err.jspError(start, ex.getMessage()); 335 } 336 } 337 338 342 private void parsePageDirective(Node parent) throws JasperException { 343 Attributes attrs = parseAttributes(); 344 Node.PageDirective n = new Node.PageDirective(attrs, start, parent); 345 346 351 for (int i = 0; i < attrs.getLength(); i++) { 352 if ("import".equals(attrs.getQName(i))) { 353 n.addImport(attrs.getValue(i)); 354 } 355 } 356 } 357 358 362 private void parseIncludeDirective(Node parent) throws JasperException { 363 Attributes attrs = parseAttributes(); 364 365 Node includeNode = new Node.IncludeDirective(attrs, start, parent); 367 processIncludeDirective(attrs.getValue("file"), includeNode); 368 } 369 370 374 private void addInclude(Node parent, List files) throws JasperException { 375 if (files != null) { 376 Iterator iter = files.iterator(); 377 while (iter.hasNext()) { 378 String file = (String ) iter.next(); 379 AttributesImpl attrs = new AttributesImpl (); 380 attrs.addAttribute("", "file", "file", "CDATA", file); 381 382 Node includeNode = new Node.IncludeDirective(attrs, reader 384 .mark(), parent); 385 processIncludeDirective(file, includeNode); 386 } 387 } 388 } 389 390 394 private void parseTaglibDirective(Node parent) throws JasperException { 395 396 Attributes attrs = parseAttributes(); 397 String uri = attrs.getValue("uri"); 398 String prefix = attrs.getValue("prefix"); 399 if (prefix != null) { 400 Mark prevMark = pageInfo.getNonCustomTagPrefix(prefix); 401 if (prevMark != null) { 402 err.jspError(reader.mark(), "jsp.error.prefix.use_before_dcl", 403 prefix, prevMark.getFile(), "" 404 + prevMark.getLineNumber()); 405 } 406 if (uri != null) { 407 String uriPrev = pageInfo.getURI(prefix); 408 if (uriPrev != null && !uriPrev.equals(uri)) { 409 err.jspError(reader.mark(), "jsp.error.prefix.refined", 410 prefix, uri, uriPrev); 411 } 412 if (pageInfo.getTaglib(uri) == null) { 413 TagLibraryInfoImpl impl = null; 414 if (ctxt.getOptions().isCaching()) { 415 impl = (TagLibraryInfoImpl) ctxt.getOptions() 416 .getCache().get(uri); 417 } 418 if (impl == null) { 419 String [] location = ctxt.getTldLocation(uri); 420 impl = new TagLibraryInfoImpl(ctxt, parserController, pageInfo, 421 prefix, uri, location, err); 422 if (ctxt.getOptions().isCaching()) { 423 ctxt.getOptions().getCache().put(uri, impl); 424 } 425 } 426 pageInfo.addTaglib(uri, impl); 427 } 428 pageInfo.addPrefixMapping(prefix, uri); 429 } else { 430 String tagdir = attrs.getValue("tagdir"); 431 if (tagdir != null) { 432 String urnTagdir = URN_JSPTAGDIR + tagdir; 433 if (pageInfo.getTaglib(urnTagdir) == null) { 434 pageInfo.addTaglib(urnTagdir, 435 new ImplicitTagLibraryInfo(ctxt, 436 parserController, pageInfo, prefix, tagdir, err)); 437 } 438 pageInfo.addPrefixMapping(prefix, urnTagdir); 439 } 440 } 441 } 442 443 new Node.TaglibDirective(attrs, start, parent); 444 } 445 446 455 private void parseDirective(Node parent) throws JasperException { 456 reader.skipSpaces(); 457 458 String directive = null; 459 if (reader.matches("page")) { 460 directive = "<%@ page"; 461 if (isTagFile) { 462 err.jspError(reader.mark(), "jsp.error.directive.istagfile", 463 directive); 464 } 465 parsePageDirective(parent); 466 } else if (reader.matches("include")) { 467 directive = "<%@ include"; 468 parseIncludeDirective(parent); 469 } else if (reader.matches("taglib")) { 470 if (directivesOnly) { 471 return; 474 } 475 directive = "<%@ taglib"; 476 parseTaglibDirective(parent); 477 } else if (reader.matches("tag")) { 478 directive = "<%@ tag"; 479 if (!isTagFile) { 480 err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", 481 directive); 482 } 483 parseTagDirective(parent); 484 } else if (reader.matches("attribute")) { 485 directive = "<%@ attribute"; 486 if (!isTagFile) { 487 err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", 488 directive); 489 } 490 parseAttributeDirective(parent); 491 } else if (reader.matches("variable")) { 492 directive = "<%@ variable"; 493 if (!isTagFile) { 494 err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", 495 directive); 496 } 497 parseVariableDirective(parent); 498 } else { 499 err.jspError(reader.mark(), "jsp.error.invalid.directive"); 500 } 501 502 reader.skipSpaces(); 503 if (!reader.matches("%>")) { 504 err.jspError(start, "jsp.error.unterminated", directive); 505 } 506 } 507 508 521 private void parseXMLDirective(Node parent) throws JasperException { 522 reader.skipSpaces(); 523 524 String eTag = null; 525 if (reader.matches("page")) { 526 eTag = "jsp:directive.page"; 527 if (isTagFile) { 528 err.jspError(reader.mark(), "jsp.error.directive.istagfile", 529 "<" + eTag); 530 } 531 parsePageDirective(parent); 532 } else if (reader.matches("include")) { 533 eTag = "jsp:directive.include"; 534 parseIncludeDirective(parent); 535 } else if (reader.matches("tag")) { 536 eTag = "jsp:directive.tag"; 537 if (!isTagFile) { 538 err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", 539 "<" + eTag); 540 } 541 parseTagDirective(parent); 542 } else if (reader.matches("attribute")) { 543 eTag = "jsp:directive.attribute"; 544 if (!isTagFile) { 545 err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", 546 "<" + eTag); 547 } 548 parseAttributeDirective(parent); 549 } else if (reader.matches("variable")) { 550 eTag = "jsp:directive.variable"; 551 if (!isTagFile) { 552 err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", 553 "<" + eTag); 554 } 555 parseVariableDirective(parent); 556 } else { 557 err.jspError(reader.mark(), "jsp.error.invalid.directive"); 558 } 559 560 reader.skipSpaces(); 561 if (reader.matches(">")) { 562 reader.skipSpaces(); 563 if (!reader.matchesETag(eTag)) { 564 err.jspError(start, "jsp.error.unterminated", "<" + eTag); 565 } 566 } else if (!reader.matches("/>")) { 567 err.jspError(start, "jsp.error.unterminated", "<" + eTag); 568 } 569 } 570 571 575 private void parseTagDirective(Node parent) throws JasperException { 576 Attributes attrs = parseAttributes(); 577 Node.TagDirective n = new Node.TagDirective(attrs, start, parent); 578 579 584 for (int i = 0; i < attrs.getLength(); i++) { 585 if ("import".equals(attrs.getQName(i))) { 586 n.addImport(attrs.getValue(i)); 587 } 588 } 589 } 590 591 595 private void parseAttributeDirective(Node parent) throws JasperException { 596 Attributes attrs = parseAttributes(); 597 Node.AttributeDirective n = new Node.AttributeDirective(attrs, start, 598 parent); 599 } 600 601 605 private void parseVariableDirective(Node parent) throws JasperException { 606 Attributes attrs = parseAttributes(); 607 Node.VariableDirective n = new Node.VariableDirective(attrs, start, 608 parent); 609 } 610 611 614 private void parseComment(Node parent) throws JasperException { 615 start = reader.mark(); 616 Mark stop = reader.skipUntil("--%>"); 617 if (stop == null) { 618 err.jspError(start, "jsp.error.unterminated", "<%--"); 619 } 620 621 new Node.Comment(reader.getText(start, stop), start, parent); 622 } 623 624 627 private void parseDeclaration(Node parent) throws JasperException { 628 start = reader.mark(); 629 Mark stop = reader.skipUntil("%>"); 630 if (stop == null) { 631 err.jspError(start, "jsp.error.unterminated", "<%!"); 632 } 633 634 new Node.Declaration(parseScriptText(reader.getText(start, stop)), 635 start, parent); 636 } 637 638 644 private void parseXMLDeclaration(Node parent) throws JasperException { 645 reader.skipSpaces(); 646 if (!reader.matches("/>")) { 647 if (!reader.matches(">")) { 648 err.jspError(start, "jsp.error.unterminated", 649 "<jsp:declaration>"); 650 } 651 Mark stop; 652 String text; 653 while (true) { 654 start = reader.mark(); 655 stop = reader.skipUntil("<"); 656 if (stop == null) { 657 err.jspError(start, "jsp.error.unterminated", 658 "<jsp:declaration>"); 659 } 660 text = parseScriptText(reader.getText(start, stop)); 661 new Node.Declaration(text, start, parent); 662 if (reader.matches("![CDATA[")) { 663 start = reader.mark(); 664 stop = reader.skipUntil("]]>"); 665 if (stop == null) { 666 err.jspError(start, "jsp.error.unterminated", "CDATA"); 667 } 668 text = parseScriptText(reader.getText(start, stop)); 669 new Node.Declaration(text, start, parent); 670 } else { 671 break; 672 } 673 } 674 675 if (!reader.matchesETagWithoutLessThan("jsp:declaration")) { 676 err.jspError(start, "jsp.error.unterminated", 677 "<jsp:declaration>"); 678 } 679 } 680 } 681 682 685 private void parseExpression(Node parent) throws JasperException { 686 start = reader.mark(); 687 Mark stop = reader.skipUntil("%>"); 688 if (stop == null) { 689 err.jspError(start, "jsp.error.unterminated", "<%="); 690 } 691 692 new Node.Expression(parseScriptText(reader.getText(start, stop)), 693 start, parent); 694 } 695 696 700 private void parseXMLExpression(Node parent) throws JasperException { 701 reader.skipSpaces(); 702 if (!reader.matches("/>")) { 703 if (!reader.matches(">")) { 704 err.jspError(start, "jsp.error.unterminated", 705 "<jsp:expression>"); 706 } 707 Mark stop; 708 String text; 709 while (true) { 710 start = reader.mark(); 711 stop = reader.skipUntil("<"); 712 if (stop == null) { 713 err.jspError(start, "jsp.error.unterminated", 714 "<jsp:expression>"); 715 } 716 text = parseScriptText(reader.getText(start, stop)); 717 new Node.Expression(text, start, parent); 718 if (reader.matches("![CDATA[")) { 719 start = reader.mark(); 720 stop = reader.skipUntil("]]>"); 721 if (stop == null) { 722 err.jspError(start, "jsp.error.unterminated", "CDATA"); 723 } 724 text = parseScriptText(reader.getText(start, stop)); 725 new Node.Expression(text, start, parent); 726 } else { 727 break; 728 } 729 } 730 if (!reader.matchesETagWithoutLessThan("jsp:expression")) { 731 err.jspError(start, "jsp.error.unterminated", 732 "<jsp:expression>"); 733 } 734 } 735 } 736 737 741 private void parseELExpression(Node parent, char type) throws JasperException { 742 start = reader.mark(); 743 Mark last = null; 744 boolean singleQuoted = false, doubleQuoted = false; 745 int currentChar; 746 do { 747 last = reader.mark(); currentChar = reader.nextChar(); 750 if (currentChar == '\\' && (singleQuoted || doubleQuoted)) { 751 reader.nextChar(); 753 currentChar = reader.nextChar(); 754 } 755 if (currentChar == -1) 756 err.jspError(start, "jsp.error.unterminated", type + "{"); 757 if (currentChar == '"') 758 doubleQuoted = !doubleQuoted; 759 if (currentChar == '\'') 760 singleQuoted = !singleQuoted; 761 } while (currentChar != '}' || (singleQuoted || doubleQuoted)); 762 763 new Node.ELExpression(type, reader.getText(start, last), start, parent); 764 } 765 766 769 private void parseScriptlet(Node parent) throws JasperException { 770 start = reader.mark(); 771 Mark stop = reader.skipUntil("%>"); 772 if (stop == null) { 773 err.jspError(start, "jsp.error.unterminated", "<%"); 774 } 775 776 new Node.Scriptlet(parseScriptText(reader.getText(start, stop)), start, 777 parent); 778 } 779 780 784 private void parseXMLScriptlet(Node parent) throws JasperException { 785 reader.skipSpaces(); 786 if (!reader.matches("/>")) { 787 if (!reader.matches(">")) { 788 err.jspError(start, "jsp.error.unterminated", 789 "<jsp:scriptlet>"); 790 } 791 Mark stop; 792 String text; 793 while (true) { 794 start = reader.mark(); 795 stop = reader.skipUntil("<"); 796 if (stop == null) { 797 err.jspError(start, "jsp.error.unterminated", 798 "<jsp:scriptlet>"); 799 } 800 text = parseScriptText(reader.getText(start, stop)); 801 new Node.Scriptlet(text, start, parent); 802 if (reader.matches("![CDATA[")) { 803 start = reader.mark(); 804 stop = reader.skipUntil("]]>"); 805 if (stop == null) { 806 err.jspError(start, "jsp.error.unterminated", "CDATA"); 807 } 808 text = parseScriptText(reader.getText(start, stop)); 809 new Node.Scriptlet(text, start, parent); 810 } else { 811 break; 812 } 813 } 814 815 if (!reader.matchesETagWithoutLessThan("jsp:scriptlet")) { 816 err.jspError(start, "jsp.error.unterminated", 817 "<jsp:scriptlet>"); 818 } 819 } 820 } 821 822 825 private void parseParam(Node parent) throws JasperException { 826 if (!reader.matches("<jsp:param")) { 827 err.jspError(reader.mark(), "jsp.error.paramexpected"); 828 } 829 Attributes attrs = parseAttributes(); 830 reader.skipSpaces(); 831 832 Node paramActionNode = new Node.ParamAction(attrs, start, parent); 833 834 parseEmptyBody(paramActionNode, "jsp:param"); 835 836 reader.skipSpaces(); 837 } 838 839 850 private void parseInclude(Node parent) throws JasperException { 851 Attributes attrs = parseAttributes(); 852 reader.skipSpaces(); 853 854 Node includeNode = new Node.IncludeAction(attrs, start, parent); 855 856 parseOptionalBody(includeNode, "jsp:include", JAVAX_BODY_CONTENT_PARAM); 857 } 858 859 862 private void parseForward(Node parent) throws JasperException { 863 Attributes attrs = parseAttributes(); 864 reader.skipSpaces(); 865 866 Node forwardNode = new Node.ForwardAction(attrs, start, parent); 867 868 parseOptionalBody(forwardNode, "jsp:forward", JAVAX_BODY_CONTENT_PARAM); 869 } 870 871 private void parseInvoke(Node parent) throws JasperException { 872 Attributes attrs = parseAttributes(); 873 reader.skipSpaces(); 874 875 Node invokeNode = new Node.InvokeAction(attrs, start, parent); 876 877 parseEmptyBody(invokeNode, "jsp:invoke"); 878 } 879 880 private void parseDoBody(Node parent) throws JasperException { 881 Attributes attrs = parseAttributes(); 882 reader.skipSpaces(); 883 884 Node doBodyNode = new Node.DoBodyAction(attrs, start, parent); 885 886 parseEmptyBody(doBodyNode, "jsp:doBody"); 887 } 888 889 private void parseElement(Node parent) throws JasperException { 890 Attributes attrs = parseAttributes(); 891 reader.skipSpaces(); 892 893 Node elementNode = new Node.JspElement(attrs, start, parent); 894 895 parseOptionalBody(elementNode, "jsp:element", TagInfo.BODY_CONTENT_JSP); 896 } 897 898 901 private void parseGetProperty(Node parent) throws JasperException { 902 Attributes attrs = parseAttributes(); 903 reader.skipSpaces(); 904 905 Node getPropertyNode = new Node.GetProperty(attrs, start, parent); 906 907 parseOptionalBody(getPropertyNode, "jsp:getProperty", 908 TagInfo.BODY_CONTENT_EMPTY); 909 } 910 911 914 private void parseSetProperty(Node parent) throws JasperException { 915 Attributes attrs = parseAttributes(); 916 reader.skipSpaces(); 917 918 Node setPropertyNode = new Node.SetProperty(attrs, start, parent); 919 920 parseOptionalBody(setPropertyNode, "jsp:setProperty", 921 TagInfo.BODY_CONTENT_EMPTY); 922 } 923 924 928 private void parseEmptyBody(Node parent, String tag) throws JasperException { 929 if (reader.matches("/>")) { 930 } else if (reader.matches(">")) { 932 if (reader.matchesETag(tag)) { 933 } else if (reader.matchesOptionalSpacesFollowedBy("<jsp:attribute")) { 935 parseNamedAttributes(parent); 937 if (!reader.matchesETag(tag)) { 938 err.jspError(reader.mark(), 940 "jsp.error.jspbody.emptybody.only", "<" + tag); 941 } 942 } else { 943 err.jspError(reader.mark(), "jsp.error.jspbody.emptybody.only", 944 "<" + tag); 945 } 946 } else { 947 err.jspError(reader.mark(), "jsp.error.unterminated", "<" + tag); 948 } 949 } 950 951 954 private void parseUseBean(Node parent) throws JasperException { 955 Attributes attrs = parseAttributes(); 956 reader.skipSpaces(); 957 958 Node useBeanNode = new Node.UseBean(attrs, start, parent); 959 960 parseOptionalBody(useBeanNode, "jsp:useBean", TagInfo.BODY_CONTENT_JSP); 961 } 962 963 986 private void parseOptionalBody(Node parent, String tag, String bodyType) 987 throws JasperException { 988 if (reader.matches("/>")) { 989 return; 991 } 992 993 if (!reader.matches(">")) { 994 err.jspError(reader.mark(), "jsp.error.unterminated", "<" + tag); 995 } 996 997 if (reader.matchesETag(tag)) { 998 return; 1000 } 1001 1002 if (!parseJspAttributeAndBody(parent, tag, bodyType)) { 1003 parseBody(parent, tag, bodyType); 1005 } 1006 } 1007 1008 1015 private boolean parseJspAttributeAndBody(Node parent, String tag, 1016 String bodyType) throws JasperException { 1017 boolean result = false; 1018 1019 if (reader.matchesOptionalSpacesFollowedBy("<jsp:attribute")) { 1020 1023 parseNamedAttributes(parent); 1025 1026 result = true; 1027 } 1028 1029 if (reader.matchesOptionalSpacesFollowedBy("<jsp:body")) { 1030 parseJspBody(parent, bodyType); 1032 reader.skipSpaces(); 1033 if (!reader.matchesETag(tag)) { 1034 err.jspError(reader.mark(), "jsp.error.unterminated", "<" 1035 + tag); 1036 } 1037 1038 result = true; 1039 } else if (result && !reader.matchesETag(tag)) { 1040 err.jspError(reader.mark(), "jsp.error.jspbody.required", "<" 1043 + tag); 1044 } 1045 1046 return result; 1047 } 1048 1049 1053 private void parseJspParams(Node parent) throws JasperException { 1054 Node jspParamsNode = new Node.ParamsAction(start, parent); 1055 parseOptionalBody(jspParamsNode, "jsp:params", JAVAX_BODY_CONTENT_PARAM); 1056 } 1057 1058 1063 private void parseFallBack(Node parent) throws JasperException { 1064 Node fallBackNode = new Node.FallBackAction(start, parent); 1065 parseOptionalBody(fallBackNode, "jsp:fallback", 1066 JAVAX_BODY_CONTENT_TEMPLATE_TEXT); 1067 } 1068 1069 1080 private void parsePlugin(Node parent) throws JasperException { 1081 Attributes attrs = parseAttributes(); 1082 reader.skipSpaces(); 1083 1084 Node pluginNode = new Node.PlugIn(attrs, start, parent); 1085 1086 parseOptionalBody(pluginNode, "jsp:plugin", JAVAX_BODY_CONTENT_PLUGIN); 1087 } 1088 1089 1093 private void parsePluginTags(Node parent) throws JasperException { 1094 reader.skipSpaces(); 1095 1096 if (reader.matches("<jsp:params")) { 1097 parseJspParams(parent); 1098 reader.skipSpaces(); 1099 } 1100 1101 if (reader.matches("<jsp:fallback")) { 1102 parseFallBack(parent); 1103 reader.skipSpaces(); 1104 } 1105 } 1106 1107 1114 private void parseStandardAction(Node parent) throws JasperException { 1115 Mark start = reader.mark(); 1116 1117 if (reader.matches(INCLUDE_ACTION)) { 1118 parseInclude(parent); 1119 } else if (reader.matches(FORWARD_ACTION)) { 1120 parseForward(parent); 1121 } else if (reader.matches(INVOKE_ACTION)) { 1122 if (!isTagFile) { 1123 err.jspError(reader.mark(), "jsp.error.action.isnottagfile", 1124 "<jsp:invoke"); 1125 } 1126 parseInvoke(parent); 1127 } else if (reader.matches(DOBODY_ACTION)) { 1128 if (!isTagFile) { 1129 err.jspError(reader.mark(), "jsp.error.action.isnottagfile", 1130 "<jsp:doBody"); 1131 } 1132 parseDoBody(parent); 1133 } else if (reader.matches(GET_PROPERTY_ACTION)) { 1134 parseGetProperty(parent); 1135 } else if (reader.matches(SET_PROPERTY_ACTION)) { 1136 parseSetProperty(parent); 1137 } else if (reader.matches(USE_BEAN_ACTION)) { 1138 parseUseBean(parent); 1139 } else if (reader.matches(PLUGIN_ACTION)) { 1140 parsePlugin(parent); 1141 } else if (reader.matches(ELEMENT_ACTION)) { 1142 parseElement(parent); 1143 } else if (reader.matches(ATTRIBUTE_ACTION)) { 1144 err.jspError(start, "jsp.error.namedAttribute.invalidUse"); 1145 } else if (reader.matches(BODY_ACTION)) { 1146 err.jspError(start, "jsp.error.jspbody.invalidUse"); 1147 } else if (reader.matches(FALLBACK_ACTION)) { 1148 err.jspError(start, "jsp.error.fallback.invalidUse"); 1149 } else if (reader.matches(PARAMS_ACTION)) { 1150 err.jspError(start, "jsp.error.params.invalidUse"); 1151 } else if (reader.matches(PARAM_ACTION)) { 1152 err.jspError(start, "jsp.error.param.invalidUse"); 1153 } else if (reader.matches(OUTPUT_ACTION)) { 1154 err.jspError(start, "jsp.error.jspoutput.invalidUse"); 1155 } else { 1156 err.jspError(start, "jsp.error.badStandardAction"); 1157 } 1158 } 1159 1160 1182 private boolean parseCustomTag(Node parent) throws JasperException { 1183 1184 if (reader.peekChar() != '<') { 1185 return false; 1186 } 1187 1188 reader.nextChar(); String tagName = reader.parseToken(false); 1191 int i = tagName.indexOf(':'); 1192 if (i == -1) { 1193 reader.reset(start); 1194 return false; 1195 } 1196 1197 String prefix = tagName.substring(0, i); 1198 String shortTagName = tagName.substring(i + 1); 1199 1200 String uri = pageInfo.getURI(prefix); 1202 if (uri == null) { 1203 reader.reset(start); 1204 pageInfo.putNonCustomTagPrefix(prefix, reader.mark()); 1206 return false; 1207 } 1208 1209 TagLibraryInfo tagLibInfo = pageInfo.getTaglib(uri); 1210 TagInfo tagInfo = tagLibInfo.getTag(shortTagName); 1211 TagFileInfo tagFileInfo = tagLibInfo.getTagFile(shortTagName); 1212 if (tagInfo == null && tagFileInfo == null) { 1213 err.jspError(start, "jsp.error.bad_tag", shortTagName, prefix); 1214 } 1215 Class tagHandlerClass = null; 1216 if (tagInfo != null) { 1217 String handlerClassName = tagInfo.getTagClassName(); 1220 try { 1221 tagHandlerClass = ctxt.getClassLoader().loadClass( 1222 handlerClassName); 1223 } catch (Exception e) { 1224 err.jspError(start, "jsp.error.loadclass.taghandler", 1225 handlerClassName, tagName); 1226 } 1227 } 1228 1229 1233 Attributes attrs = parseAttributes(); 1235 reader.skipSpaces(); 1236 1237 if (reader.matches("/>")) { 1239 if (tagInfo != null) { 1240 new Node.CustomTag(tagName, prefix, shortTagName, uri, attrs, 1241 start, parent, tagInfo, tagHandlerClass); 1242 } else { 1243 new Node.CustomTag(tagName, prefix, shortTagName, uri, attrs, 1244 start, parent, tagFileInfo); 1245 } 1246 return true; 1247 } 1248 1249 1253 String bc; 1257 if (tagInfo != null) { 1258 bc = tagInfo.getBodyContent(); 1259 } else { 1260 bc = tagFileInfo.getTagInfo().getBodyContent(); 1261 } 1262 1263 Node tagNode = null; 1264 if (tagInfo != null) { 1265 tagNode = new Node.CustomTag(tagName, prefix, shortTagName, uri, 1266 attrs, start, parent, tagInfo, tagHandlerClass); 1267 } else { 1268 tagNode = new Node.CustomTag(tagName, prefix, shortTagName, uri, 1269 attrs, start, parent, tagFileInfo); 1270 } 1271 1272 parseOptionalBody(tagNode, tagName, bc); 1273 1274 return true; 1275 } 1276 1277 1281 private void parseTemplateText(Node parent) throws JasperException { 1282 1283 if (!reader.hasMoreInput()) 1284 return; 1285 1286 CharArrayWriter ttext = new CharArrayWriter (); 1287 int ch = reader.nextChar(); 1289 if (ch == '\\') { 1290 reader.pushChar(); 1291 } else { 1292 ttext.write(ch); 1293 } 1294 1295 while (reader.hasMoreInput()) { 1296 ch = reader.nextChar(); 1297 if (ch == '<') { 1298 reader.pushChar(); 1299 break; 1300 } else if (ch == '$' || ch == '#') { 1301 if (!reader.hasMoreInput()) { 1302 ttext.write(ch); 1303 break; 1304 } 1305 if (reader.nextChar() == '{') { 1306 reader.pushChar(); 1307 reader.pushChar(); 1308 break; 1309 } 1310 ttext.write(ch); 1311 reader.pushChar(); 1312 continue; 1313 } else if (ch == '\\') { 1314 if (!reader.hasMoreInput()) { 1315 ttext.write('\\'); 1316 break; 1317 } 1318 char next = (char) reader.peekChar(); 1319 if (next == '%' || next == '$' || next == '#') { 1325 ch = reader.nextChar(); 1326 } 1327 } 1328 ttext.write(ch); 1329 } 1330 new Node.TemplateText(ttext.toString(), start, parent); 1331 } 1332 1333 1338 private void parseXMLTemplateText(Node parent) throws JasperException { 1339 reader.skipSpaces(); 1340 if (!reader.matches("/>")) { 1341 if (!reader.matches(">")) { 1342 err.jspError(start, "jsp.error.unterminated", 1343 "<jsp:text>"); 1344 } 1345 CharArrayWriter ttext = new CharArrayWriter (); 1346 while (reader.hasMoreInput()) { 1347 int ch = reader.nextChar(); 1348 if (ch == '<') { 1349 if (!reader.matches("![CDATA[")) { 1351 break; 1352 } 1353 start = reader.mark(); 1354 Mark stop = reader.skipUntil("]]>"); 1355 if (stop == null) { 1356 err.jspError(start, "jsp.error.unterminated", "CDATA"); 1357 } 1358 String text = reader.getText(start, stop); 1359 ttext.write(text, 0, text.length()); 1360 } else if (ch == '\\') { 1361 if (!reader.hasMoreInput()) { 1362 ttext.write('\\'); 1363 break; 1364 } 1365 ch = reader.nextChar(); 1366 if (ch != '$' && ch != '#') { 1367 ttext.write('\\'); 1368 } 1369 ttext.write(ch); 1370 } else if (ch == '$' || ch == '#') { 1371 if (!reader.hasMoreInput()) { 1372 ttext.write(ch); 1373 break; 1374 } 1375 if (reader.nextChar() != '{') { 1376 ttext.write(ch); 1377 reader.pushChar(); 1378 continue; 1379 } 1380 new Node.TemplateText(ttext.toString(), start, parent); 1382 1383 start = reader.mark(); 1385 parseELExpression(parent, (char) ch); 1386 1387 start = reader.mark(); 1388 ttext = new CharArrayWriter (); 1389 } else { 1390 ttext.write(ch); 1391 } 1392 } 1393 1394 new Node.TemplateText(ttext.toString(), start, parent); 1395 1396 if (!reader.hasMoreInput()) { 1397 err.jspError(start, "jsp.error.unterminated", 1398 "<jsp:text>"); 1399 } else if (!reader.matchesETagWithoutLessThan("jsp:text")) { 1400 err.jspError(start, "jsp.error.jsptext.badcontent"); 1401 } 1402 } 1403 } 1404 1405 1413 private void parseElements(Node parent) throws JasperException { 1414 if (scriptlessCount > 0) { 1415 parseElementsScriptless(parent); 1419 return; 1420 } 1421 1422 start = reader.mark(); 1423 if (reader.matches("<%--")) { 1424 parseComment(parent); 1425 } else if (reader.matches("<%@")) { 1426 parseDirective(parent); 1427 } else if (reader.matches("<jsp:directive.")) { 1428 parseXMLDirective(parent); 1429 } else if (reader.matches("<%!")) { 1430 parseDeclaration(parent); 1431 } else if (reader.matches("<jsp:declaration")) { 1432 parseXMLDeclaration(parent); 1433 } else if (reader.matches("<%=")) { 1434 parseExpression(parent); 1435 } else if (reader.matches("<jsp:expression")) { 1436 parseXMLExpression(parent); 1437 } else if (reader.matches("<%")) { 1438 parseScriptlet(parent); 1439 } else if (reader.matches("<jsp:scriptlet")) { 1440 parseXMLScriptlet(parent); 1441 } else if (reader.matches("<jsp:text")) { 1442 parseXMLTemplateText(parent); 1443 } else if (reader.matches("${")) { 1444 parseELExpression(parent, '$'); 1445 } else if (reader.matches("#{")) { 1446 parseELExpression(parent, '#'); 1447 } else if (reader.matches("<jsp:")) { 1448 parseStandardAction(parent); 1449 } else if (!parseCustomTag(parent)) { 1450 checkUnbalancedEndTag(); 1451 parseTemplateText(parent); 1452 } 1453 } 1454 1455 1464 private void parseElementsScriptless(Node parent) throws JasperException { 1465 scriptlessCount++; 1468 1469 start = reader.mark(); 1470 if (reader.matches("<%--")) { 1471 parseComment(parent); 1472 } else if (reader.matches("<%@")) { 1473 parseDirective(parent); 1474 } else if (reader.matches("<jsp:directive.")) { 1475 parseXMLDirective(parent); 1476 } else if (reader.matches("<%!")) { 1477 err.jspError(reader.mark(), "jsp.error.no.scriptlets"); 1478 } else if (reader.matches("<jsp:declaration")) { 1479 err.jspError(reader.mark(), "jsp.error.no.scriptlets"); 1480 } else if (reader.matches("<%=")) { 1481 err.jspError(reader.mark(), "jsp.error.no.scriptlets"); 1482 } else if (reader.matches("<jsp:expression")) { 1483 err.jspError(reader.mark(), "jsp.error.no.scriptlets"); 1484 } else if (reader.matches("<%")) { 1485 err.jspError(reader.mark(), "jsp.error.no.scriptlets"); 1486 } else if (reader.matches("<jsp:scriptlet")) { 1487 err.jspError(reader.mark(), "jsp.error.no.scriptlets"); 1488 } else if (reader.matches("<jsp:text")) { 1489 parseXMLTemplateText(parent); 1490 } else if (reader.matches("${")) { 1491 parseELExpression(parent, '$'); 1492 } else if (reader.matches("#{")) { 1493 parseELExpression(parent, '#'); 1494 } else if (reader.matches("<jsp:")) { 1495 parseStandardAction(parent); 1496 } else if (!parseCustomTag(parent)) { 1497 checkUnbalancedEndTag(); 1498 parseTemplateText(parent); 1499 } 1500 1501 scriptlessCount--; 1502 } 1503 1504 1512 private void parseElementsTemplateText(Node parent) throws JasperException { 1513 start = reader.mark(); 1514 if (reader.matches("<%--")) { 1515 parseComment(parent); 1516 } else if (reader.matches("<%@")) { 1517 parseDirective(parent); 1518 } else if (reader.matches("<jsp:directive.")) { 1519 parseXMLDirective(parent); 1520 } else if (reader.matches("<%!")) { 1521 err.jspError(reader.mark(), "jsp.error.not.in.template", 1522 "Declarations"); 1523 } else if (reader.matches("<jsp:declaration")) { 1524 err.jspError(reader.mark(), "jsp.error.not.in.template", 1525 "Declarations"); 1526 } else if (reader.matches("<%=")) { 1527 err.jspError(reader.mark(), "jsp.error.not.in.template", 1528 "Expressions"); 1529 } else if (reader.matches("<jsp:expression")) { 1530 err.jspError(reader.mark(), "jsp.error.not.in.template", 1531 "Expressions"); 1532 } else if (reader.matches("<%")) { 1533 err.jspError(reader.mark(), "jsp.error.not.in.template", 1534 "Scriptlets"); 1535 } else if (reader.matches("<jsp:scriptlet")) { 1536 err.jspError(reader.mark(), "jsp.error.not.in.template", 1537 "Scriptlets"); 1538 } else if (reader.matches("<jsp:text")) { 1539 err.jspError(reader.mark(), "jsp.error.not.in.template", 1540 "<jsp:text"); 1541 } else if (reader.matches("${")) { 1542 err.jspError(reader.mark(), "jsp.error.not.in.template", 1543 "Expression language"); 1544 } else if (reader.matches("#{")) { 1545 err.jspError(reader.mark(), "jsp.error.not.in.template", 1546 "Expression language"); 1547 } else if (reader.matches("<jsp:")) { 1548 err.jspError(reader.mark(), "jsp.error.not.in.template", 1549 "Standard actions"); 1550 } else if (parseCustomTag(parent)) { 1551 err.jspError(reader.mark(), "jsp.error.not.in.template", 1552 "Custom actions"); 1553 } else { 1554 checkUnbalancedEndTag(); 1555 parseTemplateText(parent); 1556 } 1557 } 1558 1559 1562 private void checkUnbalancedEndTag() throws JasperException { 1563 1564 if (!reader.matches("</")) { 1565 return; 1566 } 1567 1568 if (reader.matches("jsp:")) { 1570 err.jspError(start, "jsp.error.unbalanced.endtag", "jsp:"); 1571 } 1572 1573 String tagName = reader.parseToken(false); 1575 int i = tagName.indexOf(':'); 1576 if (i == -1 || pageInfo.getURI(tagName.substring(0, i)) == null) { 1577 reader.reset(start); 1578 return; 1579 } 1580 1581 err.jspError(start, "jsp.error.unbalanced.endtag", tagName); 1582 } 1583 1584 1587 private void parseTagDependentBody(Node parent, String tag) 1588 throws JasperException { 1589 Mark bodyStart = reader.mark(); 1590 Mark bodyEnd = reader.skipUntilETag(tag); 1591 if (bodyEnd == null) { 1592 err.jspError(start, "jsp.error.unterminated", "<" + tag); 1593 } 1594 new Node.TemplateText(reader.getText(bodyStart, bodyEnd), bodyStart, 1595 parent); 1596 } 1597 1598 1601 private void parseJspBody(Node parent, String bodyType) 1602 throws JasperException { 1603 Mark start = reader.mark(); 1604 Node bodyNode = new Node.JspBody(start, parent); 1605 1606 reader.skipSpaces(); 1607 if (!reader.matches("/>")) { 1608 if (!reader.matches(">")) { 1609 err.jspError(start, "jsp.error.unterminated", "<jsp:body"); 1610 } 1611 parseBody(bodyNode, "jsp:body", bodyType); 1612 } 1613 } 1614 1615 1620 private void parseBody(Node parent, String tag, String bodyType) 1621 throws JasperException { 1622 if (bodyType.equalsIgnoreCase(TagInfo.BODY_CONTENT_TAG_DEPENDENT)) { 1623 parseTagDependentBody(parent, tag); 1624 } else if (bodyType.equalsIgnoreCase(TagInfo.BODY_CONTENT_EMPTY)) { 1625 if (!reader.matchesETag(tag)) { 1626 err.jspError(start, "jasper.error.emptybodycontent.nonempty", 1627 tag); 1628 } 1629 } else if (bodyType == JAVAX_BODY_CONTENT_PLUGIN) { 1630 parsePluginTags(parent); 1633 if (!reader.matchesETag(tag)) { 1634 err.jspError(reader.mark(), "jsp.error.unterminated", "<" 1635 + tag); 1636 } 1637 } else if (bodyType.equalsIgnoreCase(TagInfo.BODY_CONTENT_JSP) 1638 || bodyType.equalsIgnoreCase(TagInfo.BODY_CONTENT_SCRIPTLESS) 1639 || (bodyType == JAVAX_BODY_CONTENT_PARAM) 1640 || (bodyType == JAVAX_BODY_CONTENT_TEMPLATE_TEXT)) { 1641 while (reader.hasMoreInput()) { 1642 if (reader.matchesETag(tag)) { 1643 return; 1644 } 1645 1646 if (tag.equals("jsp:body") || tag.equals("jsp:attribute")) { 1648 if (reader.matches("<jsp:attribute")) { 1649 err.jspError(reader.mark(), 1650 "jsp.error.nested.jspattribute"); 1651 } else if (reader.matches("<jsp:body")) { 1652 err.jspError(reader.mark(), "jsp.error.nested.jspbody"); 1653 } 1654 } 1655 1656 if (bodyType.equalsIgnoreCase(TagInfo.BODY_CONTENT_JSP)) { 1657 parseElements(parent); 1658 } else if (bodyType 1659 .equalsIgnoreCase(TagInfo.BODY_CONTENT_SCRIPTLESS)) { 1660 parseElementsScriptless(parent); 1661 } else if (bodyType == JAVAX_BODY_CONTENT_PARAM) { 1662 reader.skipSpaces(); 1665 parseParam(parent); 1666 } else if (bodyType == JAVAX_BODY_CONTENT_TEMPLATE_TEXT) { 1667 parseElementsTemplateText(parent); 1668 } 1669 } 1670 err.jspError(start, "jsp.error.unterminated", "<" + tag); 1671 } else { 1672 err.jspError(start, "jasper.error.bad.bodycontent.type"); 1673 } 1674 } 1675 1676 1679 private void parseNamedAttributes(Node parent) throws JasperException { 1680 do { 1681 Mark start = reader.mark(); 1682 Attributes attrs = parseAttributes(); 1683 Node.NamedAttribute namedAttributeNode = new Node.NamedAttribute( 1684 attrs, start, parent); 1685 1686 reader.skipSpaces(); 1687 if (!reader.matches("/>")) { 1688 if (!reader.matches(">")) { 1689 err.jspError(start, "jsp.error.unterminated", 1690 "<jsp:attribute"); 1691 } 1692 if (namedAttributeNode.isTrim()) { 1693 reader.skipSpaces(); 1694 } 1695 parseBody(namedAttributeNode, "jsp:attribute", 1696 getAttributeBodyType(parent, attrs.getValue("name"))); 1697 if (namedAttributeNode.isTrim()) { 1698 Node.Nodes subElems = namedAttributeNode.getBody(); 1699 if (subElems != null) { 1700 Node lastNode = subElems.getNode(subElems.size() - 1); 1701 if (lastNode instanceof Node.TemplateText) { 1702 ((Node.TemplateText) lastNode).rtrim(); 1703 } 1704 } 1705 } 1706 } 1707 reader.skipSpaces(); 1708 } while (reader.matches("<jsp:attribute")); 1709 } 1710 1711 1714 private String getAttributeBodyType(Node n, String name) { 1715 1716 if (n instanceof Node.CustomTag) { 1717 TagInfo tagInfo = ((Node.CustomTag) n).getTagInfo(); 1718 TagAttributeInfo [] tldAttrs = tagInfo.getAttributes(); 1719 for (int i = 0; i < tldAttrs.length; i++) { 1720 if (name.equals(tldAttrs[i].getName())) { 1721 if (tldAttrs[i].isFragment()) { 1722 return TagInfo.BODY_CONTENT_SCRIPTLESS; 1723 } 1724 if (tldAttrs[i].canBeRequestTime()) { 1725 return TagInfo.BODY_CONTENT_JSP; 1726 } 1727 } 1728 } 1729 if (tagInfo.hasDynamicAttributes()) { 1730 return TagInfo.BODY_CONTENT_JSP; 1731 } 1732 } else if (n instanceof Node.IncludeAction) { 1733 if ("page".equals(name)) { 1734 return TagInfo.BODY_CONTENT_JSP; 1735 } 1736 } else if (n instanceof Node.ForwardAction) { 1737 if ("page".equals(name)) { 1738 return TagInfo.BODY_CONTENT_JSP; 1739 } 1740 } else if (n instanceof Node.SetProperty) { 1741 if ("value".equals(name)) { 1742 return TagInfo.BODY_CONTENT_JSP; 1743 } 1744 } else if (n instanceof Node.UseBean) { 1745 if ("beanName".equals(name)) { 1746 return TagInfo.BODY_CONTENT_JSP; 1747 } 1748 } else if (n instanceof Node.PlugIn) { 1749 if ("width".equals(name) || "height".equals(name)) { 1750 return TagInfo.BODY_CONTENT_JSP; 1751 } 1752 } else if (n instanceof Node.ParamAction) { 1753 if ("value".equals(name)) { 1754 return TagInfo.BODY_CONTENT_JSP; 1755 } 1756 } else if (n instanceof Node.JspElement) { 1757 return TagInfo.BODY_CONTENT_JSP; 1758 } 1759 1760 return JAVAX_BODY_CONTENT_TEMPLATE_TEXT; 1761 } 1762 1763 private void parseTagFileDirectives(Node parent) throws JasperException { 1764 reader.setSingleFile(true); 1765 reader.skipUntil("<"); 1766 while (reader.hasMoreInput()) { 1767 start = reader.mark(); 1768 if (reader.matches("%--")) { 1769 parseComment(parent); 1770 } else if (reader.matches("%@")) { 1771 parseDirective(parent); 1772 } else if (reader.matches("jsp:directive.")) { 1773 parseXMLDirective(parent); 1774 } 1775 reader.skipUntil("<"); 1776 } 1777 } 1778} 1779 | Popular Tags |