📄 generator.java
字号:
* <prefix:shortName> tag
*/
private Hashtable handlerInfos;
private Hashtable tagVarNumbers;
private String parent;
private boolean isSimpleTagParent; // Is parent a SimpleTag?
private String pushBodyCountVar;
private String simpleTagHandlerVar;
private boolean isSimpleTagHandler;
private boolean isFragment;
private boolean isTagFile;
private ServletWriter out;
private ArrayList methodsBuffered;
private FragmentHelperClass fragmentHelperClass;
private int methodNesting;
private TagInfo tagInfo;
private ClassLoader loader;
private int charArrayCount;
private HashMap textMap;
/**
* Constructor.
*/
public GenerateVisitor(
boolean isTagFile,
ServletWriter out,
ArrayList methodsBuffered,
FragmentHelperClass fragmentHelperClass,
ClassLoader loader,
TagInfo tagInfo) {
this.isTagFile = isTagFile;
this.out = out;
this.methodsBuffered = methodsBuffered;
this.fragmentHelperClass = fragmentHelperClass;
this.loader = loader;
this.tagInfo = tagInfo;
methodNesting = 0;
handlerInfos = new Hashtable();
tagVarNumbers = new Hashtable();
textMap = new HashMap();
}
/**
* Returns an attribute value, optionally URL encoded. If
* the value is a runtime expression, the result is the expression
* itself, as a string. If the result is an EL expression, we insert
* a call to the interpreter. If the result is a Named Attribute
* we insert the generated variable name. Otherwise the result is a
* string literal, quoted and escaped.
*
* @param attr An JspAttribute object
* @param encode true if to be URL encoded
* @param expectedType the expected type for an EL evaluation
* (ignored for attributes that aren't EL expressions)
*/
private String attributeValue(
Node.JspAttribute attr,
boolean encode,
Class expectedType) {
String v = attr.getValue();
if (!attr.isNamedAttribute() && (v == null))
return "";
if (attr.isExpression()) {
if (encode) {
return "org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode(String.valueOf("
+ v
+ "), request.getCharacterEncoding())";
}
return v;
} else if (attr.isELInterpreterInput()) {
boolean replaceESC = v.indexOf(Constants.ESC) > 0;
v =
JspUtil.interpreterCall(
this.isTagFile,
v,
expectedType,
attr.getEL().getMapName(),
false);
// XXX ESC replacement hack
if (replaceESC) {
v = "(" + v + ").replace(" + Constants.ESCStr + ", '$')";
}
if (encode) {
return "org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("
+ v
+ ", request.getCharacterEncoding())";
}
return v;
} else if (attr.isNamedAttribute()) {
return attr.getNamedAttributeNode().getTemporaryVariableName();
} else {
if (encode) {
return "org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("
+ quote(v)
+ ", request.getCharacterEncoding())";
}
return quote(v);
}
}
/**
* Prints the attribute value specified in the param action, in the
* form of name=value string.
*
* @param n the parent node for the param action nodes.
*/
private void printParams(Node n, String pageParam, boolean literal)
throws JasperException {
class ParamVisitor extends Node.Visitor {
String separator;
ParamVisitor(String separator) {
this.separator = separator;
}
public void visit(Node.ParamAction n) throws JasperException {
out.print(" + ");
out.print(separator);
out.print(" + ");
out.print(
"org.apache.jasper.runtime.JspRuntimeLibrary."
+ "URLEncode("
+ quote(n.getTextAttribute("name"))
+ ", request.getCharacterEncoding())");
out.print("+ \"=\" + ");
out.print(attributeValue(n.getValue(), true, String.class));
// The separator is '&' after the second use
separator = "\"&\"";
}
}
String sep;
if (literal) {
sep = pageParam.indexOf('?') > 0 ? "\"&\"" : "\"?\"";
} else {
sep = "((" + pageParam + ").indexOf('?')>0? '&': '?')";
}
if (n.getBody() != null) {
n.getBody().visit(new ParamVisitor(sep));
}
}
public void visit(Node.Expression n) throws JasperException {
n.setBeginJavaLine(out.getJavaLine());
out.printin("out.print(");
out.printMultiLn(n.getText());
out.println(");");
n.setEndJavaLine(out.getJavaLine());
}
public void visit(Node.Scriptlet n) throws JasperException {
n.setBeginJavaLine(out.getJavaLine());
out.printMultiLn(n.getText());
out.println();
n.setEndJavaLine(out.getJavaLine());
}
public void visit(Node.ELExpression n) throws JasperException {
n.setBeginJavaLine(out.getJavaLine());
if (!pageInfo.isELIgnored()) {
out.printil(
"out.write("
+ JspUtil.interpreterCall(
this.isTagFile,
"${" + new String(n.getText()) + "}",
String.class,
n.getEL().getMapName(),
false)
+ ");");
} else {
out.printil(
"out.write("
+ quote("${" + new String(n.getText()) + "}")
+ ");");
}
n.setEndJavaLine(out.getJavaLine());
}
public void visit(Node.IncludeAction n) throws JasperException {
String flush = n.getTextAttribute("flush");
Node.JspAttribute page = n.getPage();
boolean isFlush = false; // default to false;
if ("true".equals(flush))
isFlush = true;
n.setBeginJavaLine(out.getJavaLine());
String pageParam;
if (page.isNamedAttribute()) {
// If the page for jsp:include was specified via
// jsp:attribute, first generate code to evaluate
// that body.
pageParam =
generateNamedAttributeValue(page.getNamedAttributeNode());
} else {
pageParam = attributeValue(page, false, String.class);
}
// If any of the params have their values specified by
// jsp:attribute, prepare those values first.
Node jspBody = findJspBody(n);
if (jspBody != null) {
prepareParams(jspBody);
} else {
prepareParams(n);
}
out.printin(
"org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "
+ pageParam);
printParams(n, pageParam, page.isLiteral());
out.println(", out, " + isFlush + ");");
n.setEndJavaLine(out.getJavaLine());
}
/**
* Scans through all child nodes of the given parent for
* <param> subelements. For each <param> element, if its value
* is specified via a Named Attribute (<jsp:attribute>),
* generate the code to evaluate those bodies first.
* <p>
* If parent is null, simply returns.
*/
private void prepareParams(Node parent) throws JasperException {
if (parent == null)
return;
Node.Nodes subelements = parent.getBody();
if (subelements != null) {
for (int i = 0; i < subelements.size(); i++) {
Node n = subelements.getNode(i);
if (n instanceof Node.ParamAction) {
Node.Nodes paramSubElements = n.getBody();
for (int j = 0;
(paramSubElements != null)
&& (j < paramSubElements.size());
j++) {
Node m = paramSubElements.getNode(j);
if (m instanceof Node.NamedAttribute) {
generateNamedAttributeValue(
(Node.NamedAttribute)m);
}
}
}
}
}
}
/**
* Finds the <jsp:body> subelement of the given parent node.
* If not found, null is returned.
*/
private Node.JspBody findJspBody(Node parent) throws JasperException {
Node.JspBody result = null;
Node.Nodes subelements = parent.getBody();
for (int i = 0;
(subelements != null) && (i < subelements.size());
i++) {
Node n = subelements.getNode(i);
if (n instanceof Node.JspBody) {
result = (Node.JspBody)n;
break;
}
}
return result;
}
public void visit(Node.ForwardAction n) throws JasperException {
Node.JspAttribute page = n.getPage();
n.setBeginJavaLine(out.getJavaLine());
out.printil("if (true) {"); // So that javac won't complain about
out.pushIndent(); // codes after "return"
String pageParam;
if (page.isNamedAttribute()) {
// If the page for jsp:forward was specified via
// jsp:attribute, first generate code to evaluate
// that body.
pageParam =
generateNamedAttributeValue(page.getNamedAttributeNode());
} else {
pageParam = attributeValue(page, false, String.class);
}
// If any of the params have their values specified by
// jsp:attribute, prepare those values first.
Node jspBody = findJspBody(n);
if (jspBody != null) {
prepareParams(jspBody);
} else {
prepareParams(n);
}
out.printin("_jspx_page_context.forward(");
out.print(pageParam);
printParams(n, pageParam, page.isLiteral());
out.println(");");
if (isTagFile || isFragment) {
out.printil("throw new SkipPageException();");
} else {
out.printil((methodNesting > 0) ? "return true;" : "return;");
}
out.popIndent();
out.printil("}");
n.setEndJavaLine(out.getJavaLine());
// XXX Not sure if we can eliminate dead codes after this.
}
public void visit(Node.GetProperty n) throws JasperException {
String name = n.getTextAttribute("name");
String property = n.getTextAttribute("property");
n.setBeginJavaLine(out.getJavaLine());
if (beanInfo.checkVariable(name)) {
// Bean is defined using useBean, introspect at compile time
Class bean = beanInfo.getBeanType(name);
String beanName = JspUtil.getCanonicalName(bean);
java.lang.reflect.Method meth =
JspRuntimeLibrary.getReadMethod(bean, property);
String methodName = meth.getName();
out.printil(
"out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString("
+ "((("
+ beanName
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -