if (attrs.getLocalName(i).equals(tldAttrs[j].getName())
&& (attrs.getURI(i) == null
|| attrs.getURI(i).length() == 0 || attrs
.getURI(i).equals(n.getURI()))) {
TagAttributeInfo tldAttr = tldAttrs[j];
if (tldAttr.canBeRequestTime()
|| tldAttr.isDeferredMethod() || tldAttr.isDeferredValue()) { // JSP 2.1
if (!expression) {
String expectedType = null;
if (tldAttr.isDeferredMethod()) {
// The String literal must be castable to what is declared as type
// for the attribute
String m = tldAttr.getMethodSignature();
if (m != null) {
m = m.trim();
int rti = m.indexOf(' ');
if (rti > 0) {
expectedType = m.substring(0, rti).trim();
}
} else {
expectedType = "java.lang.Object";
}
if ("void".equals(expectedType)) {
// Can't specify a literal for a
// deferred method with an expected type
// of void - JSP.2.3.4
err.jspError(n,
"jsp.error.literal_with_void",
tldAttr.getName());
}
}
if (tldAttr.isDeferredValue()) {
// The String literal must be castable to what is declared as type
// for the attribute
expectedType = tldAttr.getExpectedTypeName();
}
if (expectedType != null) {
Class<?> expectedClass = String.class;
try {
expectedClass = JspUtil.toClass(expectedType, loader);
} catch (ClassNotFoundException e) {
err.jspError
(n, "jsp.error.unknown_attribute_type",
tldAttr.getName(), expectedType);
}
// Check casting - not possible for all types
if (String.class.equals(expectedClass) ||
expectedClass == Long.TYPE ||
expectedClass == Double.TYPE ||
expectedClass == Byte.TYPE ||
expectedClass == Short.TYPE ||
expectedClass == Integer.TYPE ||
expectedClass == Float.TYPE ||
Number.class.isAssignableFrom(expectedClass) ||
Character.class.equals(expectedClass) ||
Character.TYPE == expectedClass ||
Boolean.class.equals(expectedClass) ||
Boolean.TYPE == expectedClass ||
expectedClass.isEnum()) {
try {
expressionFactory.coerceToType(attrs.getValue(i), expectedClass);
} catch (Exception e) {
err.jspError
(n, "jsp.error.coerce_to_type",
tldAttr.getName(), expectedType, attrs.getValue(i));
}
}
}
jspAttrs[i] = new Node.JspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i), attrs
.getLocalName(i),
attrs.getValue(i), false, null, false);
} else {
if (deferred && !tldAttr.isDeferredMethod() && !tldAttr.isDeferredValue()) {
// No deferred expressions allowed for this attribute
err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
tldAttr.getName());
}
if (!deferred && !tldAttr.canBeRequestTime()) {
// Only deferred expressions are allowed for this attribute
err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
tldAttr.getName());
}
if (elExpression) {
// El expression
validateFunctions(el, n);
jspAttrs[i] = new Node.JspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i),
attrs.getLocalName(i),
attrs.getValue(i), false, el, false);
ELContextImpl ctx = new ELContextImpl(
expressionFactory);
ctx.setFunctionMapper(getFunctionMapper(el));
try {
jspAttrs[i].validateEL(this.pageInfo.getExpressionFactory(), ctx);
} catch (ELException e) {
this.err.jspError(n.getStart(),
"jsp.error.invalid.expression",
attrs.getValue(i), e.toString());
}
} else {
// Runtime expression
jspAttrs[i] = getJspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i),
attrs.getLocalName(i), attrs
.getValue(i), n, false);
}
}
} else {
// Attribute does not accept any expressions.
// Make sure its value does not contain any.
if (expression) {
err.jspError(n, "jsp.error.attribute.custom.non_rt_with_expr",
tldAttr.getName());
}
jspAttrs[i] = new Node.JspAttribute(tldAttr,
attrs.getQName(i), attrs.getURI(i), attrs
.getLocalName(i),
attrs.getValue(i), false, null, false);