privatestaticfinal JspUtil.ValidAttribute[] pageDirectiveAttrs = { new JspUtil.ValidAttribute("language"), new JspUtil.ValidAttribute("extends"), new JspUtil.ValidAttribute("import"), new JspUtil.ValidAttribute("session"), new JspUtil.ValidAttribute("buffer"), new JspUtil.ValidAttribute("autoFlush"), new JspUtil.ValidAttribute("isThreadSafe"), new JspUtil.ValidAttribute("info"), new JspUtil.ValidAttribute("errorPage"), new JspUtil.ValidAttribute("isErrorPage"), new JspUtil.ValidAttribute("contentType"), new JspUtil.ValidAttribute("pageEncoding"), new JspUtil.ValidAttribute("isELIgnored"), new JspUtil.ValidAttribute("errorOnELNotFound"), new JspUtil.ValidAttribute("deferredSyntaxAllowedAsLiteral"), new JspUtil.ValidAttribute("trimDirectiveWhitespaces")
};
@Override publicvoid visit(Node.IncludeDirective n) throws JasperException { // Since pageDirectiveSeen flag only applies to the Current page // save it here and restore it after the file is included. boolean pageEncodingSeenSave = pageEncodingSeen;
pageEncodingSeen = false;
visitBody(n);
pageEncodingSeen = pageEncodingSeenSave;
}
JspUtil.checkAttributes("Page directive", n, pageDirectiveAttrs,
err);
// JSP.2.10.1
Attributes attrs = n.getAttributes(); for (int i = 0; attrs != null && i < attrs.getLength(); i++) {
String attr = attrs.getQName(i);
String value = attrs.getValue(i);
if ("language".equals(attr)) { if (pageInfo.getLanguage(false) == null) {
pageInfo.setLanguage(value, n, err, true);
} elseif (!pageInfo.getLanguage(false).equals(value)) {
err.jspError(n, "jsp.error.page.conflict.language",
pageInfo.getLanguage(false), value);
}
} elseif ("extends".equals(attr)) { if (pageInfo.getExtends(false) == null) {
pageInfo.setExtends(value);
} elseif (!pageInfo.getExtends(false).equals(value)) {
err.jspError(n, "jsp.error.page.conflict.extends",
pageInfo.getExtends(false), value);
}
} elseif ("contentType".equals(attr)) { if (pageInfo.getContentType() == null) {
pageInfo.setContentType(value);
} elseif (!pageInfo.getContentType().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.contenttype",
pageInfo.getContentType(), value);
}
} elseif ("session".equals(attr)) { if (pageInfo.getSession() == null) {
pageInfo.setSession(value, n, err);
} elseif (!pageInfo.getSession().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.session",
pageInfo.getSession(), value);
}
} elseif ("buffer".equals(attr)) { if (pageInfo.getBufferValue() == null) {
pageInfo.setBufferValue(value, n, err);
} elseif (!pageInfo.getBufferValue().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.buffer",
pageInfo.getBufferValue(), value);
}
} elseif ("autoFlush".equals(attr)) { if (pageInfo.getAutoFlush() == null) {
pageInfo.setAutoFlush(value, n, err);
} elseif (!pageInfo.getAutoFlush().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.autoflush",
pageInfo.getAutoFlush(), value);
}
} elseif ("isThreadSafe".equals(attr)) { if (pageInfo.getIsThreadSafe() == null) {
pageInfo.setIsThreadSafe(value, n, err);
} elseif (!pageInfo.getIsThreadSafe().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.isthreadsafe",
pageInfo.getIsThreadSafe(), value);
}
} elseif ("isELIgnored".equals(attr)) { if (pageInfo.getIsELIgnored() == null) {
pageInfo.setIsELIgnored(value, n, err, true);
} elseif (!pageInfo.getIsELIgnored().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.iselignored",
pageInfo.getIsELIgnored(), value);
}
} elseif ("errorOnELNotFound".equals(attr)) { if (pageInfo.getErrorOnELNotFound() == null) {
pageInfo.setErrorOnELNotFound(value, n, err, true);
} elseif (!pageInfo.getErrorOnELNotFound().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.errorOnELNotFound",
pageInfo.getErrorOnELNotFound(), value);
}
} elseif ("isErrorPage".equals(attr)) { if (pageInfo.getIsErrorPage() == null) {
pageInfo.setIsErrorPage(value, n, err);
} elseif (!pageInfo.getIsErrorPage().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.iserrorpage",
pageInfo.getIsErrorPage(), value);
}
} elseif ("errorPage".equals(attr)) { if (pageInfo.getErrorPage() == null) {
pageInfo.setErrorPage(value);
} elseif (!pageInfo.getErrorPage().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.errorpage",
pageInfo.getErrorPage(), value);
}
} elseif ("info".equals(attr)) { if (pageInfo.getInfo() == null) {
pageInfo.setInfo(value);
} elseif (!pageInfo.getInfo().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.info",
pageInfo.getInfo(), value);
}
} elseif ("pageEncoding".equals(attr)) { if (pageEncodingSeen) {
err.jspError(n, "jsp.error.page.multi.pageencoding");
} // 'pageEncoding' can occur at most once per file
pageEncodingSeen = true;
String actual = comparePageEncodings(value, n);
n.getRoot().setPageEncoding(actual);
} elseif ("deferredSyntaxAllowedAsLiteral".equals(attr)) { if (pageInfo.getDeferredSyntaxAllowedAsLiteral() == null) {
pageInfo.setDeferredSyntaxAllowedAsLiteral(value, n,
err, true);
} elseif (!pageInfo.getDeferredSyntaxAllowedAsLiteral()
.equals(value)) {
err
.jspError(
n, "jsp.error.page.conflict.deferredsyntaxallowedasliteral",
pageInfo
.getDeferredSyntaxAllowedAsLiteral(),
value);
}
} elseif ("trimDirectiveWhitespaces".equals(attr)) { if (pageInfo.getTrimDirectiveWhitespaces() == null) {
pageInfo.setTrimDirectiveWhitespaces(value, n, err, true);
} elseif (!pageInfo.getTrimDirectiveWhitespaces().equals(
value)) {
err
.jspError(
n, "jsp.error.page.conflict.trimdirectivewhitespaces",
pageInfo.getTrimDirectiveWhitespaces(),
value);
}
}
}
// Check for bad combinations if (pageInfo.getBuffer() == 0 && !pageInfo.isAutoFlush()) {
err.jspError(n, "jsp.error.page.badCombo");
}
// Attributes for imports for this node have been processed by // the parsers, just add them to pageInfo.
pageInfo.addImports(n.getImports());
}
@Override publicvoid visit(Node.TagDirective n) throws JasperException { // Note: Most of the validation is done in TagFileProcessor // when it created a TagInfo object from the // tag file in which the directive appeared.
// This method does additional processing to collect page info
Attributes attrs = n.getAttributes(); for (int i = 0; attrs != null && i < attrs.getLength(); i++) {
String attr = attrs.getQName(i);
String value = attrs.getValue(i);
if ("language".equals(attr)) { if (pageInfo.getLanguage(false) == null) {
pageInfo.setLanguage(value, n, err, false);
} elseif (!pageInfo.getLanguage(false).equals(value)) {
err.jspError(n, "jsp.error.tag.conflict.language",
pageInfo.getLanguage(false), value);
}
} elseif ("isELIgnored".equals(attr)) { if (pageInfo.getIsELIgnored() == null) {
pageInfo.setIsELIgnored(value, n, err, false);
} elseif (!pageInfo.getIsELIgnored().equals(value)) {
err.jspError(n, "jsp.error.tag.conflict.iselignored",
pageInfo.getIsELIgnored(), value);
}
} elseif ("errorOnELNotFound".equals(attr)) { if (pageInfo.getErrorOnELNotFound() == null) {
pageInfo.setErrorOnELNotFound(value, n, err, false);
} elseif (!pageInfo.getErrorOnELNotFound().equals(value)) {
err.jspError(n, "jsp.error.tag.conflict.errorOnELNotFound",
pageInfo.getErrorOnELNotFound(), value);
}
} elseif ("pageEncoding".equals(attr)) { if (pageEncodingSeen) {
err.jspError(n, "jsp.error.tag.multi.pageencoding");
}
pageEncodingSeen = true;
compareTagEncodings(value, n);
n.getRoot().setPageEncoding(value);
} elseif ("deferredSyntaxAllowedAsLiteral".equals(attr)) { if (pageInfo.getDeferredSyntaxAllowedAsLiteral() == null) {
pageInfo.setDeferredSyntaxAllowedAsLiteral(value, n,
err, false);
} elseif (!pageInfo.getDeferredSyntaxAllowedAsLiteral()
.equals(value)) {
err
.jspError(
n, "jsp.error.tag.conflict.deferredsyntaxallowedasliteral",
pageInfo
.getDeferredSyntaxAllowedAsLiteral(),
value);
}
} elseif ("trimDirectiveWhitespaces".equals(attr)) { if (pageInfo.getTrimDirectiveWhitespaces() == null) {
pageInfo.setTrimDirectiveWhitespaces(value, n, err, false);
} elseif (!pageInfo.getTrimDirectiveWhitespaces().equals(
value)) {
err
.jspError(
n, "jsp.error.tag.conflict.trimdirectivewhitespaces",
pageInfo.getTrimDirectiveWhitespaces(),
value);
}
}
}
// Attributes for imports for this node have been processed by // the parsers, just add them to pageInfo.
pageInfo.addImports(n.getImports());
}
@Override publicvoid visit(Node.AttributeDirective n) throws JasperException { // Do nothing, since this attribute directive has already been // validated by TagFileProcessor when it created a TagInfo object // from the tag file in which the directive appeared
}
@Override publicvoid visit(Node.VariableDirective n) throws JasperException { // Do nothing, since this variable directive has already been // validated by TagFileProcessor when it created a TagInfo object // from the tag file in which the directive appeared
}
// Pattern to extract a method name from a full method signature privatestaticfinal Pattern METHOD_NAME_PATTERN =
Pattern.compile(".*[ \t\n\r]+(.+?)[ \t\n\r]*\\(.*", Pattern.DOTALL);
privatefinal PageInfo pageInfo;
privatefinal ErrorDispatcher err;
privatefinal ClassLoader loader;
privatefinal StringBuilder buf = new StringBuilder(32);
privatestaticfinal JspUtil.ValidAttribute[] jspRootAttrs = { new JspUtil.ValidAttribute("xsi:schemaLocation"), new JspUtil.ValidAttribute("version", true) };
privatestaticfinal JspUtil.ValidAttribute[] includeDirectiveAttrs = { new JspUtil.ValidAttribute( "file", true) };
privatestaticfinal JspUtil.ValidAttribute[] taglibDirectiveAttrs = { new JspUtil.ValidAttribute("uri"), new JspUtil.ValidAttribute("tagdir"), new JspUtil.ValidAttribute("prefix", true) };
privatestaticfinal JspUtil.ValidAttribute[] includeActionAttrs = { new JspUtil.ValidAttribute("page", true), new JspUtil.ValidAttribute("flush") };
privatestaticfinal JspUtil.ValidAttribute[] paramActionAttrs = { new JspUtil.ValidAttribute("name", true), new JspUtil.ValidAttribute("value", true) };
privatestaticfinal JspUtil.ValidAttribute[] forwardActionAttrs = { new JspUtil.ValidAttribute("page", true) };
privatestaticfinal JspUtil.ValidAttribute[] getPropertyAttrs = { new JspUtil.ValidAttribute("name", true), new JspUtil.ValidAttribute("property", true) };
privatestaticfinal JspUtil.ValidAttribute[] setPropertyAttrs = { new JspUtil.ValidAttribute("name", true), new JspUtil.ValidAttribute("property", true), new JspUtil.ValidAttribute("value", false), new JspUtil.ValidAttribute("param") };
privatestaticfinal JspUtil.ValidAttribute[] useBeanAttrs = { new JspUtil.ValidAttribute("id", true), new JspUtil.ValidAttribute("scope"), new JspUtil.ValidAttribute("class"), new JspUtil.ValidAttribute("type"), new JspUtil.ValidAttribute("beanName", false) };
privatestaticfinal JspUtil.ValidAttribute[] plugInAttrs = { new JspUtil.ValidAttribute("type", true), new JspUtil.ValidAttribute("code", true), new JspUtil.ValidAttribute("codebase"), new JspUtil.ValidAttribute("align"), new JspUtil.ValidAttribute("archive"), new JspUtil.ValidAttribute("height", false), new JspUtil.ValidAttribute("hspace"), new JspUtil.ValidAttribute("jreversion"), new JspUtil.ValidAttribute("name"), new JspUtil.ValidAttribute("vspace"), new JspUtil.ValidAttribute("width", false), new JspUtil.ValidAttribute("nspluginurl"), new JspUtil.ValidAttribute("iepluginurl") };
privatestaticfinal JspUtil.ValidAttribute[] attributeAttrs = { new JspUtil.ValidAttribute("name", true), new JspUtil.ValidAttribute("trim"), new JspUtil.ValidAttribute("omit")};
privatestaticfinal JspUtil.ValidAttribute[] invokeAttrs = { new JspUtil.ValidAttribute("fragment", true), new JspUtil.ValidAttribute("var"), new JspUtil.ValidAttribute("varReader"), new JspUtil.ValidAttribute("scope") };
privatestaticfinal JspUtil.ValidAttribute[] doBodyAttrs = { new JspUtil.ValidAttribute("var"), new JspUtil.ValidAttribute("varReader"), new JspUtil.ValidAttribute("scope") };
privatestaticfinal JspUtil.ValidAttribute[] jspOutputAttrs = { new JspUtil.ValidAttribute("omit-xml-declaration"), new JspUtil.ValidAttribute("doctype-root-element"), new JspUtil.ValidAttribute("doctype-public"), new JspUtil.ValidAttribute("doctype-system") };
privatefinal ExpressionFactory expressionFactory;
/* *Constructor
*/
ValidateVisitor(Compiler compiler) { this.pageInfo = compiler.getPageInfo(); this.err = compiler.getErrorDispatcher(); this.loader = compiler.getCompilationContext().getClassLoader(); // Get the cached EL expression factory for this context
expressionFactory =
JspFactory.getDefaultFactory().getJspApplicationContext(
compiler.getCompilationContext().getServletContext()).
getExpressionFactory();
}
@Override publicvoid visit(Node.TaglibDirective n) throws JasperException {
JspUtil.checkAttributes("Taglib directive", n,
taglibDirectiveAttrs, err); // Either 'uri' or 'tagdir' attribute must be specified
String uri = n.getAttributeValue("uri");
String tagdir = n.getAttributeValue("tagdir"); if (uri == null && tagdir == null) {
err.jspError(n, "jsp.error.taglibDirective.missing.location");
} if (uri != null && tagdir != null) {
err
.jspError(n, "jsp.error.taglibDirective.both_uri_and_tagdir");
}
}
@Override publicvoid visit(Node.ParamAction n) throws JasperException {
JspUtil.checkAttributes("Param action", n, paramActionAttrs, err); // make sure the value of the 'name' attribute is not a // request-time expression
throwErrorIfExpression(n, "name", "jsp:param");
n.setValue(getJspAttribute(null, "value", null, null, n
.getAttributeValue("value"), n, null, false));
visitBody(n);
}
@Override publicvoid visit(Node.ParamsAction n) throws JasperException { // Make sure we've got at least one nested jsp:param
Node.Nodes subElems = n.getBody(); if (subElems == null) {
err.jspError(n, "jsp.error.params.emptyBody");
}
visitBody(n);
}
@Override publicvoid visit(Node.IncludeAction n) throws JasperException {
JspUtil.checkAttributes("Include action", n, includeActionAttrs,
err);
n.setPage(getJspAttribute(null, "page", null, null, n
.getAttributeValue("page"), n, null, false));
visitBody(n);
}
@Override publicvoid visit(Node.ForwardAction n) throws JasperException {
JspUtil.checkAttributes("Forward", n, forwardActionAttrs, err);
n.setPage(getJspAttribute(null, "page", null, null, n
.getAttributeValue("page"), n, null, false));
visitBody(n);
}
@SuppressWarnings("null") // type can't be null after initial test
@Override publicvoid visit(Node.PlugIn n) throws JasperException {
JspUtil.checkAttributes("Plugin", n, plugInAttrs, err);
@Override publicvoid visit(Node.ELExpression n) throws JasperException { // exit if we are ignoring EL all together if (pageInfo.isELIgnored()) { return;
}
// JSP.2.2 - '#{' not allowed in template text if (n.getType() == '#') { if (!pageInfo.isDeferredSyntaxAllowedAsLiteral()) {
err.jspError(n, "jsp.error.el.template.deferred");
} else { return;
}
}
Attributes attrs = n.getAttributes(); if (attrs != null) { int attrSize = attrs.getLength();
Node.JspAttribute[] jspAttrs = new Node.JspAttribute[attrSize]; for (int i = 0; i < attrSize; i++) { // JSP.2.2 - '#{' not allowed in template text
String value = attrs.getValue(i); if (!pageInfo.isDeferredSyntaxAllowedAsLiteral()) { if (containsDeferredSyntax(value)) {
err.jspError(n, "jsp.error.el.template.deferred");
}
}
jspAttrs[i] = getJspAttribute(null, attrs.getQName(i),
attrs.getURI(i), attrs.getLocalName(i), value, n, null, false);
}
n.setJspAttributes(jspAttrs);
}
// JSP.C1: It is a (translation time) error for an action that // has one or more variable subelements to have a TagExtraInfo // class that returns a non-null object.
TagExtraInfo tei = tagInfo.getTagExtraInfo(); if (tei != null && tei.getVariableInfo(tagData) != null
&& tei.getVariableInfo(tagData).length > 0
&& tagInfo.getTagVariableInfos().length > 0) {
err.jspError("jsp.error.non_null_tei_and_var_subelems", n
.getQName());
}
Attributes attrs = n.getAttributes(); if (attrs == null) {
err.jspError(n, "jsp.error.jspelement.missing.name");
}
@SuppressWarnings("null") // Exception will have been thrown above int xmlAttrLen = attrs.getLength();
// XML-style 'name' attribute, which is mandatory, must not be // included in JspAttribute array int jspAttrSize = xmlAttrLen - 1 + namedAttrs.size();
Node.JspAttribute[] jspAttrs = new Node.JspAttribute[jspAttrSize]; int jspAttrIndex = 0;
// Process XML-style attributes for (int i = 0; i < xmlAttrLen; i++) { if ("name".equals(attrs.getLocalName(i))) {
n.setNameAttribute(getJspAttribute(null, attrs.getQName(i),
attrs.getURI(i), attrs.getLocalName(i), attrs
.getValue(i), n, null, false));
} else { if (jspAttrIndex < jspAttrSize) {
jspAttrs[jspAttrIndex++] = getJspAttribute(null,
attrs.getQName(i), attrs.getURI(i),
attrs.getLocalName(i), attrs.getValue(i), n, null, false);
}
}
} if (n.getNameAttribute() == null) {
err.jspError(n, "jsp.error.jspelement.missing.name");
}
// Process named attributes for (int i = 0; i < namedAttrs.size(); i++) {
Node.NamedAttribute na = (Node.NamedAttribute) namedAttrs
.getNode(i);
jspAttrs[jspAttrIndex++] = new Node.JspAttribute(na, null, false);
}
// When attribute is not an expression, // contains its textual value with \$ and \# escaping removed.
String textAttributeValue; if (!elExpression && el != null) { // Should be a single Text node
Iterator<ELNode> it = el.iterator(); if (it.hasNext()) {
textAttributeValue = ((ELNode.Text) it.next())
.getText();
} else {
textAttributeValue = "";
}
} else {
textAttributeValue = xmlAttributeValue;
} for (int j = 0; tldAttrs != null && j < tldAttrs.length; j++) { if (attrs.getLocalName(i).equals(tldAttrs[j].getName())
&& (attrs.getURI(i) == null
|| attrs.getURI(i).length() == 0 || attrs
.getURI(i).equals(n.getURI()))) {
String expectedType = null; if (tldAttr.isDeferredMethod()) { // The String literal must be castable to what is declared as type // for the attribute
String m = tldAttr.getMethodSignature(); if (m != null) {
m = m.trim(); int rti = m.indexOf(' '); if (rti > 0) {
expectedType = m.substring(0, rti).trim();
}
} else {
expectedType = "java.lang.Object";
} if ("void".equals(expectedType)) { // Can't specify a literal for a // deferred method with an expected type // of void - JSP.2.3.4
err.jspError(n, "jsp.error.literal_with_void",
tldAttr.getName());
}
} if (tldAttr.isDeferredValue()) { // The String literal must be castable to what is declared as type // for the attribute
expectedType = tldAttr.getExpectedTypeName();
} if (expectedType != null) { Class<?> expectedClass = String.class; try {
expectedClass = JspUtil.toClass(expectedType, loader);
} catch (ClassNotFoundException e) {
err.jspError
(n, "jsp.error.unknown_attribute_type",
tldAttr.getName(), expectedType);
} // Check casting - not possible for all types if (String.class.equals(expectedClass) ||
expectedClass == Long.TYPE ||
expectedClass == Double.TYPE ||
expectedClass == Byte.TYPE ||
expectedClass == Short.TYPE ||
expectedClass == Integer.TYPE ||
expectedClass == Float.TYPE ||
Number.class.isAssignableFrom(expectedClass) ||
Character.class.equals(expectedClass) ||
Character.TYPE == expectedClass || Boolean.class.equals(expectedClass) || Boolean.TYPE == expectedClass ||
expectedClass.isEnum()) { try {
expressionFactory.coerceToType(textAttributeValue, expectedClass);
} catch (Exception e) {
err.jspError
(n, "jsp.error.coerce_to_type",
tldAttr.getName(), expectedType, textAttributeValue);
}
}
}
if (deferred && !tldAttr.isDeferredMethod() && !tldAttr.isDeferredValue()) { // No deferred expressions allowed for this attribute
err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
tldAttr.getName());
} if (!deferred && !tldAttr.canBeRequestTime()) { // Only deferred expressions are allowed for this attribute
err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
tldAttr.getName());
}
// EL or Runtime expression
jspAttrs[i] = getJspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i),
attrs.getLocalName(i),
xmlAttributeValue, n, el, false);
}
} else { // Attribute does not accept any expressions. // Make sure its value does not contain any. if (expression) {
err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
tldAttr.getName());
}
jspAttrs[i] = new Node.JspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i),
attrs.getLocalName(i),
textAttributeValue, false, null, false);
} if (expression) {
tagDataAttrs.put(attrs.getQName(i),
TagData.REQUEST_TIME_VALUE);
} else {
tagDataAttrs.put(attrs.getQName(i),
textAttributeValue);
}
found = true; break;
}
} if (!found) { if (tagInfo.hasDynamicAttributes()) {
jspAttrs[i] = getJspAttribute(null, attrs.getQName(i),
attrs.getURI(i), attrs.getLocalName(i),
xmlAttributeValue, n, el, true);
} else {
err.jspError(n, "jsp.error.bad_attribute", attrs
.getQName(i), n.getLocalName());
}
}
}
}
/* *Makesurethegivencustomactiondoesnothaveanyinvalidnamed *attributes
*/ privatevoid checkNamedAttributes(Node.CustomTag n,
Node.JspAttribute[] jspAttrs, int start,
Map<String, Object> tagDataAttrs) throws JasperException {
// XXX Is it an error to see "%=foo%" in non-Xml page? // (We won't see "<%=foo%> in xml page because '<' is not a // valid attribute value in xml).
if (value != null) { if (n.getRoot().isXmlSyntax() && value.startsWith("%=")) {
result = new Node.JspAttribute(tai, qName, uri, localName,
value.substring(2, value.length() - 1), true, null,
dynamic);
} elseif (!n.getRoot().isXmlSyntax()
&& value.startsWith("<%=")) {
result = new Node.JspAttribute(tai, qName, uri, localName,
value.substring(3, value.length() - 2), true, null,
dynamic);
} else { if (!pageInfo.isELIgnored()) { // The attribute can contain expressions but is not a // scriptlet expression; thus, we want to run it through // the expression interpreter
// validate expression syntax if string contains // expression(s) if (el == null) {
el = ELParser.parse(value,
pageInfo.isDeferredSyntaxAllowedAsLiteral());
}
if (el.containsEL()) {
validateFunctions(el, n);
} else { // Get text with \$ and \# escaping removed. // Should be a single Text node
Iterator<ELNode> it = el.iterator(); if (it.hasNext()) {
value = ((ELNode.Text) it.next()).getText();
} else {
value = "";
}
el = null;
}
}
if (n instanceof Node.UninterpretedTag &&
n.getRoot().isXmlSyntax()) { // Attribute values of uninterpreted tags will have been // XML un-escaped during parsing. Since these attributes // are part of an uninterpreted tag the value needs to // be re-escaped before being included in the output. // The wrinkle is that the output of any EL must not be // re-escaped as that must be output as is. if (el != null) {
XmlEscapeNonELVisitor v = new XmlEscapeNonELVisitor(
pageInfo.isDeferredSyntaxAllowedAsLiteral());
el.visit(v);
value = v.getText();
} else {
value = Escape.xml(value);
}
}
result = new Node.JspAttribute(tai, qName, uri, localName,
value, false, el, dynamic);
if (el != null) {
ELContextImpl ctx = new ELContextImpl(expressionFactory);
ctx.setFunctionMapper(getFunctionMapper(el));
try {
result.validateEL(this.pageInfo
.getExpressionFactory(), ctx);
} catch (ELException e) { this.err.jspError(n.getStart(), "jsp.error.invalid.expression", value, e
.toString());
}
}
}
} else { // Value is null. Check for any NamedAttribute subnodes // that might contain the value for this attribute. // Otherwise, the attribute wasn't found so we return null.
Node.NamedAttribute namedAttributeNode = n
.getNamedAttributeNode(qName); if (namedAttributeNode != null) {
result = new Node.JspAttribute(namedAttributeNode, tai,
dynamic);
}
}
for (Node p = n; p != null; p = p.getParent()) {
Attributes attrs = p.getTaglibAttributes(); if (attrs == null) { continue;
} for (int i = 0; i < attrs.getLength(); i++) {
String name = attrs.getQName(i); int k = name.indexOf(':'); if (prefix == null && k < 0) { // prefix not specified and a default ns found return attrs.getValue(i);
} if (prefix != null && k >= 0
&& prefix.equals(name.substring(k + 1))) { return attrs.getValue(i);
}
}
} returnnull;
}
@Override publicvoid visit(ELNode.Function func) throws JasperException {
String prefix = func.getPrefix();
String function = func.getName();
String uri = null;
if (n.getRoot().isXmlSyntax()) {
uri = findUri(prefix, n);
} elseif (prefix != null) {
uri = pageInfo.getURI(prefix);
}
if (uri == null) { if (prefix == null) { // This can occur when lambda expressions define // functions and when functions are imported. No // longer able to be sure this is an error. return;
} else {
err.jspError(n, "jsp.error.attribute.invalidPrefix",
prefix);
}
}
TagLibraryInfo taglib = pageInfo.getTaglib(uri);
FunctionInfo funcInfo = null; if (taglib != null) {
funcInfo = taglib.getFunction(function);
} if (funcInfo == null) {
err.jspError(n, "jsp.error.noFunction", function);
} // Skip TLD function uniqueness check. Done by Schema ?
func.setUri(uri);
func.setFunctionInfo(funcInfo);
processSignature(func);
}
}
el.visit(new FVVisitor(n));
}
privatevoid prepareExpression(ELNode.Nodes el, Node n, String expr) throws JasperException {
validateFunctions(el, n);
// test it out
ELContextImpl ctx = new ELContextImpl(expressionFactory);
ctx.setFunctionMapper(this.getFunctionMapper(el));
ExpressionFactory ef = this.pageInfo.getExpressionFactory(); try {
ef.createValueExpression(ctx, expr, Object.class);
} catch (ELException e) { thrownew JasperException(e);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.