1 17 18 package org.apache.jasper.compiler; 19 20 import java.io.FileInputStream ; 21 import java.io.FileNotFoundException ; 22 import java.io.InputStream ; 23 import java.io.PrintWriter ; 24 import java.io.StringWriter ; 25 import java.net.JarURLConnection ; 26 import java.net.URL ; 27 import java.util.Collection ; 28 import java.util.Enumeration ; 29 import java.util.Hashtable ; 30 import java.util.Iterator ; 31 import java.util.Map ; 32 import java.util.Vector ; 33 import java.util.jar.JarFile ; 34 import java.util.zip.ZipEntry ; 35 36 import javax.servlet.jsp.tagext.FunctionInfo ; 37 import javax.servlet.jsp.tagext.PageData ; 38 import javax.servlet.jsp.tagext.TagAttributeInfo ; 39 import javax.servlet.jsp.tagext.TagExtraInfo ; 40 import javax.servlet.jsp.tagext.TagFileInfo ; 41 import javax.servlet.jsp.tagext.TagInfo ; 42 import javax.servlet.jsp.tagext.TagLibraryInfo ; 43 import javax.servlet.jsp.tagext.TagLibraryValidator ; 44 import javax.servlet.jsp.tagext.TagVariableInfo ; 45 import javax.servlet.jsp.tagext.ValidationMessage ; 46 import javax.servlet.jsp.tagext.VariableInfo ; 47 48 import org.apache.commons.logging.Log; 49 import org.apache.commons.logging.LogFactory; 50 import org.apache.jasper.JasperException; 51 import org.apache.jasper.JspCompilationContext; 52 import org.apache.jasper.xmlparser.ParserUtils; 53 import org.apache.jasper.xmlparser.TreeNode; 54 55 64 class TagLibraryInfoImpl extends TagLibraryInfo implements TagConstants { 65 66 private Log log = LogFactory.getLog(TagLibraryInfoImpl.class); 68 69 private JspCompilationContext ctxt; 70 71 private PageInfo pi; 72 73 private ErrorDispatcher err; 74 75 private ParserController parserController; 76 77 private final void print(String name, String value, PrintWriter w) { 78 if (value != null) { 79 w.print(name + " = {\n\t"); 80 w.print(value); 81 w.print("\n}\n"); 82 } 83 } 84 85 public String toString() { 86 StringWriter sw = new StringWriter (); 87 PrintWriter out = new PrintWriter (sw); 88 print("tlibversion", tlibversion, out); 89 print("jspversion", jspversion, out); 90 print("shortname", shortname, out); 91 print("urn", urn, out); 92 print("info", info, out); 93 print("uri", uri, out); 94 print("tagLibraryValidator", "" + tagLibraryValidator, out); 95 96 for (int i = 0; i < tags.length; i++) 97 out.println(tags[i].toString()); 98 99 for (int i = 0; i < tagFiles.length; i++) 100 out.println(tagFiles[i].toString()); 101 102 for (int i = 0; i < functions.length; i++) 103 out.println(functions[i].toString()); 104 105 return sw.toString(); 106 } 107 108 private InputStream getResourceAsStream(String uri) 113 throws FileNotFoundException { 114 try { 115 String real = ctxt.getRealPath(uri); 117 if (real == null) { 118 return ctxt.getResourceAsStream(uri); 119 } else { 120 return new FileInputStream (real); 121 } 122 } catch (FileNotFoundException ex) { 123 return ctxt.getResourceAsStream(uri); 126 } 127 128 } 129 130 133 public TagLibraryInfoImpl(JspCompilationContext ctxt, ParserController pc, PageInfo pi, 134 String prefix, String uriIn, String [] location, ErrorDispatcher err) 135 throws JasperException { 136 super(prefix, uriIn); 137 138 this.ctxt = ctxt; 139 this.parserController = pc; 140 this.pi = pi; 141 this.err = err; 142 InputStream in = null; 143 JarFile jarFile = null; 144 145 if (location == null) { 146 location = generateTLDLocation(uri, ctxt); 149 } 150 151 try { 152 if (!location[0].endsWith("jar")) { 153 try { 155 in = getResourceAsStream(location[0]); 156 if (in == null) { 157 throw new FileNotFoundException (location[0]); 158 } 159 } catch (FileNotFoundException ex) { 160 err.jspError("jsp.error.file.not.found", location[0]); 161 } 162 163 parseTLD(ctxt, location[0], in, null); 164 PageInfo pageInfo = ctxt.createCompiler().getPageInfo(); 166 if (pageInfo != null) { 167 pageInfo.addDependant(location[0]); 168 } 169 } else { 170 try { 172 URL jarFileUrl = new URL ("jar:" + location[0] + "!/"); 173 JarURLConnection conn = (JarURLConnection ) jarFileUrl 174 .openConnection(); 175 conn.setUseCaches(false); 176 conn.connect(); 177 jarFile = conn.getJarFile(); 178 ZipEntry jarEntry = jarFile.getEntry(location[1]); 179 in = jarFile.getInputStream(jarEntry); 180 parseTLD(ctxt, location[0], in, jarFileUrl); 181 } catch (Exception ex) { 182 err.jspError("jsp.error.tld.unable_to_read", location[0], 183 location[1], ex.toString()); 184 } 185 } 186 } finally { 187 if (in != null) { 188 try { 189 in.close(); 190 } catch (Throwable t) { 191 } 192 } 193 if (jarFile != null) { 194 try { 195 jarFile.close(); 196 } catch (Throwable t) { 197 } 198 } 199 } 200 201 } 202 203 public TagLibraryInfo [] getTagLibraryInfos() { 204 Collection coll = pi.getTaglibs(); 205 return (TagLibraryInfo []) coll.toArray(new TagLibraryInfo [0]); 206 } 207 208 213 private void parseTLD(JspCompilationContext ctxt, String uri, 214 InputStream in, URL jarFileUrl) throws JasperException { 215 Vector tagVector = new Vector (); 216 Vector tagFileVector = new Vector (); 217 Hashtable functionTable = new Hashtable (); 218 219 ParserUtils pu = new ParserUtils(); 221 TreeNode tld = pu.parseXMLDocument(uri, in); 222 223 this.jspversion = tld.findAttribute("version"); 227 228 Iterator list = tld.findChildren(); 230 231 while (list.hasNext()) { 232 TreeNode element = (TreeNode) list.next(); 233 String tname = element.getName(); 234 235 if ("tlibversion".equals(tname) || "tlib-version".equals(tname)) { this.tlibversion = element.getBody(); 238 } else if ("jspversion".equals(tname) 239 || "jsp-version".equals(tname)) { 240 this.jspversion = element.getBody(); 241 } else if ("shortname".equals(tname) || "short-name".equals(tname)) 242 this.shortname = element.getBody(); 243 else if ("uri".equals(tname)) 244 this.urn = element.getBody(); 245 else if ("info".equals(tname) || "description".equals(tname)) 246 this.info = element.getBody(); 247 else if ("validator".equals(tname)) 248 this.tagLibraryValidator = createValidator(element); 249 else if ("tag".equals(tname)) 250 tagVector.addElement(createTagInfo(element, jspversion)); 251 else if ("tag-file".equals(tname)) { 252 TagFileInfo tagFileInfo = createTagFileInfo(element, uri, 253 jarFileUrl); 254 tagFileVector.addElement(tagFileInfo); 255 } else if ("function".equals(tname)) { FunctionInfo funcInfo = createFunctionInfo(element); 257 String funcName = funcInfo.getName(); 258 if (functionTable.containsKey(funcName)) { 259 err.jspError("jsp.error.tld.fn.duplicate.name", funcName, 260 uri); 261 262 } 263 functionTable.put(funcName, funcInfo); 264 } else if ("display-name".equals(tname) || "small-icon".equals(tname) || "large-icon".equals(tname) 266 || "listener".equals(tname)) { 267 ; 268 } else if ("taglib-extension".equals(tname)) { 269 } else { 271 if (log.isWarnEnabled()) { 272 log.warn(Localizer.getMessage( 273 "jsp.warning.unknown.element.in.taglib", tname)); 274 } 275 } 276 277 } 278 279 if (tlibversion == null) { 280 err.jspError("jsp.error.tld.mandatory.element.missing", 281 "tlib-version"); 282 } 283 if (jspversion == null) { 284 err.jspError("jsp.error.tld.mandatory.element.missing", 285 "jsp-version"); 286 } 287 288 this.tags = new TagInfo [tagVector.size()]; 289 tagVector.copyInto(this.tags); 290 291 this.tagFiles = new TagFileInfo [tagFileVector.size()]; 292 tagFileVector.copyInto(this.tagFiles); 293 294 this.functions = new FunctionInfo [functionTable.size()]; 295 int i = 0; 296 Enumeration enumeration = functionTable.elements(); 297 while (enumeration.hasMoreElements()) { 298 this.functions[i++] = (FunctionInfo ) enumeration.nextElement(); 299 } 300 } 301 302 310 private String [] generateTLDLocation(String uri, JspCompilationContext ctxt) 311 throws JasperException { 312 313 int uriType = TldLocationsCache.uriType(uri); 314 if (uriType == TldLocationsCache.ABS_URI) { 315 err.jspError("jsp.error.taglibDirective.absUriCannotBeResolved", 316 uri); 317 } else if (uriType == TldLocationsCache.NOROOT_REL_URI) { 318 uri = ctxt.resolveRelativeUri(uri); 319 } 320 321 String [] location = new String [2]; 322 location[0] = uri; 323 if (location[0].endsWith("jar")) { 324 URL url = null; 325 try { 326 url = ctxt.getResource(location[0]); 327 } catch (Exception ex) { 328 err.jspError("jsp.error.tld.unable_to_get_jar", location[0], ex 329 .toString()); 330 } 331 if (url == null) { 332 err.jspError("jsp.error.tld.missing_jar", location[0]); 333 } 334 location[0] = url.toString(); 335 location[1] = "META-INF/taglib.tld"; 336 } 337 338 return location; 339 } 340 341 private TagInfo createTagInfo(TreeNode elem, String jspVersion) 342 throws JasperException { 343 344 String tagName = null; 345 String tagClassName = null; 346 String teiClassName = null; 347 348 353 String bodycontent = "JSP"; 354 355 String info = null; 356 String displayName = null; 357 String smallIcon = null; 358 String largeIcon = null; 359 boolean dynamicAttributes = false; 360 361 Vector attributeVector = new Vector (); 362 Vector variableVector = new Vector (); 363 Iterator list = elem.findChildren(); 364 while (list.hasNext()) { 365 TreeNode element = (TreeNode) list.next(); 366 String tname = element.getName(); 367 368 if ("name".equals(tname)) { 369 tagName = element.getBody(); 370 } else if ("tagclass".equals(tname) || "tag-class".equals(tname)) { 371 tagClassName = element.getBody(); 372 } else if ("teiclass".equals(tname) || "tei-class".equals(tname)) { 373 teiClassName = element.getBody(); 374 } else if ("bodycontent".equals(tname) 375 || "body-content".equals(tname)) { 376 bodycontent = element.getBody(); 377 } else if ("display-name".equals(tname)) { 378 displayName = element.getBody(); 379 } else if ("small-icon".equals(tname)) { 380 smallIcon = element.getBody(); 381 } else if ("large-icon".equals(tname)) { 382 largeIcon = element.getBody(); 383 } else if ("icon".equals(tname)) { 384 TreeNode icon = element.findChild("small-icon"); 385 if (icon != null) { 386 smallIcon = icon.getBody(); 387 } 388 icon = element.findChild("large-icon"); 389 if (icon != null) { 390 largeIcon = icon.getBody(); 391 } 392 } else if ("info".equals(tname) || "description".equals(tname)) { 393 info = element.getBody(); 394 } else if ("variable".equals(tname)) { 395 variableVector.addElement(createVariable(element)); 396 } else if ("attribute".equals(tname)) { 397 attributeVector 398 .addElement(createAttribute(element, jspVersion)); 399 } else if ("dynamic-attributes".equals(tname)) { 400 dynamicAttributes = JspUtil.booleanValue(element.getBody()); 401 } else if ("example".equals(tname)) { 402 } else if ("tag-extension".equals(tname)) { 404 } else { 406 if (log.isWarnEnabled()) { 407 log.warn(Localizer.getMessage( 408 "jsp.warning.unknown.element.in.tag", tname)); 409 } 410 } 411 } 412 413 TagExtraInfo tei = null; 414 if (teiClassName != null && !teiClassName.equals("")) { 415 try { 416 Class teiClass = ctxt.getClassLoader().loadClass(teiClassName); 417 tei = (TagExtraInfo ) teiClass.newInstance(); 418 } catch (Exception e) { 419 err.jspError("jsp.error.teiclass.instantiation", teiClassName, 420 e); 421 } 422 } 423 424 TagAttributeInfo [] tagAttributeInfo = new TagAttributeInfo [attributeVector 425 .size()]; 426 attributeVector.copyInto(tagAttributeInfo); 427 428 TagVariableInfo [] tagVariableInfos = new TagVariableInfo [variableVector 429 .size()]; 430 variableVector.copyInto(tagVariableInfos); 431 432 TagInfo taginfo = new TagInfo (tagName, tagClassName, bodycontent, info, 433 this, tei, tagAttributeInfo, displayName, smallIcon, largeIcon, 434 tagVariableInfos, dynamicAttributes); 435 return taginfo; 436 } 437 438 448 private TagFileInfo createTagFileInfo(TreeNode elem, String uri, 449 URL jarFileUrl) throws JasperException { 450 451 String name = null; 452 String path = null; 453 454 Iterator list = elem.findChildren(); 455 while (list.hasNext()) { 456 TreeNode child = (TreeNode) list.next(); 457 String tname = child.getName(); 458 if ("name".equals(tname)) { 459 name = child.getBody(); 460 } else if ("path".equals(tname)) { 461 path = child.getBody(); 462 } else if ("example".equals(tname)) { 463 } else if ("tag-extension".equals(tname)) { 465 } else if ("icon".equals(tname) 467 || "display-name".equals(tname) 468 || "description".equals(tname)) { 469 } else { 471 if (log.isWarnEnabled()) { 472 log.warn(Localizer.getMessage( 473 "jsp.warning.unknown.element.in.tagfile", tname)); 474 } 475 } 476 } 477 478 if (path.startsWith("/META-INF/tags")) { 479 ctxt.setTagFileJarUrl(path, jarFileUrl); 481 } else if (!path.startsWith("/WEB-INF/tags")) { 482 err.jspError("jsp.error.tagfile.illegalPath", path); 483 } 484 485 TagInfo tagInfo = TagFileProcessor.parseTagFileDirectives( 486 parserController, name, path, this); 487 return new TagFileInfo (name, path, tagInfo); 488 } 489 490 TagAttributeInfo createAttribute(TreeNode elem, String jspVersion) { 491 String name = null; 492 String type = null; 493 String expectedType = null; 494 String methodSignature = null; 495 boolean required = false, rtexprvalue = false, reqTime = false, isFragment = false, deferredValue = false, deferredMethod = false; 496 497 Iterator list = elem.findChildren(); 498 while (list.hasNext()) { 499 TreeNode element = (TreeNode) list.next(); 500 String tname = element.getName(); 501 502 if ("name".equals(tname)) { 503 name = element.getBody(); 504 } else if ("required".equals(tname)) { 505 String s = element.getBody(); 506 if (s != null) 507 required = JspUtil.booleanValue(s); 508 } else if ("rtexprvalue".equals(tname)) { 509 String s = element.getBody(); 510 if (s != null) 511 rtexprvalue = JspUtil.booleanValue(s); 512 } else if ("type".equals(tname)) { 513 type = element.getBody(); 514 if ("1.2".equals(jspVersion) 515 && (type.equals("Boolean") || type.equals("Byte") 516 || type.equals("Character") 517 || type.equals("Double") 518 || type.equals("Float") 519 || type.equals("Integer") 520 || type.equals("Long") || type.equals("Object") 521 || type.equals("Short") || type 522 .equals("String"))) { 523 type = "java.lang." + type; 524 } 525 } else if ("fragment".equals(tname)) { 526 String s = element.getBody(); 527 if (s != null) { 528 isFragment = JspUtil.booleanValue(s); 529 } 530 } else if ("deferred-value".equals(tname)) { 531 deferredValue = true; 532 type = "javax.el.ValueExpression"; 533 TreeNode child = element.findChild("type"); 534 if (child != null) { 535 expectedType = child.getBody(); 536 if (expectedType != null) { 537 expectedType = expectedType.trim(); 538 } 539 } else { 540 expectedType = "java.lang.Object"; 541 } 542 } else if ("deferred-method".equals(tname)) { 543 deferredMethod = true; 544 type = "javax.el.MethodExpression"; 545 TreeNode child = element.findChild("method-signature"); 546 if (child != null) { 547 methodSignature = child.getBody(); 548 if (methodSignature != null) { 549 methodSignature = methodSignature.trim(); 550 } 551 } else { 552 methodSignature = "java.lang.Object method()"; 553 } 554 } else if ("description".equals(tname) || false) { 556 ; 557 } else { 558 if (log.isWarnEnabled()) { 559 log.warn(Localizer.getMessage( 560 "jsp.warning.unknown.element.in.attribute", tname)); 561 } 562 } 563 } 564 565 if (isFragment) { 566 574 type = "javax.servlet.jsp.tagext.JspFragment"; 575 rtexprvalue = true; 576 } 577 578 if (!rtexprvalue && type == null) { 579 type = "java.lang.String"; 582 } 583 584 return new TagAttributeInfo (name, required, type, rtexprvalue, 585 isFragment, null, deferredValue, deferredMethod, expectedType, 586 methodSignature); 587 } 588 589 TagVariableInfo createVariable(TreeNode elem) { 590 String nameGiven = null; 591 String nameFromAttribute = null; 592 String className = "java.lang.String"; 593 boolean declare = true; 594 int scope = VariableInfo.NESTED; 595 596 Iterator list = elem.findChildren(); 597 while (list.hasNext()) { 598 TreeNode element = (TreeNode) list.next(); 599 String tname = element.getName(); 600 if ("name-given".equals(tname)) 601 nameGiven = element.getBody(); 602 else if ("name-from-attribute".equals(tname)) 603 nameFromAttribute = element.getBody(); 604 else if ("variable-class".equals(tname)) 605 className = element.getBody(); 606 else if ("declare".equals(tname)) { 607 String s = element.getBody(); 608 if (s != null) 609 declare = JspUtil.booleanValue(s); 610 } else if ("scope".equals(tname)) { 611 String s = element.getBody(); 612 if (s != null) { 613 if ("NESTED".equals(s)) { 614 scope = VariableInfo.NESTED; 615 } else if ("AT_BEGIN".equals(s)) { 616 scope = VariableInfo.AT_BEGIN; 617 } else if ("AT_END".equals(s)) { 618 scope = VariableInfo.AT_END; 619 } 620 } 621 } else if ("description".equals(tname) || false) { 623 } else { 624 if (log.isWarnEnabled()) { 625 log.warn(Localizer.getMessage( 626 "jsp.warning.unknown.element.in.variable", tname)); 627 } 628 } 629 } 630 return new TagVariableInfo (nameGiven, nameFromAttribute, className, 631 declare, scope); 632 } 633 634 private TagLibraryValidator createValidator(TreeNode elem) 635 throws JasperException { 636 637 String validatorClass = null; 638 Map initParams = new Hashtable (); 639 640 Iterator list = elem.findChildren(); 641 while (list.hasNext()) { 642 TreeNode element = (TreeNode) list.next(); 643 String tname = element.getName(); 644 if ("validator-class".equals(tname)) 645 validatorClass = element.getBody(); 646 else if ("init-param".equals(tname)) { 647 String [] initParam = createInitParam(element); 648 initParams.put(initParam[0], initParam[1]); 649 } else if ("description".equals(tname) || false) { 651 } else { 652 if (log.isWarnEnabled()) { 653 log.warn(Localizer.getMessage( 654 "jsp.warning.unknown.element.in.validator", tname)); 655 } 656 } 657 } 658 659 TagLibraryValidator tlv = null; 660 if (validatorClass != null && !validatorClass.equals("")) { 661 try { 662 Class tlvClass = ctxt.getClassLoader() 663 .loadClass(validatorClass); 664 tlv = (TagLibraryValidator ) tlvClass.newInstance(); 665 } catch (Exception e) { 666 err.jspError("jsp.error.tlvclass.instantiation", 667 validatorClass, e); 668 } 669 } 670 if (tlv != null) { 671 tlv.setInitParameters(initParams); 672 } 673 return tlv; 674 } 675 676 String [] createInitParam(TreeNode elem) { 677 String [] initParam = new String [2]; 678 679 Iterator list = elem.findChildren(); 680 while (list.hasNext()) { 681 TreeNode element = (TreeNode) list.next(); 682 String tname = element.getName(); 683 if ("param-name".equals(tname)) { 684 initParam[0] = element.getBody(); 685 } else if ("param-value".equals(tname)) { 686 initParam[1] = element.getBody(); 687 } else if ("description".equals(tname)) { 688 ; } else { 690 if (log.isWarnEnabled()) { 691 log.warn(Localizer.getMessage( 692 "jsp.warning.unknown.element.in.initParam", tname)); 693 } 694 } 695 } 696 return initParam; 697 } 698 699 FunctionInfo createFunctionInfo(TreeNode elem) { 700 701 String name = null; 702 String klass = null; 703 String signature = null; 704 705 Iterator list = elem.findChildren(); 706 while (list.hasNext()) { 707 TreeNode element = (TreeNode) list.next(); 708 String tname = element.getName(); 709 710 if ("name".equals(tname)) { 711 name = element.getBody(); 712 } else if ("function-class".equals(tname)) { 713 klass = element.getBody(); 714 } else if ("function-signature".equals(tname)) { 715 signature = element.getBody(); 716 } else if ("display-name".equals(tname) || "small-icon".equals(tname) || "large-icon".equals(tname) 718 || "description".equals(tname) || "example".equals(tname)) { 719 } else { 720 if (log.isWarnEnabled()) { 721 log.warn(Localizer.getMessage( 722 "jsp.warning.unknown.element.in.function", tname)); 723 } 724 } 725 } 726 727 return new FunctionInfo (name, klass, signature); 728 } 729 730 733 738 public TagLibraryValidator getTagLibraryValidator() { 739 return tagLibraryValidator; 740 } 741 742 751 public ValidationMessage [] validate(PageData thePage) { 752 TagLibraryValidator tlv = getTagLibraryValidator(); 753 if (tlv == null) 754 return null; 755 756 String uri = getURI(); 757 if (uri.startsWith("/")) { 758 uri = URN_JSPTLD + uri; 759 } 760 761 return tlv.validate(getPrefixString(), uri, thePage); 762 } 763 764 protected TagLibraryValidator tagLibraryValidator; 765 } 766 | Popular Tags |