|
What this is
Other links
The source code
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed 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.Enumeration;
import java.util.Hashtable;
import java.util.Stack;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.TagAttributeInfo;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagInfo;
import javax.servlet.jsp.tagext.TagLibraryInfo;
import javax.servlet.jsp.tagext.VariableInfo;
import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspCompilationContext;
/**
* Custom tag support.
*
* @author Anil K. Vijendran
*/
public class TagBeginGenerator
extends TagGeneratorBase
implements ServiceMethodPhase
{
String prefix;
String shortTagName;
Hashtable attrs;
TagLibraryInfo tli;
TagInfo ti;
TagAttributeInfo[] attributes;
String baseVarName, thVarName;
TagCache tc;
TagData tagData;
Mark start;
TagLibraries libraries;
public TagBeginGenerator(Mark start, String prefix, String shortTagName, Hashtable attrs,
TagLibraryInfo tli, TagInfo ti, TagLibraries libraries,
Stack tagHandlerStack, Hashtable tagVarNumbers)
throws JasperException
{
setTagHandlerStack(tagHandlerStack);
setTagVarNumbers(tagVarNumbers);
this.prefix = prefix;
this.shortTagName = shortTagName;
this.attrs = attrs;
this.tli = tli;
this.ti = ti;
this.attributes = ti.getAttributes();
this.baseVarName = getTagVarName(prefix, shortTagName);
this.thVarName = "_jspx_th_"+baseVarName;
this.start = start;
this.libraries = libraries;
}
public void init(JspCompilationContext ctxt) throws JasperException {
validate();
tc = libraries.getTagCache(prefix, shortTagName);
if (tc == null) {
tc = new TagCache(shortTagName);
ClassLoader cl = ctxt.getClassLoader();
Class clz = null;
try {
clz = cl.loadClass(ti.getTagClassName());
} catch (Exception ex) {
throw new CompileException(start,
Constants.getString("jsp.error.unable.loadclass",
new Object[] { ti.getTagClassName(),
ex.getMessage()
}
));
}
tc.setTagHandlerClass(clz);
libraries.putTagCache(prefix, shortTagName, tc);
}
}
void validate() throws JasperException {
// Sigh! I wish I didn't have to clone here.
Hashtable attribs = (Hashtable) attrs.clone();
// First make sure all required attributes are indeed present.
for(int i = 0; i < attributes.length; i++)
if (attributes[i].isRequired() && attribs.get(attributes[i].getName()) == null)
throw new CompileException(start,
Constants.getString("jsp.error.missing_attribute",
new Object[] {
attributes[i].getName(),
shortTagName
}
));
// Now make sure there are no invalid attributes...
Enumeration e = attribs.keys();
while (e.hasMoreElements()) {
String attr = (String) e.nextElement();
boolean found = false;
for(int i = 0; i < attributes.length; i++)
if (attr.equals(attributes[i].getName())) {
found = true;
if (attributes[i].canBeRequestTime() &&
JspUtil.isExpression((String)attribs.get(attr)))
attribs.put(attr, TagData.REQUEST_TIME_VALUE);
}
if (!found)
throw new CompileException(start,
Constants.getString("jsp.error.bad_attribute",
new Object[] {
attr
}
));
}
tagData = new TagData(attribs);
if (!ti.isValid(tagData))
throw new CompileException(start,
Constants.getString("jsp.error.invalid_attributes"));
}
private final void generateSetters(ServletWriter writer, String parent)
throws JasperException
{
writer.println(thVarName+".setPageContext(pageContext);");
writer.println(thVarName+".setParent("+parent+");");
if (attributes.length != 0)
for(int i = 0; i < attributes.length; i++) {
String attrValue = (String) attrs.get(attributes[i].getName());
if (attrValue != null) {
String attrName = attributes[i].getName();
Method m = tc.getSetterMethod(attrName);
if (m == null)
throw new CompileException
(start, Constants.getString
("jsp.error.unable.to_find_method",
new Object[] { attrName }));
Class c[] = m.getParameterTypes();
// assert(c.length > 0)
if (attributes[i].canBeRequestTime()) {
if (JspUtil.isExpression(attrValue))
attrValue = JspUtil.getExpr(attrValue);
else
attrValue = convertString(c[0], attrValue, writer, attrName);
} else
attrValue = convertString(c[0], attrValue, writer, attrName);
writer.println(thVarName+"."+m.getName()+"("+attrValue+");");
}
}
}
public String convertString(Class c, String s, ServletWriter writer, String attrName)
throws JasperException
{
if (c == String.class) {
return writer.quoteString(s);
} else if (c == boolean.class) {
return Boolean.valueOf(s).toString();
} else if (c == Boolean.class) {
return "new Boolean(" + Boolean.valueOf(s).toString() + ")";
} else if (c == byte.class) {
return "((byte)" + Byte.valueOf(s).toString() + ")";
} else if (c == Byte.class) {
return "new Byte((byte)" + Byte.valueOf(s).toString() + ")";
} else if (c == char.class) {
// non-normative, because a normative method would fail to compile
if (s.length() > 1) {
char ch = s.charAt(0);
// this trick avoids escaping issues
return "((char) " + (int) ch + ")";
} else {
throw new NumberFormatException(Constants.getString(
"jsp.error.bad_string_char",
new Object[0]));
}
} else if (c == Character.class) {
// non-normative, because a normative method would fail to compile
if (s.length() > 1) {
char ch = s.charAt(0);
// this trick avoids escaping issues
return "new Character((char) " + (int) ch + ")";
} else {
throw new NumberFormatException(Constants.getString(
"jsp.error.bad_string_Character",
new Object[0]));
}
} else if (c == double.class) {
return Double.valueOf(s).toString();
} else if (c == Double.class) {
return "new Double(" + Double.valueOf(s).toString() + ")";
} else if (c == float.class) {
return Float.valueOf(s).toString() + "f";
} else if (c == Float.class) {
return "new Float(" + Float.valueOf(s).toString() + "f)";
} else if (c == int.class) {
return Integer.valueOf(s).toString();
} else if (c == Integer.class) {
return "new Integer(" + Integer.valueOf(s).toString() + ")";
} else if (c == long.class) {
return Long.valueOf(s).toString() + "l";
} else if (c == Long.class) {
return "new Long(" + Long.valueOf(s).toString() + "l)";
} else {
throw new CompileException
(start, Constants.getString
("jsp.error.unable.to_convert_string",
new Object[] { c.getName(), attrName }));
}
}
public void generateServiceMethodStatements(ServletWriter writer)
throws JasperException
{
TagVariableData top = topTag();
String parent = top == null ? null : top.tagHandlerInstanceName;
String evalVar = "_jspx_eval_"+baseVarName;
TagVariableData tvd = new TagVariableData(thVarName, evalVar);
String exceptionCheckName = tvd.tagExceptionCheckName;
tagBegin(tvd);
writer.println("/* ---- "+prefix+":"+shortTagName+" ---- */");
writer.println(ti.getTagClassName() + " " + thVarName + " = null;");
// set the exception check variable to false by default.
// it will be set to true if an exception is caught.
writer.println("boolean " + exceptionCheckName + " = false;");
VariableInfo[] vi = ti.getVariableInfo(tagData);
// Just declare AT_BEGIN here...
declareVariables(writer, vi, true, false, VariableInfo.AT_BEGIN);
// this first try is for tag cleanup
writer.println("try {");
writer.pushIndent();
writer.println("try {");
writer.pushIndent();
String poolName = TagPoolGenerator.getPoolVariableName(tli, ti, attrs);
writer.println("if (" + poolName + " != null) {");
writer.pushIndent();
writer.println(thVarName + " = (" + ti.getTagClassName() + ") " + poolName + ".getHandler();");
writer.popIndent();
writer.println("}");
writer.println("if (" + thVarName + " == null) {");
writer.pushIndent();
writer.println(thVarName + " = new " + ti.getTagClassName() + "();");
writer.popIndent();
writer.println("}");
generateSetters(writer, parent);
writer.println("int "+evalVar+" = "
+thVarName+".doStartTag();");
boolean implementsBodyTag = BodyTag.class.isAssignableFrom(tc.getTagHandlerClass());
// Need to update AT_BEGIN variables here
declareVariables(writer, vi, false, true, VariableInfo.AT_BEGIN);
// FIXME: I'm not too sure if this is the right approach. I don't like
// throwing English language strings into the generated servlet.
// Perhaps, I'll just define an inner classes as necessary for these
// types of exceptions? -akv
if (implementsBodyTag) {
writer.println("if ("+evalVar+" == javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE)");
writer.pushIndent();
writer.println("throw new JspTagException(\"Since tag handler "+tc.getTagHandlerClass()+
" implements BodyTag, it can't return Tag.EVAL_BODY_INCLUDE\");");
writer.popIndent();
} else {
writer.println("if ("+evalVar+" == javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_TAG)");
writer.pushIndent();
writer.println("throw new JspTagException(\"Since tag handler "+tc.getTagHandlerClass()+
" does not implement BodyTag, it can't return BodyTag.EVAL_BODY_TAG\");");
writer.popIndent();
}
writer.println("if ("+evalVar+" != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {");
writer.pushIndent();
if (implementsBodyTag) {
writer.println("try {");
writer.pushIndent();
writer.println("if ("+evalVar+" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) {");
writer.pushIndent();
writer.println("out = pageContext.pushBody();");
writer.println(thVarName+".setBodyContent((javax.servlet.jsp.tagext.BodyContent) out);");
writer.popIndent();
writer.println("}");
writer.println(thVarName+".doInitBody();");
}
writer.println("do {");
writer.pushIndent();
// Need to declare and update NESTED variables here
declareVariables(writer, vi, true, true, VariableInfo.NESTED);
// Need to update AT_BEGIN variables here
declareVariables(writer, vi, false, true, VariableInfo.AT_BEGIN);
}
public void generate(ServletWriter writer, Class phase)
throws JasperException
{
generateServiceMethodStatements(writer);
}
}
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.