in src/main/java/org/apache/sling/scripting/jsp/jasper/compiler/Generator.java [1190:1375]
public void visit(Node.UseBean n) throws JasperException {
String name = n.getTextAttribute("id");
String scope = n.getTextAttribute("scope");
String klass = n.getTextAttribute("class");
String type = n.getTextAttribute("type");
Node.JspAttribute beanName = n.getBeanName();
// If "class" is specified, try an instantiation at compile time
boolean generateNew = false;
String canonicalName = null; // Canonical name for klass
if (klass != null) {
try {
Class bean = ctxt.getClassLoader().loadClass(klass);
if (klass.indexOf('$') >= 0) {
// Obtain the canonical type name
canonicalName = JspUtil.getCanonicalName(bean);
} else {
canonicalName = klass;
}
int modifiers = bean.getModifiers();
if (!Modifier.isPublic(modifiers)
|| Modifier.isInterface(modifiers)
|| Modifier.isAbstract(modifiers)) {
throw new Exception("Invalid bean class modifier");
}
// Check that there is a 0 arg constructor
bean.getConstructor(new Class[] {});
// At compile time, we have determined that the bean class
// exists, with a public zero constructor, new() can be
// used for bean instantiation.
generateNew = true;
} catch (Exception e) {
// Cannot instantiate the specified class, either a
// compilation error or a runtime error will be raised,
// depending on a compiler flag.
if (ctxt.getOptions()
.getErrorOnUseBeanInvalidClassAttribute()) {
err.jspError(n, "jsp.error.invalid.bean", klass);
}
if (canonicalName == null) {
// Doing our best here to get a canonical name
// from the binary name, should work 99.99% of time.
canonicalName = klass.replace('$', '.');
}
}
if (type == null) {
// if type is unspecified, use "class" as type of bean
type = canonicalName;
}
}
String scopename = "PageContext.PAGE_SCOPE"; // Default to page
String lock = "_jspx_page_context";
if ("request".equals(scope)) {
scopename = "PageContext.REQUEST_SCOPE";
lock = "request";
} else if ("session".equals(scope)) {
scopename = "PageContext.SESSION_SCOPE";
lock = "session";
} else if ("application".equals(scope)) {
scopename = "PageContext.APPLICATION_SCOPE";
lock = "application";
}
n.setBeginJavaLine(out.getJavaLine());
// Declare bean
out.printin(type);
out.print(' ');
out.print(name);
out.println(" = null;");
// Lock while getting or creating bean
out.printin("synchronized (");
out.print(lock);
out.println(") {");
out.pushIndent();
// Locate bean from context
out.printin(name);
out.print(" = (");
out.print(type);
out.print(") _jspx_page_context.getAttribute(");
out.print(quote(name));
out.print(", ");
out.print(scopename);
out.println(");");
// Create bean
/*
* Check if bean is alredy there
*/
out.printin("if (");
out.print(name);
out.println(" == null){");
out.pushIndent();
if (klass == null && beanName == null) {
/*
* If both class name and beanName is not specified, the bean
* must be found locally, otherwise it's an error
*/
out
.printin("throw new java.lang.InstantiationException(\"bean ");
out.print(name);
out.println(" not found within scope\");");
} else {
/*
* Instantiate the bean if it is not in the specified scope.
*/
if (!generateNew) {
String binaryName;
if (beanName != null) {
if (beanName.isNamedAttribute()) {
// If the value for beanName was specified via
// jsp:attribute, first generate code to evaluate
// that body.
binaryName = generateNamedAttributeValue(beanName
.getNamedAttributeNode());
} else {
binaryName = attributeValue(beanName, false,
String.class);
}
} else {
// Implies klass is not null
binaryName = quote(klass);
}
out.printil("try {");
out.pushIndent();
out.printin(name);
out.print(" = (");
out.print(type);
out.print(") java.beans.Beans.instantiate(");
out.print("this.getClass().getClassLoader(), ");
out.print(binaryName);
out.println(");");
out.popIndent();
/*
* Note: Beans.instantiate throws ClassNotFoundException if
* the bean class is abstract.
*/
out.printil("} catch (ClassNotFoundException exc) {");
out.pushIndent();
out
.printil("throw new InstantiationException(exc.getMessage());");
out.popIndent();
out.printil("} catch (Exception exc) {");
out.pushIndent();
out.printin("throw new ServletException(");
out.print("\"Cannot create bean of class \" + ");
out.print(binaryName);
out.println(", exc);");
out.popIndent();
out.printil("}"); // close of try
} else {
// Implies klass is not null
// Generate codes to instantiate the bean class
out.printin(name);
out.print(" = new ");
out.print(canonicalName);
out.println("();");
}
/*
* Set attribute for bean in the specified scope
*/
out.printin("_jspx_page_context.setAttribute(");
out.print(quote(name));
out.print(", ");
out.print(name);
out.print(", ");
out.print(scopename);
out.println(");");
// Only visit the body when bean is instantiated
visitBody(n);
}
out.popIndent();
out.printil("}");
// End of lock block
out.popIndent();
out.printil("}");
n.setEndJavaLine(out.getJavaLine());
}