📄 validator.java
字号:
if (n.getAttributes() != null
&& n.getAttributes().getValue(attrName) != null
&& isExpression(n, n.getAttributes().getValue(attrName))) {
err.jspError(n,
"jsp.error.attribute.standard.non_rt_with_expr",
attrName, actionName);
}
}
private static class NamedAttributeVisitor extends Node.Visitor {
private boolean hasDynamicContent;
public void doVisit(Node n) throws JasperException {
if (!(n instanceof Node.JspText)
&& !(n instanceof Node.TemplateText)) {
hasDynamicContent = true;
}
visitBody(n);
}
public boolean hasDynamicContent() {
return hasDynamicContent;
}
}
private String findUri(String prefix, Node n) {
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);
}
}
}
return null;
}
/**
* Validate functions in EL expressions
*/
private void validateFunctions(ELNode.Nodes el, Node n)
throws JasperException {
class FVVisitor extends ELNode.Visitor {
Node n;
FVVisitor(Node n) {
this.n = n;
}
public void 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);
} else if (prefix != null) {
uri = pageInfo.getURI(prefix);
}
if (uri == null) {
if (prefix == null) {
err.jspError(n, "jsp.error.noFunctionPrefix",
function);
}
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));
}
private void processSignature(ELNode.Function func)
throws JasperException {
func.setMethodName(getMethod(func));
func.setParameters(getParameters(func));
}
/**
* Get the method name from the signature.
*/
private String getMethod(ELNode.Function func)
throws JasperException {
FunctionInfo funcInfo = func.getFunctionInfo();
String signature = funcInfo.getFunctionSignature();
int start = signature.indexOf(' ');
if (start < 0) {
err.jspError("jsp.error.tld.fn.invalid.signature",
func.getPrefix(), func.getName());
}
int end = signature.indexOf('(');
if (end < 0) {
err.jspError("jsp.error.tld.fn.invalid.signature.parenexpected",
func.getPrefix(), func.getName());
}
return signature.substring(start+1, end).trim();
}
/**
* Get the parameters types from the function signature.
* @return An array of parameter class names
*/
private String[] getParameters(ELNode.Function func)
throws JasperException {
FunctionInfo funcInfo = func.getFunctionInfo();
String signature = funcInfo.getFunctionSignature();
ArrayList params = new ArrayList();
// Signature is of the form
// <return-type> S <method-name S? '('
// < <arg-type> ( ',' <arg-type> )* )? ')'
int start = signature.indexOf('(') + 1;
boolean lastArg = false;
while (true) {
int p = signature.indexOf(',', start);
if (p < 0) {
p = signature.indexOf(')', start);
if (p < 0) {
err.jspError("jsp.error.tld.fn.invalid.signature",
func.getPrefix(), func.getName());
}
lastArg = true;
}
String arg = signature.substring(start, p).trim();
if (!"".equals(arg)) {
params.add(arg);
}
if (lastArg) {
break;
}
start = p+1;
}
return (String[]) params.toArray(new String[params.size()]);
}
private FunctionMapper getFunctionMapper(ELNode.Nodes el)
throws JasperException {
class ValidateFunctionMapper implements FunctionMapper {
private HashMap fnmap = new java.util.HashMap();
public void mapFunction(String fnQName, Method method) {
fnmap.put(fnQName, method);
}
public Method resolveFunction(String prefix,
String localName) {
return (Method) this.fnmap.get(prefix + ":" + localName);
}
}
class MapperELVisitor extends ELNode.Visitor {
ValidateFunctionMapper fmapper;
MapperELVisitor(ValidateFunctionMapper fmapper) {
this.fmapper = fmapper;
}
public void visit(ELNode.Function n) throws JasperException {
Class c = null;
Method method = null;
try {
c = loader.loadClass(
n.getFunctionInfo().getFunctionClass());
} catch (ClassNotFoundException e) {
err.jspError("jsp.error.function.classnotfound",
n.getFunctionInfo().getFunctionClass(),
n.getPrefix() + ':' + n.getName(),
e.getMessage());
}
String paramTypes[] = n.getParameters();
int size = paramTypes.length;
Class params[] = new Class[size];
int i = 0;
try {
for (i = 0; i < size; i++) {
params[i] = JspUtil.toClass(paramTypes[i], loader);
}
method = c.getDeclaredMethod(n.getMethodName(),
params);
} catch (ClassNotFoundException e) {
err.jspError("jsp.error.signature.classnotfound",
paramTypes[i],
n.getPrefix() + ':' + n.getName(),
e.getMessage());
} catch (NoSuchMethodException e ) {
err.jspError("jsp.error.noFunctionMethod",
n.getMethodName(), n.getName(),
c.getName());
}
fmapper.mapFunction(n.getPrefix() + ':' + n.getName(),
method);
}
}
ValidateFunctionMapper fmapper = new ValidateFunctionMapper();
el.visit(new MapperELVisitor(fmapper));
return fmapper;
}
} // End of ValidateVisitor
/**
* A visitor for validating TagExtraInfo classes of all tags
*/
static class TagExtraInfoVisitor extends Node.Visitor {
private PageInfo pageInfo;
private ErrorDispatcher err;
/*
* Constructor
*/
TagExtraInfoVisitor(Compiler compiler) {
this.pageInfo = compiler.getPageInfo();
this.err = compiler.getErrorDispatcher();
}
public void visit(Node.CustomTag n) throws JasperException {
TagInfo tagInfo = n.getTagInfo();
if (tagInfo == null) {
err.jspError(n, "jsp.error.missing.tagInfo", n.getQName());
}
ValidationMessage[] errors = tagInfo.validate(n.getTagData());
if (errors != null && errors.length != 0) {
StringBuffer errMsg = new StringBuffer();
errMsg.append("<h3>");
errMsg.append(Localizer.getMessage("jsp.error.tei.invalid.attributes",
n.getQName()));
errMsg.append("</h3>");
for (int i=0; i<errors.length; i++) {
errMsg.append("<p>");
if (errors[i].getId() != null) {
errMsg.append(errors[i].getId());
errMsg.append(": ");
}
errMsg.append(errors[i].getMessage());
errMsg.append("</p>");
}
err.jspError(n, errMsg.toString());
}
visitBody(n);
}
}
public static void validate(Compiler compiler,
Node.Nodes page) throws JasperException {
/*
* Visit the page/tag directives first, as they are global to the page
* and are position independent.
*/
page.visit(new DirectiveVisitor(compiler));
// Determine the default output content type
PageInfo pageInfo = compiler.getPageInfo();
String contentType = pageInfo.getContentType();
if (contentType == null || contentType.indexOf("charset=") < 0) {
boolean isXml = page.getRoot().isXmlSyntax();
String defaultType;
if (contentType == null) {
defaultType = isXml? "text/xml": "text/html";
} else {
defaultType = contentType;
}
String charset = null;
if (isXml) {
charset = "UTF-8";
} else {
if (!page.getRoot().isDefaultPageEncoding()) {
charset = page.getRoot().getPageEncoding();
}
}
if (charset != null) {
pageInfo.setContentType(defaultType + ";charset=" + charset);
} else {
pageInfo.setContentType(defaultType);
}
}
/*
* Validate all other nodes.
* This validation step includes checking a custom tag's mandatory and
* optional attributes against information in the TLD (first validation
* step for custom tags according to JSP.10.5).
*/
page.visit(new ValidateVisitor(compiler));
/*
* Invoke TagLibraryValidator classes of all imported tags
* (second validation step for custom tags according to JSP.10.5).
*/
validateXmlView(new PageDataImpl(page, compiler), compiler);
/*
* Invoke TagExtraInfo method isValid() for all imported tags
* (third validation step for custom tags according to JSP.10.5).
*/
page.visit(new TagExtraInfoVisitor(compiler));
}
//*********************************************************************
// Private (utility) methods
/**
* Validate XML view against the TagLibraryValidator classes of all
* imported tag libraries.
*/
private static void validateXmlView(PageData xmlView, Compiler compiler)
throws JasperException {
StringBuffer errMsg = null;
ErrorDispatcher errDisp = compiler.getErrorDispatcher();
for (Iterator iter=compiler.getPageInfo().getTaglibs().iterator();
iter.hasNext(); ) {
Object o = iter.next();
if (!(o instanceof TagLibraryInfoImpl))
continue;
TagLibraryInfoImpl tli = (TagLibraryInfoImpl) o;
ValidationMessage[] errors = tli.validate(xmlView);
if ((errors != null) && (errors.length != 0)) {
if (errMsg == null) {
errMsg = new StringBuffer();
}
errMsg.append("<h3>");
errMsg.append(Localizer.getMessage("jsp.error.tlv.invalid.page",
tli.getShortName(), compiler.getPageInfo().getJspFile()));
errMsg.append("</h3>");
for (int i=0; i<errors.length; i++) {
if (errors[i] != null) {
errMsg.append("<p>");
errMsg.append(errors[i].getId());
errMsg.append(": ");
errMsg.append(errors[i].getMessage());
errMsg.append("</p>");
}
}
}
}
if (errMsg != null) {
errDisp.jspError(errMsg.toString());
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -