/* * Returns the value of the uri element of the given TLD, or null if the * given TLD does not contain any such element. */ private String getUriFromTld(String resourcePath, InputStream in) throws JasperException { // Parse the tag library descriptor at the specified resource path TreeNode tld = new ParserUtils().parseXMLDocument(resourcePath, in); TreeNode uri = tld.findChild("uri"); if (uri != null) { String body = uri.getBody(); if (body != null) return body; } return null; }
/* * Populates taglib map described in web.xml. * * This is not kept in sync with o.a.c.startup.TldConfig as the Jasper only * needs the URI to TLD mappings from scan web.xml whereas TldConfig needs * to scan the actual TLD files. */ private void tldScanWebXml() throws Exception { WebXml webXml = null; try { webXml = new WebXml(ctxt); if (webXml.getInputSource() == null) { return; } boolean validate = Boolean.parseBoolean(ctxt.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM)); String blockExternalString = ctxt.getInitParameter(Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); boolean blockExternal; if (blockExternalString == null) { blockExternal = Constants.IS_SECURITY_ENABLED; } else { blockExternal = Boolean.parseBoolean(blockExternalString); } // Parse the web application deployment descriptor ParserUtils pu = new ParserUtils(validate, blockExternal); TreeNode webtld = null; webtld = pu.parseXMLDocument(webXml.getSystemId(), webXml.getInputSource()); // Allow taglib to be an element of the root or jsp-config (JSP2.0) TreeNode jspConfig = webtld.findChild("jsp-config"); if (jspConfig != null) { webtld = jspConfig; } Iterator<TreeNode> taglibs = webtld.findChildren("taglib"); while (taglibs.hasNext()) { // Parse the next <taglib> element TreeNode taglib = taglibs.next(); String tagUri = null; String tagLoc = null; TreeNode child = taglib.findChild("taglib-uri"); if (child != null) tagUri = child.getBody(); child = taglib.findChild("taglib-location"); if (child != null) tagLoc = child.getBody(); // Save this location if appropriate if (tagLoc == null) continue; if (uriType(tagLoc) == NOROOT_REL_URI) tagLoc = "/WEB-INF/" + tagLoc; TldLocation location; if (tagLoc.endsWith(JAR_EXT)) { location = new TldLocation("META-INF/taglib.tld", ctxt.getResource(tagLoc).toString()); } else { location = new TldLocation(tagLoc); } mappings.put(tagUri, location); } } finally { if (webXml != null) { webXml.close(); } } }
private void init(ErrorDispatcher err) throws JasperException { if (initialized) return; InputStream is = ctxt.getResourceAsStream(TAG_PLUGINS_XML); if (is == null) return; TreeNode root = (new ParserUtils()).parseXMLDocument(TAG_PLUGINS_XML, is); if (root == null) { return; } if (!TAG_PLUGINS_ROOT_ELEM.equals(root.getName())) { err.jspError("jsp.error.plugin.wrongRootElement", TAG_PLUGINS_XML, TAG_PLUGINS_ROOT_ELEM); } tagPlugins = new HashMap(); Iterator pluginList = root.findChildren("tag-plugin"); while (pluginList.hasNext()) { TreeNode pluginNode = (TreeNode) pluginList.next(); TreeNode tagClassNode = pluginNode.findChild("tag-class"); if (tagClassNode == null) { // Error return; } String tagClass = tagClassNode.getBody().trim(); TreeNode pluginClassNode = pluginNode.findChild("plugin-class"); if (pluginClassNode == null) { // Error return; } String pluginClassStr = pluginClassNode.getBody(); TagPlugin tagPlugin = null; try { Class pluginClass = Class.forName(pluginClassStr); tagPlugin = (TagPlugin) pluginClass.newInstance(); } catch (Exception e) { throw new JasperException(e); } if (tagPlugin == null) { return; } tagPlugins.put(tagClass, tagPlugin); } initialized = true; }
/* * Parses the tag file directives of the given TagFile and turns them into a * TagInfo. * * @param elem The <tag-file> element in the TLD @param uri The location of * the TLD, in case the tag file is specified relative to it @param jarFile * The JAR file, in case the tag file is packaged in a JAR * * @return TagInfo correspoding to tag file directives */ private TagFileInfo createTagFileInfo(TreeNode elem, String uri, URL jarFileUrl) throws JasperException { String name = null; String path = null; Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode child = (TreeNode) list.next(); String tname = child.getName(); if ("name".equals(tname)) { name = child.getBody(); } else if ("path".equals(tname)) { path = child.getBody(); } else if ("example".equals(tname)) { // Ignore <example> element: Bugzilla 33538 } else if ("tag-extension".equals(tname)) { // Ignore <tag-extension> element: Bugzilla 33538 } else if ("icon".equals(tname) || "display-name".equals(tname) || "description".equals(tname)) { // Ignore these elements: Bugzilla 38015 } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.tagfile", tname)); } } } if (path.startsWith("/META-INF/tags")) { // Tag file packaged in JAR // See https://issues.apache.org/bugzilla/show_bug.cgi?id=46471 // This needs to be removed once all the broken code that depends on // it has been removed ctxt.setTagFileJarUrl(path, jarFileUrl); } else if (!path.startsWith("/WEB-INF/tags")) { err.jspError("jsp.error.tagfile.illegalPath", path); } TagInfo tagInfo = TagFileProcessor.parseTagFileDirectives(parserController, name, path, jarFileUrl, this); return new TagFileInfo(name, path, tagInfo); }
String[] createInitParam(TreeNode elem) { String[] initParam = new String[2]; Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("param-name".equals(tname)) { initParam[0] = element.getBody(); } else if ("param-value".equals(tname)) { initParam[1] = element.getBody(); } else if ("description".equals(tname)) { // Do nothing } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.initParam", tname)); } } } return initParam; }
FunctionInfo createFunctionInfo(TreeNode elem) { String name = null; String klass = null; String signature = null; Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("name".equals(tname)) { name = element.getBody(); } else if ("function-class".equals(tname)) { klass = element.getBody(); } else if ("function-signature".equals(tname)) { signature = element.getBody(); } else if ("display-name".equals(tname) || // Ignored elements "small-icon".equals(tname) || "large-icon".equals(tname) || "description".equals(tname) || "example".equals(tname)) { } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.function", tname)); } } } return new FunctionInfo(name, klass, signature); }
/* * Scan the TLD contents in the specified input stream and add any new URIs * to the map. * * @param resourcePath Path of the resource * @param entryName If the resource is a JAR file, the name of the entry * in the JAR file * @param stream The input stream for the resource * @throws IOException */ private void tldScanStream(String resourcePath, String entryName, InputStream stream) throws IOException { try { // Parse the tag library descriptor at the specified resource path String uri = null; boolean validate = Boolean.parseBoolean(ctxt.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM)); String blockExternalString = ctxt.getInitParameter(Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); boolean blockExternal; if (blockExternalString == null) { blockExternal = Constants.IS_SECURITY_ENABLED; } else { blockExternal = Boolean.parseBoolean(blockExternalString); } ParserUtils pu = new ParserUtils(validate, blockExternal); TreeNode tld = pu.parseXMLDocument(resourcePath, stream); TreeNode uriNode = tld.findChild("uri"); if (uriNode != null) { String body = uriNode.getBody(); if (body != null) uri = body; } // Add implicit map entry only if its uri is not already // present in the map if (uri != null && mappings.get(uri) == null) { TldLocation location; if (entryName == null) { location = new TldLocation(resourcePath); } else { location = new TldLocation(entryName, resourcePath); } mappings.put(uri, location); } } catch (JasperException e) { // Hack - makes exception handling simpler throw new IOException(e); } }
private TagLibraryValidator createValidator(TreeNode elem) throws JasperException { String validatorClass = null; Map initParams = new Hashtable(); Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("validator-class".equals(tname)) validatorClass = element.getBody(); else if ("init-param".equals(tname)) { String[] initParam = createInitParam(element); initParams.put(initParam[0], initParam[1]); } else if ("description".equals(tname) || // Ignored elements false) { } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.validator", tname)); } } } TagLibraryValidator tlv = null; if (validatorClass != null && !validatorClass.equals("")) { try { Class tlvClass = ctxt.getClassLoader().loadClass(validatorClass); tlv = (TagLibraryValidator) tlvClass.newInstance(); } catch (Exception e) { err.jspError("jsp.error.tlvclass.instantiation", validatorClass, e); } } if (tlv != null) { tlv.setInitParameters(initParams); } return tlv; }
TagVariableInfo createVariable(TreeNode elem) { String nameGiven = null; String nameFromAttribute = null; String className = "java.lang.String"; boolean declare = true; int scope = VariableInfo.NESTED; Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("name-given".equals(tname)) nameGiven = element.getBody(); else if ("name-from-attribute".equals(tname)) nameFromAttribute = element.getBody(); else if ("variable-class".equals(tname)) className = element.getBody(); else if ("declare".equals(tname)) { String s = element.getBody(); if (s != null) declare = JspUtil.booleanValue(s); } else if ("scope".equals(tname)) { String s = element.getBody(); if (s != null) { if ("NESTED".equals(s)) { scope = VariableInfo.NESTED; } else if ("AT_BEGIN".equals(s)) { scope = VariableInfo.AT_BEGIN; } else if ("AT_END".equals(s)) { scope = VariableInfo.AT_END; } } } else if ("description".equals(tname) || // Ignored elements false) { } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.variable", tname)); } } } return new TagVariableInfo(nameGiven, nameFromAttribute, className, declare, scope); }
/* * Populates taglib map described in web.xml. */ protected void processWebDotXml(Map tmpMappings) throws Exception { InputStream is = null; try { // Acquire input stream to web application deployment descriptor String altDDName = (String) ctx.getAttribute(Constants.ALT_DD_ATTR); if (altDDName != null) { try { is = new FileInputStream(altDDName); } catch (FileNotFoundException e) { log.warn(Localizer.getMessage("jsp.error.internal.filenotfound", altDDName)); } } else { is = ctx.getResourceAsStream(WEB_XML); if (is == null) { log.warn(Localizer.getMessage("jsp.error.internal.filenotfound", WEB_XML)); } } if (is == null) { return; } // Parse the web application deployment descriptor TreeNode webtld = null; // altDDName is the absolute path of the DD if (altDDName != null) { webtld = new ParserUtils().parseXMLDocument(altDDName, is); } else { webtld = new ParserUtils().parseXMLDocument(WEB_XML, is); } // Allow taglib to be an element of the root or jsp-config (JSP2.0) TreeNode jspConfig = webtld.findChild("jsp-config"); if (jspConfig != null) { webtld = jspConfig; } Iterator taglibs = webtld.findChildren("taglib"); while (taglibs.hasNext()) { // Parse the next <taglib> element TreeNode taglib = (TreeNode) taglibs.next(); String tagUri = null; String tagLoc = null; TreeNode child = taglib.findChild("taglib-uri"); if (child != null) tagUri = child.getBody(); child = taglib.findChild("taglib-location"); if (child != null) tagLoc = child.getBody(); // Save this location if appropriate if (tagLoc == null) continue; if (uriType(tagLoc) == NOROOT_REL_URI) tagLoc = "/WEB-INF/" + tagLoc; String tagLoc2 = null; if (tagLoc.endsWith(JAR_FILE_SUFFIX)) { tagLoc = ctx.getResource(tagLoc).toString(); tagLoc2 = "META-INF/taglib.tld"; } tmpMappings.put(tagUri, new String[] {tagLoc, tagLoc2}); // SYNC } } finally { if (is != null) { try { is.close(); } catch (Throwable t) { } } } }
TagAttributeInfo createAttribute(TreeNode elem, String jspVersion) { String name = null; String type = null; String expectedType = null; String methodSignature = null; boolean required = false, rtexprvalue = false, reqTime = false, isFragment = false, deferredValue = false, deferredMethod = false; Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("name".equals(tname)) { name = element.getBody(); } else if ("required".equals(tname)) { String s = element.getBody(); if (s != null) required = JspUtil.booleanValue(s); } else if ("rtexprvalue".equals(tname)) { String s = element.getBody(); if (s != null) rtexprvalue = JspUtil.booleanValue(s); } else if ("type".equals(tname)) { type = element.getBody(); if ("1.2".equals(jspVersion) && (type.equals("Boolean") || type.equals("Byte") || type.equals("Character") || type.equals("Double") || type.equals("Float") || type.equals("Integer") || type.equals("Long") || type.equals("Object") || type.equals("Short") || type.equals("String"))) { type = "java.lang." + type; } } else if ("fragment".equals(tname)) { String s = element.getBody(); if (s != null) { isFragment = JspUtil.booleanValue(s); } } else if ("deferred-value".equals(tname)) { deferredValue = true; type = "javax.el.ValueExpression"; TreeNode child = element.findChild("type"); if (child != null) { expectedType = child.getBody(); if (expectedType != null) { expectedType = expectedType.trim(); } } else { expectedType = "java.lang.Object"; } } else if ("deferred-method".equals(tname)) { deferredMethod = true; type = "javax.el.MethodExpression"; TreeNode child = element.findChild("method-signature"); if (child != null) { methodSignature = child.getBody(); if (methodSignature != null) { methodSignature = methodSignature.trim(); } } else { methodSignature = "java.lang.Object method()"; } } else if ("description".equals(tname) || // Ignored elements false) {; } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.attribute", tname)); } } } if (isFragment) { /* * According to JSP.C-3 ("TLD Schema Element Structure - tag"), * 'type' and 'rtexprvalue' must not be specified if 'fragment' has * been specified (this will be enforced by validating parser). * Also, if 'fragment' is TRUE, 'type' is fixed at * javax.servlet.jsp.tagext.JspFragment, and 'rtexprvalue' is fixed * at true. See also JSP.8.5.2. */ type = "javax.servlet.jsp.tagext.JspFragment"; rtexprvalue = true; } if (!rtexprvalue && type == null) { // According to JSP spec, for static values (those determined at // translation time) the type is fixed at java.lang.String. type = "java.lang.String"; } return new TagAttributeInfo( name, required, type, rtexprvalue, isFragment, null, deferredValue, deferredMethod, expectedType, methodSignature); }
private TagInfo createTagInfo(TreeNode elem, String jspVersion) throws JasperException { String tagName = null; String tagClassName = null; String teiClassName = null; /* * Default body content for JSP 1.2 tag handlers (<body-content> has * become mandatory in JSP 2.0, because the default would be invalid for * simple tag handlers) */ String bodycontent = "JSP"; String info = null; String displayName = null; String smallIcon = null; String largeIcon = null; boolean dynamicAttributes = false; Vector attributeVector = new Vector(); Vector variableVector = new Vector(); Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("name".equals(tname)) { tagName = element.getBody(); } else if ("tagclass".equals(tname) || "tag-class".equals(tname)) { tagClassName = element.getBody(); } else if ("teiclass".equals(tname) || "tei-class".equals(tname)) { teiClassName = element.getBody(); } else if ("bodycontent".equals(tname) || "body-content".equals(tname)) { bodycontent = element.getBody(); } else if ("display-name".equals(tname)) { displayName = element.getBody(); } else if ("small-icon".equals(tname)) { smallIcon = element.getBody(); } else if ("large-icon".equals(tname)) { largeIcon = element.getBody(); } else if ("icon".equals(tname)) { TreeNode icon = element.findChild("small-icon"); if (icon != null) { smallIcon = icon.getBody(); } icon = element.findChild("large-icon"); if (icon != null) { largeIcon = icon.getBody(); } } else if ("info".equals(tname) || "description".equals(tname)) { info = element.getBody(); } else if ("variable".equals(tname)) { variableVector.addElement(createVariable(element)); } else if ("attribute".equals(tname)) { attributeVector.addElement(createAttribute(element, jspVersion)); } else if ("dynamic-attributes".equals(tname)) { dynamicAttributes = JspUtil.booleanValue(element.getBody()); } else if ("example".equals(tname)) { // Ignored elements } else if ("tag-extension".equals(tname)) { // Ignored } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.tag", tname)); } } } TagExtraInfo tei = null; if (teiClassName != null && !teiClassName.equals("")) { try { Class teiClass = ctxt.getClassLoader().loadClass(teiClassName); tei = (TagExtraInfo) teiClass.newInstance(); } catch (Exception e) { err.jspError("jsp.error.teiclass.instantiation", teiClassName, e); } } TagAttributeInfo[] tagAttributeInfo = new TagAttributeInfo[attributeVector.size()]; attributeVector.copyInto(tagAttributeInfo); TagVariableInfo[] tagVariableInfos = new TagVariableInfo[variableVector.size()]; variableVector.copyInto(tagVariableInfos); TagInfo taginfo = new TagInfo( tagName, tagClassName, bodycontent, info, this, tei, tagAttributeInfo, displayName, smallIcon, largeIcon, tagVariableInfos, dynamicAttributes); return taginfo; }
/* * @param ctxt The JSP compilation context @param uri The TLD's uri @param * in The TLD's input stream @param jarFileUrl The JAR file containing the * TLD, or null if the tag library is not packaged in a JAR */ private void parseTLD(JspCompilationContext ctxt, String uri, InputStream in, URL jarFileUrl) throws JasperException { Vector tagVector = new Vector(); Vector tagFileVector = new Vector(); Hashtable functionTable = new Hashtable(); // Create an iterator over the child elements of our <taglib> element ParserUtils pu = new ParserUtils(); TreeNode tld = pu.parseXMLDocument(uri, in); // Check to see if the <taglib> root element contains a 'version' // attribute, which was added in JSP 2.0 to replace the <jsp-version> // subelement this.jspversion = tld.findAttribute("version"); // Process each child element of our <taglib> element Iterator list = tld.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("tlibversion".equals(tname) // JSP 1.1 || "tlib-version".equals(tname)) { // JSP 1.2 this.tlibversion = element.getBody(); } else if ("jspversion".equals(tname) || "jsp-version".equals(tname)) { this.jspversion = element.getBody(); } else if ("shortname".equals(tname) || "short-name".equals(tname)) this.shortname = element.getBody(); else if ("uri".equals(tname)) this.urn = element.getBody(); else if ("info".equals(tname) || "description".equals(tname)) this.info = element.getBody(); else if ("validator".equals(tname)) this.tagLibraryValidator = createValidator(element); else if ("tag".equals(tname)) tagVector.addElement(createTagInfo(element, jspversion)); else if ("tag-file".equals(tname)) { TagFileInfo tagFileInfo = createTagFileInfo(element, uri, jarFileUrl); tagFileVector.addElement(tagFileInfo); } else if ("function".equals(tname)) { // JSP2.0 FunctionInfo funcInfo = createFunctionInfo(element); String funcName = funcInfo.getName(); if (functionTable.containsKey(funcName)) { err.jspError("jsp.error.tld.fn.duplicate.name", funcName, uri); } functionTable.put(funcName, funcInfo); } else if ("display-name".equals(tname) || // Ignored elements "small-icon".equals(tname) || "large-icon".equals(tname) || "listener".equals(tname)) {; } else if ("taglib-extension".equals(tname)) { // Recognized but ignored } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.taglib", tname)); } } } if (tlibversion == null) { err.jspError("jsp.error.tld.mandatory.element.missing", "tlib-version", uri); } if (jspversion == null) { err.jspError("jsp.error.tld.mandatory.element.missing", "jsp-version", uri); } this.tags = new TagInfo[tagVector.size()]; tagVector.copyInto(this.tags); this.tagFiles = new TagFileInfo[tagFileVector.size()]; tagFileVector.copyInto(this.tagFiles); this.functions = new FunctionInfo[functionTable.size()]; int i = 0; Enumeration enumeration = functionTable.elements(); while (enumeration.hasMoreElements()) { this.functions[i++] = (FunctionInfo) enumeration.nextElement(); } }