in velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Parse.java [139:324]
public boolean render(InternalContextAdapter context,
Writer writer, Node node)
throws IOException, ResourceNotFoundException, ParseErrorException,
MethodInvocationException
{
/*
* did we get an argument?
*/
if ( node.jjtGetNumChildren() == 0 )
{
throw new VelocityException("#" + getName() + "(): argument missing at " +
StringUtils.formatFileString(this), null, rsvc.getLogContext().getStackTrace());
}
/*
* does it have a value? If you have a null reference, then no.
*/
Object value = node.jjtGetChild(0).value( context );
if (value == null)
{
log.debug("#" + getName() + "(): null argument at {}", StringUtils.formatFileString(this));
}
/*
* get the path
*/
String sourcearg = value == null ? null : value.toString();
/*
* check to see if the argument will be changed by the event cartridge
*/
String arg = EventHandlerUtil.includeEvent( rsvc, context, sourcearg, context.getCurrentTemplateName(), getName());
/*
* if strict mode and arg was not fixed by event handler, then complain
*/
if (strictRef && value == null && arg == null)
{
throw new VelocityException("The argument to #" + getName() + " returned null at "
+ StringUtils.formatFileString(this), null, rsvc.getLogContext().getStackTrace());
}
/*
* a null return value from the event cartridge indicates we should not
* input a resource.
*/
if (arg == null)
{
// abort early, but still consider it a successful rendering
return true;
}
if (maxDepth > 0)
{
/*
* see if we have exceeded the configured depth.
*/
String[] templateStack = context.getTemplateNameStack();
if (templateStack.length >= maxDepth)
{
StringBuilder path = new StringBuilder();
for (String aTemplateStack : templateStack)
{
path.append(" > ").append(aTemplateStack);
}
log.error("Max recursion depth reached ({}). File stack: {}",
templateStack.length, path);
return false;
}
}
/*
* now use the Runtime resource loader to get the template
*/
Template t = null;
try
{
t = getTemplate(arg, getInputEncoding(context));
}
catch ( ResourceNotFoundException rnfe )
{
/*
* the arg wasn't found. Note it and throw
*/
log.error("#" + getName() + "(): cannot find template '{}', called at {}",
arg, StringUtils.formatFileString(this));
throw rnfe;
}
catch ( ParseErrorException pee )
{
/*
* the arg was found, but didn't parse - syntax error
* note it and throw
*/
log.error("#" + getName() + "(): syntax error in #" + getName() + "()-ed template '{}', called at {}",
arg, StringUtils.formatFileString(this));
throw pee;
}
/*
* pass through application level runtime exceptions
*/
catch( RuntimeException e )
{
log.error("Exception rendering #" + getName() + "({}) at {}",
arg, StringUtils.formatFileString(this));
throw e;
}
catch ( Exception e )
{
String msg = "Exception rendering #" + getName() + "(" + arg + ") at " +
StringUtils.formatFileString(this);
log.error(msg, e);
throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace());
}
/*
* Add the template name to the macro libraries list
*/
List<Template> macroLibraries = context.getMacroLibraries();
/*
* if macroLibraries are not set create a new one
*/
if (macroLibraries == null)
{
macroLibraries = new ArrayList<>();
}
context.setMacroLibraries(macroLibraries);
/* instead of adding the name of the template, add the Template reference */
macroLibraries.add(t);
/*
* and render it
*/
try
{
preRender(context);
context.pushCurrentTemplateName(arg);
((SimpleNode) t.getData()).render(context, writer);
}
catch( StopCommand stop )
{
if (!stop.isFor(this))
{
throw stop;
}
}
/*
* pass through application level runtime exceptions
*/
catch( RuntimeException e )
{
/*
* Log #parse errors so the user can track which file called which.
*/
log.error("Exception rendering #" + getName() + "({}) at {}",
arg, StringUtils.formatFileString(this));
throw e;
}
catch ( Exception e )
{
String msg = "Exception rendering #" + getName() + "(" + arg + ") at " +
StringUtils.formatFileString(this);
log.error(msg, e);
throw new VelocityException(msg, e, rsvc.getLogContext().getStackTrace());
}
finally
{
context.popCurrentTemplateName();
postRender(context);
}
/*
* note - a blocked input is still a successful operation as this is
* expected behavior.
*/
return true;
}