if (!locationArg.startsWith("/")) {
String base = ResourceUtil.getResourceBase(req);
locationArg = base + "/" + locationArg;
}
Template template = configuration.getTemplate(locationArg, deduceLocale());
TemplateModel model = createModel();
// Give subclasses a chance to hook into preprocessing
if (preTemplateProcess(template, model)) {
try {
// Process the template
Writer writer = getWriter();
if (isWriteIfCompleted() || configuration.getTemplateExceptionHandler() == TemplateExceptionHandler.RETHROW_HANDLER) {
CharArrayWriter parentCharArrayWriter = (CharArrayWriter) req.getAttribute(PARENT_TEMPLATE_WRITER);
boolean isTopTemplate = false;
if (isTopTemplate = (parentCharArrayWriter == null)) {
//this is the top template
parentCharArrayWriter = new CharArrayWriter();
//set it in the request because when the "action" tag is used a new VS and ActionContext is created
req.setAttribute(PARENT_TEMPLATE_WRITER, parentCharArrayWriter);
}
try {
template.process(model, parentCharArrayWriter);
if (isTopTemplate) {
parentCharArrayWriter.flush();
parentCharArrayWriter.writeTo(writer);
}
} catch (TemplateException e) {
if (LOG.isErrorEnabled()) {
LOG.error("Error processing Freemarker result!", e);
}
throw e;
} catch (IOException e) {
if (LOG.isErrorEnabled()){
LOG.error("Error processing Freemarker result!", e);
}
throw e;
} finally {
if (isTopTemplate && parentCharArrayWriter != null) {
req.removeAttribute(PARENT_TEMPLATE_WRITER);
parentCharArrayWriter.close();
}
}
} else {
template.process(model, writer);
}
} finally {
// Give subclasses a chance to hook into postprocessing
postTemplateProcess(template, model);
}