1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 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.jasper.JasperException; 49 import org.apache.jasper.JspCompilationContext; 50 import org.apache.jasper.xmlparser.ParserUtils; 51 import org.apache.jasper.xmlparser.TreeNode; 52 import org.apache.juli.logging.Log; 53 import org.apache.juli.logging.LogFactory; 54 55 /** 56 * Implementation of the TagLibraryInfo class from the JSP spec. 57 * 58 * @author Anil K. Vijendran 59 * @author Mandar Raje 60 * @author Pierre Delisle 61 * @author Kin-man Chung 62 * @author Jan Luehe 63 */ 64 class TagLibraryInfoImpl extends TagLibraryInfo implements TagConstants { 65 66 // Logger 67 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 // XXX FIXME 109 // resolveRelativeUri and/or getResourceAsStream don't seem to properly 110 // handle relative paths when dealing when home and getDocBase are set 111 // the following is a workaround until these problems are resolved. 112 private InputStream getResourceAsStream(String uri) 113 throws FileNotFoundException { 114 try { 115 // see if file exists on the filesystem first 116 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 // if file not found on filesystem, get the resource through 124 // the context 125 return ctxt.getResourceAsStream(uri); 126 } 127 128 } 129 130 /** 131 * Constructor. 132 */ 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 // The URI points to the TLD itself or to a JAR file in which the 147 // TLD is stored 148 location = generateTLDLocation(uri, ctxt); 149 } 150 151 try { 152 if (!location[0].endsWith("jar")) { 153 // Location points to TLD file 154 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 // Add TLD to dependency list 165 PageInfo pageInfo = ctxt.createCompiler().getPageInfo(); 166 if (pageInfo != null) { 167 pageInfo.addDependant(location[0]); 168 } 169 } else { 170 // Tag library is packaged in JAR file 171 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 /* 209 * @param ctxt The JSP compilation context @param uri The TLD's uri @param 210 * in The TLD's input stream @param jarFileUrl The JAR file containing the 211 * TLD, or null if the tag library is not packaged in a JAR 212 */ 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 // Create an iterator over the child elements of our <taglib> element 220 ParserUtils pu = new ParserUtils(); 221 TreeNode tld = pu.parseXMLDocument(uri, in); 222 223 // Check to see if the <taglib> root element contains a 'version' 224 // attribute, which was added in JSP 2.0 to replace the <jsp-version> 225 // subelement 226 this.jspversion = tld.findAttribute("version"); 227 228 // Process each child element of our <taglib> element 229 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) // JSP 1.1 236 || "tlib-version".equals(tname)) { // JSP 1.2 237 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)) { // JSP2.0 256 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) || // Ignored elements 265 "small-icon".equals(tname) || "large-icon".equals(tname) 266 || "listener".equals(tname)) { 267 ; 268 } else if ("taglib-extension".equals(tname)) { 269 // Recognized but ignored 270 } 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", uri); 282 } 283 if (jspversion == null) { 284 err.jspError("jsp.error.tld.mandatory.element.missing", 285 "jsp-version", uri); 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 /* 303 * @param uri The uri of the TLD @param ctxt The compilation context 304 * 305 * @return String array whose first element denotes the path to the TLD. If 306 * the path to the TLD points to a jar file, then the second element denotes 307 * the name of the TLD entry in the jar file, which is hardcoded to 308 * META-INF/taglib.tld. 309 */ 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 /* 349 * Default body content for JSP 1.2 tag handlers (<body-content> has 350 * become mandatory in JSP 2.0, because the default would be invalid for 351 * simple tag handlers) 352 */ 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 // Ignored elements 403 } else if ("tag-extension".equals(tname)) { 404 // Ignored 405 } 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 /* 439 * Parses the tag file directives of the given TagFile and turns them into a 440 * TagInfo. 441 * 442 * @param elem The <tag-file> element in the TLD @param uri The location of 443 * the TLD, in case the tag file is specified relative to it @param jarFile 444 * The JAR file, in case the tag file is packaged in a JAR 445 * 446 * @return TagInfo correspoding to tag file directives 447 */ 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 // Ignore <example> element: Bugzilla 33538 464 } else if ("tag-extension".equals(tname)) { 465 // Ignore <tag-extension> element: Bugzilla 33538 466 } else if ("icon".equals(tname) 467 || "display-name".equals(tname) 468 || "description".equals(tname)) { 469 // Ignore these elements: Bugzilla 38015 470 } 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 // Tag file packaged in JAR 480 // See https://issues.apache.org/bugzilla/show_bug.cgi?id=46471 481 // This needs to be removed once all the broken code that depends on 482 // it has been removed 483 ctxt.setTagFileJarUrl(path, jarFileUrl); 484 } else if (!path.startsWith("/WEB-INF/tags")) { 485 err.jspError("jsp.error.tagfile.illegalPath", path); 486 } 487 488 TagInfo tagInfo = TagFileProcessor.parseTagFileDirectives( 489 parserController, name, path, jarFileUrl, this); 490 return new TagFileInfo(name, path, tagInfo); 491 } 492 493 TagAttributeInfo createAttribute(TreeNode elem, String jspVersion) { 494 String name = null; 495 String type = null; 496 String expectedType = null; 497 String methodSignature = null; 498 boolean required = false, rtexprvalue = false, reqTime = false, isFragment = false, deferredValue = false, deferredMethod = false; 499 500 Iterator list = elem.findChildren(); 501 while (list.hasNext()) { 502 TreeNode element = (TreeNode) list.next(); 503 String tname = element.getName(); 504 505 if ("name".equals(tname)) { 506 name = element.getBody(); 507 } else if ("required".equals(tname)) { 508 String s = element.getBody(); 509 if (s != null) 510 required = JspUtil.booleanValue(s); 511 } else if ("rtexprvalue".equals(tname)) { 512 String s = element.getBody(); 513 if (s != null) 514 rtexprvalue = JspUtil.booleanValue(s); 515 } else if ("type".equals(tname)) { 516 type = element.getBody(); 517 if ("1.2".equals(jspVersion) 518 && (type.equals("Boolean") || type.equals("Byte") 519 || type.equals("Character") 520 || type.equals("Double") 521 || type.equals("Float") 522 || type.equals("Integer") 523 || type.equals("Long") || type.equals("Object") 524 || type.equals("Short") || type 525 .equals("String"))) { 526 type = "java.lang." + type; 527 } 528 } else if ("fragment".equals(tname)) { 529 String s = element.getBody(); 530 if (s != null) { 531 isFragment = JspUtil.booleanValue(s); 532 } 533 } else if ("deferred-value".equals(tname)) { 534 deferredValue = true; 535 type = "javax.el.ValueExpression"; 536 TreeNode child = element.findChild("type"); 537 if (child != null) { 538 expectedType = child.getBody(); 539 if (expectedType != null) { 540 expectedType = expectedType.trim(); 541 } 542 } else { 543 expectedType = "java.lang.Object"; 544 } 545 } else if ("deferred-method".equals(tname)) { 546 deferredMethod = true; 547 type = "javax.el.MethodExpression"; 548 TreeNode child = element.findChild("method-signature"); 549 if (child != null) { 550 methodSignature = child.getBody(); 551 if (methodSignature != null) { 552 methodSignature = methodSignature.trim(); 553 } 554 } else { 555 methodSignature = "java.lang.Object method()"; 556 } 557 } else if ("description".equals(tname) || // Ignored elements 558 false) { 559 ; 560 } else { 561 if (log.isWarnEnabled()) { 562 log.warn(Localizer.getMessage( 563 "jsp.warning.unknown.element.in.attribute", tname)); 564 } 565 } 566 } 567 568 if (isFragment) { 569 /* 570 * According to JSP.C-3 ("TLD Schema Element Structure - tag"), 571 * 'type' and 'rtexprvalue' must not be specified if 'fragment' has 572 * been specified (this will be enforced by validating parser). 573 * Also, if 'fragment' is TRUE, 'type' is fixed at 574 * javax.servlet.jsp.tagext.JspFragment, and 'rtexprvalue' is fixed 575 * at true. See also JSP.8.5.2. 576 */ 577 type = "javax.servlet.jsp.tagext.JspFragment"; 578 rtexprvalue = true; 579 } 580 581 if (!rtexprvalue && type == null) { 582 // According to JSP spec, for static values (those determined at 583 // translation time) the type is fixed at java.lang.String. 584 type = "java.lang.String"; 585 } 586 587 return new TagAttributeInfo(name, required, type, rtexprvalue, 588 isFragment, null, deferredValue, deferredMethod, expectedType, 589 methodSignature); 590 } 591 592 TagVariableInfo createVariable(TreeNode elem) { 593 String nameGiven = null; 594 String nameFromAttribute = null; 595 String className = "java.lang.String"; 596 boolean declare = true; 597 int scope = VariableInfo.NESTED; 598 599 Iterator list = elem.findChildren(); 600 while (list.hasNext()) { 601 TreeNode element = (TreeNode) list.next(); 602 String tname = element.getName(); 603 if ("name-given".equals(tname)) 604 nameGiven = element.getBody(); 605 else if ("name-from-attribute".equals(tname)) 606 nameFromAttribute = element.getBody(); 607 else if ("variable-class".equals(tname)) 608 className = element.getBody(); 609 else if ("declare".equals(tname)) { 610 String s = element.getBody(); 611 if (s != null) 612 declare = JspUtil.booleanValue(s); 613 } else if ("scope".equals(tname)) { 614 String s = element.getBody(); 615 if (s != null) { 616 if ("NESTED".equals(s)) { 617 scope = VariableInfo.NESTED; 618 } else if ("AT_BEGIN".equals(s)) { 619 scope = VariableInfo.AT_BEGIN; 620 } else if ("AT_END".equals(s)) { 621 scope = VariableInfo.AT_END; 622 } 623 } 624 } else if ("description".equals(tname) || // Ignored elements 625 false) { 626 } else { 627 if (log.isWarnEnabled()) { 628 log.warn(Localizer.getMessage( 629 "jsp.warning.unknown.element.in.variable", tname)); 630 } 631 } 632 } 633 return new TagVariableInfo(nameGiven, nameFromAttribute, className, 634 declare, scope); 635 } 636 637 private TagLibraryValidator createValidator(TreeNode elem) 638 throws JasperException { 639 640 String validatorClass = null; 641 Map initParams = new Hashtable(); 642 643 Iterator list = elem.findChildren(); 644 while (list.hasNext()) { 645 TreeNode element = (TreeNode) list.next(); 646 String tname = element.getName(); 647 if ("validator-class".equals(tname)) 648 validatorClass = element.getBody(); 649 else if ("init-param".equals(tname)) { 650 String[] initParam = createInitParam(element); 651 initParams.put(initParam[0], initParam[1]); 652 } else if ("description".equals(tname) || // Ignored elements 653 false) { 654 } else { 655 if (log.isWarnEnabled()) { 656 log.warn(Localizer.getMessage( 657 "jsp.warning.unknown.element.in.validator", tname)); 658 } 659 } 660 } 661 662 TagLibraryValidator tlv = null; 663 if (validatorClass != null && !validatorClass.equals("")) { 664 try { 665 Class tlvClass = ctxt.getClassLoader() 666 .loadClass(validatorClass); 667 tlv = (TagLibraryValidator) tlvClass.newInstance(); 668 } catch (Exception e) { 669 err.jspError("jsp.error.tlvclass.instantiation", 670 validatorClass, e); 671 } 672 } 673 if (tlv != null) { 674 tlv.setInitParameters(initParams); 675 } 676 return tlv; 677 } 678 679 String[] createInitParam(TreeNode elem) { 680 String[] initParam = new String[2]; 681 682 Iterator list = elem.findChildren(); 683 while (list.hasNext()) { 684 TreeNode element = (TreeNode) list.next(); 685 String tname = element.getName(); 686 if ("param-name".equals(tname)) { 687 initParam[0] = element.getBody(); 688 } else if ("param-value".equals(tname)) { 689 initParam[1] = element.getBody(); 690 } else if ("description".equals(tname)) { 691 // Do nothing 692 } else { 693 if (log.isWarnEnabled()) { 694 log.warn(Localizer.getMessage( 695 "jsp.warning.unknown.element.in.initParam", tname)); 696 } 697 } 698 } 699 return initParam; 700 } 701 702 FunctionInfo createFunctionInfo(TreeNode elem) { 703 704 String name = null; 705 String klass = null; 706 String signature = null; 707 708 Iterator list = elem.findChildren(); 709 while (list.hasNext()) { 710 TreeNode element = (TreeNode) list.next(); 711 String tname = element.getName(); 712 713 if ("name".equals(tname)) { 714 name = element.getBody(); 715 } else if ("function-class".equals(tname)) { 716 klass = element.getBody(); 717 } else if ("function-signature".equals(tname)) { 718 signature = element.getBody(); 719 } else if ("display-name".equals(tname) || // Ignored elements 720 "small-icon".equals(tname) || "large-icon".equals(tname) 721 || "description".equals(tname) || "example".equals(tname)) { 722 } else { 723 if (log.isWarnEnabled()) { 724 log.warn(Localizer.getMessage( 725 "jsp.warning.unknown.element.in.function", tname)); 726 } 727 } 728 } 729 730 return new FunctionInfo(name, klass, signature); 731 } 732 733 // ********************************************************************* 734 // Until javax.servlet.jsp.tagext.TagLibraryInfo is fixed 735 736 /** 737 * The instance (if any) for the TagLibraryValidator class. 738 * 739 * @return The TagLibraryValidator instance, if any. 740 */ 741 public TagLibraryValidator getTagLibraryValidator() { 742 return tagLibraryValidator; 743 } 744 745 /** 746 * Translation-time validation of the XML document associated with the JSP 747 * page. This is a convenience method on the associated TagLibraryValidator 748 * class. 749 * 750 * @param thePage 751 * The JSP page object 752 * @return A string indicating whether the page is valid or not. 753 */ 754 public ValidationMessage[] validate(PageData thePage) { 755 TagLibraryValidator tlv = getTagLibraryValidator(); 756 if (tlv == null) 757 return null; 758 759 String uri = getURI(); 760 if (uri.startsWith("/")) { 761 uri = URN_JSPTLD + uri; 762 } 763 764 return tlv.validate(getPrefixString(), uri, thePage); 765 } 766 767 protected TagLibraryValidator tagLibraryValidator; 768 }