📄 validator.java
字号:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jasper.compiler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import javax.el.ELException;
import javax.el.ExpressionFactory;
import javax.el.FunctionMapper;
import javax.servlet.jsp.tagext.FunctionInfo;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.PageData;
import javax.servlet.jsp.tagext.TagAttributeInfo;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtraInfo;
import javax.servlet.jsp.tagext.TagInfo;
import javax.servlet.jsp.tagext.TagLibraryInfo;
import javax.servlet.jsp.tagext.ValidationMessage;
import org.apache.el.lang.ELSupport;
import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
import org.apache.jasper.el.ELContextImpl;
import org.xml.sax.Attributes;
/**
* Performs validation on the page elements. Attributes are checked for
* mandatory presence, entry value validity, and consistency. As a side effect,
* some page global value (such as those from page direcitves) are stored, for
* later use.
*
* @author Kin-man Chung
* @author Jan Luehe
* @author Shawn Bayern
* @author Mark Roth
*/
class Validator {
/**
* A visitor to validate and extract page directive info
*/
static class DirectiveVisitor extends Node.Visitor {
private PageInfo pageInfo;
private ErrorDispatcher err;
private static final 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("deferredSyntaxAllowedAsLiteral"),
new JspUtil.ValidAttribute("trimDirectiveWhitespaces")
};
private boolean pageEncodingSeen = false;
/*
* Constructor
*/
DirectiveVisitor(Compiler compiler) throws JasperException {
this.pageInfo = compiler.getPageInfo();
this.err = compiler.getErrorDispatcher();
}
public void 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;
}
public void visit(Node.PageDirective n) throws JasperException {
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);
} else if (!pageInfo.getLanguage(false).equals(value)) {
err.jspError(n, "jsp.error.page.conflict.language",
pageInfo.getLanguage(false), value);
}
} else if ("extends".equals(attr)) {
if (pageInfo.getExtends(false) == null) {
pageInfo.setExtends(value, n);
} else if (!pageInfo.getExtends(false).equals(value)) {
err.jspError(n, "jsp.error.page.conflict.extends",
pageInfo.getExtends(false), value);
}
} else if ("contentType".equals(attr)) {
if (pageInfo.getContentType() == null) {
pageInfo.setContentType(value);
} else if (!pageInfo.getContentType().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.contenttype",
pageInfo.getContentType(), value);
}
} else if ("session".equals(attr)) {
if (pageInfo.getSession() == null) {
pageInfo.setSession(value, n, err);
} else if (!pageInfo.getSession().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.session",
pageInfo.getSession(), value);
}
} else if ("buffer".equals(attr)) {
if (pageInfo.getBufferValue() == null) {
pageInfo.setBufferValue(value, n, err);
} else if (!pageInfo.getBufferValue().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.buffer",
pageInfo.getBufferValue(), value);
}
} else if ("autoFlush".equals(attr)) {
if (pageInfo.getAutoFlush() == null) {
pageInfo.setAutoFlush(value, n, err);
} else if (!pageInfo.getAutoFlush().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.autoflush",
pageInfo.getAutoFlush(), value);
}
} else if ("isThreadSafe".equals(attr)) {
if (pageInfo.getIsThreadSafe() == null) {
pageInfo.setIsThreadSafe(value, n, err);
} else if (!pageInfo.getIsThreadSafe().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.isthreadsafe",
pageInfo.getIsThreadSafe(), value);
}
} else if ("isELIgnored".equals(attr)) {
if (pageInfo.getIsELIgnored() == null) {
pageInfo.setIsELIgnored(value, n, err, true);
} else if (!pageInfo.getIsELIgnored().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.iselignored",
pageInfo.getIsELIgnored(), value);
}
} else if ("isErrorPage".equals(attr)) {
if (pageInfo.getIsErrorPage() == null) {
pageInfo.setIsErrorPage(value, n, err);
} else if (!pageInfo.getIsErrorPage().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.iserrorpage",
pageInfo.getIsErrorPage(), value);
}
} else if ("errorPage".equals(attr)) {
if (pageInfo.getErrorPage() == null) {
pageInfo.setErrorPage(value);
} else if (!pageInfo.getErrorPage().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.errorpage",
pageInfo.getErrorPage(), value);
}
} else if ("info".equals(attr)) {
if (pageInfo.getInfo() == null) {
pageInfo.setInfo(value);
} else if (!pageInfo.getInfo().equals(value)) {
err.jspError(n, "jsp.error.page.conflict.info",
pageInfo.getInfo(), value);
}
} else if ("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);
} else if ("deferredSyntaxAllowedAsLiteral".equals(attr)) {
if (pageInfo.getDeferredSyntaxAllowedAsLiteral() == null) {
pageInfo.setDeferredSyntaxAllowedAsLiteral(value, n,
err, true);
} else if (!pageInfo.getDeferredSyntaxAllowedAsLiteral()
.equals(value)) {
err
.jspError(
n,
"jsp.error.page.conflict.deferredsyntaxallowedasliteral",
pageInfo
.getDeferredSyntaxAllowedAsLiteral(),
value);
}
} else if ("trimDirectiveWhitespaces".equals(attr)) {
if (pageInfo.getTrimDirectiveWhitespaces() == null) {
pageInfo.setTrimDirectiveWhitespaces(value, n, err,
true);
} else if (!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());
}
public void 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);
} else if (!pageInfo.getLanguage(false).equals(value)) {
err.jspError(n, "jsp.error.tag.conflict.language",
pageInfo.getLanguage(false), value);
}
} else if ("isELIgnored".equals(attr)) {
if (pageInfo.getIsELIgnored() == null) {
pageInfo.setIsELIgnored(value, n, err, false);
} else if (!pageInfo.getIsELIgnored().equals(value)) {
err.jspError(n, "jsp.error.tag.conflict.iselignored",
pageInfo.getIsELIgnored(), value);
}
} else if ("pageEncoding".equals(attr)) {
if (pageEncodingSeen)
err.jspError(n, "jsp.error.tag.multi.pageencoding");
pageEncodingSeen = true;
compareTagEncodings(value, n);
n.getRoot().setPageEncoding(value);
} else if ("deferredSyntaxAllowedAsLiteral".equals(attr)) {
if (pageInfo.getDeferredSyntaxAllowedAsLiteral() == null) {
pageInfo.setDeferredSyntaxAllowedAsLiteral(value, n,
err, false);
} else if (!pageInfo.getDeferredSyntaxAllowedAsLiteral()
.equals(value)) {
err
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -