1 17 18 package org.apache.jasper.compiler; 19 20 import java.io.FileNotFoundException ; 21 import java.io.IOException ; 22 import java.net.URL ; 23 import java.net.URLClassLoader ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Vector ; 27 import java.util.HashMap ; 28 29 import javax.el.MethodExpression; 30 import javax.el.ValueExpression; 31 import javax.servlet.jsp.tagext.TagAttributeInfo ; 32 import javax.servlet.jsp.tagext.TagExtraInfo ; 33 import javax.servlet.jsp.tagext.TagFileInfo ; 34 import javax.servlet.jsp.tagext.TagInfo ; 35 import javax.servlet.jsp.tagext.TagLibraryInfo ; 36 import javax.servlet.jsp.tagext.TagVariableInfo ; 37 import javax.servlet.jsp.tagext.VariableInfo ; 38 39 import org.apache.jasper.JasperException; 40 import org.apache.jasper.JspCompilationContext; 41 import org.apache.jasper.servlet.JspServletWrapper; 42 import org.apache.jasper.runtime.JspSourceDependent; 43 44 50 51 class TagFileProcessor { 52 53 private Vector tempVector; 54 55 58 private static class TagFileDirectiveVisitor extends Node.Visitor { 59 60 private static final JspUtil.ValidAttribute[] tagDirectiveAttrs = { 61 new JspUtil.ValidAttribute("display-name"), 62 new JspUtil.ValidAttribute("body-content"), 63 new JspUtil.ValidAttribute("dynamic-attributes"), 64 new JspUtil.ValidAttribute("small-icon"), 65 new JspUtil.ValidAttribute("large-icon"), 66 new JspUtil.ValidAttribute("description"), 67 new JspUtil.ValidAttribute("example"), 68 new JspUtil.ValidAttribute("pageEncoding"), 69 new JspUtil.ValidAttribute("language"), 70 new JspUtil.ValidAttribute("import"), 71 new JspUtil.ValidAttribute("deferredSyntaxAllowedAsLiteral"), new JspUtil.ValidAttribute("trimDirectiveWhitespaces"), new JspUtil.ValidAttribute("isELIgnored") }; 74 75 private static final JspUtil.ValidAttribute[] attributeDirectiveAttrs = { 76 new JspUtil.ValidAttribute("name", true), 77 new JspUtil.ValidAttribute("required"), 78 new JspUtil.ValidAttribute("fragment"), 79 new JspUtil.ValidAttribute("rtexprvalue"), 80 new JspUtil.ValidAttribute("type"), 81 new JspUtil.ValidAttribute("deferredValue"), new JspUtil.ValidAttribute("deferredValueType"), new JspUtil.ValidAttribute("deferredMethod"), new JspUtil.ValidAttribute("deferredMethodSignature"), new JspUtil.ValidAttribute("description") }; 86 87 private static final JspUtil.ValidAttribute[] variableDirectiveAttrs = { 88 new JspUtil.ValidAttribute("name-given"), 89 new JspUtil.ValidAttribute("name-from-attribute"), 90 new JspUtil.ValidAttribute("alias"), 91 new JspUtil.ValidAttribute("variable-class"), 92 new JspUtil.ValidAttribute("scope"), 93 new JspUtil.ValidAttribute("declare"), 94 new JspUtil.ValidAttribute("description") }; 95 96 private ErrorDispatcher err; 97 98 private TagLibraryInfo tagLibInfo; 99 100 private String name = null; 101 102 private String path = null; 103 104 private TagExtraInfo tei = null; 105 106 private String bodycontent = null; 107 108 private String description = null; 109 110 private String displayName = null; 111 112 private String smallIcon = null; 113 114 private String largeIcon = null; 115 116 private String dynamicAttrsMapName; 117 118 private String example = null; 119 120 private Vector attributeVector; 121 122 private Vector variableVector; 123 124 private static final String ATTR_NAME = "the name attribute of the attribute directive"; 125 126 private static final String VAR_NAME_GIVEN = "the name-given attribute of the variable directive"; 127 128 private static final String VAR_NAME_FROM = "the name-from-attribute attribute of the variable directive"; 129 130 private static final String VAR_ALIAS = "the alias attribute of the variable directive"; 131 132 private static final String TAG_DYNAMIC = "the dynamic-attributes attribute of the tag directive"; 133 134 private HashMap nameTable = new HashMap (); 135 136 private HashMap nameFromTable = new HashMap (); 137 138 public TagFileDirectiveVisitor(Compiler compiler, 139 TagLibraryInfo tagLibInfo, String name, String path) { 140 err = compiler.getErrorDispatcher(); 141 this.tagLibInfo = tagLibInfo; 142 this.name = name; 143 this.path = path; 144 attributeVector = new Vector (); 145 variableVector = new Vector (); 146 } 147 148 public void visit(Node.TagDirective n) throws JasperException { 149 150 JspUtil.checkAttributes("Tag directive", n, tagDirectiveAttrs, err); 151 152 bodycontent = checkConflict(n, bodycontent, "body-content"); 153 if (bodycontent != null 154 && !bodycontent 155 .equalsIgnoreCase(TagInfo.BODY_CONTENT_EMPTY) 156 && !bodycontent 157 .equalsIgnoreCase(TagInfo.BODY_CONTENT_TAG_DEPENDENT) 158 && !bodycontent 159 .equalsIgnoreCase(TagInfo.BODY_CONTENT_SCRIPTLESS)) { 160 err.jspError(n, "jsp.error.tagdirective.badbodycontent", 161 bodycontent); 162 } 163 dynamicAttrsMapName = checkConflict(n, dynamicAttrsMapName, 164 "dynamic-attributes"); 165 if (dynamicAttrsMapName != null) { 166 checkUniqueName(dynamicAttrsMapName, TAG_DYNAMIC, n); 167 } 168 smallIcon = checkConflict(n, smallIcon, "small-icon"); 169 largeIcon = checkConflict(n, largeIcon, "large-icon"); 170 description = checkConflict(n, description, "description"); 171 displayName = checkConflict(n, displayName, "display-name"); 172 example = checkConflict(n, example, "example"); 173 } 174 175 private String checkConflict(Node n, String oldAttrValue, String attr) 176 throws JasperException { 177 178 String result = oldAttrValue; 179 String attrValue = n.getAttributeValue(attr); 180 if (attrValue != null) { 181 if (oldAttrValue != null && !oldAttrValue.equals(attrValue)) { 182 err.jspError(n, "jsp.error.tag.conflict.attr", attr, 183 oldAttrValue, attrValue); 184 } 185 result = attrValue; 186 } 187 return result; 188 } 189 190 public void visit(Node.AttributeDirective n) throws JasperException { 191 192 JspUtil.checkAttributes("Attribute directive", n, 193 attributeDirectiveAttrs, err); 194 195 boolean deferredValue = false; 198 boolean deferredValueSpecified = false; 199 String deferredValueString = n.getAttributeValue("deferredValue"); 200 if (deferredValueString != null) { 201 deferredValueSpecified = true; 202 deferredValue = JspUtil.booleanValue(deferredValueString); 203 } 204 String deferredValueType = n.getAttributeValue("deferredValueType"); 205 if (deferredValueType != null) { 206 if (deferredValueSpecified && !deferredValue) { 207 err.jspError(n, "jsp.error.deferredvaluetypewithoutdeferredvalue"); 208 } else { 209 deferredValue = true; 210 } 211 } else if (deferredValue) { 212 deferredValueType = "java.lang.Object"; 213 } else { 214 deferredValueType = "java.lang.String"; 215 } 216 217 boolean deferredMethod = false; 220 boolean deferredMethodSpecified = false; 221 String deferredMethodString = n.getAttributeValue("deferredMethod"); 222 if (deferredMethodString != null) { 223 deferredMethodSpecified = true; 224 deferredMethod = JspUtil.booleanValue(deferredMethodString); 225 } 226 String deferredMethodSignature = n 227 .getAttributeValue("deferredMethodSignature"); 228 if (deferredMethodSignature != null) { 229 if (deferredMethodSpecified && !deferredMethod) { 230 err.jspError(n, "jsp.error.deferredmethodsignaturewithoutdeferredmethod"); 231 } else { 232 deferredMethod = true; 233 } 234 } else if (deferredMethod) { 235 deferredMethodSignature = "void methodname()"; 236 } 237 238 if (deferredMethod && deferredValue) { 239 err.jspError(n, "jsp.error.deferredmethodandvalue"); 240 } 241 242 String attrName = n.getAttributeValue("name"); 243 boolean required = JspUtil.booleanValue(n 244 .getAttributeValue("required")); 245 boolean rtexprvalue = true; 246 String rtexprvalueString = n.getAttributeValue("rtexprvalue"); 247 if (rtexprvalueString != null) { 248 rtexprvalue = JspUtil.booleanValue(rtexprvalueString); 249 } 250 boolean fragment = JspUtil.booleanValue(n 251 .getAttributeValue("fragment")); 252 String type = n.getAttributeValue("type"); 253 if (fragment) { 254 if (type != null) { 257 err.jspError(n, "jsp.error.fragmentwithtype"); 258 } 259 rtexprvalue = true; 262 if (rtexprvalueString != null) { 263 err.jspError(n, "jsp.error.frgmentwithrtexprvalue"); 264 } 265 } else { 266 if (type == null) 267 type = "java.lang.String"; 268 269 if (deferredValue) { 270 type = ValueExpression.class.getName(); 271 } else if (deferredMethod) { 272 type = MethodExpression.class.getName(); 273 } 274 } 275 276 if ("2.0".equals(tagLibInfo.getRequiredVersion()) 277 && (deferredMethodSpecified || deferredMethod 278 || deferredValueSpecified || deferredValue)) { 279 err.jspError("jsp.error.invalid.version", path); 280 } 281 282 TagAttributeInfo tagAttributeInfo = new TagAttributeInfo (attrName, 283 required, type, rtexprvalue, fragment, null, deferredValue, 284 deferredMethod, deferredValueType, deferredMethodSignature); 285 attributeVector.addElement(tagAttributeInfo); 286 checkUniqueName(attrName, ATTR_NAME, n, tagAttributeInfo); 287 } 288 289 public void visit(Node.VariableDirective n) throws JasperException { 290 291 JspUtil.checkAttributes("Variable directive", n, 292 variableDirectiveAttrs, err); 293 294 String nameGiven = n.getAttributeValue("name-given"); 295 String nameFromAttribute = n 296 .getAttributeValue("name-from-attribute"); 297 if (nameGiven == null && nameFromAttribute == null) { 298 err.jspError("jsp.error.variable.either.name"); 299 } 300 301 if (nameGiven != null && nameFromAttribute != null) { 302 err.jspError("jsp.error.variable.both.name"); 303 } 304 305 String alias = n.getAttributeValue("alias"); 306 if (nameFromAttribute != null && alias == null 307 || nameFromAttribute == null && alias != null) { 308 err.jspError("jsp.error.variable.alias"); 309 } 310 311 String className = n.getAttributeValue("variable-class"); 312 if (className == null) 313 className = "java.lang.String"; 314 315 String declareStr = n.getAttributeValue("declare"); 316 boolean declare = true; 317 if (declareStr != null) 318 declare = JspUtil.booleanValue(declareStr); 319 320 int scope = VariableInfo.NESTED; 321 String scopeStr = n.getAttributeValue("scope"); 322 if (scopeStr != null) { 323 if ("NESTED".equals(scopeStr)) { 324 } else if ("AT_BEGIN".equals(scopeStr)) { 326 scope = VariableInfo.AT_BEGIN; 327 } else if ("AT_END".equals(scopeStr)) { 328 scope = VariableInfo.AT_END; 329 } 330 } 331 332 if (nameFromAttribute != null) { 333 339 nameGiven = alias; 340 checkUniqueName(nameFromAttribute, VAR_NAME_FROM, n); 341 checkUniqueName(alias, VAR_ALIAS, n); 342 } else { 343 checkUniqueName(nameGiven, VAR_NAME_GIVEN, n); 345 } 346 347 variableVector.addElement(new TagVariableInfo (nameGiven, 348 nameFromAttribute, className, declare, scope)); 349 } 350 351 355 public Vector getAttributesVector() { 356 return attributeVector; 357 } 358 359 362 public Vector getVariablesVector() { 363 return variableVector; 364 } 365 366 369 public String getDynamicAttributesMapName() { 370 return dynamicAttrsMapName; 371 } 372 373 public TagInfo getTagInfo() throws JasperException { 374 375 if (name == null) { 376 } 378 379 if (bodycontent == null) { 380 bodycontent = TagInfo.BODY_CONTENT_SCRIPTLESS; 381 } 382 383 String tagClassName = JspUtil.getTagHandlerClassName(path, err); 384 385 TagVariableInfo [] tagVariableInfos = new TagVariableInfo [variableVector 386 .size()]; 387 variableVector.copyInto(tagVariableInfos); 388 389 TagAttributeInfo [] tagAttributeInfo = new TagAttributeInfo [attributeVector 390 .size()]; 391 attributeVector.copyInto(tagAttributeInfo); 392 393 return new JasperTagInfo(name, tagClassName, bodycontent, 394 description, tagLibInfo, tei, tagAttributeInfo, 395 displayName, smallIcon, largeIcon, tagVariableInfos, 396 dynamicAttrsMapName); 397 } 398 399 static class NameEntry { 400 private String type; 401 402 private Node node; 403 404 private TagAttributeInfo attr; 405 406 NameEntry(String type, Node node, TagAttributeInfo attr) { 407 this.type = type; 408 this.node = node; 409 this.attr = attr; 410 } 411 412 String getType() { 413 return type; 414 } 415 416 Node getNode() { 417 return node; 418 } 419 420 TagAttributeInfo getTagAttributeInfo() { 421 return attr; 422 } 423 } 424 425 439 private void checkUniqueName(String name, String type, Node n) 440 throws JasperException { 441 checkUniqueName(name, type, n, null); 442 } 443 444 private void checkUniqueName(String name, String type, Node n, 445 TagAttributeInfo attr) throws JasperException { 446 447 HashMap table = (type == VAR_NAME_FROM) ? nameFromTable : nameTable; 448 NameEntry nameEntry = (NameEntry) table.get(name); 449 if (nameEntry != null) { 450 if (type != TAG_DYNAMIC || nameEntry.getType() != TAG_DYNAMIC) { 451 int line = nameEntry.getNode().getStart().getLineNumber(); 452 err.jspError(n, "jsp.error.tagfile.nameNotUnique", type, 453 nameEntry.getType(), Integer.toString(line)); 454 } 455 } else { 456 table.put(name, new NameEntry(type, n, attr)); 457 } 458 } 459 460 463 void postCheck() throws JasperException { 464 Iterator iter = nameFromTable.keySet().iterator(); 466 while (iter.hasNext()) { 467 String nameFrom = (String ) iter.next(); 468 NameEntry nameEntry = (NameEntry) nameTable.get(nameFrom); 469 NameEntry nameFromEntry = (NameEntry) nameFromTable 470 .get(nameFrom); 471 Node nameFromNode = nameFromEntry.getNode(); 472 if (nameEntry == null) { 473 err.jspError(nameFromNode, 474 "jsp.error.tagfile.nameFrom.noAttribute", nameFrom); 475 } else { 476 Node node = nameEntry.getNode(); 477 TagAttributeInfo tagAttr = nameEntry.getTagAttributeInfo(); 478 if (!"java.lang.String".equals(tagAttr.getTypeName()) 479 || !tagAttr.isRequired() 480 || tagAttr.canBeRequestTime()) { 481 err.jspError(nameFromNode, 482 "jsp.error.tagfile.nameFrom.badAttribute", 483 nameFrom, Integer.toString(node.getStart() 484 .getLineNumber())); 485 } 486 } 487 } 488 } 489 } 490 491 507 public static TagInfo parseTagFileDirectives(ParserController pc, 508 String name, String path, TagLibraryInfo tagLibInfo) 509 throws JasperException { 510 511 ErrorDispatcher err = pc.getCompiler().getErrorDispatcher(); 512 513 Node.Nodes page = null; 514 try { 515 page = pc.parseTagFileDirectives(path); 516 } catch (FileNotFoundException e) { 517 err.jspError("jsp.error.file.not.found", path); 518 } catch (IOException e) { 519 err.jspError("jsp.error.file.not.found", path); 520 } 521 522 TagFileDirectiveVisitor tagFileVisitor = new TagFileDirectiveVisitor(pc 523 .getCompiler(), tagLibInfo, name, path); 524 page.visit(tagFileVisitor); 525 tagFileVisitor.postCheck(); 526 527 return tagFileVisitor.getTagInfo(); 528 } 529 530 533 private Class loadTagFile(Compiler compiler, String tagFilePath, 534 TagInfo tagInfo, PageInfo parentPageInfo) throws JasperException { 535 536 JspCompilationContext ctxt = compiler.getCompilationContext(); 537 JspRuntimeContext rctxt = ctxt.getRuntimeContext(); 538 JspServletWrapper wrapper = (JspServletWrapper) rctxt 539 .getWrapper(tagFilePath); 540 541 synchronized (rctxt) { 542 if (wrapper == null) { 543 wrapper = new JspServletWrapper(ctxt.getServletContext(), ctxt 544 .getOptions(), tagFilePath, tagInfo, ctxt 545 .getRuntimeContext(), ctxt.getTagFileJarUrl(tagFilePath)); 546 rctxt.addWrapper(tagFilePath, wrapper); 547 548 wrapper.getJspEngineContext().setClassLoader( 550 (URLClassLoader ) ctxt.getClassLoader()); 551 wrapper.getJspEngineContext().setClassPath(ctxt.getClassPath()); 552 } else { 553 wrapper.getJspEngineContext().setTagInfo(tagInfo); 558 } 559 560 Class tagClazz; 561 int tripCount = wrapper.incTripCount(); 562 try { 563 if (tripCount > 0) { 564 569 JspServletWrapper tempWrapper = new JspServletWrapper(ctxt 570 .getServletContext(), ctxt.getOptions(), 571 tagFilePath, tagInfo, ctxt.getRuntimeContext(), 572 ctxt.getTagFileJarUrl(tagFilePath)); 573 tagClazz = tempWrapper.loadTagFilePrototype(); 574 tempVector.add(tempWrapper.getJspEngineContext() 575 .getCompiler()); 576 } else { 577 tagClazz = wrapper.loadTagFile(); 578 } 579 } finally { 580 wrapper.decTripCount(); 581 } 582 583 try { 587 Object tagIns = tagClazz.newInstance(); 588 if (tagIns instanceof JspSourceDependent) { 589 Iterator iter = ((List ) ((JspSourceDependent) tagIns) 590 .getDependants()).iterator(); 591 while (iter.hasNext()) { 592 parentPageInfo.addDependant((String ) iter.next()); 593 } 594 } 595 } catch (Exception e) { 596 } 598 599 return tagClazz; 600 } 601 } 602 603 607 private class TagFileLoaderVisitor extends Node.Visitor { 608 609 private Compiler compiler; 610 611 private PageInfo pageInfo; 612 613 TagFileLoaderVisitor(Compiler compiler) { 614 615 this.compiler = compiler; 616 this.pageInfo = compiler.getPageInfo(); 617 } 618 619 public void visit(Node.CustomTag n) throws JasperException { 620 TagFileInfo tagFileInfo = n.getTagFileInfo(); 621 if (tagFileInfo != null) { 622 String tagFilePath = tagFileInfo.getPath(); 623 JspCompilationContext ctxt = compiler.getCompilationContext(); 624 if (ctxt.getTagFileJarUrl(tagFilePath) == null) { 625 pageInfo.addDependant(tagFilePath); 627 } 628 Class c = loadTagFile(compiler, tagFilePath, n.getTagInfo(), 629 pageInfo); 630 n.setTagHandlerClass(c); 631 } 632 visitBody(n); 633 } 634 } 635 636 642 public void loadTagFiles(Compiler compiler, Node.Nodes page) 643 throws JasperException { 644 645 tempVector = new Vector (); 646 page.visit(new TagFileLoaderVisitor(compiler)); 647 } 648 649 656 public void removeProtoTypeFiles(String classFileName) { 657 Iterator iter = tempVector.iterator(); 658 while (iter.hasNext()) { 659 Compiler c = (Compiler ) iter.next(); 660 if (classFileName == null) { 661 c.removeGeneratedClassFiles(); 662 } else if (classFileName.equals(c.getCompilationContext() 663 .getClassFileName())) { 664 c.removeGeneratedClassFiles(); 665 tempVector.remove(c); 666 return; 667 } 668 } 669 } 670 } 671 | Popular Tags |