📄 tagfileprocessor.java
字号:
* name of the variable that is being aliased
*/
nameGiven = alias;
checkUniqueName(nameFromAttribute, VAR_NAME_FROM, n);
checkUniqueName(alias, VAR_ALIAS, n);
} else {
// name-given specified
checkUniqueName(nameGiven, VAR_NAME_GIVEN, n);
}
variableVector.addElement(new TagVariableInfo(nameGiven,
nameFromAttribute, className, declare, scope));
}
/*
* Returns the vector of attributes corresponding to attribute
* directives.
*/
public Vector getAttributesVector() {
return attributeVector;
}
/*
* Returns the vector of variables corresponding to variable directives.
*/
public Vector getVariablesVector() {
return variableVector;
}
/*
* Returns the value of the dynamic-attributes tag directive attribute.
*/
public String getDynamicAttributesMapName() {
return dynamicAttrsMapName;
}
public TagInfo getTagInfo() throws JasperException {
if (name == null) {
// XXX Get it from tag file name
}
if (bodycontent == null) {
bodycontent = TagInfo.BODY_CONTENT_SCRIPTLESS;
}
String tagClassName = JspUtil.getTagHandlerClassName(path, err);
TagVariableInfo[] tagVariableInfos = new TagVariableInfo[variableVector
.size()];
variableVector.copyInto(tagVariableInfos);
TagAttributeInfo[] tagAttributeInfo = new TagAttributeInfo[attributeVector
.size()];
attributeVector.copyInto(tagAttributeInfo);
return new JasperTagInfo(name, tagClassName, bodycontent,
description, tagLibInfo, tei, tagAttributeInfo,
displayName, smallIcon, largeIcon, tagVariableInfos,
dynamicAttrsMapName);
}
static class NameEntry {
private String type;
private Node node;
private TagAttributeInfo attr;
NameEntry(String type, Node node, TagAttributeInfo attr) {
this.type = type;
this.node = node;
this.attr = attr;
}
String getType() {
return type;
}
Node getNode() {
return node;
}
TagAttributeInfo getTagAttributeInfo() {
return attr;
}
}
/**
* Reports a translation error if names specified in attributes of
* directives are not unique in this translation unit.
*
* The value of the following attributes must be unique. 1. 'name'
* attribute of an attribute directive 2. 'name-given' attribute of a
* variable directive 3. 'alias' attribute of variable directive 4.
* 'dynamic-attributes' of a tag directive except that
* 'dynamic-attributes' can (and must) have the same value when it
* appears in multiple tag directives.
*
* Also, 'name-from' attribute of a variable directive cannot have the
* same value as that from another variable directive.
*/
private void checkUniqueName(String name, String type, Node n)
throws JasperException {
checkUniqueName(name, type, n, null);
}
private void checkUniqueName(String name, String type, Node n,
TagAttributeInfo attr) throws JasperException {
HashMap table = (type == VAR_NAME_FROM) ? nameFromTable : nameTable;
NameEntry nameEntry = (NameEntry) table.get(name);
if (nameEntry != null) {
if (type != TAG_DYNAMIC || nameEntry.getType() != TAG_DYNAMIC) {
int line = nameEntry.getNode().getStart().getLineNumber();
err.jspError(n, "jsp.error.tagfile.nameNotUnique", type,
nameEntry.getType(), Integer.toString(line));
}
} else {
table.put(name, new NameEntry(type, n, attr));
}
}
/**
* Perform miscellean checks after the nodes are visited.
*/
void postCheck() throws JasperException {
// Check that var.name-from-attributes has valid values.
Iterator iter = nameFromTable.keySet().iterator();
while (iter.hasNext()) {
String nameFrom = (String) iter.next();
NameEntry nameEntry = (NameEntry) nameTable.get(nameFrom);
NameEntry nameFromEntry = (NameEntry) nameFromTable
.get(nameFrom);
Node nameFromNode = nameFromEntry.getNode();
if (nameEntry == null) {
err.jspError(nameFromNode,
"jsp.error.tagfile.nameFrom.noAttribute", nameFrom);
} else {
Node node = nameEntry.getNode();
TagAttributeInfo tagAttr = nameEntry.getTagAttributeInfo();
if (!"java.lang.String".equals(tagAttr.getTypeName())
|| !tagAttr.isRequired()
|| tagAttr.canBeRequestTime()) {
err.jspError(nameFromNode,
"jsp.error.tagfile.nameFrom.badAttribute",
nameFrom, Integer.toString(node.getStart()
.getLineNumber()));
}
}
}
}
}
/**
* Parses the tag file, and collects information on the directives included
* in it. The method is used to obtain the info on the tag file, when the
* handler that it represents is referenced. The tag file is not compiled
* here.
*
* @param pc
* the current ParserController used in this compilation
* @param name
* the tag name as specified in the TLD
* @param tagfile
* the path for the tagfile
* @param tagLibInfo
* the TagLibraryInfo object associated with this TagInfo
* @return a TagInfo object assembled from the directives in the tag file.
*/
public static TagInfo parseTagFileDirectives(ParserController pc,
String name, String path, TagLibraryInfo tagLibInfo)
throws JasperException {
ErrorDispatcher err = pc.getCompiler().getErrorDispatcher();
Node.Nodes page = null;
try {
page = pc.parseTagFileDirectives(path);
} catch (FileNotFoundException e) {
err.jspError("jsp.error.file.not.found", path);
} catch (IOException e) {
err.jspError("jsp.error.file.not.found", path);
}
TagFileDirectiveVisitor tagFileVisitor = new TagFileDirectiveVisitor(pc
.getCompiler(), tagLibInfo, name, path);
page.visit(tagFileVisitor);
tagFileVisitor.postCheck();
return tagFileVisitor.getTagInfo();
}
/**
* Compiles and loads a tagfile.
*/
private Class loadTagFile(Compiler compiler, String tagFilePath,
TagInfo tagInfo, PageInfo parentPageInfo) throws JasperException {
JspCompilationContext ctxt = compiler.getCompilationContext();
JspRuntimeContext rctxt = ctxt.getRuntimeContext();
JspServletWrapper wrapper = (JspServletWrapper) rctxt
.getWrapper(tagFilePath);
synchronized (rctxt) {
if (wrapper == null) {
wrapper = new JspServletWrapper(ctxt.getServletContext(), ctxt
.getOptions(), tagFilePath, tagInfo, ctxt
.getRuntimeContext(), ctxt.getTagFileJarUrl(tagFilePath));
rctxt.addWrapper(tagFilePath, wrapper);
// Use same classloader and classpath for compiling tag files
wrapper.getJspEngineContext().setClassLoader(
(URLClassLoader) ctxt.getClassLoader());
wrapper.getJspEngineContext().setClassPath(ctxt.getClassPath());
} else {
// Make sure that JspCompilationContext gets the latest TagInfo
// for the tag file. TagInfo instance was created the last
// time the tag file was scanned for directives, and the tag
// file may have been modified since then.
wrapper.getJspEngineContext().setTagInfo(tagInfo);
}
Class tagClazz;
int tripCount = wrapper.incTripCount();
try {
if (tripCount > 0) {
// When tripCount is greater than zero, a circular
// dependency exists. The circularily dependant tag
// file is compiled in prototype mode, to avoid infinite
// recursion.
JspServletWrapper tempWrapper = new JspServletWrapper(ctxt
.getServletContext(), ctxt.getOptions(),
tagFilePath, tagInfo, ctxt.getRuntimeContext(),
ctxt.getTagFileJarUrl(tagFilePath));
tagClazz = tempWrapper.loadTagFilePrototype();
tempVector.add(tempWrapper.getJspEngineContext()
.getCompiler());
} else {
tagClazz = wrapper.loadTagFile();
}
} finally {
wrapper.decTripCount();
}
// Add the dependants for this tag file to its parent's
// dependant list. The only reliable dependency information
// can only be obtained from the tag instance.
try {
Object tagIns = tagClazz.newInstance();
if (tagIns instanceof JspSourceDependent) {
Iterator iter = ((List) ((JspSourceDependent) tagIns)
.getDependants()).iterator();
while (iter.hasNext()) {
parentPageInfo.addDependant((String) iter.next());
}
}
} catch (Exception e) {
// ignore errors
}
return tagClazz;
}
}
/*
* Visitor which scans the page and looks for tag handlers that are tag
* files, compiling (if necessary) and loading them.
*/
private class TagFileLoaderVisitor extends Node.Visitor {
private Compiler compiler;
private PageInfo pageInfo;
TagFileLoaderVisitor(Compiler compiler) {
this.compiler = compiler;
this.pageInfo = compiler.getPageInfo();
}
public void visit(Node.CustomTag n) throws JasperException {
TagFileInfo tagFileInfo = n.getTagFileInfo();
if (tagFileInfo != null) {
String tagFilePath = tagFileInfo.getPath();
JspCompilationContext ctxt = compiler.getCompilationContext();
if (ctxt.getTagFileJarUrl(tagFilePath) == null) {
// Omit tag file dependency info on jar files for now.
pageInfo.addDependant(tagFilePath);
}
Class c = loadTagFile(compiler, tagFilePath, n.getTagInfo(),
pageInfo);
n.setTagHandlerClass(c);
}
visitBody(n);
}
}
/**
* Implements a phase of the translation that compiles (if necessary) the
* tag files used in a JSP files. The directives in the tag files are
* assumed to have been proccessed and encapsulated as TagFileInfo in the
* CustomTag nodes.
*/
public void loadTagFiles(Compiler compiler, Node.Nodes page)
throws JasperException {
tempVector = new Vector();
page.visit(new TagFileLoaderVisitor(compiler));
}
/**
* Removed the java and class files for the tag prototype generated from the
* current compilation.
*
* @param classFileName
* If non-null, remove only the class file with with this name.
*/
public void removeProtoTypeFiles(String classFileName) {
Iterator iter = tempVector.iterator();
while (iter.hasNext()) {
Compiler c = (Compiler) iter.next();
if (classFileName == null) {
c.removeGeneratedClassFiles();
} else if (classFileName.equals(c.getCompilationContext()
.getClassFileName())) {
c.removeGeneratedClassFiles();
tempVector.remove(c);
return;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -